/* global React, ReactDOM, Icon, Button, Badge, Sheet, ToastHost,
HomeScreen, CatalogScreen, ProductScreen, CartScreen, CheckoutScreen,
ServicesScreen, WholesaleScreen, FilterContent, BotFlow, useState, useEffect */
function Header({ route, go, cartCount, shipBar = true }) {
const titles = { catalog: "Catálogo", cart: "Tu carrito", checkout: "Checkout", services: "Servicios", mayorista: "Mayorista", confirm: "Compra confirmada" };
const showBack = ["checkout"].includes(route);
return (
{route === "home" && shipBar && (
Envío gratis en Chivilcoy · Asesoramiento sin cargo
)}
{showBack ? (
) : (
)}
{route === "home" || route === "catalog" ? (
go("catalog")}>
) : (
{titles[route]}
)}
);
}
const ic = { width: 44, height: 44, display: "grid", placeItems: "center", borderRadius: 12 };
function TabBar({ route, go, cartCount }) {
const tabs = [
{ id: "home", label: "Inicio", icon: "home" },
{ id: "catalog", label: "Catálogo", icon: "grid" },
{ id: "cart", label: "Carrito", icon: "cart", badge: cartCount },
{ id: "services", label: "Servicios", icon: "spark" },
{ id: "mayorista", label: "Mayorista", icon: "store" },
];
return (
{tabs.map((t) => (
))}
);
}
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
"accent": "#0077b6",
"radius": "redondo",
"display": "Schibsted Grotesk",
"shipBar": true
}/*EDITMODE-END*/;
// Paletas de acento curadas: cada una recalcula la rampa primary por hue
const ACCENTS = {
"#0077b6": { soft: "#e6f7ff", s200: "#99d7f4", s300: "#5fbcea", s500: "#0a87c6", s700: "#005d8f", s900: "#003f63" },
"#1f8a5b": { soft: "#e6f4ed", s200: "#a9dcc5", s300: "#74c7a3", s500: "#23a06b", s700: "#13633f", s900: "#0d4630" },
"#e8521e": { soft: "#fdeee7", s200: "#f9c9b3", s300: "#f4a684", s500: "#f06a36", s700: "#b53d10", s900: "#7a2c0e" },
"#102a3a": { soft: "#e9f2f8", s200: "#c4d6e2", s300: "#93a8b6", s500: "#24414f", s700: "#16303d", s900: "#0a1c27" },
};
const RADII = {
"recto": { sm: "3px", md: "5px", lg: "7px", xl: "10px" },
"medio": { sm: "6px", md: "10px", lg: "14px", xl: "20px" },
"redondo":{ sm: "10px", md: "16px", lg: "22px", xl: "28px" },
};
function App() {
const NOGO = window.NOGO;
const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
useEffect(() => {
const r = document.documentElement.style;
const a = ACCENTS[t.accent] || ACCENTS["#0077b6"];
r.setProperty("--color-primary-600", t.accent);
r.setProperty("--color-primary-700", a.s700);
r.setProperty("--color-primary-800", a.s700);
r.setProperty("--color-primary-900", a.s900);
r.setProperty("--color-primary-500", a.s500);
r.setProperty("--color-primary-300", a.s300);
r.setProperty("--color-primary-200", a.s200);
r.setProperty("--color-primary-50", a.soft);
const rad = RADII[t.radius] || RADII.medio;
Object.entries(rad).forEach(([k, v]) => r.setProperty(`--radius-${k}`, v));
r.setProperty("--font-display", `"${t.display}", "Helvetica Neue", Arial, sans-serif`);
}, [t.accent, t.radius, t.display]);
const [stack, setStack] = useState(["home"]);
const route = stack[stack.length - 1];
const [product, setProduct] = useState(null);
const [cart, setCart] = useState([]);
const [filters, setFilters] = useState({ use: null, colorFam: null });
const [filterOpen, setFilterOpen] = useState(false);
const [bot, setBot] = useState(null); // {product, presId, color}
const [toasts, setToasts] = useState([]);
const go = (to) => {
if (to === -1) { setStack((s) => (s.length > 1 ? s.slice(0, -1) : s)); return; }
if (to === route) return;
setStack((s) => [...s, to]);
};
const openProduct = (p) => { setProduct(p); setStack((s) => [...s, "product"]); };
const addToast = (msg, opts = {}) => {
const id = Date.now() + Math.random();
setToasts((t) => [...t, { id, msg, ...opts }]);
setTimeout(() => setToasts((t) => t.filter((x) => x.id !== id)), 2600);
};
const cartCount = cart.reduce((n, i) => n + i.qty, 0);
const onAdd = ({ product, presId, color }) => setBot({ product, presId, color });
const startAdvisor = () => {
const product = NOGO.products.find((p) => p.featured) || NOGO.products[0];
const presId = product.pres[Math.min(1, product.pres.length - 1)];
const fam = product.colors[0];
const color = NOGO.palette[fam][2] || NOGO.palette[fam][0];
setBot({ product, presId, color });
};
useEffect(() => {
if (window.NOGO_DEPLOY_MODE && window.location.hash === "#asesor") {
startAdvisor();
}
}, []);
const onBotConfirm = (items) => {
setCart((prev) => {
const next = [...prev];
items.forEach((it) => {
const k = next.findIndex((x) => x.productId === it.productId && x.presId === it.presId && (x.color?.hex || null) === (it.color?.hex || null));
if (k >= 0) next[k] = { ...next[k], qty: next[k].qty + it.qty };
else next.push(it);
});
return next;
});
setBot(null);
addToast("Agregado al carrito", { tone: "success", icon: "check" });
setStack((s) => (s[s.length - 1] === "product" ? s.slice(0, -1) : s));
};
const setQty = (idx, q) => setCart((c) => c.map((it, i) => (i === idx ? { ...it, qty: q } : it)));
const removeItem = (idx) => setCart((c) => c.filter((_, i) => i !== idx));
const onPlace = () => { setStack((s) => [...s, "confirm"]); };
// limpiar carrito al confirmar
useEffect(() => { if (route === "confirm") { setTimeout(() => setCart([]), 400); } }, [route]);
const openFilters = (k, v) => {
if (k) { setFilters((f) => ({ ...f, [k]: f[k] === v ? null : v })); }
else setFilterOpen(true);
};
const showChrome = !["product", "checkout", "confirm"].includes(route) || route === "checkout";
const showTabs = ["home", "catalog", "cart", "services", "mayorista"].includes(route);
return (
{route !== "product" && route !== "confirm" &&
}
{route === "home" &&
}
{route === "catalog" &&
}
{route === "product" && product &&
}
{route === "cart" &&
}
{route === "checkout" &&
}
{route === "services" &&
}
{route === "mayorista" &&
}
{route === "confirm" &&
}
{showTabs &&
}
{filterOpen && (
setFilterOpen(false)}
footer={}>
setFilterOpen(false)} />
)}
{bot && (
<>
setBot(null)} />
setBot(null)} />
>
)}
{toasts.length > 0 &&
}
{!window.NOGO_DEPLOY_MODE && window.TweaksPanel && ReactDOM.createPortal(
setTweak("accent", v)} />
setTweak("radius", v)} />
setTweak("display", v)} />
setTweak("shipBar", v)} />
,
document.body
)}
);
}
function ConfirmScreen({ go }) {
return (
¡Gracias por tu compra!
Te enviamos el comprobante por email. Podés seguir tu pedido desde Mi cuenta.
N° de pedido#NGP-{Math.floor(1000 + Math.random() * 9000)}
);
}
Object.assign(window, { MobileApp: App });
if (!window.NOGO_SKIP_AUTOMOUNT) {
ReactDOM.createRoot(document.getElementById("root")).render(
);
}