import React, { createContext, useContext, useEffect, useState, useCallback } from 'react'; import { Customer, fetchMe, logoutCustomer } from './customerApi'; interface CustomerAuthValue { customer: Customer | null; loading: boolean; refresh: () => void; logout: () => Promise; } const CustomerAuthContext = createContext({ customer: null, loading: true, refresh: () => {}, logout: async () => {} }); export function useCustomerAuth() { return useContext(CustomerAuthContext); } export function CustomerAuthProvider({ children }: { children: React.ReactNode }) { const [customer, setCustomer] = useState(null); const [loading, setLoading] = useState(true); const refresh = useCallback(() => { setLoading(true); // A rejection here previously left `loading` true forever, which renders // as a permanent spinner rather than a signed-out page. void fetchMe() .then(c => setCustomer(c)) .catch(() => setCustomer(null)) .finally(() => setLoading(false)); }, []); useEffect(() => { refresh(); }, [refresh]); // Logging out has to clear the context, not just call the endpoint — // otherwise `customer` stays set and the header keeps offering "My Account" // until something happens to refetch. Clearing here rather than calling // refresh() avoids a window where the session is gone but the UI still shows // the customer as signed in. // // Rejects if the server did not accept the logout, leaving the customer // signed in, because the session cookie is still valid in that case. const logout = useCallback(async () => { await logoutCustomer(); setCustomer(null); setLoading(false); }, []); return ( {children} ); }