// 彤冠茶莊 website — App root (router + cart + language state) const { products: TG_PRODUCTS, i18n: TG_I18N, journal: TG_JOURNAL } = window.TG; function useStored(key, initial) { const [v, setV] = React.useState(() => { try { const s = localStorage.getItem(key); return s != null ? JSON.parse(s) : initial; } catch (e) { return initial; } }); React.useEffect(() => { try { localStorage.setItem(key, JSON.stringify(v)); } catch (e) {} }, [key, v]); return [v, setV]; } function App() { const [lang, setLang] = useStored("tg_lang", "zh"); const [route, setRoute] = React.useState({ name: "home", param: null }); const [cart, setCart] = useStored("tg_cart", []); const [cartOpen, setCartOpen] = React.useState(false); const t = TG_I18N[lang]; React.useEffect(() => { document.documentElement.lang = lang; }, [lang]); React.useEffect(() => { if (window.lucide) window.lucide.createIcons(); }); const go = (name, param = null) => { setRoute({ name, param }); if (name !== "product") window.scrollTo({ top: 0, behavior: "instant" in window ? "instant" : "auto" }); else window.scrollTo(0, 0); }; const addToCart = (id, qty = 1) => { setCart((c) => { const ex = c.find((x) => x.id === id); if (ex) return c.map((x) => x.id === id ? { ...x, qty: x.qty + qty } : x); return [...c, { id, qty }]; }); setCartOpen(true); }; const setQty = (id, n) => setCart((c) => c.map((x) => x.id === id ? { ...x, qty: n } : x)); const removeItem = (id) => setCart((c) => c.filter((x) => x.id !== id)); const clearCart = () => setCart([]); const cartCount = cart.reduce((s, x) => s + x.qty, 0); let page; if (route.name === "shop") page = ; else if (route.name === "product") page = ; else if (route.name === "checkout") page = ; else if (route.name === "story") page = ; else if (route.name === "journal") page = ; else page = ; return (
setCartOpen(true)} /> {page}
); } window.App = App;