"use client"; import { create } from "zustand"; import { createJSONStorage, persist } from "zustand/middleware"; // Cuenta de cliente real conectada a Medusa (Store API, via // /api/customer/*), mismo patron que cart-store.ts: token + datos basicos // persistidos en localStorage, resincronizados contra el servidor al // rehidratar (el token puede llevar dias, o haber sido revocado). export interface Customer { id: string; email: string; firstName: string | null; lastName: string | null; } interface CustomerState { token: string | null; customer: Customer | null; hasHydrated: boolean; loading: boolean; error: string | null; setHasHydrated: (value: boolean) => void; register: (email: string, password: string, firstName: string, lastName: string) => Promise; login: (email: string, password: string) => Promise; logout: () => void; syncCustomer: () => Promise; } async function postJson(url: string, body: unknown) { const response = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), }); return response.json(); } function toCustomer(data: Record): Customer { return { id: data.id as string, email: data.email as string, firstName: (data.firstName as string | null) ?? null, lastName: (data.lastName as string | null) ?? null, }; } export const useCustomerStore = create()( persist( (set, get) => ({ token: null, customer: null, hasHydrated: false, loading: false, error: null, setHasHydrated: (value) => set({ hasHydrated: value }), register: async (email, password, firstName, lastName) => { set({ loading: true, error: null }); const result = await postJson("/api/customer/register", { email, password, firstName, lastName }); if (result.error) { set({ loading: false, error: result.error }); return false; } set({ loading: false, token: result.token, customer: toCustomer(result) }); return true; }, login: async (email, password) => { set({ loading: true, error: null }); const result = await postJson("/api/customer/login", { email, password }); if (result.error) { set({ loading: false, error: result.error }); return false; } set({ loading: false, token: result.token, customer: toCustomer(result) }); return true; }, logout: () => set({ token: null, customer: null, error: null }), // El token guardado en localStorage puede llevar dias o haber sido // revocado -- se refresca contra el servidor en vez de confiar en el // ultimo snapshot local. syncCustomer: async () => { const token = get().token; if (!token) return; try { const response = await fetch(`/api/customer/me?token=${encodeURIComponent(token)}`); if (!response.ok) { set({ token: null, customer: null }); return; } const result = await response.json(); if (result.id) set({ customer: toCustomer(result) }); } catch { // Sin red: se queda con el ultimo estado local conocido. } }, }), { name: "ari-shopping-customer-v1", storage: createJSONStorage(() => localStorage), partialize: (state) => ({ token: state.token, customer: state.customer }), onRehydrateStorage: () => (state) => { state?.setHasHydrated(true); void state?.syncCustomer(); }, }, ), );