/* global React, Spark, openLead, useBus */ const { useState: useStateCart, useEffect: useEffectCart, useCallback: useCbCart } = React; const PB2026 = "assets/products2026/"; const DISCOUNT = 0.3; function optPrice(rrp) { return Math.round((rrp || 0) * (1 - DISCOUNT)); } function fmtKzt(n) { return (n || 0).toLocaleString("ru-RU") + " ₸"; } /* ---- Cart store (module-level + localStorage + subscribe) ---------- */ const CART_KEY = "mereke_cart_v1"; function cartLoad() { try { return JSON.parse(localStorage.getItem(CART_KEY)) || {}; } catch (_) { return {}; } } let cartItems = cartLoad(); const cartListeners = new Set(); function cartPersist() { try { localStorage.setItem(CART_KEY, JSON.stringify(cartItems)); } catch (_) {} cartListeners.forEach((l) => l()); } // normalize a product OR box object into a cart line function cartItemFrom(p) { return { key: p.img, name: p.name || p.tier, kz: p.kz || "", img: p.img, rrp: p.rrp, price: optPrice(p.rrp) }; } function cartAdd(p) { const it = cartItemFrom(p); const k = it.key; cartItems[k] = cartItems[k] ? { ...cartItems[k], qty: cartItems[k].qty + 1 } : { ...it, qty: 1 }; cartPersist(); } function cartSetQty(k, q) { if (!cartItems[k]) return; if (q <= 0) delete cartItems[k]; else cartItems[k] = { ...cartItems[k], qty: q }; cartPersist(); } function cartRemove(k) { delete cartItems[k]; cartPersist(); } function cartClear() { cartItems = {}; cartPersist(); } function cartList() { return Object.values(cartItems); } function cartCount() { return cartList().reduce((s, i) => s + i.qty, 0); } function cartTotal() { return cartList().reduce((s, i) => s + (i.price || 0) * i.qty, 0); } function cartHas(key) { return !!cartItems[key]; } function useCart() { const [, force] = useStateCart(0); useEffectCart(() => { const l = () => force((x) => x + 1); cartListeners.add(l); return () => { cartListeners.delete(l); }; }, []); return { list: cartList(), count: cartCount(), total: cartTotal(), has: cartHas, add: cartAdd, setQty: cartSetQty, remove: cartRemove, clear: cartClear }; } function openCart() { window.dispatchEvent(new CustomEvent("mereke:cart")); } /* ---- Cart glyph (line icon) --------------------------------------- */ const CartGlyph = ({ style = {} }) => React.createElement("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", style, "aria-hidden": "true" }, React.createElement("circle", { cx: 9, cy: 20, r: 1.4 }), React.createElement("circle", { cx: 18, cy: 20, r: 1.4 }), React.createElement("path", { d: "M2 3h3l2.2 11.2a2 2 0 0 0 2 1.6h7.7a2 2 0 0 0 2-1.6L21.5 7H6.2" })); /* ---- Price block: РРЦ (strike) + −30% + opt price ------------------ */ function PriceTag({ rrp, onRed = false }) { if (!rrp) return null; return React.createElement("div", { className: `lp-price${onRed ? " on-red" : ""}` }, React.createElement("span", { className: "rrp" }, fmtKzt(rrp)), React.createElement("span", { className: "off" }, "−30%"), React.createElement("span", { className: "now" }, fmtKzt(optPrice(rrp)))); } /* ---- Add-to-cart button ------------------------------------------- */ function AddToCartBtn({ p, variant = "amber", block = true }) { const cart = useCart(); const inCart = cart.has(p.img); const onClick = (e) => { e.stopPropagation(); cart.add(p); }; return React.createElement("button", { type: "button", className: `lp-btn lp-btn-${variant} lp-btn-sm lp-addcart${inCart ? " in" : ""}`, onClick, style: block ? { width: "100%" } : {} }, React.createElement(CartGlyph, { style: { width: 15, height: 15 } }), inCart ? "В корзине · " + cartItems[p.img].qty : "В корзину"); } /* ---- Nav cart icon with count badge ------------------------------- */ function CartNavButton() { const { count } = useCart(); return React.createElement("button", { className: "lp-cart-ico", "aria-label": "Корзина", onClick: openCart }, React.createElement(CartGlyph, { style: { width: 22, height: 22 } }), count > 0 ? React.createElement("span", { className: "lp-cart-badge" }, count) : null); } /* ---- Cart row ------------------------------------------------------ */ function CartRow({ i, cart }) { const [val, setVal] = useStateCart(String(i.qty)); useEffectCart(() => { setVal(String(i.qty)); }, [i.qty]); const commit = () => { const n = parseInt(val, 10); cart.setQty(i.key, isNaN(n) ? 0 : Math.min(n, 999)); }; return React.createElement("div", { className: "lp-cart-item" }, React.createElement("div", { className: "thumb" }, React.createElement("img", { src: PB2026 + i.img, alt: i.name })), React.createElement("div", { className: "info" }, React.createElement("div", { className: "nm" }, i.name), React.createElement("div", { className: "pr" }, fmtKzt(i.price), " / шт")), React.createElement("div", { className: "ctrl" }, React.createElement("div", { className: "lp-qty" }, React.createElement("button", { type: "button", "aria-label": "Меньше", onClick: () => cart.setQty(i.key, i.qty - 1) }, "−"), React.createElement("input", { type: "text", inputMode: "numeric", "aria-label": "Количество", maxLength: 3, value: val, onChange: (e) => setVal(e.target.value.replace(/\D/g, "")), onFocus: (e) => e.target.select(), onBlur: commit, onKeyDown: (e) => { if (e.key === "Enter") e.target.blur(); } }), React.createElement("button", { type: "button", "aria-label": "Больше", onClick: () => cart.setQty(i.key, Math.min(i.qty + 1, 999)) }, "+")), React.createElement("div", { className: "line" }, fmtKzt(i.price * i.qty)), React.createElement("button", { type: "button", className: "rm", "aria-label": "Удалить", onClick: () => cart.remove(i.key) }, "×"))); } /* ---- Cart drawer (slide-in panel) --------------------------------- */ function CartDrawer() { const [open, setOpen] = useStateCart(false); const cart = useCart(); const close = useCbCart(() => setOpen(false), []); useBus("mereke:cart", useCbCart(() => setOpen(true), [])); useEffectCart(() => { if (!open) return; const onKey = (e) => { if (e.key === "Escape") close(); }; document.addEventListener("keydown", onKey); const prev = document.body.style.overflow; document.body.style.overflow = "hidden"; return () => { document.removeEventListener("keydown", onKey); document.body.style.overflow = prev; }; }, [open, close]); const checkout = () => { close(); openLead(); }; return React.createElement("div", { className: `lp-modal-back ${open ? "open" : ""}`, onClick: close, "aria-hidden": !open }, React.createElement("aside", { className: `lp-cartdrawer ${open ? "open" : ""}`, role: "dialog", "aria-label": "Корзина", onClick: (e) => e.stopPropagation() }, React.createElement("div", { className: "lp-cart-head" }, React.createElement("h3", null, "Корзина", cart.count ? React.createElement("span", { className: "cnt" }, cart.count) : null), React.createElement("button", { type: "button", className: "close", "aria-label": "Закрыть", onClick: close }, "×")), cart.list.length === 0 ? React.createElement("div", { className: "lp-cart-empty" }, React.createElement(CartGlyph, { style: { width: 44, height: 44, opacity: 0.28 } }), React.createElement("p", null, "Корзина пуста"), React.createElement("span", null, "Добавьте игрушки из каталога — соберём заказ одной заявкой."), React.createElement("button", { type: "button", className: "lp-btn lp-btn-red lp-btn-sm", onClick: close, style: { marginTop: 6 } }, "В каталог")) : React.createElement(React.Fragment, null, React.createElement("div", { className: "lp-cart-items" }, cart.list.map((i) => React.createElement(CartRow, { key: i.key, i, cart }))), React.createElement("div", { className: "lp-cart-foot" }, React.createElement("div", { className: "sum" }, React.createElement("span", null, "Итого"), React.createElement("b", null, fmtKzt(cart.total))), React.createElement("button", { type: "button", className: "lp-btn lp-btn-amber", style: { width: "100%" }, onClick: checkout }, "Оформить заявку", React.createElement(Spark, { style: { width: 15, height: 15 } })), React.createElement("button", { type: "button", className: "lp-cart-clear", onClick: cart.clear }, "Очистить корзину")))) ); } Object.assign(window, { useCart, openCart, optPrice, fmtKzt, cartItemFrom, cartList, cartTotal, cartCount, CartGlyph, PriceTag, AddToCartBtn, CartNavButton, CartDrawer });