/* global React, ReactDOM, OCEAN_SELECTION */ const { useState, useMemo, useCallback } = React; function App() { const data = OCEAN_SELECTION; // cart key = `${ref}::${colorLabel}` -> { qty, item, color } const [cart, setCart] = useState({}); const [drawerOpen, setDrawerOpen] = useState(false); const [deliveryIdx, setDeliveryIdx] = useState(0); const lines = useMemo(() => Object.entries(cart).map(([key, v]) => ({ key, ...v })), [cart] ); const total = useMemo(() => lines.reduce((sum, l) => sum + l.item.price * l.qty, 0), [lines] ); const count = useMemo(() => lines.reduce((s, l) => s + l.qty, 0), [lines] ); const keyOf = (item, color) => item.ref + "::" + (color ? color.label : "Unique"); const add = useCallback((item, color) => { const key = keyOf(item, color); setCart(c => ({ ...c, [key]: { qty: (c[key]?.qty || 0) + 1, item, color }, })); }, []); const remove = useCallback((item, color) => { const key = keyOf(item, color); setCart(c => { const q = (c[key]?.qty || 0) - 1; const n = { ...c }; if (q <= 0) delete n[key]; else n[key] = { ...n[key], qty: q }; return n; }); }, []); const order = useCallback(() => { const fmt = (n) => n.toFixed(2).replace(".", ","); const orderedLines = lines.map(l => { const colorTxt = (l.color && l.color.label !== "Unique") ? ` (${l.color.label})` : ""; return `- ${l.item.ref} ${l.item.name}${colorTxt} ×${l.qty} = ${fmt(l.item.price * l.qty)} €`; }); const deliv = data.delivery.options[deliveryIdx] || data.delivery.options[0]; const delivTxt = deliv.price > 0 ? `${deliv.label} (+${fmt(deliv.price)} €)` : `${deliv.label} (offerte)`; const grand = total + deliv.price; const body = `Bonjour, je souhaite commander dans notre Collection ${data.name} :\n\n${orderedLines.join("\n")}\n\nSous-total : ${fmt(total)} € HT\nLivraison : ${delivTxt}\nTotal : ${fmt(grand)} € HT`; const url = `https://wa.me/${data.whatsappNumber.replace(/\D/g, "")}?text=${encodeURIComponent(body)}`; window.open(url, "_blank"); }, [lines, total, data, deliveryIdx]); return (