'use client' import { useState, useEffect } from 'react' import Image from 'next/image' import Link from 'next/link' import { Check, Minus, Plus, ShoppingBag } from 'lucide-react' import { useMedusaCart } from '@/hooks/useMedusaCart' import YouMayAlsoLike from '@/components/shop/YouMayAlsoLike' const CURRENCY_SYMBOLS: Record = { zar: 'R', usd: '$', eur: '€', gbp: '£', kes: 'KSh', ngn: '₦', ghs: '₵' } const formatPrice = (amount: number, code?: string) => { const sym = CURRENCY_SYMBOLS[(code ?? '').toLowerCase()] ?? (code?.toUpperCase() ?? '') return `${sym}${(amount / 100).toFixed(2)}` } interface MedusaVariant { id: string; title: string; prices: Array<{ amount: number; currency_code: string }> } interface MedusaProduct { id: string; title: string; description: string | null thumbnail: string | null; images?: Array<{ url: string }> variants: MedusaVariant[]; collection?: { id: string; title: string } } export default function ProductDetailClient({ product: initialProduct, productId }: { product: MedusaProduct | null; productId: string }) { const [product, setProduct] = useState(initialProduct) const [loading, setLoading] = useState(!initialProduct) const [selectedVariant, setSelectedVariant] = useState(initialProduct?.variants?.[0] ?? null) const [activeImage, setActiveImage] = useState(0) const [quantity, setQuantity] = useState(1) const [added, setAdded] = useState(false) const { addToCart } = useMedusaCart() useEffect(() => { if (initialProduct) return const run = async () => { try { const regionRes = await fetch('/api/medusa/store/regions?limit=1') const regionData = regionRes.ok ? await regionRes.json() : {} const regionId = regionData?.regions?.[0]?.id const params = new URLSearchParams({ fields: '+variants.prices.amount,+variants.prices.currency_code,+collection,+categories,+images' }) if (regionId) params.set('region_id', regionId) const res = await fetch(`/api/medusa/store/products/${productId}?${params}`) if (!res.ok) { setLoading(false); return } const { product: p } = await res.json() p.variants = (p.variants ?? []).map((v: any) => ({ ...v, prices: v.prices?.length ? v.prices : v.calculated_price ? [{ amount: v.calculated_price.calculated_amount, currency_code: v.calculated_price.currency_code }] : [], })) setProduct(p) setSelectedVariant(p.variants?.[0] ?? null) } catch { setProduct(null) } finally { setLoading(false) } } run() }, [productId, initialProduct]) const handleAddToCart = async () => { if (!selectedVariant?.id) return await addToCart(selectedVariant.id, quantity) setAdded(true) setTimeout(() => setAdded(false), 2500) window.dispatchEvent(new CustomEvent('cart-drawer-open')) } if (loading) return (
) if (!product) return (

Product not found.

Back to Products
) const images = [product.thumbnail, ...(product.images?.map(i => i.url) ?? [])].filter(Boolean) as string[] const price = selectedVariant?.prices?.[0] const mainImage = images[activeImage] ?? images[0] return (
{mainImage ? ( {product.title} ) : (
)}
{images.length > 1 && (
{images.map((url, i) => ( ))}
)}
{product.collection?.title && ( {product.collection.title} )}

{product.title}

{price && (

{formatPrice(price.amount, price.currency_code)}

)} {product.description && (

{product.description}

)} {product.variants.length > 1 && (

Option

{product.variants.map(v => ( ))}
)}
{quantity}
) }