diff options
author | Matthew Lemon <y@yulqen.org> | 2024-10-20 16:42:21 +0100 |
---|---|---|
committer | Matthew Lemon <y@yulqen.org> | 2024-10-20 16:42:21 +0100 |
commit | fce28f5be8ba8831eed5ccf482fa2abf5432ee89 (patch) | |
tree | 3f0260c44accb04fa46f1e493bed466fff31c871 | |
parent | 791cf758caaf25a9375005bdd7f699e614729823 (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.py | 2 | ||||
-rw-r--r-- | alphabetlearning/payments/views.py | 9 | ||||
-rw-r--r-- | alphabetlearning/resources/views.py | 13 | ||||
-rw-r--r-- | alphabetlearning/static/css/custom.css | 18 | ||||
-rw-r--r-- | alphabetlearning/static/scss/custom.scss | 24 | ||||
-rw-r--r-- | alphabetlearning/templates/base.html | 29 | ||||
-rw-r--r-- | alphabetlearning/templates/resources/resource_card_featured.html | 15 | ||||
-rw-r--r-- | alphabetlearning/templates/resources/resource_card_standard.html | 18 | ||||
-rw-r--r-- | alphabetlearning/templates/resources/resource_detail.html | 19 |
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> |