import { createContext, useContext, useState, useEffect, useCallback, type ReactNode, } from 'react'; import { getMe, login as apiLogin, logout as apiLogout } from '../api/auth'; import { setOnUnauthorized } from '../api/client'; interface AuthState { user: { login: string } | null; loading: boolean; error: string | null; login: (username: string, password: string) => Promise; logout: () => Promise; } const AuthContext = createContext(null); export function AuthProvider({ children }: { children: ReactNode }) { const [user, setUser] = useState<{ login: string } | null>(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const clearUser = useCallback(() => { setUser(null); }, []); useEffect(() => { setOnUnauthorized(clearUser); getMe() .then((me) => setUser({ login: me.login })) .catch(() => setUser(null)) .finally(() => setLoading(false)); }, [clearUser]); const login = useCallback(async (username: string, password: string) => { setError(null); try { await apiLogin({ login: username, password }); const me = await getMe(); setUser({ login: me.login }); } catch (e: unknown) { const msg = e instanceof Error ? e.message : 'Ошибка входа'; setError(msg); throw e; } }, []); const logout = useCallback(async () => { try { await apiLogout(); } finally { setUser(null); } }, []); return ( {children} ); } export function useAuth(): AuthState { const ctx = useContext(AuthContext); if (!ctx) throw new Error('useAuth must be used within AuthProvider'); return ctx; }