import { createContext, useCallback, useContext, useEffect, useMemo, useState, type ReactNode, } from "react"; import type { Member } from "../domain/types"; import type { MemberProfilePatch } from "../data/repos"; import { useRepos } from "../data/DataContext"; type AuthContextValue = { member: Member | null; loading: boolean; login: (email: string, password: string) => Promise; logout: () => Promise; reload: () => Promise; updateProfile: (patch: MemberProfilePatch) => Promise; }; const AuthContext = createContext(null); export function AuthProvider({ children }: { children: ReactNode }) { const repos = useRepos(); const [member, setMember] = useState(null); const [loading, setLoading] = useState(true); const reload = useCallback(async () => { // 已進過 app 後不要再把 loading=true:否則 RequireAuth 會卸載整棵 /app, // 各頁本地 state(如用量「全體」分頁)會被重掛成預設。 try { const me = await repos.auth.me(); setMember(me); } finally { setLoading(false); } }, [repos.auth]); useEffect(() => { void reload(); }, [reload]); const login = useCallback( async (email: string, password: string) => { const { member: m } = await repos.auth.login(email, password); setMember(m); }, [repos.auth], ); const logout = useCallback(async () => { await repos.auth.logout(); setMember(null); }, [repos.auth]); const updateProfile = useCallback( async (patch: MemberProfilePatch) => { const next = await repos.auth.updateProfile(patch); setMember(next); return next; }, [repos.auth], ); const value = useMemo( () => ({ member, loading, login, logout, reload, updateProfile }), [member, loading, login, logout, reload, updateProfile], ); return {children}; } export function useAuth(): AuthContextValue { const ctx = useContext(AuthContext); if (!ctx) throw new Error("useAuth must be used within AuthProvider"); return ctx; }