-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) => { | ||
Check failure on line 14 in src/components/cart/Cart.tsx GitHub Actions / Build (20)
Check failure on line 14 in src/components/cart/Cart.tsx GitHub Actions / Build (20)
Check failure on line 14 in src/components/cart/Cart.tsx GitHub Actions / Build (20)
Check failure on line 14 in src/components/cart/Cart.tsx GitHub Actions / Build (20)
Check failure on line 14 in src/components/cart/Cart.tsx GitHub Actions / Build (20)
|
||
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; | ||
Check failure on line 24 in src/components/cart/Cart.tsx GitHub Actions / Build (20)
|
||
setItems(totalItems); | ||
} | ||
}, [isSuccess, carts]); | ||
|
||
let content; | ||
if (isLoading) { | ||
content = <div>Loading</div> | ||
} else if (isSuccess) { | ||
console.log(carts) | ||
const renderedCart = carts.cartProducts.map((cart, index) => ( | ||
Check failure on line 34 in src/components/cart/Cart.tsx GitHub Actions / Build (20)
Check failure on line 34 in src/components/cart/Cart.tsx GitHub Actions / Build (20)
Check failure on line 34 in src/components/cart/Cart.tsx GitHub Actions / Build (20)
Check failure on line 34 in src/components/cart/Cart.tsx GitHub Actions / Build (20)
Check failure on line 34 in src/components/cart/Cart.tsx GitHub Actions / Build (20)
|
||
< CartItem key={index} {...cart} /> | ||
)) | ||
content = renderedCart | ||
} else if (isError) { | ||
content = <div>{error.toString()}</div> | ||
} | ||
return ( | ||
<div className="w-full min-h-screen overflow-x-hidden font-roboto flex flex-col 2xl:items-center"> | ||
<Navbar /> | ||
<div className="w-full px-3 pt-5 flex flex-col gap-2 md:p-4 xl:px-10 2xl:w-[1440px]"> | ||
<h1 className="leading-none font-semibold text-lg subpixel-antialiased tracking-wide">Shopping Cart ({items})</h1> | ||
<p className="leading-none subpixel-antialiased text-xs tracking-wide font-light hidden md:block">Your cart contains {items} items and comes to a total of $210</p> | ||
<div className="flex flex-col md:flex-row-reverse lg:gap-10 xl:gap-12"> | ||
<div className="flex flex-col gap-4 px-3 py-2 pt-4 md:flex-grow lg:w-72 lg:flex-grow-0 xl:flex-grow-0 xl:w-80"> | ||
<div className="flex justify-between text-sm font-medium"> | ||
<span className="md:font-semibold md:text-lg">Total:</span> | ||
<span className="md:font-semibold md:text-lg">${totalPrice}</span> | ||
</div> | ||
<button className="leading-none bg-greenColor hover:bg-[#1a6461] rounded-full px-5 py-3 text-whiteColor font-medium text-xs transition-all delay-75 ease-in cursor-pointer">Checkout</button> | ||
</div> | ||
<div className="bg-[#f7f7f7] flex flex-col py-3 mt-2 md:flex-grow"> | ||
{content} | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
) | ||
} | ||
export default Cart |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<CartItem> = ({ id, name, image, sizes, quantity }) => { | ||
const [itemTotalPrice, setItemTotalPrice] = useState(sizes[0].price * quantity) | ||
Check failure on line 12 in src/components/cart/CartItem.tsx GitHub Actions / Build (20)
Check failure on line 12 in src/components/cart/CartItem.tsx GitHub Actions / Build (20)
Check failure on line 12 in src/components/cart/CartItem.tsx GitHub Actions / Build (20)
|
||
const [updateCart] = useUpdateCartMutation() | ||
const currentPrice = sizes[0].price; | ||
Check failure on line 14 in src/components/cart/CartItem.tsx GitHub Actions / Build (20)
|
||
|
||
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 ( | ||
<> | ||
<div className="flex gap-1 border-b border-b-grayColor py-2 px-3"> | ||
<div className="h-36 max-w-[98px] min-w-[100px]"> | ||
<img src={image} alt="" className="w-full h-36" /> | ||
</div> | ||
<div className="flex flex-col gap-2 ml-3 w-full"> | ||
<div className="flex justify-between font-semibold"> | ||
<h3 className="leading-5 w-2/3 text-wrap capitalize text-sm break-words font-medium tracking-normal outline-none | ||
md:text-lg">{name}</h3> | ||
<span className="text-xs md:text-base">${itemTotalPrice}</span> | ||
</div> | ||
<div className=""> | ||
<div className="flex flex-col gap-2 md:gap-1"> | ||
<div className="flex flex-col gap-1 font-light mt-1 md:gap-1"> | ||
<label htmlFor="size" className="leading-none text-xs opacity-70">Size</label> | ||
<div id="size" className="border border-greenColor rounded-full h-9 p-[6px] text-sm bg-whiteColor w-4/5 font-medium outline-none md:w-1/2 justify-start flex items-center leading-none px-3"> | ||
{sizes[0].size !== null ? sizes[0].size : 'One'} | ||
</div> | ||
</div> | ||
<div className="flex flex-col font-light gap-1 mt-2"> | ||
<label htmlFor="quantity" className="leading-none text-xs opacity-70">Quantity</label> | ||
<div> | ||
<button | ||
onClick={() => removeQty(quantity, id, sizes[0].id)} | ||
className="border w-10 h-9 text-greenColor rounded-l-full bg-whiteColor cursor-pointer text-center" | ||
>-</button> | ||
<input type="text" value={quantity} className="h-9 w-9 border-t border-t-greenColor border-b text-center outline-none" /> | ||
<button | ||
onClick={() => addQty(quantity, id, sizes[0].id)} | ||
className="border w-10 h-9 text-greenColor rounded-r-full bg-whiteColor cursor-pointer text-center" | ||
>+</button> | ||
</div> | ||
</div> | ||
<div className="flex justify-end gap-2 mt-2 flex-col sm:flex-row"> | ||
<button className="border border-greenColor rounded-full px-3 py-1 text-xs font-medium cursor-pointer">Save For Later</button> | ||
<button className="border border-greenColor rounded-full px-3 py-1 text-xs font-medium cursor-pointer">Remove</button> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</> | ||
) | ||
} | ||
export default CartItem |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<Cart[], void>({ | ||
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 |