"use client"; import { type ReactNode, useMemo, useState } from "react"; import { formatPrice } from "@/data/sample"; import type { ProductStoreVariant, ProductVariation } from "@/lib/meshkee"; import { useAuth } from "@/context/AuthContext"; import { useCart } from "@/context/CartContext"; function CheckIcon({ className }: { className?: string }) { return ( ); } export function ProductPurchasePanel({ header, variations, storeVariants, fallbackPrice, inStock, contactPhone, storeName, initialSelections, }: { header: ReactNode; variations: ProductVariation[]; storeVariants: ProductStoreVariant[]; fallbackPrice: { minPrice: number | null; maxPrice: number | null; oldPrice?: number | null; discount?: number; }; inStock: boolean; contactPhone?: string; storeName?: string; // Pre-select the variant a shopper landed on directly (e.g. a store-item // detail page for one specific variant), instead of defaulting to the // first option of every variation. initialSelections?: Record; }) { const { user, openLoginModal } = useAuth(); const { addItem } = useCart(); const [selected, setSelected] = useState>(() => { if (initialSelections && Object.keys(initialSelections).length > 0) return initialSelections; const initial: Record = {}; for (const variation of variations) { if (variation.options[0]) initial[variation.id] = variation.options[0].id; } return initial; }); const [quantity, setQuantity] = useState(1); const [cartStatus, setCartStatus] = useState<"idle" | "busy" | "done">("idle"); const [cartError, setCartError] = useState(null); const matchedVariant = useMemo(() => { if (storeVariants.length === 0) return null; if (variations.length === 0) return storeVariants[0] ?? null; return ( storeVariants.find((variant) => variations.every((variation) => { const selection = variant.selections.find((s) => s.variationId === variation.id); return selection?.optionId === selected[variation.id]; }), ) ?? null ); }, [variations, storeVariants, selected]); const hasVariations = variations.length > 0; const price = hasVariations ? (matchedVariant?.discountedPrice ?? matchedVariant?.price ?? null) : fallbackPrice.minPrice; const priceRangeLabel = !hasVariations && fallbackPrice.minPrice != null && fallbackPrice.maxPrice != null && fallbackPrice.minPrice !== fallbackPrice.maxPrice ? `${formatPrice(fallbackPrice.minPrice)} - ${formatPrice(fallbackPrice.maxPrice)}` : null; const variantOldPrice = matchedVariant?.discountedPrice != null && matchedVariant?.price != null && matchedVariant.price !== matchedVariant.discountedPrice ? matchedVariant.price : null; const oldPrice = hasVariations ? variantOldPrice : (fallbackPrice.oldPrice ?? null); const discount = hasVariations ? (oldPrice != null && price != null ? Math.round((1 - price / oldPrice) * 100) : null) : (fallbackPrice.discount ?? null); const stockQuantity = matchedVariant ? matchedVariant.stockQuantity : null; const available = matchedVariant ? stockQuantity! > 0 : inStock; const maxQty = stockQuantity && stockQuantity > 0 ? stockQuantity : 99; const handleAddToCart = async () => { if (!matchedVariant) return; if (!user) { openLoginModal(); return; } setCartError(null); setCartStatus("busy"); const res = await addItem(matchedVariant.id, quantity); if (res.ok) { setCartStatus("done"); setTimeout(() => setCartStatus("idle"), 1500); } else { setCartStatus("idle"); setCartError(res.message ?? "افزودن به سبد ناموفق بود."); } }; return ( <>
{header} {hasVariations && (
{variations.map((variation) => (

{variation.type === "color" ? "انتخاب رنگ" : variation.name}

{variation.options.map((option) => { const isSelected = selected[variation.id] === option.id; const swatch = option.colorHex ?? (variation.type === "color" ? option.value : null); return ( ); })}
))}
)}
{storeName &&

{storeName}

}
موجودی: {available ? "موجود" : "ناموجود"}
{price != null ? ( <>
{!priceRangeLabel && oldPrice != null && (
{formatPrice(oldPrice)} {discount != null && ( {discount}٪ )}
)}

{priceRangeLabel ?? formatPrice(price)} تومان

تعداد:
{quantity}
{cartError &&

{cartError}

} ) : contactPhone ? ( 📞 تماس با فروشگاه ) : ( )}
); }