diff --git a/db.json b/db.json index f3d29c6..1b8bd90 100644 --- a/db.json +++ b/db.json @@ -79,7 +79,7 @@ "id": "c06c", "productId": "d317", "userId": "1", - "quantity": 2 + "quantity": 48 } ] } \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx index b1f721c..755225d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -21,7 +21,7 @@ export default function App() { } } - }, [userStore.data, userStore.loading]) + }, [userStore.data, userStore.loading, userStore.reloadCart]) return ( <> { diff --git a/src/apis/core/cart.api.ts b/src/apis/core/cart.api.ts index 21b79bb..1ecd369 100644 --- a/src/apis/core/cart.api.ts +++ b/src/apis/core/cart.api.ts @@ -14,12 +14,12 @@ export const CartApi = { let resultExisted = await axios.get(`${import.meta.env.VITE_SV_HOST}/carts?productId=${data.productId}`) if (!resultExisted.data[0]) { /* thêm mới */ - await axios.post(`${import.meta.env.VITE_SV_HOST}/carts`, { + let addRes = await axios.post(`${import.meta.env.VITE_SV_HOST}/carts`, { ...data, quantity: 1 }) - return + return addRes.data } /* cập nhật */ @@ -27,6 +27,6 @@ export const CartApi = { quantity: resultExisted.data[0].quantity + 1 }) - return true + return resultUpdate.data } } \ No newline at end of file diff --git a/src/pages/home/cart/Cart.tsx b/src/pages/home/cart/Cart.tsx index 950a7a8..eea7b23 100644 --- a/src/pages/home/cart/Cart.tsx +++ b/src/pages/home/cart/Cart.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, { useEffect, useState } from 'react' import { useSelector } from 'react-redux' import type { StoreType } from '../../../stores' import type { CartItem } from '../../../types/cart.type' @@ -6,34 +6,99 @@ import { Apis } from '../../../apis' import type { Product } from '../../../types/product.type' export default function Cart() { - const userStore = useSelector((store: StoreType) => store.user) + const userStore = useSelector((store: StoreType) => store.user) + const [products, setProducts] = useState([]) + + // Lấy thông tin product cho từng item trong giỏ + useEffect(() => { + async function fetchProducts() { + let temsArr: Product[] = [] + for (const item of userStore.cart || []) { + const res = await Apis.product.findProductById(item.productId) + temsArr.push(res) + } + setProducts(temsArr) + } + fetchProducts() + }, [userStore.cart]) + + + + // Tính tổng tiền + const total = userStore.cart?.reduce((sum, item) => { + const p = products[item.productId] + return sum + (p ? p.price * item.quantity : 0) + }, 0) || 0 - // - //đây là api lấy product id let data = Apis.product.findProductById(productId) - // data có interface là Product - // cho bạn interface product luôn - /* - export interface Product { - id: string; - categoryId: string; - price: number; - iconUrl: string; - isActive: boolean; - name: string; - des: string; -} - - */ return ( -
- Cart Page - +
+

🛒 Giỏ hàng của bạn

+ + {userStore.cart?.length === 0 ? ( +

Giỏ hàng trống.

+ ) : ( +
+
    + {userStore.cart.map((item: CartItem) => { + const product = products.find(pro => pro.id == item.productId) + return ( +
  • + {/* Ảnh sản phẩm */} +
    + {product ? ( + {product.name} + ) : ( +
    + )} +
    + + {/* Thông tin */} +
    +

    + {product ? product.name : 'Đang tải...'} +

    +

    + {product ? product.price.toLocaleString() + ' đ' : ''} +

    +
    + + {/* Số lượng & tổng */} +
    +

    SL: {item.quantity}

    + {product && ( +

    + {(product.price * item.quantity).toLocaleString()} đ +

    + )} +
    +
  • + ) + })} +
+ + {/* Tổng tiền */} +
+

+ Tổng cộng:{' '} + {total.toLocaleString()} đ +

+
+ + {/* Nút hành động */} +
+ +
+
+ )}
) } diff --git a/src/pages/home/product/ProductDetail.tsx b/src/pages/home/product/ProductDetail.tsx index 9b5c34b..8d53c75 100644 --- a/src/pages/home/product/ProductDetail.tsx +++ b/src/pages/home/product/ProductDetail.tsx @@ -3,13 +3,15 @@ import { useParams } from 'react-router' import { Apis } from '../../../apis' import type { Product } from '../../../types/product.type' import { Button } from 'antd' -import { useSelector } from 'react-redux' +import { useDispatch, useSelector } from 'react-redux' import type { StoreType } from '../../../stores' +import { userAction } from '../../../stores/slices/user.slice' export default function ProductDetail() { const { productId } = useParams() const [product, setProduct] = useState(null) const userStore = useSelector((store: StoreType) => store.user) + const dipatch = useDispatch() useEffect(() => { if (!productId) return @@ -35,7 +37,9 @@ export default function ProductDetail() { productId: product.id, userId: userStore.data?.id }) - alert("thành công") + console.log("result", result) + + dipatch(userAction.changeLoad()) } catch (err) { } diff --git a/src/stores/slices/user.slice.ts b/src/stores/slices/user.slice.ts index c9f0bbc..668c23a 100644 --- a/src/stores/slices/user.slice.ts +++ b/src/stores/slices/user.slice.ts @@ -7,13 +7,15 @@ import type { CartItem } from "../../types/cart.type"; interface UserState { data: User | null, loading: boolean; - cart: CartItem[] + cart: CartItem[], + reloadCart: boolean } const InitUserState: UserState = { data: null, loading: false, - cart: [] + cart: [], + reloadCart: false } @@ -23,7 +25,27 @@ const userSlice = createSlice({ reducers: { initCartData: (state, action) =>{ state.cart = action.payload + }, + changeLoad: (state) => { + state.reloadCart = !state.reloadCart } + // addToCart: (state, action) => { + // let existedItem = state.cart.find(item => item.productId == action.payload.productId) + + // if(existedItem) { + // state.cart = state.cart.map(item => { + // if(item.id == existedItem.id) { + // return { + // ...existedItem, + // quantity: action.payload.quantity + // } + // } + // return item + // }) + // }else { + // state.cart.push(action.payload) + // } + // } }, extraReducers: (bd) => { bd.addCase(fetchUserData.pending, (state, action) => {