'use client'; import ProductBanner from '@/assets/product.png'; import { cart_api } from '@/features/cart/lib/api'; import { BASE_URL } from '@/shared/config/api/URLs'; import { useRouter } from '@/shared/config/i18n/navigation'; import { useCartId } from '@/shared/hooks/cartId'; import formatPrice from '@/shared/lib/formatPrice'; import { Button } from '@/shared/ui/button'; import { Input } from '@/shared/ui/input'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { AxiosError } from 'axios'; import { ArrowLeft, CreditCard, Minus, Plus, ShoppingBag, Trash, Truck, } from 'lucide-react'; import { useTranslations } from 'next-intl'; import Image from 'next/image'; import { useEffect, useRef, useState } from 'react'; import { toast } from 'sonner'; const CartPage = () => { const { cart_id } = useCartId(); const queryClient = useQueryClient(); const router = useRouter(); const t = useTranslations(); const { data: cartItems, isLoading } = useQuery({ queryKey: ['cart_items', cart_id], queryFn: () => cart_api.get_cart_items(cart_id!), enabled: !!cart_id, select: (data) => data.data.cart_item, }); const [quantities, setQuantities] = useState>({}); const debounceRef = useRef>({}); // Initial state useEffect(() => { if (!cartItems) return; const initialQuantities: Record = {}; cartItems.forEach((item) => { initialQuantities[item.id] = item.quantity; debounceRef.current[item.id] = null; }); setQuantities(initialQuantities); }, [cartItems]); // Update cart item mutation const { mutate: updateCartItem } = useMutation({ mutationFn: ({ body, cart_item_id, }: { body: { quantity: number }; cart_item_id: string; }) => cart_api.update_cart_item({ body, cart_item_id }), onSuccess: (_, variables) => { queryClient.invalidateQueries({ queryKey: ['cart_items', cart_id] }); const item = cartItems?.find( (i) => String(i.id) === variables.cart_item_id, ); if (item) { const measurementName = item.product.meansurement?.name || null; toast.success( `${t('Miqdor')} ${variables.body.quantity} ${measurementName || 'шт.'} ${t('ga yangilandi')}`, { richColors: true, position: 'top-center' }, ); } }, onError: (err: AxiosError) => toast.error(err.message, { richColors: true, position: 'top-center' }), }); // Delete cart item mutation const { mutate: deleteCartItem } = useMutation({ mutationFn: ({ cart_item_id }: { cart_item_id: string }) => cart_api.delete_cart_item(cart_item_id), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['cart_items', cart_id] }); toast.success(t("Savatdan o'chirildi"), { richColors: true, position: 'top-center', }); }, onError: (err: AxiosError) => toast.error(err.message, { richColors: true, position: 'top-center' }), }); const handleCheckout = () => router.push('/cart/order'); if (isLoading) return (
Loading...
); if (!cartItems || cartItems.length === 0) return (

{t("Savatingiz bo'sh")}

{t("Mahsulotlar qo'shish uchun katalogga o'ting")}

); const subtotal = cartItems.reduce((sum, item) => { if (!item.product.prices.length) return sum; const maxPrice = Math.max( ...item.product.prices.map((p) => Number(p.price)), ); return sum + maxPrice * (quantities[item.id] || item.quantity); }, 0) || 0; const handleQuantityChange = ( itemId: number, delta: number = 0, newValue?: number, ) => { setQuantities((prev) => { const item = cartItems?.find((i) => i.id === Number(itemId)); if (!item) return prev; const isGram = item.product.meansurement?.name?.toLowerCase() === 'gr'; const STEP = isGram ? 100 : 1; const MIN_QTY = isGram ? 100 : 1; let updatedQty; if (newValue !== undefined) { // Input'dan kiritilgan qiymat - minimal limitni qo'llash shart emas updatedQty = newValue; } else { // +/- tugmalar bosilganda - STEP qo'llash va minimal limit updatedQty = (prev[itemId] ?? MIN_QTY) + delta * STEP; if (updatedQty < MIN_QTY) updatedQty = MIN_QTY; } // Debounce server update if (debounceRef.current[itemId]) clearTimeout(debounceRef.current[itemId]!); debounceRef.current[itemId] = setTimeout(() => { if (updatedQty <= 0) deleteCartItem({ cart_item_id: itemId.toString() }); else updateCartItem({ body: { quantity: updatedQty }, cart_item_id: itemId.toString(), }); }, 500); return { ...prev, [itemId]: updatedQty }; }); }; return (

{t('Savat')}

{cartItems.length} {t('ta mahsulot')}

{cartItems.map((item, index) => { const measurementDisplay = item.product.meansurement?.name || 'шт.'; return (
0 ? item.product.images[0].image.includes(BASE_URL) ? item.product.images[0].image : BASE_URL + item.product.images[0].image : ProductBanner } alt={item.product.name} width={500} height={500} unoptimized className="object-cover" style={{ width: '100%', height: '100%' }} />

{item.product.name}

{formatPrice( Math.max( ...item.product.prices.map((p) => Number(p.price)), ), true, )} /{measurementDisplay}

{t('Miqdor')}: {quantities[item.id]} {measurementDisplay}

{ const cleaned = e.target.value.replace(/\D/g, ''); const val = cleaned === '' ? 0 : Number(cleaned); handleQuantityChange(item.id, 0, val); }} type="text" className="w-14 text-center border-none p-0" /> {measurementDisplay}
); })}

{t('Buyurtma haqida')}

{t('Mahsulotlar narxi')}: {formatPrice(subtotal, true)}
{t('Yetkazib berish')}: {t('Bepul')}
{t('Jami')}: {formatPrice(subtotal, true)}
); }; export default CartPage;