/* ============================================================ EXTRAS — visor de PDF, banner de sugeridos, promo del día, y cross-sell (relacionados) para no perder la venta ============================================================ */ const { MENU_PDF: EX_PDF, WEEKLY_PROMOS: EX_PROMOS, FEATURE: EX_FEATURE } = window; /* ---- Visor de menú en PDF (anclado a la página, overlay) ---- */ function PdfModal({ onClose }) { useEffect(() => { document.body.style.overflow = "hidden"; const esc = (e) => e.key === "Escape" && onClose(); window.addEventListener("keydown", esc); return () => { document.body.style.overflow = ""; window.removeEventListener("keydown", esc); }; }, []); return (
e.stopPropagation()}>
Menú digital · Dos Océanos
Abrir en pestaña ↗
Cargando el menú digital…
); } /* ---- Promo del día (miércoles de mariscos, etc.) ---- */ function getWeeklyPromo() { const p = EX_PROMOS[new Date().getDay()]; return p || null; } function WeeklyPromo({ promo, onCta }) { if (!promo) return null; return (
{promo.kicker}

{promo.title}

{promo.msg}

); } /* ---- Banner de platos sugeridos: solo Premium y Favorito ---- (la especialidad ya se destaca arriba, en el hero principal) */ function SuggestedBanner({ onOpen, store }) { const items = []; window.CATS.forEach(c => c.items.forEach(it => { if ((it.tag === "Favorito" || it.tag === "Premium") && itemAvailable(store, it.n)) items.push({ item: it, cat: c }); })); if (!items.length) return null; return (
El chef sugiere

Lo que no te puedes perder

{items.map(({ item, cat }, i) => ( ))}
); } /* ---- Cross-sell: relacionados dentro del modal ---- */ const PAIR_DRINKS = ["Limonada de Coco", "Borojó", "Limonada Cerezada"]; const PAIR_STARTERS = ["Ceviche de la casa", "Cóctel de camarón"]; function getRelated(item, cat, store) { const names = []; if (cat.id === "bebidas") { names.push("Pargo Rojo", "Arroz Marinero", "Ceviche de la casa"); } else if (cat.id === "entradas") { names.push("Pargo Rojo", "Cazuela de Mariscos", "Limonada de Coco"); } else { names.push(PAIR_STARTERS[0], PAIR_DRINKS[0], "Cazuela de Mariscos", EX_FEATURE.n); } const out = []; names.forEach(n => { if (n === item.n) return; if (!itemAvailable(store, n)) return; const f = findItem(n); if (f && !out.find(o => o.item.n === f.item.n)) out.push(f); }); return out.slice(0, 3); } function RelatedItems({ item, cat, store, onQuickAdd, onTotalChange }) { const rel = getRelated(item, cat, store); const [count, setCount] = useState({}); // {nombre: cuántos agregados} if (!rel.length) return null; function add(f) { onQuickAdd(f.item, f.cat); setCount(c => { const next = { ...c, [f.item.n]: (c[f.item.n] || 0) + 1 }; if (onTotalChange) { const sum = rel.reduce((s, r) => s + (next[r.item.n] || 0) * r.item.from, 0); onTotalChange(sum); } return next; }); } return (
Acompáñalo con · y queda redondo
{rel.map((f, i) => { const n = count[f.item.n] || 0; return (
{f.item.n} {n ? Agregado{n > 1 ? " ×" + n : ""} · en tu pedido : priceLabel(f.item)}
); })}
); } Object.assign(window, { PdfModal, getWeeklyPromo, WeeklyPromo, SuggestedBanner, getRelated, RelatedItems });