// single definition of the cart item shape - imported by every page script // that touches the cart. price_cents is authoritative naming; the server // re-prices from the catalog at checkout regardless. export interface CartItem { slug: string; name: string; name_en: string; price_cents: number; image: string; unit_size: number; unit: string; stock: number; qty: number; } const KEY = 'cart'; export function getCart(): CartItem[] { try { const raw = JSON.parse(localStorage.getItem(KEY) || '[]'); if (!Array.isArray(raw)) return []; return raw.filter(it => it && typeof it.slug === 'string' && Number.isFinite(it.price_cents) && Number.isInteger(it.qty) && it.qty > 0).map(it => ({ ...it, unit_size: it.unit_size || 100, unit: it.unit || 'g', stock: it.stock || 99, image: resolveImage(it.image || ''), name_en: it.name_en || it.name || '', })); } catch { return []; } } function save(cart: CartItem[]) { localStorage.setItem(KEY, JSON.stringify(cart)); window.dispatchEvent(new CustomEvent('cart-updated')); } function resolveImage(raw: string): string { try { const arr = JSON.parse(raw); return arr?.[0] || raw || '/images/logo.png'; } catch { return raw || '/images/logo.png'; } } export function addToCart(item: Omit, qty = 1) { const cart = getCart(); const existing = cart.find(it => it.slug === item.slug); const resolved = { ...item, unit_size: item.unit_size || 100, unit: item.unit || 'g', stock: item.stock || 99, image: resolveImage(item.image) }; const limit = resolved.stock; if (existing) { existing.qty = Math.min(limit, existing.qty + qty); } else { cart.push({ ...resolved, qty: Math.min(limit, Math.max(1, qty)) }); } save(cart); } export function setQty(index: number, qty: number) { const cart = getCart(); if (!cart[index]) return; const limit = cart[index].stock; const newQty = Math.min(limit, Math.max(0, qty)); if (newQty < 1) { cart.splice(index, 1); } else { cart[index].qty = newQty; } save(cart); } export function removeItem(index: number) { const cart = getCart(); cart.splice(index, 1); save(cart); } export function clearCart() { save([]); } export function cartCount(): number { return getCart().reduce((sum, it) => sum + it.qty, 0); } export function cartSubtotalCents(): number { return getCart().reduce((sum, it) => sum + it.price_cents * it.qty, 0); } export function formatLv(cents: number): string { return (cents / 100).toFixed(2) + ' EUR'; } export function escapeHtml(s: string): string { return s.replace(/[&<>"']/g, c => ({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[c]!)); }