import { createContext, useContext, useState, useEffect, type ReactNode } from 'react'; import { getAccessToken, clearTokens, setTokens, apiFetch } from './api'; type User = { id: string; email: string; name: string; hasPassword?: boolean }; type AuthContextType = { user: User | null; loading: boolean; login: (email: string, password: string) => Promise; register: (email: string, password: string, name: string) => Promise; logout: () => void; updateUser: (updates: Partial) => void; loginWithTokens: (accessToken: string, refreshToken: string) => Promise; }; const AuthContext = createContext(null); export function AuthProvider({ children }: { children: ReactNode }) { const [user, setUser] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { if (getAccessToken()) { apiFetch('/auth/me') .then(setUser) .catch(() => clearTokens()) .finally(() => setLoading(false)); } else { setLoading(false); } }, []); const login = async (email: string, password: string) => { const data = await apiFetch<{ user: User; accessToken: string; refreshToken: string }>( '/auth/login', { method: 'POST', body: JSON.stringify({ email, password }) }, ); setTokens(data.accessToken, data.refreshToken); setUser(data.user); }; const register = async (email: string, password: string, name: string) => { const data = await apiFetch<{ user: User; accessToken: string; refreshToken: string }>( '/auth/register', { method: 'POST', body: JSON.stringify({ email, password, name }) }, ); setTokens(data.accessToken, data.refreshToken); setUser(data.user); }; const logout = () => { clearTokens(); setUser(null); }; const updateUser = (updates: Partial) => { setUser(prev => prev ? { ...prev, ...updates } : null); }; const loginWithTokens = async (access: string, refresh: string) => { setTokens(access, refresh); const user = await apiFetch('/auth/me'); setUser(user); }; return ( {children} ); } export function useAuth() { const ctx = useContext(AuthContext); if (!ctx) throw new Error('useAuth must be used within AuthProvider'); return ctx; }