// aerOS Guest v2 — Menu screen: hero + featured + sticky scroll-spy nav + live search + filters + sections.
const { useState: _mn2S, useRef: _mn2R, useMemo: _mn2M, useEffect: _mn2E } = React;
function G2Menu({ C, t, lang, tw, onSelect, onQuickAdd, onCart, onWaiter, cartCount, cartTotal, onLang, onCurrency, brand, brandSub, onBack, onSettings }) {
const D = window.G2DATA;
const animate = tw.animate;
const [activeCat, setActiveCat] = _mn2S(D.CATS[0].id);
const [q, setQ] = _mn2S('');
const [showSearch, setShowSearch] = _mn2S(false);
const [diet, setDiet] = _mn2S([]);
const MAXP = 750, MAXC = 900;
const [priceMax, setPriceMax] = _mn2S(MAXP);
const [calMax, setCalMax] = _mn2S(MAXC);
const scroller = _mn2R(null), navRef = _mn2R(null), pillBar = _mn2R(null);
const secRefs = _mn2R({}), pillRefs = _mn2R({});
const clickScroll = _mn2R(false);
const staggerCls = animate ? 'g2-stagger' : '';
const name = p => lang === 'en' ? p.en : p.name;
const filterCount = diet.length + (priceMax < MAXP ? 1 : 0) + (calMax < MAXC ? 1 : 0);
const searching = q.trim() || filterCount > 0;
const matches = p => {
if (diet.length && !diet.every(d => p.diet.includes(d))) return false;
if (p.price > priceMax) return false;
if (p.cal > calMax) return false;
if (q.trim()) { const ql = q.toLowerCase(); return (p.name + ' ' + p.en + ' ' + p.desc + ' ' + p.en_desc).toLowerCase().includes(ql); }
return true;
};
const flat = _mn2M(() => D.PRODUCTS.filter(matches), [q, diet, priceMax, calMax]);
const featured = _mn2M(() => D.PRODUCTS.filter(p => p.badge === 'chef' || p.badge === 'signature' || p.badge === 'popular').slice(0, 6), []);
const dietCounts = _mn2M(() => { const c = {}; ['veg', 'vegan', 'gf', 'spicy'].forEach(d => c[d] = D.PRODUCTS.filter(p => p.diet.includes(d)).length); return c; }, []);
// scroll spy
const onScroll = () => {
if (clickScroll.current || searching || !scroller.current || !navRef.current) return;
const navBottom = navRef.current.getBoundingClientRect().bottom;
let cur = D.CATS[0].id;
for (const c of D.CATS) { const el = secRefs.current[c.id]; if (el && el.getBoundingClientRect().top - navBottom < 16) cur = c.id; }
setActiveCat(cur);
};
_mn2E(() => { // keep active pill visible
const pill = pillRefs.current[activeCat], bar = pillBar.current;
if (pill && bar) { const want = pill.offsetLeft - bar.offsetWidth / 2 + pill.offsetWidth / 2; bar.scrollTo({ left: Math.max(0, want), behavior: 'smooth' }); }
}, [activeCat]);
const goCat = (id) => {
setActiveCat(id);
const el = secRefs.current[id]; if (!el || !scroller.current || !navRef.current) return;
const navH = navRef.current.offsetHeight;
const delta = el.getBoundingClientRect().top - scroller.current.getBoundingClientRect().top - navH - 6;
clickScroll.current = true;
scroller.current.scrollTo({ top: scroller.current.scrollTop + delta, behavior: 'smooth' });
setTimeout(() => { clickScroll.current = false; }, 520);
};
const layout = tw.layout;
const gridStyle = layout === 'gallery' ? { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 } : layout === 'text' ? { display: 'block' } : { display: 'flex', flexDirection: 'column', gap: layout === 'magazine' ? 16 : 11 };
const toggleDiet = d => setDiet(s => s.includes(d) ? s.filter(x => x !== d) : [...s, d]);
const _ctx = window.G2CTX || {};
const modeLabel = tw.mode === 'room' ? (t.roomLabel + (_ctx.room ? ' ' + _ctx.room : '')) : tw.mode === 'view' ? t.viewOnly : (t.tableLabel + (_ctx.table ? ' ' + _ctx.table : ''));
// ── HERO ──
const langSwitch = (onDark) => (
);
const iconBtn = (icon, onClick, onDark, label) => (
);
const rightCluster = (onDark) => (
{langSwitch(onDark)}
{onSettings && iconBtn(Icon.settings, onSettings, onDark, t.settings)}
);
let hero;
if (tw.heroStyle === 'minimal') {
hero = (
{onBack ? iconBtn(Icon.chevLeft, onBack, false, t.back) : }
{rightCluster(false)}
{modeLabel}
{brand}
{brandSub}
);
} else if (tw.heroStyle === 'gradient') {
hero = (
{onBack && iconBtn(Icon.chevLeft, onBack, true, t.back)}
{Icon.utensils({ size: 13 })}{modeLabel}
{rightCluster(true)}
{brand}
{brandSub}
);
} else { // photo
hero = (
{onBack && iconBtn(Icon.chevLeft, onBack, true, t.back)}
{Icon.utensils({ size: 13 })}{modeLabel}
{rightCluster(true)}
{t.welcome}
{brand}
{brandSub}
);
}
return (
{hero}
{/* featured carousel */}
{tw.featured && !searching && (
{Icon.sparkles({ size: 17 })}
{t.featured}
{featured.map(p => (
))}
)}
{/* sticky bar: search + filters + category nav */}
{Icon.search({ size: 18 })}
setQ(e.target.value)} placeholder={t.search} style={{ flex: 1, border: 'none', background: 'transparent', outline: 'none', fontSize: 14.5, fontFamily: G2THEME.BODY_FONT, color: C.ink }} />
{q && }
{!searching && (
tw.catNav === 'tabs' ? (
{D.CATS.map(c => { const on = activeCat === c.id; return (
); })}
) : (
{D.CATS.map(c => pillRefs.current[c.id] = el}> goCat(c.id)} C={C}>{lang === 'en' ? c.en : c.name})}
)
)}
{/* body */}
0 ? 150 : 96 }}>
{searching ? (
flat.length === 0 ? (
{Icon.search({ size: 28 })}
{t.noResults}
) : (
<>
{flat.length} {t.items}
{flat.map((p, i) => )}
>
)
) : (
D.CATS.map(c => {
const items = D.PRODUCTS.filter(p => p.cat === c.id);
if (!items.length) return null;
return (
secRefs.current[c.id] = el} style={{ marginBottom: 26, scrollMarginTop: 120 }}>
{lang === 'en' ? c.en : c.name}
{items.length} {t.items}
{items.map((p, i) => )}
);
})
)}
{/* filter sheet */}
setShowSearch(false)} C={C} t={t} tw={tw} diet={diet} toggleDiet={toggleDiet} counts={dietCounts} priceMax={priceMax} setPriceMax={setPriceMax} calMax={calMax} setCalMax={setCalMax} maxP={MAXP} maxC={MAXC} resultCount={flat.length} onClear={() => { setDiet([]); setPriceMax(MAXP); setCalMax(MAXC); }} animate={animate} />
{/* floating actions */}
{cartCount > 0 && (
)}
{tw.mode !== 'view' && (
)}
);
}
window.G2Menu = G2Menu;