this repo has no description
at fix-ts-uint8array 102 lines 2.5 kB view raw
1import { createContext, useState, useEffect, useCallback, type ReactNode } from 'react'; 2import { apiClient } from '../api/client'; 3 4const TOKEN_KEY = 'ayos_token'; 5 6export interface UserResponse { 7 id: string; 8 username: string; 9 email: string; 10} 11 12interface AuthState { 13 user: UserResponse | null; 14 token: string | null; 15 loading: boolean; 16} 17 18export interface AuthContextValue extends AuthState { 19 login: (email: string, password: string) => Promise<void>; 20 register: (username: string, email: string, password: string) => Promise<void>; 21 logout: () => void; 22} 23 24export const AuthContext = createContext<AuthContextValue | null>(null); 25 26interface LoginResponse { 27 token: string; 28 user: UserResponse; 29} 30 31interface RegisterResponse { 32 token: string; 33 user: UserResponse; 34} 35 36export function AuthProvider({ children }: { children: ReactNode }) { 37 const [state, setState] = useState<AuthState>({ 38 user: null, 39 token: localStorage.getItem(TOKEN_KEY), 40 loading: true, 41 }); 42 43 useEffect(() => { 44 const token = localStorage.getItem(TOKEN_KEY); 45 if (!token) { 46 setState({ user: null, token: null, loading: false }); 47 return; 48 } 49 50 apiClient 51 .get<UserResponse>('/api/me') 52 .then((user) => { 53 setState({ user, token, loading: false }); 54 }) 55 .catch(() => { 56 localStorage.removeItem(TOKEN_KEY); 57 setState({ user: null, token: null, loading: false }); 58 }); 59 }, []); 60 61 const login = useCallback(async (email: string, password: string) => { 62 const data = await apiClient.post<LoginResponse>('/api/login', { 63 email, 64 password, 65 }); 66 localStorage.setItem(TOKEN_KEY, data.token); 67 setState({ user: data.user, token: data.token, loading: false }); 68 }, []); 69 70 const register = useCallback( 71 async (username: string, email: string, password: string) => { 72 const data = await apiClient.post<RegisterResponse>('/api/register', { 73 username, 74 email, 75 password, 76 }); 77 localStorage.setItem(TOKEN_KEY, data.token); 78 setState({ user: data.user, token: data.token, loading: false }); 79 }, 80 [], 81 ); 82 83 const logout = useCallback(() => { 84 localStorage.removeItem(TOKEN_KEY); 85 setState({ user: null, token: null, loading: false }); 86 }, []); 87 88 return ( 89 <AuthContext.Provider 90 value={{ 91 user: state.user, 92 token: state.token, 93 loading: state.loading, 94 login, 95 register, 96 logout, 97 }} 98 > 99 {children} 100 </AuthContext.Provider> 101 ); 102}