aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Lemon <y@yulqen.org>2024-10-20 16:42:21 +0100
committerMatthew Lemon <y@yulqen.org>2024-10-20 16:42:21 +0100
commitfce28f5be8ba8831eed5ccf482fa2abf5432ee89 (patch)
tree3f0260c44accb04fa46f1e493bed466fff31c871
parent791cf758caaf25a9375005bdd7f699e614729823 (diff)
Cart shows items in it; disables buttons if item in basket
- Rough cart icon in navbar - Shows items in cart - Styled dependent on existence - Add to cart buttons disabled if resource in cart, on resource list page and detail page - Throws 404 error if trying add item to cart which has no price - eventually all items will have a price
-rw-r--r--alphabetlearning/payments/tests/test_views.py2
-rw-r--r--alphabetlearning/payments/views.py9
-rw-r--r--alphabetlearning/resources/views.py13
-rw-r--r--alphabetlearning/static/css/custom.css18
-rw-r--r--alphabetlearning/static/scss/custom.scss24
-rw-r--r--alphabetlearning/templates/base.html29
-rw-r--r--alphabetlearning/templates/resources/resource_card_featured.html15
-rw-r--r--alphabetlearning/templates/resources/resource_card_standard.html18
-rw-r--r--alphabetlearning/templates/resources/resource_detail.html19
9 files changed, 131 insertions, 16 deletions
diff --git a/alphabetlearning/payments/tests/test_views.py b/alphabetlearning/payments/tests/test_views.py
index 7d0f8b5..3289c12 100644
--- a/alphabetlearning/payments/tests/test_views.py
+++ b/alphabetlearning/payments/tests/test_views.py
@@ -13,7 +13,7 @@ def test_cart_view(client, user):
@pytest.mark.django_db
def test_add_resource_to_cart(client, resource, user):
- url = reverse("payments:add_to_cart", kwargs={"resource_id": resource.id})
+ url = reverse("payments:add_to_basket", kwargs={"resource_id": resource.id})
client.force_login(user)
response = client.get(url)
assert response.status_code == 200
diff --git a/alphabetlearning/payments/views.py b/alphabetlearning/payments/views.py
index d32542b..95eb5c8 100644
--- a/alphabetlearning/payments/views.py
+++ b/alphabetlearning/payments/views.py
@@ -1,5 +1,5 @@
import stripe
-from django.http import HttpResponse
+from django.http import HttpResponse, HttpResponseBadRequest
from django.core.mail import send_mail
from django.conf import settings
from django.contrib.auth.decorators import login_required
@@ -21,9 +21,11 @@ from .models import ShoppingCart
# TODO get the cart integrated with Stripe
# Steps to convert our Cart into something that can be used with Stripe:
#
+# - Fix the total in the cart
# - X Sort out the webhook
# - Associate the purchases with the users profile page
# - We need a profile page!
+# - Link in navbar (when logged in)
# - Fix the email and make it nice
# - Associate each of our resources with a Product item
# - this should be done in the create resource page
@@ -94,7 +96,10 @@ def add_to_cart(request, resource_id):
def cart_detail(request):
cart, created = ShoppingCart.objects.get_or_create(user=request.user)
resources = [i.resource for i in cart.items.all()]
- total = sum([r.price_obj.first().price for r in resources])
+ try:
+ total = sum([r.price_obj.first().price for r in resources])
+ except AttributeError:
+ return HttpResponseBadRequest(f"There is no price assigned to at least one of the resources you have added to the basket. Please contact Alphabet Learning Support.")
context = {
"cart": cart,
"resources": resources,
diff --git a/alphabetlearning/resources/views.py b/alphabetlearning/resources/views.py
index 3bf3d22..c09ff78 100644
--- a/alphabetlearning/resources/views.py
+++ b/alphabetlearning/resources/views.py
@@ -128,6 +128,15 @@ def index(request):
resource_list = [_extract_metadata_from_resource(r) for r in resource_objs]
+ for r in resource_list:
+ # TODO test for this existing - it will fail if no cart
+ try:
+ cart_items = request.user.shoppingcart.items.all()
+ if r.name in [r.resource.name for r in cart_items]:
+ r.in_cart = True
+ except:
+ pass
+
# Create a separate queryset for Featured resources
featured_resources = [r for r in resource_list if r.feature_slot]
featured_resources = sorted(featured_resources, key=lambda resource: resource.feature_slot)
@@ -313,6 +322,10 @@ def resource_detail(request, resource_id):
"created": resource_metadata.created,
"updated": resource_metadata.updated,
}
+ # TODO test for this existing - it will fail if no cart
+ cart_items = request.user.shoppingcart.items.all()
+ if resource["name"] in [r.resource.name for r in cart_items]:
+ resource.update(in_cart=True)
return render(request, "resources/resource_detail.html", {"resource": resource})
diff --git a/alphabetlearning/static/css/custom.css b/alphabetlearning/static/css/custom.css
index 42833bd..802b9b5 100644
--- a/alphabetlearning/static/css/custom.css
+++ b/alphabetlearning/static/css/custom.css
@@ -2312,6 +2312,24 @@ progress {
color: red;
}
+.gray-icon svg path {
+ fill: #808080; /* Adjust this hex value to any desired shade of gray */
+}
+
+.empty-basket-button {
+ background-color: lightgray;
+ border: none;
+ padding: 8px;
+ display: flex;
+}
+
+.full-basket-button {
+ background-color: lightgreen;
+ border: none;
+ padding: 8px;
+ display: flex;
+}
+
.alert {
--bs-alert-bg: transparent;
--bs-alert-padding-x: 1rem;
diff --git a/alphabetlearning/static/scss/custom.scss b/alphabetlearning/static/scss/custom.scss
index b65db4c..789e00d 100644
--- a/alphabetlearning/static/scss/custom.scss
+++ b/alphabetlearning/static/scss/custom.scss
@@ -93,6 +93,30 @@ $ml-font-label-weight: 500;
.asteriskField {
color: red;
}
+
+// for the SVG icons
+.gray-icon {
+ svg {
+ path {
+ fill: #808080; /* Adjust this hex value to any desired shade of gray */
+ }
+ }
+}
+
+.empty-basket-button {
+ background-color: lightgray;
+ border: none;
+ padding: 8px;
+ display: flex;
+}
+
+.full-basket-button {
+ background-color: lightgreen;
+ border: none;
+ padding: 8px;
+ display: flex;
+}
+
// 6. Add additional Bootstrap components as needed
@import "alert";
@import "card";
diff --git a/alphabetlearning/templates/base.html b/alphabetlearning/templates/base.html
index faadcd5..1bb67d4 100644
--- a/alphabetlearning/templates/base.html
+++ b/alphabetlearning/templates/base.html
@@ -109,6 +109,35 @@
<a class="nav-link text-gray fw-bold" href="{% url "account_logout" %}">Log out</a>
{% endif %}
</li>
+ <li class="nav-item">
+
+ {% if request.user.shoppingcart %}
+
+ <div class="mx-2 gray-icon">
+ <a href="{% url "payments:cart_detail" %}" class="full-basket-button">
+ <span class="fw-bold px-1">
+ Items in cart (
+ {{ request.user.shoppingcart.items.count }}
+ )
+ </span>
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" class="bi bi-bag" viewBox="0 0 16 16">
+ <path d="M8 1a2.5 2.5 0 0 1 2.5 2.5V4h-5v-.5A2.5 2.5 0 0 1 8 1m3.5 3v-.5a3.5 3.5 0 1 0-7 0V4H1v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V4zM2 5h12v9a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1z"/>
+ </svg>
+ </a>
+ </div>
+
+ {% else %}
+
+ <div class="mx-2 gray-icon">
+ <button class="empty-basket-button"><span class="fw-bold px-1">Empty Basket</span>
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" class="bi bi-bag-x" viewBox="0 0 16 16">
+ <path fill-rule="evenodd" d="M6.146 8.146a.5.5 0 0 1 .708 0L8 9.293l1.146-1.147a.5.5 0 1 1 .708.708L8.707 10l1.147 1.146a.5.5 0 0 1-.708.708L8 10.707l-1.146 1.147a.5.5 0 0 1-.708-.708L7.293 10 6.146 8.854a.5.5 0 0 1 0-.708"/>
+ <path d="M8 1a2.5 2.5 0 0 1 2.5 2.5V4h-5v-.5A2.5 2.5 0 0 1 8 1m3.5 3v-.5a3.5 3.5 0 1 0-7 0V4H1v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V4zM2 5h12v9a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1z"/>
+ </svg>
+ </button>
+ </div>
+ {% endif %}
+ </li>
</ul>
</div>
</div>
diff --git a/alphabetlearning/templates/resources/resource_card_featured.html b/alphabetlearning/templates/resources/resource_card_featured.html
index c83ac0f..0782b0c 100644
--- a/alphabetlearning/templates/resources/resource_card_featured.html
+++ b/alphabetlearning/templates/resources/resource_card_featured.html
@@ -32,10 +32,17 @@
{% endif %}
<div class="d-flex flex-row justify-content-between align-items-end mt-2">
<p class="card-text m-1"><small class="text-muted">1 credit</small></p>
- <form action="{% url 'payments:add_to_basket' resource.id %}" method="POST">
- {% csrf_token %}
- <button type="submit" class="btn btn-success fs-6 px-2 py-0">Add to basket</button>
- </form>
+ {% if resource.in_cart %}
+ <form action="{% url 'payments:add_to_basket' resource.id %}" method="POST">
+ {% csrf_token %}
+ <button type="submit" class="btn btn-success fs-6 px-2 py-0" disabled>In basket</button>
+ </form>
+ {% else %}
+ <form action="{% url 'payments:add_to_basket' resource.id %}" method="POST">
+ {% csrf_token %}
+ <button type="submit" class="btn btn-success fs-6 px-2 py-0">Add to basket</button>
+ </form>
+ {% endif %}
</div>
</div>
diff --git a/alphabetlearning/templates/resources/resource_card_standard.html b/alphabetlearning/templates/resources/resource_card_standard.html
index 9850117..640f75d 100644
--- a/alphabetlearning/templates/resources/resource_card_standard.html
+++ b/alphabetlearning/templates/resources/resource_card_standard.html
@@ -37,10 +37,20 @@
</div>
<div class="d-flex flex-row justify-content-between align-items-end mt-2">
<p class="card-text m-1"><small class="text-muted">1 credit</small></p>
- <form action="{% url 'payments:add_to_basket' resource.id %}" method="POST">
- {% csrf_token %}
- <button type="submit" class="btn btn-success fs-6 px-2 py-0">Add to basket</button>
- </form>
+
+ {% if resource.in_cart %}
+ <form action="{% url 'payments:add_to_basket' resource.id %}" method="POST">
+ {% csrf_token %}
+ <button type="submit" class="btn btn-success fs-6 px-2 py-0" disabled>In basket</button>
+ </form>
+ {% else %}
+ <form action="{% url 'payments:add_to_basket' resource.id %}" method="POST">
+ {% csrf_token %}
+ <button type="submit" class="btn btn-success fs-6 px-2 py-0">Add to basket</button>
+ </form>
+ {% endif %}
+
+
</div>
</div>
</div>
diff --git a/alphabetlearning/templates/resources/resource_detail.html b/alphabetlearning/templates/resources/resource_detail.html
index 6c6ceda..b92ba52 100644
--- a/alphabetlearning/templates/resources/resource_detail.html
+++ b/alphabetlearning/templates/resources/resource_detail.html
@@ -48,11 +48,20 @@
</div>
<div class="row align-items-end">
<div class="my-4 d-flex justify-content-center">
- <form action="{% url 'payments:add_to_cart' resource.id %}" method="get" accept-charset="utf-8">
- <button class="btn btn-primary w-100">
- Add to cart
- </button>
- </form>
+ {% if resource.in_cart %}
+ <form action="{% url 'payments:add_to_basket' resource.id %}" method="get" accept-charset="utf-8">
+ <button class="btn btn-primary w-100" disabled>
+ In basket
+ </button>
+ </form>
+ {% else %}
+ <form action="{% url 'payments:add_to_basket' resource.id %}" method="get" accept-charset="utf-8">
+ <button class="btn btn-primary w-100">
+ Add to basket
+ </button>
+ </form>
+
+ {% endif %}
</div>
</div>
</div>