/* ============================================================ MENU — tarjeta de plato + modal de personalización (estilo Yanuba) ============================================================ */ const { RICE: _RICE, DRINKS: _DRINKS } = window; const PHOTOS = window.PHOTOS; // bebida incluida por defecto (no aparece como opción seleccionable) const _DRINK_DEFAULT = (_DRINKS.find(d => d.included) || _DRINKS[0]).id; /* ---- Tarjeta de plato ---- */ function MenuCard({ it, cat, onOpen, store }) { const av = !store || itemAvailable(store, it.n); return (
av && onOpen(it, cat)}>
{av && it.tag && {it.tag}} {!av && Agotado}

{it.n}

{it.d &&

{it.d}

}
{priceLabel(it)} {av ? : }
); } /* ---- Modal de personalización ---- */ function ProductModal({ item, cat, store, onAdd, onQuickAdd, onClose }) { const inc = (item.includes || cat.includes || {}); const serves = item.serves || cat.serves; const [rice, setRice] = useState(_RICE[0].id); const [drink, setDrink] = useState(_DRINK_DEFAULT); const [qty, setQty] = useState(1); const [notes, setNotes] = useState(""); const [added, setAdded] = useState(false); const [relatedTotal, setRelatedTotal] = useState(0); useEffect(() => { document.body.style.overflow = "hidden"; const onEsc = (e) => e.key === "Escape" && onClose(); window.addEventListener("keydown", onEsc); return () => { document.body.style.overflow = ""; window.removeEventListener("keydown", onEsc); }; }, []); const drinkObj = inc.drink ? _DRINKS.find(d => d.id === drink) : null; const drinkExtra = drinkObj ? (drinkObj.extra || 0) : 0; const unit = item.from + drinkExtra; const total = unit * qty + relatedTotal; function add() { const riceObj = inc.rice ? _RICE.find(r => r.id === rice) : null; onAdd({ uid: "L" + Date.now() + Math.random().toString(36).slice(2, 6), name: item.n, catName: cat.name, unitPrice: unit, ranged: !!(item.to && item.to !== item.from), from: item.from, to: item.to, drinkExtra, weights: item.weights || null, size: null, qty, rice: riceObj ? riceObj.label : null, drink: drinkObj ? drinkObj.label + (drinkExtra ? " (+" + fmt(drinkExtra) + ")" : "") : null, notes: notes.trim(), }); setAdded(true); setTimeout(onClose, 650); } return (
e.stopPropagation()}>
{item.tag && {item.tag}}
{cat.kicker || cat.name}

{item.n}

{priceLabel(item)} {item.to && item.to !== item.from && · según tamaño}
{item.d &&

{item.d}

} {item.ing && (
Ingredientes
{item.ing.map((g, i) => {g})}
)} {serves && (
Incluye

{serves}

)}
{inc.rice && (
Elige el arroz
{_RICE.map(r => ( ))}
)} {inc.drink && (
Elige tu bebida incluida
{_DRINKS.map(d => ( ))}
)}
Notas especiales setNotes(sanitizeBase(e.target.value, 80))} placeholder="Sin cebolla, extra patacón, bien dorado…" />
{onQuickAdd && setRelatedTotal(sum)} />}
); } Object.assign(window, { MenuCard, ProductModal });