'use client'; import React, { createContext, useContext, useState, useEffect, useCallback } from 'react'; import { authApi, usersApi, User } from './api'; interface AcceptedProject { projectId: string; projectName: string; } interface AuthContextValue { user: User | null; token: string | null; loading: boolean; acceptedProjects: AcceptedProject[]; justRegisteredName: string; clearAcceptedProjects: () => void; login: (email: string, password: string) => Promise; register: (email: string, name: string, password: string, inviteToken?: string) => Promise; logout: () => Promise; refreshUser: () => Promise; updateUserData: (data: Partial) => void; } const AuthContext = createContext(null); export function AuthProvider({ children }: { children: React.ReactNode }) { const [user, setUser] = useState(null); const [token, setToken] = useState(null); const [loading, setLoading] = useState(true); const [acceptedProjects, setAcceptedProjects] = useState([]); const [justRegisteredName, setJustRegisteredName] = useState(''); useEffect(() => { const savedToken = localStorage.getItem('vidreview_token'); const savedUser = localStorage.getItem('vidreview_user'); if (savedToken && savedUser) { setToken(savedToken); try { setUser(JSON.parse(savedUser)); } catch { localStorage.removeItem('vidreview_token'); localStorage.removeItem('vidreview_user'); } } setLoading(false); }, []); const clearAcceptedProjects = useCallback(() => setAcceptedProjects([]), []); const login = useCallback(async (email: string, password: string) => { const { user: u, token: t, acceptedProjects: ap } = await authApi.login({ email, password }); localStorage.setItem('vidreview_token', t); localStorage.setItem('vidreview_user', JSON.stringify(u)); setToken(t); setUser(u); setAcceptedProjects(ap ?? []); }, []); const register = useCallback(async (email: string, name: string, password: string, inviteToken?: string) => { const result = await authApi.register({ email, name, password, inviteToken }); const { user: u, token: t, acceptedProjects: ap, userName } = result; localStorage.setItem('vidreview_token', t); localStorage.setItem('vidreview_user', JSON.stringify(u)); setToken(t); setUser(u); setAcceptedProjects(ap ?? []); setJustRegisteredName(userName ?? name); }, []); const logout = useCallback(async () => { try { await authApi.logout(); } catch { /* ignore */ } localStorage.removeItem('vidreview_token'); localStorage.removeItem('vidreview_user'); setToken(null); setUser(null); setAcceptedProjects([]); }, []); const refreshUser = useCallback(async () => { if (!token) return; try { const { user: u } = await usersApi.getMe(token); setUser(u); localStorage.setItem('vidreview_user', JSON.stringify(u)); } catch { /* ignore refresh errors */ } }, [token]); const updateUserData = useCallback((data: Partial) => { setUser(prev => { if (!prev) return prev; const updated = { ...prev, ...data }; localStorage.setItem('vidreview_user', JSON.stringify(updated)); return updated; }); }, []); return ( {children} ); } export function useAuth() { const ctx = useContext(AuthContext); if (!ctx) throw new Error('useAuth must be used within AuthProvider'); return ctx as Required; }