From 4d40bb75694f545eceaa1a2ef797974a93e28f49 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sat, 11 Oct 2025 16:28:30 +0000 Subject: [PATCH] Fix: Resolve perpetual loading state --- src/hooks/useAuth.tsx | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/hooks/useAuth.tsx b/src/hooks/useAuth.tsx index 7ef53641..87335f99 100644 --- a/src/hooks/useAuth.tsx +++ b/src/hooks/useAuth.tsx @@ -35,6 +35,7 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) { const novuUpdateTimeoutRef = useRef(null); const previousEmailRef = useRef(null); const loadingTimeoutRef = useRef(null); + const loadingStateRef = useRef(loading); const fetchProfile = async (userId: string, retryCount = 0, onComplete?: () => void) => { try { @@ -153,6 +154,12 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) { } }; + // Keep loading state ref in sync + useEffect(() => { + loadingStateRef.current = loading; + console.log('[Auth] Loading state changed:', loading); + }, [loading]); + useEffect(() => { // CRITICAL: Set up listener FIRST to catch all events const { @@ -168,12 +175,17 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) { // Clear any error setSessionError(null); - // Explicitly handle SIGNED_IN event for iframe compatibility + // Explicitly handle SIGNED_IN and INITIAL_SESSION events if (event === 'SIGNED_IN' && session) { console.log('[Auth] SIGNED_IN detected, setting session and user'); setSession(session); setUser(session.user); sessionVerifiedRef.current = true; + } else if (event === 'INITIAL_SESSION' && session) { + console.log('[Auth] INITIAL_SESSION detected, setting session and user'); + setSession(session); + setUser(session.user); + sessionVerifiedRef.current = true; } else if (event === 'SIGNED_OUT') { console.log('[Auth] SIGNED_OUT detected, clearing session'); setSession(null); @@ -260,11 +272,13 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) { } // Defer profile fetch to avoid deadlock - const shouldWaitForProfile = event === 'SIGNED_IN'; + const shouldWaitForProfile = event === 'SIGNED_IN' || event === 'INITIAL_SESSION'; + console.log('[Auth] Profile fetch deferred, shouldWaitForProfile:', shouldWaitForProfile, 'event:', event); profileFetchTimeoutRef.current = setTimeout(() => { if (!isMountedRef.current) return; fetchProfile(session.user.id, 0, () => { if (isMountedRef.current && shouldWaitForProfile) { + console.log('[Auth] Profile fetch complete, setting loading to false'); setLoading(false); } }); @@ -276,10 +290,11 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) { } } - // Only set loading false immediately for non-SIGNED_IN events - if (event !== 'SIGNED_IN') { - setLoading(false); - } + // Only set loading false immediately for events that don't need profile fetch + if (event !== 'SIGNED_IN' && event !== 'INITIAL_SESSION') { + console.log('[Auth] Setting loading to false immediately for event:', event); + setLoading(false); + } }); // THEN get initial session @@ -311,8 +326,8 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) { // Add a safety timeout to force loading to resolve loadingTimeoutRef.current = setTimeout(() => { - if (isMountedRef.current && loading) { - console.warn('[Auth] Loading timeout reached, forcing loading to false'); + if (isMountedRef.current && loadingStateRef.current) { + console.warn('[Auth] Loading timeout reached after 5 seconds, forcing loading to false'); setLoading(false); } }, 5000);