diff --git a/artel/Dockerfile.local b/artel/Dockerfile.local index e42726d..deccf97 100644 --- a/artel/Dockerfile.local +++ b/artel/Dockerfile.local @@ -23,7 +23,9 @@ RUN apt-get update --yes --quiet && apt-get install --yes --quiet --no-install-r # Install the project requirements. COPY requirements.txt / +COPY requirements_dev.txt / RUN pip install -r /requirements.txt +RUN pip install -r /requirements_dev.txt # Use /app folder as a directory where the source code is stored. WORKDIR /app diff --git a/artel/artel/static/images/icons/trash.svg b/artel/artel/static/images/icons/trash.svg new file mode 100644 index 0000000..4d0ee36 --- /dev/null +++ b/artel/artel/static/images/icons/trash.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/artel/artel/templates/base.html b/artel/artel/templates/base.html index 4ad7ce8..168e650 100644 --- a/artel/artel/templates/base.html +++ b/artel/artel/templates/base.html @@ -51,7 +51,7 @@ - + {% block extra_js %} {# Override this in templates to add extra javascript #} {% endblock %} diff --git a/artel/docker-compose.yml b/artel/docker-compose.yml index 7c7d896..8f4da6c 100644 --- a/artel/docker-compose.yml +++ b/artel/docker-compose.yml @@ -13,6 +13,8 @@ services: - DATABASE_URL env_file: - .env + stdin_open: true + tty: true db: image: postgres restart: always diff --git a/artel/requirements_dev.txt b/artel/requirements_dev.txt index 54eda76..bcc4fae 100644 --- a/artel/requirements_dev.txt +++ b/artel/requirements_dev.txt @@ -2,3 +2,4 @@ FLAKE8>=6.0.0 pre-commit>=3.3.1 isort>=5.12 black>=23.3.0 +ipdb==0.12.3 diff --git a/artel/store/cart.py b/artel/store/cart.py index f35f788..f46b728 100644 --- a/artel/store/cart.py +++ b/artel/store/cart.py @@ -51,9 +51,9 @@ class SessionCart(BaseCart): self.validate_item_id(item_id) quantity = int(quantity) item_id = int(item_id) - - if not self.session[settings.CART_SESSION_ID].get(item_id): + if not self.session[settings.CART_SESSION_ID].get(str(item_id)): self.session[settings.CART_SESSION_ID][item_id] = quantity + self.session.modified = True else: self.update_item_quantity(item_id, quantity) @@ -61,6 +61,7 @@ class SessionCart(BaseCart): self.validate_item_id(item_id) try: self.session[settings.CART_SESSION_ID].pop(item_id) + self.session.modified = True except KeyError: # TODO - add logging ... @@ -68,7 +69,8 @@ class SessionCart(BaseCart): def update_item_quantity(self, item_id: int, change: int) -> None: self.validate_item_id(item_id) try: - self.session[settings.CART_SESSION_ID][item_id] += change + self.session[settings.CART_SESSION_ID][str(item_id)] += change + self.session.modified = True except KeyError: # TODO - add logging self.add_item(item_id, change) diff --git a/artel/store/serializers.py b/artel/store/serializers.py index 65268e9..584bb49 100644 --- a/artel/store/serializers.py +++ b/artel/store/serializers.py @@ -28,10 +28,10 @@ class CartProductAddSerializer(serializers.Serializer): def validate_product_id(self, value): try: - self.product = Product.obejcts.get(id=value) - except Product.objects.DoesNotExist: + Product.objects.get(id=value) + except Product.DoesNotExist: raise serializers.ValidationError("Unable to add not existing product") return value def save(self, cart): - cart.add_item(self.product, self.validated_data["quantity"]) + cart.add_item(self.validated_data["product_id"], self.validated_data["quantity"]) diff --git a/artel/store/static/js/cart.js b/artel/store/static/js/cart.js index d86432a..228a2ab 100644 --- a/artel/store/static/js/cart.js +++ b/artel/store/static/js/cart.js @@ -4,10 +4,11 @@ $(document).on('click', '.add-to-cart-button', function(event) { event.preventDefault(); const button = $(this); const formData = new FormData(); - const productID = $(this).data('product-id'); - const quantity = $('#quantity'+productID).val(); + const productID = parseInt($(this).data('product-id')); + const quantity = parseInt($('#quantity'+productID).val()); const addToCartURL = $(this).data('add-to-cart-url'); const csrfToken = $(this).data('csrf-token'); + console.log(productID); formData.append('product_id', productID); formData.append('quantity', quantity); // Serialize the form data correctly button.prop('disabled', true); @@ -107,15 +108,16 @@ $(document).on('click', '.add-to-cart-button', function(event) { const button = $(this); const productId = button.data('product-id'); const csrfToken = button.data('csrf-token'); - + const url = button.data('remove-from-cart-url'); $.ajax({ - type: 'DELETE', - url: '/cart/item/' + parseInt(productId) + '/', + type: 'POST', + url: url, + data: {"product_id": productId}, headers: { 'X-CSRFToken': csrfToken }, dataType: 'json', success: function(data) { - alert(data.message); - fetchCartItems(csrfToken); + alert("Item has been removed"); + location.reload(); }, error: function() { alert("Error occurred while removing the item from the cart."); diff --git a/artel/store/templates/store/cart.html b/artel/store/templates/store/cart.html index b2ea3e3..175d7d2 100644 --- a/artel/store/templates/store/cart.html +++ b/artel/store/templates/store/cart.html @@ -1,7 +1,5 @@ {% extends 'base.html' %} {% load static %} - - {% block content %} diff --git a/artel/store/templates/store/partials/cart_item.html b/artel/store/templates/store/partials/cart_item.html index 5edaa1b..0e563f7 100644 --- a/artel/store/templates/store/partials/cart_item.html +++ b/artel/store/templates/store/partials/cart_item.html @@ -1,3 +1,5 @@ +{% load static %} + @@ -27,7 +29,12 @@ {{item.product.price}} ZŁ - + + + diff --git a/artel/store/templates/store/partials/product_card.html b/artel/store/templates/store/partials/product_card.html index 4e08d75..515cfff 100644 --- a/artel/store/templates/store/partials/product_card.html +++ b/artel/store/templates/store/partials/product_card.html @@ -1,6 +1,4 @@ -{% load static %} - - +{% load static %} {{item.title}} @@ -13,8 +11,10 @@ + data-product-id="{{item.id}}" + data-csrf-token="{{csrf_token}}" + data-add-to-cart-url={% url "cart-action-add-product" %} + > diff --git a/artel/store/templates/store/product_list_page.html b/artel/store/templates/store/product_list_page.html index bde7a29..dd22dff 100644 --- a/artel/store/templates/store/product_list_page.html +++ b/artel/store/templates/store/product_list_page.html @@ -1,6 +1,5 @@ {% extends 'base.html'%} {% load static %} - {% block content %} diff --git a/artel/store/views.py b/artel/store/views.py index c11f3c7..58ed41f 100644 --- a/artel/store/views.py +++ b/artel/store/views.py @@ -34,19 +34,27 @@ class CartActionView(ViewSet): # get cart items cart = SessionCart(self.request) items = cart.get_items() - serialzier = CartProductSerializer(instance=items, many=True) - return Response(serialzier.data) + serializer = CartProductSerializer(instance=items, many=True) + return Response(serializer.data) @action(detail=False, methods=["post"]) def add_product(self, request): cart = SessionCart(self.request) serializer = CartProductAddSerializer(data=request.POST) - if serializer.is_valid(): + if not serializer.is_valid(): return Response(serializer.errors, status=400) serializer.save(cart) items = cart.get_items() - serialzier = CartProductSerializer(instance=items, many=True) - return Response(serialzier.data, status=201) + serializer = CartProductSerializer(instance=items, many=True) + return Response(serializer.data, status=201) - # TODO - same for remove product + @action(detail=False, methods=["post"]) + def remove_product(self, request): + cart = SessionCart(self.request) + product_id = request.POST.get("product_id") + cart.remove_item(product_id) + + items = cart.get_items() + serializer = CartProductSerializer(instance=items, many=True) + return Response(serializer.data, status=201)