diff --git a/src/App.tsx b/src/App.tsx index 94bc59d4..90f7b320 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -61,10 +61,10 @@ const queryClient = new QueryClient({ function AppContent() { return ( - - - + + +
diff --git a/src/hooks/useAuth.tsx b/src/hooks/useAuth.tsx index 47662812..d8c04ef6 100644 --- a/src/hooks/useAuth.tsx +++ b/src/hooks/useAuth.tsx @@ -31,13 +31,8 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) { // Refs for lifecycle and cleanup management const isMountedRef = useRef(true); const profileFetchTimeoutRef = useRef(null); - const profileRetryCountRef = useRef(0); - const sessionVerifiedRef = useRef(false); const novuUpdateTimeoutRef = useRef(null); const previousEmailRef = useRef(null); - const loadingTimeoutRef = useRef(null); - const loadingStateRef = useRef(loading); - const lastVisibilityVerificationRef = useRef(Date.now()); const fetchProfile = async (userId: string) => { try { @@ -78,60 +73,37 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) { } }; - // Verify session is still valid + // Verify session is still valid - simplified const verifySession = async (updateLoadingState = false) => { - if (updateLoadingState && isMountedRef.current) { - setLoading(true); - } - try { const { data: { session }, error } = await supabase.auth.getSession(); if (error) { authError('[Auth] Session verification failed:', error); setSessionError(error.message); - if (updateLoadingState && isMountedRef.current) { - setLoading(false); - } return false; } if (!session) { authLog('[Auth] No active session found'); - if (updateLoadingState && isMountedRef.current) { - setLoading(false); - } return false; } authLog('[Auth] Session verified:', session.user.email); - sessionVerifiedRef.current = true; // Update state if session was found but not set if (!user && isMountedRef.current) { setSession(session); setUser(session.user); - sessionVerifiedRef.current = true; - } else if (updateLoadingState && isMountedRef.current) { - setLoading(false); } return true; } catch (error) { authError('[Auth] Session verification error:', error); - if (updateLoadingState && isMountedRef.current) { - setLoading(false); - } return false; } }; - // Keep loading state ref in sync - useEffect(() => { - loadingStateRef.current = loading; - authLog('[Auth] Loading state changed:', loading); - }, [loading]); - useEffect(() => { authLog('[Auth] Initializing auth provider'); @@ -153,35 +125,31 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) { // Update session and user state based on event if (event === 'SIGNED_IN' && session) { - authLog('[Auth] SIGNED_IN detected, setting session and user'); + authLog('[Auth] SIGNED_IN - user authenticated'); setSession(session); setUser(session.user); - sessionVerifiedRef.current = true; - setLoading(false); // Resolved - user exists + setLoading(false); } else if (event === 'INITIAL_SESSION') { if (session?.user) { - authLog('[Auth] INITIAL_SESSION with user, setting session'); + authLog('[Auth] INITIAL_SESSION - user exists'); setSession(session); setUser(session.user); - sessionVerifiedRef.current = true; - setLoading(false); // Resolved - user exists + setLoading(false); } else { - authLog('[Auth] INITIAL_SESSION with no user - setting loading to false'); + authLog('[Auth] INITIAL_SESSION - no user'); setSession(null); setUser(null); setProfile(null); - sessionVerifiedRef.current = false; - setLoading(false); // Resolved - no user - return; // Exit early, no need to fetch profile + setLoading(false); + return; } } else if (event === 'SIGNED_OUT') { - authLog('[Auth] SIGNED_OUT detected, clearing all state'); + authLog('[Auth] SIGNED_OUT - clearing state'); setSession(null); setUser(null); setProfile(null); - sessionVerifiedRef.current = false; setLoading(false); - return; // Exit early, no need to fetch profile + return; } else { setSession(session); setUser(session?.user ?? null); @@ -279,57 +247,10 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) { authLog('[Auth] getSession completed, session exists:', !!session); }); - // Add a STRONG safety timeout to force loading to resolve - loadingTimeoutRef.current = setTimeout(() => { - if (loadingStateRef.current) { - authWarn('[Auth] ⚠️ SAFETY TIMEOUT: Forcing loading to false after 3 seconds'); - setLoading(false); - } - }, 3000); - - // Session verification fallback - const verificationTimeout = setTimeout(() => { - if (!sessionVerifiedRef.current) { - authLog('[Auth] Session not verified after 2s, attempting manual verification'); - verifySession(); - } - }, 2000); - - // Handle page visibility changes - only verify if inactive for >5 minutes - const handleVisibilityChange = () => { - const timeSinceLastCheck = Date.now() - lastVisibilityVerificationRef.current; - const FIVE_MINUTES = 5 * 60 * 1000; - - console.log('🔐 [AUTH] Visibility changed', { - state: document.visibilityState, - timeSinceLastCheck: Math.round(timeSinceLastCheck / 1000) + 's', - willVerifySession: document.visibilityState === 'visible' && timeSinceLastCheck > FIVE_MINUTES - }); - - if (document.visibilityState === 'visible') { - if (timeSinceLastCheck > FIVE_MINUTES) { - authLog('[Auth] Tab visible after 5+ minutes, verifying session'); - console.log(' ⚠️ Verifying session - this may cause component re-renders'); - lastVisibilityVerificationRef.current = Date.now(); - verifySession(); - } else { - authLog('[Auth] Tab visible, session recently verified, skipping'); - console.log(' ✅ Session recently verified, skipping verification'); - } - } - }; - - document.addEventListener('visibilitychange', handleVisibilityChange); - return () => { authLog('[Auth] Cleaning up auth provider'); isMountedRef.current = false; subscription.unsubscribe(); - clearTimeout(verificationTimeout); - if (loadingTimeoutRef.current) { - clearTimeout(loadingTimeoutRef.current); - } - document.removeEventListener('visibilitychange', handleVisibilityChange); // Clear any pending timeouts if (profileFetchTimeoutRef.current) {