From 083964ff41674e7668bc5f5d6d60f7c36716a317 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Mon, 13 Oct 2025 17:06:03 +0000 Subject: [PATCH] Refactor: Simplify auth loading state --- src/components/auth/AuthButtons.tsx | 4 +- src/hooks/useAuth.tsx | 65 ++++------------------------- 2 files changed, 10 insertions(+), 59 deletions(-) diff --git a/src/components/auth/AuthButtons.tsx b/src/components/auth/AuthButtons.tsx index 73ad476e..18b9b58a 100644 --- a/src/components/auth/AuthButtons.tsx +++ b/src/components/auth/AuthButtons.tsx @@ -42,8 +42,8 @@ export function AuthButtons() { } }; - // Show loading skeleton during auth check OR when user exists but profile hasn't loaded yet - if (loading || (user && !profile)) { + // Show loading skeleton only during initial auth check + if (loading) { return (
diff --git a/src/hooks/useAuth.tsx b/src/hooks/useAuth.tsx index 72056060..47662812 100644 --- a/src/hooks/useAuth.tsx +++ b/src/hooks/useAuth.tsx @@ -39,7 +39,7 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) { const loadingStateRef = useRef(loading); const lastVisibilityVerificationRef = useRef(Date.now()); - const fetchProfile = async (userId: string, retryCount = 0, onComplete?: () => void) => { + const fetchProfile = async (userId: string) => { try { const { data, error } = await supabase .from('profiles') @@ -49,59 +49,25 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) { if (error && error.code !== 'PGRST116') { authError('[Auth] Error fetching profile:', error); - - // Retry up to 3 times with exponential backoff - if (retryCount < 3 && isMountedRef.current) { - const delay = Math.pow(2, retryCount) * 1000; // 1s, 2s, 4s - authLog(`[Auth] Retrying profile fetch in ${delay}ms (attempt ${retryCount + 1}/3)`); - setTimeout(() => { - if (isMountedRef.current) { - fetchProfile(userId, retryCount + 1, onComplete); - } - }, delay); - return; - } - - // All retries exhausted - complete anyway if (isMountedRef.current) { - authWarn('[Auth] Profile fetch failed after 3 retries'); setProfile(null); - onComplete?.(); } return; } - // Success - update state and complete if (isMountedRef.current) { - // Always log profile loading (production-safe) console.log('[Auth] ✅ Profile loaded:', { userId: data?.user_id, username: data?.username, avatar_url: data?.avatar_url, - avatar_image_id: data?.avatar_image_id, hasData: !!data }); setProfile(data as Profile); - profileRetryCountRef.current = 0; - onComplete?.(); } } catch (error) { authError('[Auth] Error fetching profile:', error); - - // Retry logic for network errors - if (retryCount < 3 && isMountedRef.current) { - const delay = Math.pow(2, retryCount) * 1000; - setTimeout(() => { - if (isMountedRef.current) { - fetchProfile(userId, retryCount + 1, onComplete); - } - }, delay); - } else { - // All retries exhausted - if (isMountedRef.current) { - setProfile(null); - onComplete?.(); - } + if (isMountedRef.current) { + setProfile(null); } } }; @@ -191,24 +157,21 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) { setSession(session); setUser(session.user); sessionVerifiedRef.current = true; - // Keep loading true until profile is fetched - setLoading(true); + setLoading(false); // Resolved - user exists } else if (event === 'INITIAL_SESSION') { if (session?.user) { authLog('[Auth] INITIAL_SESSION with user, setting session'); setSession(session); setUser(session.user); sessionVerifiedRef.current = true; - // Keep loading true until profile is fetched (same as SIGNED_IN) - setLoading(true); + setLoading(false); // Resolved - user exists } else { authLog('[Auth] INITIAL_SESSION with no user - setting loading to false'); setSession(null); setUser(null); setProfile(null); sessionVerifiedRef.current = false; - // CRITICAL: Set loading to false immediately when no session - setLoading(false); + setLoading(false); // Resolved - no user return; // Exit early, no need to fetch profile } } else if (event === 'SIGNED_OUT') { @@ -287,30 +250,18 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) { previousEmailRef.current = currentEmail; } - // Handle profile fetching for authenticated users + // Handle profile fetching for authenticated users (async, doesn't block loading) if (session?.user) { - // Clear any existing profile fetch timeout if (profileFetchTimeoutRef.current) { clearTimeout(profileFetchTimeoutRef.current); } - // Only wait for profile on initial auth events - const shouldWaitForProfile = (event === 'SIGNED_IN' || event === 'INITIAL_SESSION'); - authLog('[Auth] Fetching profile, shouldWaitForProfile:', shouldWaitForProfile); - profileFetchTimeoutRef.current = setTimeout(() => { - fetchProfile(session.user.id, 0, () => { - // Always set loading to false after profile fetch for authenticated users - authLog('[Auth] Profile fetch complete, setting loading to false'); - setLoading(false); - }); + fetchProfile(session.user.id); profileFetchTimeoutRef.current = null; }, 0); } else { - // No session/user - clear profile and resolve loading setProfile(null); - authLog('[Auth] No user, setting loading to false'); - setLoading(false); } });