// src/shell.jsx — top chrome: logo, address switcher, search, account, cart button. Works on desktop and mobile (responsive via useMedia hook). function useMedia(query) { const [m, setM] = React.useState(() => typeof window !== "undefined" && window.matchMedia(query).matches); React.useEffect(() => { const mq = window.matchMedia(query); const fn = () => setM(mq.matches); mq.addEventListener ? mq.addEventListener("change", fn) : mq.addListener(fn); return () => mq.removeEventListener ? mq.removeEventListener("change", fn) : mq.removeListener(fn); }, [query]); return m; } function TopBar({ nav, cart, onNav, onOpenCart, onOpenSearch, address, onOpenAddress, isDark, onToggleDark }) { const isMobile = useMedia("(max-width: 720px)"); const cartCount = cart.items.reduce((s, x) => s + x.qty, 0); return (
{/* Logo */} {/* Address + time pill (desktop only) */} {!isMobile && ( )} {/* Search box */} {/* Right side */} {!isMobile && ( )} {!isMobile && ( )}
); } // Mobile bottom-nav (optional — matches mobile convention) function MobileTabBar({ current, onNav }) { const isMobile = useMedia("(max-width: 720px)"); if (!isMobile) return null; const tabs = [ { id: "home", label: "Home", icon: "Home" }, { id: "search", label: "Search", icon: "Search" }, { id: "orders", label: "Orders", icon: "Receipt" }, { id: "account", label: "Account", icon: "User" }, ]; return ( ); } // Global site footer — shown below every screen. Mirrors the voice of // opalink.com (neighborhood marketplace, shop independent, real humans). function SiteFooter({ onNav }) { const isMobile = useMedia("(max-width: 720px)"); const cols = [ { title: "Marketplace", links: [ { label: "How Opa works", to: { screen: "home" } }, { label: "Stores near you", to: { screen: "home" } }, { label: "Ask Opa", to: { screen: "home" } }, { label: "Your orders", to: { screen: "orders" } }, ]}, { title: "For shops", links: [ { label: "List your store" }, { label: "Merchant support" }, { label: "Opa for bodegas" }, { label: "Local producers" }, ]}, { title: "Company", links: [ { label: "About" }, { label: "Press" }, { label: "Careers" }, { label: "Contact" }, ]}, ]; return ( ); } Object.assign(window, { TopBar, MobileTabBar, useMedia, SiteFooter });