Files
react_cart_flow/src/pages/home/cart/Cart.tsx
2025-10-09 10:06:25 +07:00

105 lines
3.6 KiB
TypeScript

import React, { useEffect, useState } from 'react'
import { useSelector } from 'react-redux'
import type { StoreType } from '../../../stores'
import type { CartItem } from '../../../types/cart.type'
import { Apis } from '../../../apis'
import type { Product } from '../../../types/product.type'
export default function Cart() {
const userStore = useSelector((store: StoreType) => store.user)
const [products, setProducts] = useState<Product[]>([])
// 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
return (
<div className="max-w-4xl mx-auto p-6">
<h1 className="text-2xl font-bold mb-6 text-center">🛒 Giỏ hàng của bạn</h1>
{userStore.cart?.length === 0 ? (
<p className="text-center text-gray-500">Giỏ hàng trống.</p>
) : (
<div className="bg-white shadow-md rounded-2xl p-4">
<ul className="divide-y divide-gray-200">
{userStore.cart.map((item: CartItem) => {
const product = products.find(pro => pro.id == item.productId)
return (
<li
key={item.id}
className="flex items-center gap-4 py-4"
>
{/* Ảnh sản phẩm */}
<div className="w-16 h-16 flex-shrink-0 overflow-hidden rounded-lg border">
{product ? (
<img
src={product.iconUrl}
alt={product.name}
className="w-full h-full object-cover"
/>
) : (
<div className="w-full h-full bg-gray-200 animate-pulse" />
)}
</div>
{/* Thông tin */}
<div className="flex-1">
<h2 className="font-semibold text-gray-800">
{product ? product.name : 'Đang tải...'}
</h2>
<p className="text-sm text-gray-500">
{product ? product.price.toLocaleString() + ' đ' : ''}
</p>
</div>
{/* Số lượng & tổng */}
<div className="text-right">
<p className="text-sm text-gray-700">SL: {item.quantity}</p>
{product && (
<p className="font-semibold text-gray-800">
{(product.price * item.quantity).toLocaleString()} đ
</p>
)}
</div>
</li>
)
})}
</ul>
{/* Tổng tiền */}
<div className="mt-6 border-t pt-4 text-right">
<p className="text-lg font-semibold">
Tổng cộng:{' '}
<span className="text-blue-600">{total.toLocaleString()} đ</span>
</p>
</div>
{/* Nút hành động */}
<div className="mt-6 text-right">
<button className="px-6 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-xl transition">
Thanh toán
</button>
</div>
</div>
)}
</div>
)
}