"use client"; import React, { createContext, useContext, useState, useEffect, useRef } from 'react'; import { usePathname } from 'next/navigation'; import { useRouter } from 'next/navigation'; import { apiLayer } from '@/lib/api'; type UserData = { id: number; email: string; name: string; is_admin: boolean; avatar_url?: string | null; google_avatar_url?: string | null; created_at?: string | null; }; type AuthContextType = { isAuthenticated: boolean; user: UserData | null; loading: boolean; logout: () => void; updateUser: (data: Partial) => void; }; const AuthContext = createContext({ isAuthenticated: false, user: null, loading: true, logout: () => {}, updateUser: () => {} }); export function AuthProvider({ children }: { children: React.ReactNode }) { const [isAuthenticated, setIsAuthenticated] = useState(false); const [user, setUser] = useState(null); const [loading, setLoading] = useState(true); // Guard against double-execution in React StrictMode / Next.js App Router // (router from useRouter() gets a new identity on every render, so we NEVER // put it in the dep array — we check auth exactly once on mount) const hasFetched = useRef(false); const router = useRouter(); const pathname = usePathname(); useEffect(() => { if (hasFetched.current) return; hasFetched.current = true; setLoading(true); apiLayer.getCurrentUser() .then((res) => { setUser(res.data); setIsAuthenticated(true); }) .catch(() => { setIsAuthenticated(false); setUser(null); // Only redirect to login from protected routes if (pathname?.includes('/dashboard') || pathname?.includes('/profile')) { router.push('/login'); } }) .finally(() => { setLoading(false); }); // Empty deps: intentional. Auth is checked once on mount, never on re-render. // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const logout = () => { localStorage.removeItem("access_token"); setIsAuthenticated(false); setUser(null); hasFetched.current = false; // Allow re-check after logout router.push("/login"); }; const updateUser = (data: Partial) => { setUser(prev => prev ? { ...prev, ...data } : null); }; return ( {children} ); } export const useAuth = () => useContext(AuthContext);