export interface Customer { id: number; email: string; name: string | null; email_verified: boolean; marketing_consent: boolean; created_at: string; } export interface OrderHistoryItem { id: number; processor: string; amount_cents: number; status: string; created_at: string; item_name: string; } async function handle(res: Response): Promise { if (!res.ok) { const data = await res.json().catch(() => ({})); throw new Error(data.error || 'Request failed'); } return res.json(); } export function registerCustomer(email: string, password: string, name: string, marketingConsent: boolean): Promise { return fetch('/api/customers/register', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, password, name, marketingConsent }) }).then(res => handle(res)); } export function loginCustomer(email: string, password: string): Promise { return fetch('/api/customers/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, password }) }).then(res => handle(res)); } export function verifyEmail(token: string): Promise<{ status: string }> { return fetch('/api/customers/verify-email', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ token }) }).then(res => handle<{ status: string }>(res)); } export function logoutCustomer(): Promise { // Not routed through handle(): logout answers 204 with no body, so parsing // JSON would throw on success. The failure case still has to reject — the // session cookie survives a failed logout, so reporting success would leave // the customer logged in and silently signed back in on their next reload. return fetch('/api/customers/logout', { method: 'POST' }).then(async (res) => { if (!res.ok) { const data = await res.json().catch(() => ({})); throw new Error(data.error || 'Request failed'); } }); } export function fetchMe(): Promise { return fetch('/api/customers/me').then(res => (res.ok ? res.json() : null)); } export function updateConsent(marketingConsent: boolean): Promise { return fetch('/api/customers/me/consent', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ marketingConsent }) }).then(() => undefined); } export function fetchMyOrders(): Promise { return fetch('/api/customers/me/orders').then(res => handle(res)); } export function deleteMyAccount(): Promise { return fetch('/api/customers/me', { method: 'DELETE' }).then(() => undefined); } export function exportMyData(): void { window.location.href = '/api/customers/me/export'; } export function requestPasswordReset(email: string): Promise<{ status: string }> { return fetch('/api/customers/request-password-reset', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email }) }).then(res => handle<{ status: string }>(res)); } export function resetPassword(token: string, password: string): Promise { return fetch('/api/customers/reset-password', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ token, password }) }).then(res => handle(res)); }