cart.ts
2.3 kB · typescript · 92 lines
1import { CART_KEY } from "../config/shop.ts";23declare const SHOP: string;45type Line = { id: string; key: string; title: string; size: string; price: string; image: string; qty: number };67/* STORE */89const EMPTY: Line[] = [];1011const shop = () => (typeof SHOP === "string" ? SHOP : "");1213const listeners = new Set<() => void>();1415let lines: Line[] = EMPTY;1617let ready = false;1819function read(): Line[] {20 try {21 const raw = localStorage.getItem(CART_KEY);22 const items = raw ? JSON.parse(raw) : [];23 return Array.isArray(items) ? items : EMPTY;24 } catch {25 return EMPTY;26 }27}2829const tell = () => {30 for (const fn of listeners) fn();31};3233const sync = (event: StorageEvent) => {34 if (event.key && event.key !== CART_KEY) return;35 lines = read();36 tell();37};3839export function load(): Line[] {40 if (!ready && typeof window !== "undefined") {41 ready = true;42 lines = read();43 }44 return lines;45}4647export const server = () => EMPTY;4849export function subscribe(fn: () => void) {50 if (!listeners.size) addEventListener("storage", sync);51 listeners.add(fn);52 return () => {53 listeners.delete(fn);54 if (!listeners.size) removeEventListener("storage", sync);55 };56}5758function save(items: Line[]) {59 try {60 if (items.length) localStorage.setItem(CART_KEY, JSON.stringify(items));61 else localStorage.removeItem(CART_KEY);62 } catch {}63 ready = true;64 lines = items;65 tell();66 return items;67}6869export function add(line: Omit<Line, "qty">) {70 const items = load().map((item) => ({ ...item }));71 const found = items.find((item) => item.id === line.id);72 if (found) found.qty += 1;73 else items.push({ ...line, qty: 1 });74 return save(items);75}7677export const remove = (id: string) => save(load().filter((item) => item.id !== id));7879export function setQty(id: string, qty: number) {80 if (qty < 1) return remove(id);81 return save(load().map((item) => (item.id === id ? { ...item, qty } : item)));82}8384export const clear = () => save([]);8586/* SUMS */8788export const count = (items: Line[]) => items.reduce((sum, item) => sum + item.qty, 0);8990export const total = (items: Line[]) => items.reduce((sum, item) => sum + Number(item.price) * item.qty, 0).toFixed(2);9192export const checkoutUrl = (items: Line[]) => (items.length && shop() ? `https://${shop()}/cart/${items.map((item) => `${item.id}:${item.qty}`).join(",")}` : "");