/* store-app.jsx — top-level state (cart, wishlist, quick view), cart drawer,
cursor glow, and page assembly. */
const { Button: ABtn } = window.FluvexDesignsDesignSystem_072666;
const { CursorGlow: ACursorGlow, StoreIcon: AIcon } = window;
const {
Hero, TrustBar, Marquee, BestSellers, Shop, Categories, Bundle, Gallery,
Why, HowItWorks, Reviews, FAQ, FinalCTA, Footer, QuickView,
} = window;
/* ---- Cart drawer ---- */
function CartDrawer({ open, items, onClose, onQty, onRemove }) {
React.useEffect(() => {
if (open) document.body.style.overflow = "hidden";
else document.body.style.overflow = "";
return () => { document.body.style.overflow = ""; };
}, [open]);
// Escape closes the drawer (desktop). Listener lives only while open, so
// no duplicate handlers accumulate.
React.useEffect(() => {
if (!open) return;
const onKey = (e) => { if (e.key === "Escape") onClose(); };
window.addEventListener("keydown", onKey);
return () => window.removeEventListener("keydown", onKey);
}, [open, onClose]);
const total = items.reduce((s, it) => s + it.product.price * it.qty, 0);
return (
<>
>
);
}
/* ---- Toast ---- */
function Toast({ msg }) {
return (
);
}
function App() {
// Cart persists across refreshes via localStorage. Read is defensive:
// any parse/shape error falls back to an empty cart instead of throwing.
const [cart, setCart] = React.useState(() => {
try {
const raw = localStorage.getItem("fx_cart_v1");
const parsed = raw ? JSON.parse(raw) : [];
return Array.isArray(parsed) ? parsed.filter((it) => it && it.product && it.product.id) : [];
} catch (e) { return []; }
});
React.useEffect(() => {
try { localStorage.setItem("fx_cart_v1", JSON.stringify(cart)); } catch (e) {}
}, [cart]);
const [wishes, setWishes] = React.useState(new Set());
const [quick, setQuick] = React.useState(null);
const [cartOpen, setCartOpen] = React.useState(false);
const [toast, setToast] = React.useState("");
const toastTimer = React.useRef(null);
const showToast = (m) => {
setToast(m);
clearTimeout(toastTimer.current);
toastTimer.current = setTimeout(() => setToast(""), 1800);
};
const addToCart = (p) => {
setCart((c) => {
const found = c.find((it) => it.product.id === p.id);
if (found) return c.map((it) => it.product.id === p.id ? { ...it, qty: it.qty + 1 } : it);
return [...c, { product: p, qty: 1 }];
});
showToast(`Added “${p.title}” to cart`);
if (window.FluvexTracking) window.FluvexTracking.trackAddToCart(p);
};
const changeQty = (id, d) => setCart((c) => c.map((it) => it.product.id === id ? { ...it, qty: Math.max(1, it.qty + d) } : it));
const removeItem = (id) => {
if (window.FluvexTracking) { const found = cart.find((it) => it.product.id === id); if (found) window.FluvexTracking.trackRemoveFromCart(found.product); }
setCart((c) => c.filter((it) => it.product.id !== id));
};
const openQuick = (p) => { setQuick(p); if (window.FluvexTracking) window.FluvexTracking.trackQuickView(p); };
const toggleWish = (id) => setWishes((w) => { const n = new Set(w); n.has(id) ? n.delete(id) : n.add(id); return n; });
const cartCount = cart.reduce((s, it) => s + it.qty, 0);
const openCart = () => setCartOpen(true);
const pickFilter = () => {}; // filter handled inside Shop; anchor scroll is enough
return (
{quick &&
setQuick(null)} onAdd={addToCart} />}
setCartOpen(false)} onQty={changeQty} onRemove={removeItem} />
);
}
ReactDOM.createRoot(document.getElementById("root")).render();