/* ============================================================ ATUKASA SUSHI — App principal (Rail layout) ============================================================ */ const { useState, useEffect, useRef, useMemo } = React; const REVIEWS_DATA = [ { name: "María A.", rating: "★★★★★", text: "El mejor sushi de San Cristóbal, sin discusión. El crispy chicken lo pedimos cada vez que vamos.", time: "Hace 2 sem." }, { name: "Carlos M.", rating: "★★★★★", text: "Nunca pensé encontrar sushi así aquí. El tempura roll con queso Philadelphia te cambia la vida.", time: "Hace 1 mes" }, { name: "Ana L.", rating: "★★★★★", text: "Lo mejor que tiene San Cristóbal. Los dumplings son perfectos. Volvemos siempre.", time: "Hace 3 sem." }, { name: "Lucia P.", rating: "★★★★★", text: "Primera vez comiendo sushi y ahora soy adicta. El crispy con plátano maduro es increíble.", time: "Hace 1 mes" }, { name: "Roberto F.", rating: "★★★★★", text: "He comido en la capital y el de Atukasa está igual de bueno. Calidad real en San Cristóbal.", time: "Hace 2 m." }, { name: "Diana V.", rating: "★★★★★", text: "El delivery siempre a tiempo y el sushi en perfectas condiciones. Muy recomendado.", time: "Hace 1 sem." }, ]; function ReviewsTicker() { const all = [...REVIEWS_DATA, ...REVIEWS_DATA]; return (
{all.map((r, i) => (
{r.name.charAt(0)}
{r.name}
{r.rating}
{r.time}

{r.text}

))}
); } function App() { const { CATEGORIES, PRODUCTS, BUSINESS } = window.ATUKASA; const [active, setActive] = useState(CATEGORIES[0].id); const [modal, setModal] = useState(null); const [cartOpen, setCartOpen] = useState(false); const [loyaltyOpen, setLoyaltyOpen] = useState(false); const { user, login } = useLoyalty(); const [items, setItems] = useState(() => { try { return JSON.parse(localStorage.getItem("atukasa_cart") || "[]"); } catch (e) { return []; } }); const [toast, setToast] = useState(null); const scrollRef = useRef(null); const sectionRefs = useRef({}); const lockSpy = useRef(false); useEffect(() => { localStorage.setItem("atukasa_cart", JSON.stringify(items)); }, [items]); const countByCat = useMemo(() => { const m = {}; PRODUCTS.forEach((p) => { m[p.cat] = (m[p.cat] || 0) + 1; }); return m; }, []); const cartCount = items.reduce((s, it) => s + it.qty, 0); const cartTotal = items.reduce((s, it) => s + it.unit * it.qty, 0); const goToCat = (id) => { setActive(id); const cont = scrollRef.current; if (!cont) return; lockSpy.current = true; if (id === "promos") { cont.scrollTo({ top: cont.scrollHeight, behavior: "smooth" }); } else { const el = sectionRefs.current[id]; if (el) cont.scrollTo({ top: el.offsetTop - 8, behavior: "smooth" }); } setTimeout(() => { lockSpy.current = false; }, 600); }; const onScroll = () => { if (lockSpy.current) return; const cont = scrollRef.current; const top = cont.scrollTop + 80; let current = CATEGORIES[0].id; for (const c of CATEGORIES) { const el = sectionRefs.current[c.id]; if (el && el.offsetTop <= top) current = c.id; } setActive((a) => (a === current ? a : current)); }; const addItem = (item) => { setItems((cur) => { const found = cur.find((x) => x.key === item.key); if (found) return cur.map((x) => x.key === item.key ? { ...x, qty: x.qty + item.qty } : x); return [...cur, item]; }); setToast(item.name + " agregado"); setTimeout(() => setToast(null), 1800); }; const setQty = (key, q) => setItems((cur) => cur.map((x) => x.key === key ? { ...x, qty: q } : x)); const removeItem = (key) => setItems((cur) => cur.filter((x) => x.key !== key)); const clearCart = () => setItems([]); const now = new Date(); const isOpen = BUSINESS.openDays.includes(now.getDay()) && now.getHours() >= BUSINESS.openFrom && now.getHours() < BUSINESS.openTo; const mapsUrl = "https://google.com/maps/place/AtuKasa+Sushi/data=!4m2!3m1!1s0x0:0xaed0104586fa4d07?sa=X&ved=1t:2428&ictx=111"; return (
{/* ── HEADER ── */}
Atukasa Sushi ATUKASA SUSHI
San Cristóbal {isOpen ? "Abierto ahora" : "Cerrado"}
setLoyaltyOpen(true)} /> setLoyaltyOpen(true)} />
{/* ── LAYOUT ── */}
{/* HERO */}
The Dominikkei Experience

El sabor de

sentirse bien.

La fusión perfecta entre Japón y República Dominicana. Pide en segundos desde tu celular: elige porciones, agrega toppings y ordena por WhatsApp.

{/* SECCIONES */} {CATEGORIES.map((c) => { const prods = PRODUCTS.filter((p) => p.cat === c.id); return (
(sectionRefs.current[c.id] = el)}>

{c.name}

{c.note}

{prods.length > 0 && ( {prods.length} {prods.length === 1 ? "plato" : "platos"} )}
{prods.length === 0 && c.id === "promos" ? (
Los miércoles son de todos

Empanizados

gratis.
) : prods.length === 0 ? (
%

Próximamente

Estamos cocinando nuevas promociones para ti. Vuelve pronto o escríbenos por WhatsApp para conocer las ofertas del día.

) : prods.map((p) => ( ))}
); })} {/* FOOTER */}

Visítanos

{/* Dirección + GPS */}
{BUSINESS.address} {BUSINESS.hoursLabel} · {isOpen ? "Abierto ahora" : "Cerrado"} 18°25'N, 70°06'O · Ver en Google Maps
{/* Reseñas Google (reemplaza Delivery) */}
Lo que dice la gente Ver en Google Maps →
{/* Redes */}
{BUSINESS.ig} Instagram · Facebook · TikTok

{BUSINESS.web} · Precios en RD$ con ITBIS incluido. Imágenes de referencia, reemplazables por fotos reales.

{/* BARRA MÓVIL */} {cartCount > 0 && ( )} {/* LOYALTY MODAL */} {loyaltyOpen && setLoyaltyOpen(false)} member={user} />} {/* MODAL */} {modal && setModal(null)} onAdd={addItem} />} {/* DRAWER */} setCartOpen(false)} onQty={setQty} onRemove={removeItem} onClear={clearCart} user={user} onOpenLoyalty={() => setLoyaltyOpen(true)} /> {/* TOAST */} {toast && (
{toast}
)}
); } ReactDOM.createRoot(document.getElementById("root")).render();