'use client' import { useState, useEffect, useCallback } from 'react' import Link from 'next/link' import { ArrowRight, Minus, Package, Plus, ShoppingCart, Trash2, X } from 'lucide-react' import { broadcastCartCount } from '@/hooks/useMedusaCart' 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)}` } const PUB_KEY = process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY || '' async function medusaFetch(path: string, init?: RequestInit): Promise { const res = await fetch(`/api/medusa${path}`, { ...init, headers: { 'content-type': 'application/json', 'x-publishable-api-key': PUB_KEY, ...(init?.headers ?? {}) }, signal: AbortSignal.timeout(30000), }) if (!res.ok) throw new Error(`Medusa ${res.status}`) return res.json() } interface CartItem { id: string; title: string; product_title?: string; thumbnail: string | null; quantity: number; unit_price: number; subtotal: number; variant: { id: string; title: string } | null } interface Cart { id: string; items: CartItem[]; subtotal: number; region: { currency_code: string } | null } export default function CartDrawer() { const [isOpen, setIsOpen] = useState(false) const [cart, setCart] = useState(null) const [loading, setLoading] = useState(false) const fetchCart = useCallback(async () => { const cartId = localStorage.getItem('medusa_cart_id') if (!cartId) { setCart(null); return } setLoading(true) try { const { cart: c } = await medusaFetch<{ cart: Cart }>(`/store/carts/${cartId}`) setCart(c) } catch { setCart(null) } finally { setLoading(false) } }, []) useEffect(() => { const open = () => { setIsOpen(true); fetchCart() } window.addEventListener('cart-drawer-open', open) return () => window.removeEventListener('cart-drawer-open', open) }, [fetchCart]) useEffect(() => { const handler = () => { if (isOpen) fetchCart() } window.addEventListener('medusa-cart-updated', handler) return () => window.removeEventListener('medusa-cart-updated', handler) }, [isOpen, fetchCart]) useEffect(() => { document.body.style.overflow = isOpen ? 'hidden' : '' return () => { document.body.style.overflow = '' } }, [isOpen]) const close = () => setIsOpen(false) const removeItem = async (itemId: string) => { if (!cart) return await medusaFetch(`/store/carts/${cart.id}/line-items/${itemId}`, { method: 'DELETE' }) const newItems = cart.items.filter(i => i.id !== itemId) setCart(prev => prev ? { ...prev, items: newItems, subtotal: newItems.reduce((s, i) => s + i.subtotal, 0) } : null) broadcastCartCount(newItems.reduce((s, i) => s + i.quantity, 0)) } const updateQty = async (itemId: string, quantity: number) => { if (!cart) return if (quantity < 1) { removeItem(itemId); return } const { cart: updated } = await medusaFetch<{ cart: Cart }>( `/store/carts/${cart.id}/line-items/${itemId}`, { method: 'POST', body: JSON.stringify({ quantity }) } ) setCart(updated) broadcastCartCount(updated.items?.reduce((s, i) => s + i.quantity, 0) ?? 0) } const items = cart?.items ?? [] const currencyCode = cart?.region?.currency_code return ( <> {isOpen && (