"use client"; import { useEffect } from "react"; import { useRouter } from "next/navigation"; import Link from "next/link"; import { motion, AnimatePresence } from "framer-motion"; import Image from "next/image"; import { IoCloseOutline, IoAddOutline, IoRemoveOutline, IoTrashOutline } from "react-icons/io5"; import { IconButton } from "@/components/IconButton"; import { useCart } from "./CartContext"; import { FORMAT_GROUPS } from "@/lib/variants"; import type { MedusaLineItem } from "@/lib/medusa"; /** Build a suffix → friendly-name map from the variant taxonomy. */ const suffixToLabel: Record = {}; for (const group of FORMAT_GROUPS) { for (const v of group.variants ?? []) suffixToLabel[v.suffix] = v.title; for (const sg of group.subgroups ?? []) { for (const v of sg.variants) suffixToLabel[v.suffix] = v.title; } } function variantLabel(item: MedusaLineItem): string { const sku = item.variant?.sku; if (sku) { const suffix = sku.split("_").pop()?.toUpperCase(); if (suffix && suffixToLabel[suffix]) return suffixToLabel[suffix]; } return item.variant?.title ?? item.title; } function formatPrice(amount: number, currencyCode: string) { return new Intl.NumberFormat("en-US", { style: "currency", currency: currencyCode, minimumFractionDigits: 2, }).format(amount); } const overlayVariants = { open: { opacity: 1, pointerEvents: "auto" as const, transition: { type: "tween" as const, ease: "easeInOut" as const, duration: 0.2 }, }, closed: { opacity: 0, transition: { type: "tween" as const, ease: "easeInOut" as const, duration: 0.2, delay: 0.15 }, transitionEnd: { pointerEvents: "none" as const }, }, }; const panelVariants = { open: { opacity: 1, transition: { type: "tween" as const, ease: "easeInOut" as const, duration: 0.4 }, }, closed: { opacity: 0, }, exit: { opacity: 0, transition: { type: "tween" as const, ease: "easeInOut" as const, duration: 0.3, delay: 0.1 }, }, }; function CartItemContent({ item, currencyCode }: { item: MedusaLineItem; currencyCode: string }) { return ( <> {/* Thumbnail */}
{item.thumbnail ? ( {item.product_title ) : (
No img
)}
{/* Info */}

{item.product_title ?? item.title}

{variantLabel(item)}

{formatPrice(item.unit_price, currencyCode)}{" "} x {item.quantity}

); } export function CartDrawer() { const { cart, drawerOpen, setDrawerOpen, removeItem, updateItem } = useCart(); const router = useRouter(); useEffect(() => { if (!drawerOpen) return; const onKeyDown = (e: KeyboardEvent) => { if (e.key === "Escape") setDrawerOpen(false); }; window.addEventListener("keydown", onKeyDown); return () => window.removeEventListener("keydown", onKeyDown); }, [drawerOpen, setDrawerOpen]); useEffect(() => { if (drawerOpen) { document.documentElement.style.overflow = "hidden"; document.body.style.overflow = "hidden"; } else { document.documentElement.style.overflow = ""; document.body.style.overflow = ""; } return () => { document.documentElement.style.overflow = ""; document.body.style.overflow = ""; }; }, [drawerOpen]); const items = cart?.items ?? []; const currencyCode = cart?.currency_code ?? "eur"; return ( {drawerOpen && ( setDrawerOpen(false)} > {/* Backdrop */}
{/* Panel */} e.stopPropagation()} > {/* Header */}

Cart

setDrawerOpen(false)} aria-label="Close cart">
{/* Items */}
{items.length === 0 ? (

Your cart is empty.

) : (
    {items.map((item) => (
  • {/* Thumbnail + Info (wrapped in link when product_handle exists) */} {item.product_handle ? ( setDrawerOpen(false)} className="flex min-w-0 flex-1 items-center gap-3" > ) : (
    )} {/* Remove */}
  • ))}
)}
{/* Footer */} {items.length > 0 && (
Subtotal {formatPrice(cart?.subtotal ?? 0, currencyCode)}
{(cart?.discount_total ?? 0) > 0 && (
Discount −{formatPrice(cart!.discount_total!, currencyCode)}
)}
)}
)} ); }