TheBird

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(",")}` : "");