// W2Go shared UI atoms — photo placeholders, buttons, chips, navbar, etc. const { useState, useEffect, useRef, useMemo } = React; // ─── Photo placeholder ───────────────────────────────────────── // Striped slot with monospace caption — drop a real product shot in later. function Photo({ tag = 'food shot', tone = 'cream', radius = 18, height = 200, width = '100%', stripes = true, scrim = false, src, alt, children, style = {} }) { const tones = { cream: { bg: '#EFE6D6', fg: '#7A6E58', stripe: 'rgba(0,76,75,0.06)' }, green: { bg: '#0F5C5B', fg: '#CBE3E2', stripe: 'rgba(255,255,255,0.05)' }, onyx: { bg: '#1F2222', fg: '#9BA09F', stripe: 'rgba(255,255,255,0.04)' }, charcoal: { bg: '#3B353E', fg: '#B6AEB7', stripe: 'rgba(255,255,255,0.05)' }, warm: { bg: '#E9D6BC', fg: '#735C3A', stripe: 'rgba(0,0,0,0.05)' }, }; const t = tones[tone] || tones.cream; return (
{src ? ( {alt ) : (stripes &&
)} {scrim &&
} {!src && (
img · {tag}
)}
{children}
); } // ─── Buttons ─────────────────────────────────────────────────── function Btn({ children, kind = 'primary', size = 'lg', icon, iconRight, onClick, full, style = {}, disabled, animate = false }) { const sizes = { lg: { h: 56, px: 26, fs: 16, r: 999 }, md: { h: 46, px: 20, fs: 14, r: 999 }, sm: { h: 36, px: 14, fs: 13, r: 999 }, }; const kinds = { primary: { bg: 'var(--w-onyx)', fg: 'var(--w-cream)' }, onyx: { bg: 'var(--w-onyx)', fg: 'var(--w-cream)' }, green: { bg: 'var(--w-green)', fg: 'var(--w-cream)' }, cream: { bg: 'var(--w-cream)', fg: 'var(--w-onyx)' }, ghost: { bg: 'transparent', fg: 'var(--w-onyx)', border: '1.5px solid rgba(23,25,25,0.18)' }, ghostInv: { bg: 'transparent', fg: 'var(--w-cream)', border: '1.5px solid rgba(249,242,232,0.35)' }, danger: { bg: '#C24A2C', fg: '#fff' }, }; const s = sizes[size]; const k = kinds[kind]; return ( ); } // ─── Chip / tag ──────────────────────────────────────────────── function Chip({ children, active, onClick, kind = 'default', style = {} }) { const kinds = { default: { bg: 'rgba(23,25,25,0.06)', fg: 'var(--w-onyx)', abg: 'var(--w-onyx)', afg: 'var(--w-cream)' }, green: { bg: 'rgba(0,76,75,0.10)', fg: 'var(--w-green)', abg: 'var(--w-green)', afg: 'var(--w-cream)' }, cream: { bg: 'var(--w-cream)', fg: 'var(--w-onyx)', abg: 'var(--w-cream)', afg: 'var(--w-onyx)' }, }; const k = kinds[kind]; return ( ); } // ─── Tiny tag (top-left of food cards) ──────────────────────── function TinyTag({ children, color = '#004C4B' }) { return {children}; } // ─── Top bar (back / title / right) ─────────────────────────── function TopBar({ onBack, title, right, dark = false, transparent = false, style = {} }) { const fg = dark ? '#F9F2E8' : '#171919'; return (
{title}
{right}
); } // ─── Bottom tab bar ─────────────────────────────────────────── function TabBar({ active, onChange, badge = 0 }) { const tabs = [ { id: 'home', label: 'Home', icon: Ic.Home }, { id: 'search', label: 'Browse', icon: Ic.Search }, { id: 'cart', label: 'Bag', icon: Ic.Bag, badge }, { id: 'orders', label: 'Orders', icon: Ic.Receipt }, { id: 'account', label: 'You', icon: Ic.User }, ]; return (
{tabs.map(t => { const isActive = active === t.id; const I = t.icon; return ( ); })}
); } // ─── Bottom CTA dock ────────────────────────────────────────── function BottomDock({ children, dark = false, style = {} }) { return (
{children}
); } // ─── W2GO wordmark ──────────────────────────────────────────── // Bold sans, all-caps, condensed — echoes the real W2GO mark // where "2" sits on the same baseline as W and GO. function Wordmark({ size = 40, color = '#F9F2E8', sub = 'CRAFTED BY W DOHA' }) { return (
W2GO
{sub &&
{sub}
}
); } // ─── Scroll-area utility (auto bottom padding) ──────────────── function Scroll({ children, pad = 120, style = {} }) { return (
{children}
); } Object.assign(window, { Photo, Btn, Chip, TinyTag, TopBar, TabBar, BottomDock, Wordmark, Scroll });