7f37f111e8
Checkout now persists orders server-side (Payload orders collection, re-priced from live product data, discount codes redeemed exactly once) instead of writing a client-only sessionStorage snapshot. Buying requires an account (registration inline in checkout, no separate step) — accounts get order history with delivery status, profile/address editing, password change, and a cart that syncs across devices while logged in. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
39 lines
1.3 KiB
TypeScript
39 lines
1.3 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useRef } from "react";
|
|
import { useCart } from "../lib/cart";
|
|
|
|
// Mirrors the local cart to the server whenever it changes, so a logged-in
|
|
// customer's cart follows them across devices (see Customers.ts's `cart`
|
|
// field). Renders nothing — mounted once in the root layout. Debounced
|
|
// (not fired on every keystroke-equivalent quantity bump) and silently a
|
|
// no-op when logged out — POST /api/account/cart 401s in that case, which
|
|
// this component doesn't need to distinguish from success; there's simply
|
|
// nothing to keep in sync yet.
|
|
export function CartSync() {
|
|
const cart = useCart();
|
|
const isFirstRender = useRef(true);
|
|
|
|
useEffect(() => {
|
|
// Skip the mount-time fire — this would otherwise POST on every page
|
|
// load even when nothing actually changed.
|
|
if (isFirstRender.current) {
|
|
isFirstRender.current = false;
|
|
return;
|
|
}
|
|
const timeout = setTimeout(() => {
|
|
fetch("/api/account/cart", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({ cart }),
|
|
}).catch(() => {
|
|
// Best-effort — a failed sync just means the next cart change (or
|
|
// the next login-time merge) tries again.
|
|
});
|
|
}, 800);
|
|
return () => clearTimeout(timeout);
|
|
}, [cart]);
|
|
|
|
return null;
|
|
}
|