"use client" import React, { createContext, useContext, useEffect, useState } from 'react' import { safeLocalStorage } from '@/lib/utils' import { logout as logoutApi } from '@/components/apis/authApiClients' interface User { id: string email: string username: string role?: 'user' | 'admin' } interface AuthContextValue { user: User | null isAdmin: boolean isLoading: boolean setUserFromApi: (user: User) => void logout: () => Promise } const AuthContext = createContext(undefined) export function AuthProvider({ children }: { children: React.ReactNode }) { const [user, setUser] = useState(null) const [isLoading, setIsLoading] = useState(true) useEffect(() => { const stored = safeLocalStorage.getItem('codenuk_user') const accessToken = safeLocalStorage.getItem('accessToken') const refreshToken = safeLocalStorage.getItem('refreshToken') console.log('🔐 [AuthContext] Checking localStorage for user data...') console.log('🔐 [AuthContext] Stored user data:', stored) console.log('🔐 [AuthContext] Access token exists:', !!accessToken) console.log('🔐 [AuthContext] Refresh token exists:', !!refreshToken) console.log('🔐 [AuthContext] Token details:', { accessTokenLength: accessToken?.length || 0, refreshTokenLength: refreshToken?.length || 0, timestamp: new Date().toISOString() }) // Only restore user if we have both user data AND at least one token if (stored && (accessToken || refreshToken)) { try { const userData = JSON.parse(stored) console.log('🔐 [AuthContext] Restoring user session:', userData?.username) console.log('🔐 [AuthContext] User ID from localStorage:', userData?.id) setUser(userData) } catch (error) { console.error('Failed to parse stored user data:', error) safeLocalStorage.removeItem('codenuk_user') } } else { console.log('🔐 [AuthContext] No valid user session found') // Clear any partial data if (stored && !accessToken && !refreshToken) { console.log('🔐 [AuthContext] Clearing orphaned user data without tokens') safeLocalStorage.removeItem('codenuk_user') } } setIsLoading(false) }, []) // Listen for storage changes to sync auth state across tabs useEffect(() => { const handleStorageChange = (e: StorageEvent) => { if (e.key === 'codenuk_user' || e.key === 'accessToken' || e.key === 'refreshToken') { console.log('🔐 [AuthContext] Storage changed, re-checking auth state') const stored = safeLocalStorage.getItem('codenuk_user') const accessToken = safeLocalStorage.getItem('accessToken') const refreshToken = safeLocalStorage.getItem('refreshToken') if (stored && (accessToken || refreshToken)) { try { const userData = JSON.parse(stored) setUser(userData) } catch (error) { console.error('Failed to parse user data after storage change:', error) setUser(null) } } else { setUser(null) } } } window.addEventListener('storage', handleStorageChange) return () => window.removeEventListener('storage', handleStorageChange) }, []) const setUserFromApi = (u: User) => { console.log('🔐 [AuthContext] Setting user from API:', u) console.log('🔐 [AuthContext] User ID being set:', u?.id) setUser(u) safeLocalStorage.setItem('codenuk_user', JSON.stringify(u)) console.log('🔐 [AuthContext] User data saved to localStorage') } const logout = async () => { try { // Call the logout API to invalidate tokens on the server await logoutApi() } catch (error) { console.error('Logout API call failed:', error) // Continue with local logout even if API call fails } finally { // Always clear local data setUser(null) safeLocalStorage.removeItem('codenuk_user') safeLocalStorage.removeItem('accessToken') safeLocalStorage.removeItem('refreshToken') // Redirect to signin page window.location.href = '/signin' } } return ( {children} ) } export function useAuth() { const ctx = useContext(AuthContext) if (!ctx) throw new Error('useAuth must be used within AuthProvider') return ctx }