"use client"; import { useFavorites, useAddToCart, useRemoveFromFavorites, } from "@/lib/hooks"; import { useState, useCallback, useMemo } from "react"; import Image from "next/image"; import Link from "next/link"; import { Heart, ShoppingCart } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Card } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Skeleton } from "@/components/ui/skeleton"; import { useToast } from "@/hooks/use-toast"; import { useTranslations } from "next-intl"; import type { Favorite } from "@/lib/types/api"; export default function FavoritesPage() { const [isHovered, setIsHovered] = useState(null); const { toast } = useToast(); const t = useTranslations(); const { data: favorites, isLoading, isError } = useFavorites(); const { mutate: removeFromFavorites, isPending: isRemoving } = useRemoveFromFavorites(); const { mutate: addToCart, isPending: isAddingToCart } = useAddToCart(); const handleRemoveFromFavorites = useCallback((productId: number) => { removeFromFavorites(productId, { onSuccess: () => { toast({ title: t("removed_from_favorites"), }); }, onError: (error) => { toast({ title: t("error"), description: error.message, variant: "destructive", }); }, }); }, [removeFromFavorites, toast, t]); const handleAddToCart = useCallback((productId: number) => { addToCart( { productId }, { onSuccess: () => { toast({ title: t("added_to_cart"), }); }, onError: (error) => { toast({ title: t("error"), description: error.message, variant: "destructive", }); }, } ); }, [addToCart, toast, t]); const loadingSkeleton = useMemo(() => (

{t("favorite_products")}

{Array.from({ length: 10 }).map((_, i) => ( ))}
), [t]); if (isLoading) { return loadingSkeleton; } if (isError || !favorites || favorites.length === 0) { return (

{t("favorite_products")}

{t("empty_favorites")}

); } return (

{t("favorite_products")}

{favorites.map((favorite: Favorite) => ( handleRemoveFromFavorites(favorite.product.id)} onAddToCart={() => handleAddToCart(favorite.product.id)} onHover={setIsHovered} isHovered={isHovered === favorite.product.id} isRemoving={isRemoving} isAddingToCart={isAddingToCart} /> ))}
); } interface Product { id: number; name: string; slug: string; price_amount: string; old_price_amount?: string | null; media: Array<{ thumbnail: string; images_400x400: string; images_720x720: string; images_800x800: string; images_1200x1200: string; }>; stock: number; } interface ProductCardProps { productId: number; product: Product; onRemove: () => void; onAddToCart: () => void; onHover: (id: number | null) => void; isHovered: boolean; isRemoving: boolean; isAddingToCart: boolean; } function ProductCard({ productId, product, onRemove, onAddToCart, onHover, isHovered, isRemoving, isAddingToCart, }: ProductCardProps) { const t = useTranslations(); if (!product) return null; const imageUrl = product.media?.[0]?.images_800x800 || product.media?.[0]?.thumbnail || "/placeholder.svg"; const price = `${parseFloat(product.price_amount).toFixed(2)} TMT`; const oldPrice = product.old_price_amount ? `${parseFloat(product.old_price_amount).toFixed(2)} TMT` : null; return ( onHover(productId)} onMouseLeave={() => onHover(null)} >
{/* Favorite Button */} {/* Product Image */} {product.name} {/* Out of Stock Badge */} {product.stock === 0 && (
{t("out_of_stock")}
)}
{/* Product Info */}

{product.name}

{oldPrice && (

{oldPrice}

)}

{price}

{/* Add to Cart Button - показывается при hover */} {isHovered && product.stock > 0 && (
)}
); }