Files
shop-front/src/share/components/Cart.tsx
T
2025-09-15 15:59:45 +03:30

127 lines
5.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { ShoppingCart, Trash } from 'iconsax-react'
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover"
import { useGetCart } from '@/app/cart/hooks/useCartData'
import { useRemoveFromCart } from '@/app/cart/hooks/useCartData'
import { CartItemType } from '@/app/cart/types/Types'
import { NumberFormat } from '@/config/func'
import Image from 'next/image'
import Link from 'next/link'
import { Button } from '@/components/ui/button'
const Cart = () => {
const { data: cartData, isLoading } = useGetCart()
const removeFromCartMutation = useRemoveFromCart()
const handleRemoveItem = async (productId: number, variantId: string) => {
try {
await removeFromCartMutation.mutateAsync({
productId,
variantId
})
} catch (error) {
console.error('Error removing item from cart:', error)
}
}
const cart = cartData?.results?.cart
const items = cart?.items || []
const itemsCount = cart?.items_count || 0
return (
<Popover>
<PopoverTrigger asChild>
<div className='h-10 p-3 rounded-[12px] border border-border flex items-center gap-2.5 relative'>
<ShoppingCart size={20} color='#333333' />
{itemsCount > 0 && (
<div className='absolute -top-2 -right-2 bg-primary text-white text-xs rounded-full w-5 h-5 flex items-center justify-center'>
{itemsCount}
</div>
)}
</div>
</PopoverTrigger>
<PopoverContent className="w-[350px] ml-2 z-[9999] p-0 max-h-[600px] overflow-y-auto" style={{ left: 4 }}>
<div className='p-4'>
{/* Header */}
{
itemsCount > 0 && (
<div className='text-primary text-sm font-medium mb-4'>
{itemsCount} کالا در سبد خرید شما ثبت شده
</div>
)
}
{/* Cart Items */}
<div className='space-y-3 mb-4'>
{isLoading ? (
<div className='text-center py-4 text-gray-500'>در حال بارگذاری...</div>
) : items.length > 0 ? (
items.slice(0, 3).map((item: CartItemType) => (
<CartItemCard
key={`${item.product._id}-${item.variant._id}`}
item={item}
onRemove={() => handleRemoveItem(item.product._id, item.variant._id)}
/>
))
) : (
<div className='text-center py-4 text-gray-500'>سبد خرید شما خالی است</div>
)}
</div>
{/* View Cart Button */}
{itemsCount > 0 && (
<Link href="/cart" className='block'>
<Button className='w-full bg-primary hover:bg-primary/90 text-white rounded-lg py-3'>
مشاهده سبد خرید
</Button>
</Link>
)}
</div>
</PopoverContent>
</Popover>
)
}
// Cart Item Card Component
const CartItemCard = ({ item, onRemove }: { item: CartItemType, onRemove: () => void }) => {
return (
<div className='bg-white rounded-lg p-3 flex gap-3 shadow-sm border border-gray-100'>
{/* Product Image */}
<div className='flex-shrink-0'>
<Image
src={item.product.imagesUrl.cover}
alt={item.product.title_fa}
width={60}
height={60}
className='w-15 h-15 object-contain rounded'
/>
</div>
{/* Product Details */}
<div className='flex-1 min-w-0'>
<div className='text-xs text-gray-500 mb-1'>
{item.product.category?._id || 'دسته‌بندی'}
</div>
<div className='text-sm text-gray-800 mb-2 line-clamp-2'>
{item.product.title_fa}
</div>
<div className='flex items-center justify-between'>
<div className='text-sm font-semibold text-gray-900'>
{NumberFormat(item.variant.price.selling_price)} تومان
</div>
<button
onClick={onRemove}
className='p-1 hover:bg-red-100 rounded'
>
<Trash size={16} color='#AD3434' />
</button>
</div>
</div>
</div>
)
}
export default Cart