diff --git a/src/App.tsx b/src/App.tsx index 19593e4..5a45181 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -24,6 +24,7 @@ import CategoriesPage from './pages/CategoriesPage'; import ResetPassword from './pages/ResetPassword'; import NewPassword from './pages/NewPassword'; import { ProductDetail } from './pages/product/ProductDetail'; +import Cart from './components/cart/Cart'; const App = () => { const { data, error, isLoading } = useGetProductsQuery(); @@ -70,6 +71,10 @@ const App = () => { path: 'auth/success/:token', element: , }, + { + path: 'shoppingcart', + element: + }, { path: 'categories/:categoryId', element: , diff --git a/src/components/cart/Cart.tsx b/src/components/cart/Cart.tsx new file mode 100644 index 0000000..f5028a1 --- /dev/null +++ b/src/components/cart/Cart.tsx @@ -0,0 +1,63 @@ +import React, { useEffect, useState } from "react" +import Navbar from "../navbar/Navbar" +import CartItem from "./CartItem" +import { useGetCartsQuery } from "../../services/cartApi" + +const Cart: React.FC = () => { + const { data: carts, isLoading, isSuccess, isError, error } = useGetCartsQuery() + const [totalPrice, setTotalPrice] = useState(0) + const [items, setItems] = useState(0) + + useEffect(() => { + if (isSuccess && carts) { + // Calculate total price + const calculatedTotalPrice = carts.cartProducts.reduce((total, cart) => { + const pricePerItem = cart.sizes[0]?.price || 0; + const itemTotalPrice = pricePerItem * cart.quantity; + return total + itemTotalPrice; + }, 0); + + // Update total price state + setTotalPrice(calculatedTotalPrice); + + // Optionally calculate the number of items if needed + const totalItems = carts.cartProducts.length; + setItems(totalItems); + } + }, [isSuccess, carts]); + + let content; + if (isLoading) { + content =
Loading
+ } else if (isSuccess) { + console.log(carts) + const renderedCart = carts.cartProducts.map((cart, index) => ( + < CartItem key={index} {...cart} /> + )) + content = renderedCart + } else if (isError) { + content =
{error.toString()}
+ } + return ( +
+ +
+

Shopping Cart ({items})

+

Your cart contains {items} items and comes to a total of $210

+
+
+
+ Total: + ${totalPrice} +
+ +
+
+ {content} +
+
+
+
+ ) +} +export default Cart diff --git a/src/components/cart/CartItem.tsx b/src/components/cart/CartItem.tsx new file mode 100644 index 0000000..8a110fb --- /dev/null +++ b/src/components/cart/CartItem.tsx @@ -0,0 +1,75 @@ +import React, { useEffect, useState } from 'react' +import { useUpdateCartMutation } from '../../services/cartApi' +interface CartItem { + id: string, + name: string, + image: string, + price: number, + sizes: [], + quantity: number +} +const CartItem: React.FC = ({ id, name, image, sizes, quantity }) => { + const [itemTotalPrice, setItemTotalPrice] = useState(sizes[0].price * quantity) + const [updateCart] = useUpdateCartMutation() + const currentPrice = sizes[0].price; + + useEffect(() => { + setItemTotalPrice(currentPrice * quantity); + }, [quantity, currentPrice]); + + const addQty = (quantity, productId, sizeId) => { + const newQuantity = quantity + 1; + updateCart({ id, updatedCart: { productId, quantity: newQuantity, sizeId } }) + } + const removeQty = (quantity, productId, sizeId) => { + const newQuantity = quantity - 1; + if (newQuantity > 0) { + updateCart({ id, updatedCart: { productId, quantity: newQuantity, sizeId } }) + } + } + return ( + <> +
+
+ +
+
+
+

{name}

+ ${itemTotalPrice} +
+
+
+
+ +
+ {sizes[0].size !== null ? sizes[0].size : 'One'} +
+
+
+ +
+ + + +
+
+
+ + +
+
+
+
+
+ + ) +} +export default CartItem diff --git a/src/services/cartApi.ts b/src/services/cartApi.ts index cfbded3..6c5add9 100644 --- a/src/services/cartApi.ts +++ b/src/services/cartApi.ts @@ -1,17 +1,48 @@ -import { mavericksApi } from '.'; -import { ICart } from '../utils/schemas'; +import { mavericksApi } from "."; +import { Cart } from "../types/Types"; -export const cartApi = mavericksApi.injectEndpoints({ +const cartsApi = mavericksApi.injectEndpoints({ endpoints: builder => ({ - addProductToCart: builder.mutation({ - query: (cart: ICart) => ({ - url: 'cart', - method: 'POST', - body: cart, + getCarts: builder.query({ + query: () => '/cart', + providesTags: ["Carts"] + }), + updateCart: builder.mutation({ + query: ({ id, updatedCart }) => ({ + url: `/cart/${id}`, + method: 'PATCH', + body: updatedCart }), + invalidatesTags: ["Carts"], + // async onQueryStarted({ id, updatedCart }, { dispatch, queryFulfilled }) { + // const patchResult = dispatch( + // mavericksApi.util.updateQueryData('getCarts', undefined, draft => { + // console.log(draft) + // const cart = draft.find(cart => cart.id === id) + // if (cart) { + // const size = cart.sizes.find(size => size.id === updatedCart.sizeId) + // if (size) { + // cart.quantity = updatedCart.quantity; + // size.price = updatedCart.price + // } + // } + // }) + // ); + // try { + // await queryFulfilled + // } catch (error) { + // patchResult.undo() + // } + // } }), - }), - overrideExisting: false, -}); + deleteCart: builder.mutation({ + query: (cartId) => ({ + url: `/cart/${cartId}`, + method: 'DELETE' + }), + invalidatesTags: ["Carts"] + }) + }) +}) -export const { useAddProductToCartMutation } = cartApi; +export const { useGetCartsQuery, useDeleteCartMutation, useUpdateCartMutation } = cartsApi \ No newline at end of file