"use client"; import { useSyncExternalStore } from "react"; // Mirrors lib/cart.ts's exact pattern (localStorage + useSyncExternalStore) // so an applied discount survives the /cart → /checkout transition the // same way the cart itself does — Checkout only ever displays this, it // has no input of its own (see CartContent.tsx for where a code gets // applied via /api/discount/validate). const DISCOUNT_KEY = "ep_discount"; const DISCOUNT_EVENT = "ep-discount-updated"; export type AppliedDiscount = { code: string; type: "percent" | "fixed"; value: number }; function writeDiscount(discount: AppliedDiscount | null) { if (discount) window.localStorage.setItem(DISCOUNT_KEY, JSON.stringify(discount)); else window.localStorage.removeItem(DISCOUNT_KEY); window.dispatchEvent(new Event(DISCOUNT_EVENT)); } export function applyDiscount(discount: AppliedDiscount) { writeDiscount(discount); } // Called after a completed purchase (order.ts's clearCart() sibling) and // by the cart's own "Entfernen" affordance. export function clearDiscount() { writeDiscount(null); } // Cached-by-raw-string, not a fresh JSON.parse() every call — same // reasoning as lib/cart.ts's getCart(): useSyncExternalStore requires // getSnapshot to return the same reference when nothing actually changed. let cachedRaw: string | null | undefined; let cachedDiscount: AppliedDiscount | null = null; export function getDiscount(): AppliedDiscount | null { if (typeof window === "undefined") return null; const raw = window.localStorage.getItem(DISCOUNT_KEY); if (raw === cachedRaw) return cachedDiscount; cachedRaw = raw; try { cachedDiscount = raw ? JSON.parse(raw) : null; } catch { cachedDiscount = null; } return cachedDiscount; } function subscribe(onStoreChange: () => void) { window.addEventListener(DISCOUNT_EVENT, onStoreChange); window.addEventListener("storage", onStoreChange); return () => { window.removeEventListener(DISCOUNT_EVENT, onStoreChange); window.removeEventListener("storage", onStoreChange); }; } export function useDiscount(): AppliedDiscount | null { return useSyncExternalStore(subscribe, getDiscount, () => null); }