Add real order persistence, customer accounts, and cart sync

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>
This commit is contained in:
Marco
2026-07-22 06:45:42 +00:00
parent 516945fc8c
commit 7f37f111e8
27 changed files with 1697 additions and 89 deletions
+18
View File
@@ -106,3 +106,21 @@ export function useCartCount(): number {
export function useCart(): CartItem[] {
return useSyncExternalStore(subscribe, getCart, () => EMPTY_CART);
}
// Called right after a successful login (LoginForm.tsx, CheckoutContent.tsx's
// inline login toggle) — folds whatever was saved server-side into the
// local cart by quantity (addToCart adds to an existing line rather than
// overwriting it), so items added before logging in aren't lost. CartSync
// then picks up the resulting change and pushes the merged cart back to
// the server on its own, closing the loop without a separate save call here.
export async function mergeServerCartIntoLocal(): Promise<void> {
try {
const res = await fetch("/api/account/cart");
if (!res.ok) return;
const data: { cart?: CartItem[] } = await res.json();
for (const item of data.cart ?? []) addToCart(item.id, item.qty);
} catch {
// Best-effort — a failed merge just means the server-side cart stays
// as it was; nothing local is lost either way.
}
}