"use client"; import Image from "next/image"; import Link from "next/link"; import { Heart, ShoppingBag, Sparkles, TriangleAlert } from "lucide-react"; import { useState } from "react"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import type { Product } from "@/lib/headless/types"; import { formatMoney, LOW_STOCK_THRESHOLD } from "@/lib/utils"; import { useCartStore } from "@/store/cart-store"; import { useWishlistStore } from "@/store/wishlist-store"; export function ProductCard({ product, priority = false }: { product: Product; priority?: boolean }) { const addItem = useCartStore((state) => state.addItem); const wishlistProducts = useWishlistStore((state) => state.products); const wishlistHydrated = useWishlistStore((state) => state.hasHydrated); const toggleProduct = useWishlistStore((state) => state.toggleProduct); const isFavorite = wishlistHydrated && wishlistProducts.some((item) => item.id === product.id); const discountPercent = product.compareAtPrice && product.price ? Math.round((1 - product.price / product.compareAtPrice) * 100) : null; const [selectedVariantId, setSelectedVariantId] = useState(product.variants[0]?.id); const selectedVariant = product.variants.find((variant) => variant.id === selectedVariantId) ?? product.variants[0]; const lowStock = selectedVariant?.inventoryQuantity !== null && selectedVariant?.inventoryQuantity !== undefined && selectedVariant.inventoryQuantity > 0 && selectedVariant.inventoryQuantity <= LOW_STOCK_THRESHOLD ? selectedVariant.inventoryQuantity : null; return (
{product.name}
{discountPercent && discountPercent > 0 && -{discountPercent}%}{product.isNew && Nuevo}{product.featured && Top}
{product.category}{product.collection}

{product.name}

{product.shortDescription}

{product.variants.length > 1 && (
{product.variants.map((variant) => ( ))}
)} {lowStock !== null && ( Quedan {lowStock} )}
{product.compareAtPrice && {formatMoney(product.compareAtPrice, product.currency)}} {/* ADR 0007: smoke test de font-display (Fraunces) en el precio -- si se aprueba visualmente, se propaga al resto de precios en Sub-fase 3. */} {formatMoney(product.price, product.currency)}
{/* ADR 0007: smoke test de la variant "primary" (terracota) -- si se aprueba visualmente, reemplaza "magenta" en el resto del sitio en Sub-fases 2-5. */}
); }