| import { createContext, useContext, useEffect, useState, type ReactNode } from "react"; |
| import { api, getToken, setToken } from "./api"; |
| import type { User } from "./types"; |
|
|
| interface AuthState { |
| user: User | null; |
| loading: boolean; |
| login: (email: string, password: string) => Promise<User>; |
| register: (b: { name: string; email: string; password: string; zip: string; phone?: string }) => Promise<void>; |
| logout: () => void; |
| } |
|
|
| const AuthContext = createContext<AuthState | null>(null); |
|
|
| export function AuthProvider({ children }: { children: ReactNode }) { |
| const [user, setUser] = useState<User | null>(null); |
| const [loading, setLoading] = useState(true); |
|
|
| useEffect(() => { |
| if (!getToken()) { |
| setLoading(false); |
| return; |
| } |
| api |
| .me() |
| .then(setUser) |
| .catch(() => setToken(null)) |
| .finally(() => setLoading(false)); |
| }, []); |
|
|
| async function login(email: string, password: string): Promise<User> { |
| const { access_token } = await api.login({ email, password }); |
| setToken(access_token); |
| const me = await api.me(); |
| setUser(me); |
| return me; |
| } |
|
|
| async function register(b: { name: string; email: string; password: string; zip: string; phone?: string }) { |
| const { access_token } = await api.register(b); |
| setToken(access_token); |
| setUser(await api.me()); |
| } |
|
|
| function logout() { |
| setToken(null); |
| setUser(null); |
| } |
|
|
| return ( |
| <AuthContext.Provider value={{ user, loading, login, register, logout }}> |
| {children} |
| </AuthContext.Provider> |
| ); |
| } |
|
|
| export function useAuth(): AuthState { |
| const ctx = useContext(AuthContext); |
| if (!ctx) throw new Error("useAuth must be used within AuthProvider"); |
| return ctx; |
| } |
|
|