// Rein clientseitiger Warenkorb (Phase 1, kein Backend). Speichert im localStorage. // TODO Phase 2: durch echten Cloudflare-Worker-Warenkorb/Checkout ersetzen. import { getProduct } from "../data/products"; import { effektiverZeilenpreis } from "../data/rabatt"; import { findeGutschein, gutscheinRabatt, type Gutschein } from "../data/gutscheine"; export interface CartItem { slug: string; name: string; preis: number; menge: number; // Ob dieser Artikel gerade gekauft werden soll oder nur "im Warenkorb liegen bleibt" für // später. Fehlt das Feld (ältere, bereits gespeicherte Warenkörbe), gilt es als ausgewählt — // siehe istAusgewaehlt(). ausgewaehlt?: boolean; } /** true, sofern nicht explizit auf false gesetzt — hält ältere localStorage-Warenkörbe ohne * dieses Feld weiterhin vollständig "ausgewählt" (kein Verhaltensbruch für Bestandsbesucher). */ export function istAusgewaehlt(item: CartItem): boolean { return item.ausgewaehlt !== false; } const KEY = "vandiy_cart_v1"; export function getCart(): CartItem[] { if (typeof localStorage === "undefined") return []; try { return JSON.parse(localStorage.getItem(KEY) || "[]"); } catch { return []; } } export function saveCart(items: CartItem[]) { localStorage.setItem(KEY, JSON.stringify(items)); window.dispatchEvent(new CustomEvent("cart:changed", { detail: items })); } export function addToCart(item: Omit, menge = 1) { const cart = getCart(); const existing = cart.find((i) => i.slug === item.slug); if (existing) { existing.menge += menge; } else { cart.push({ ...item, menge }); } saveCart(cart); } export function updateQuantity(slug: string, menge: number) { let cart = getCart(); if (menge <= 0) { cart = cart.filter((i) => i.slug !== slug); } else { const item = cart.find((i) => i.slug === slug); if (item) item.menge = menge; } saveCart(cart); } export function removeFromCart(slug: string) { saveCart(getCart().filter((i) => i.slug !== slug)); } /** Legt fest, ob ein Artikel jetzt gekauft werden soll (true) oder nur im Warenkorb liegen * bleibt, ohne mitgekauft zu werden (false) — z.B. wenn man sich noch nicht sicher ist. */ export function setAusgewaehlt(slug: string, ausgewaehlt: boolean) { const cart = getCart(); const item = cart.find((i) => i.slug === slug); if (item) item.ausgewaehlt = ausgewaehlt; saveCart(cart); } export function cartCount(): number { return getCart().reduce((sum, i) => sum + i.menge, 0); } // Zwischensumme inkl. Produkt-Rabatt (Prozent/Betrag) UND Mengenrabatt-Staffel — schaut sich // dafür live die aktuellen Produktdaten an (nicht den bei addToCart gespeicherten Preis), damit // ein nachträglich geänderter/abgelaufener Rabatt sich sofort korrekt auswirkt. Zählt NUR // Artikel, die gerade zum Kauf ausgewählt sind — abgewählte Artikel bleiben im Warenkorb liegen, // fließen aber nicht in Summe/Checkout ein. export function cartTotal(): number { return getCart() .filter(istAusgewaehlt) .reduce((sum, i) => { const produkt = getProduct(i.slug); return sum + (produkt ? effektiverZeilenpreis(produkt, i.menge) : i.menge * i.preis); }, 0); } const COUPON_KEY = "vandiy_coupon_v1"; export function getCouponCode(): string { if (typeof localStorage === "undefined") return ""; return localStorage.getItem(COUPON_KEY) || ""; } export function setCouponCode(code: string) { localStorage.setItem(COUPON_KEY, code.trim()); window.dispatchEvent(new CustomEvent("cart:changed", { detail: getCart() })); } export function clearCoupon() { localStorage.removeItem(COUPON_KEY); window.dispatchEvent(new CustomEvent("cart:changed", { detail: getCart() })); } /** Der aktuell eingelöste Gutschein, falls der gespeicherte Code (noch) gültig ist. */ export function appliedCoupon(): Gutschein | undefined { const code = getCouponCode(); if (!code) return undefined; return findeGutschein(code); } /** Rabatt-Betrag in Euro, den der eingelöste Gutschein auf die gegebene Zwischensumme gibt. */ export function couponDiscount(subtotal: number): number { const g = appliedCoupon(); return g ? gutscheinRabatt(g, subtotal) : 0; }