popover account + popover cart

This commit is contained in:
hamid zarghami
2025-09-15 15:59:45 +03:30
parent 220c8be526
commit ab29dc26dd
7 changed files with 741 additions and 13 deletions
+127
View File
@@ -0,0 +1,127 @@
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