Refactor: Simplify auth loading state

This commit is contained in:
gpt-engineer-app[bot]
2025-10-13 17:06:03 +00:00
parent 8b54a2303b
commit 083964ff41
2 changed files with 10 additions and 59 deletions

View File

@@ -42,8 +42,8 @@ export function AuthButtons() {
} }
}; };
// Show loading skeleton during auth check OR when user exists but profile hasn't loaded yet // Show loading skeleton only during initial auth check
if (loading || (user && !profile)) { if (loading) {
return ( return (
<div className="flex gap-2 items-center"> <div className="flex gap-2 items-center">
<div className="h-8 w-16 bg-muted animate-pulse rounded" /> <div className="h-8 w-16 bg-muted animate-pulse rounded" />

View File

@@ -39,7 +39,7 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) {
const loadingStateRef = useRef(loading); const loadingStateRef = useRef(loading);
const lastVisibilityVerificationRef = useRef<number>(Date.now()); const lastVisibilityVerificationRef = useRef<number>(Date.now());
const fetchProfile = async (userId: string, retryCount = 0, onComplete?: () => void) => { const fetchProfile = async (userId: string) => {
try { try {
const { data, error } = await supabase const { data, error } = await supabase
.from('profiles') .from('profiles')
@@ -49,59 +49,25 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) {
if (error && error.code !== 'PGRST116') { if (error && error.code !== 'PGRST116') {
authError('[Auth] Error fetching profile:', error); 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) { 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); setProfile(null);
onComplete?.();
} }
return; return;
} }
// Success - update state and complete
if (isMountedRef.current) { if (isMountedRef.current) {
// Always log profile loading (production-safe)
console.log('[Auth] ✅ Profile loaded:', { console.log('[Auth] ✅ Profile loaded:', {
userId: data?.user_id, userId: data?.user_id,
username: data?.username, username: data?.username,
avatar_url: data?.avatar_url, avatar_url: data?.avatar_url,
avatar_image_id: data?.avatar_image_id,
hasData: !!data hasData: !!data
}); });
setProfile(data as Profile); setProfile(data as Profile);
profileRetryCountRef.current = 0;
onComplete?.();
} }
} catch (error) { } catch (error) {
authError('[Auth] Error fetching profile:', 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) { if (isMountedRef.current) {
setProfile(null); setProfile(null);
onComplete?.();
}
} }
} }
}; };
@@ -191,24 +157,21 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) {
setSession(session); setSession(session);
setUser(session.user); setUser(session.user);
sessionVerifiedRef.current = true; sessionVerifiedRef.current = true;
// Keep loading true until profile is fetched setLoading(false); // Resolved - user exists
setLoading(true);
} else if (event === 'INITIAL_SESSION') { } else if (event === 'INITIAL_SESSION') {
if (session?.user) { if (session?.user) {
authLog('[Auth] INITIAL_SESSION with user, setting session'); authLog('[Auth] INITIAL_SESSION with user, setting session');
setSession(session); setSession(session);
setUser(session.user); setUser(session.user);
sessionVerifiedRef.current = true; sessionVerifiedRef.current = true;
// Keep loading true until profile is fetched (same as SIGNED_IN) setLoading(false); // Resolved - user exists
setLoading(true);
} else { } else {
authLog('[Auth] INITIAL_SESSION with no user - setting loading to false'); authLog('[Auth] INITIAL_SESSION with no user - setting loading to false');
setSession(null); setSession(null);
setUser(null); setUser(null);
setProfile(null); setProfile(null);
sessionVerifiedRef.current = false; sessionVerifiedRef.current = false;
// CRITICAL: Set loading to false immediately when no session setLoading(false); // Resolved - no user
setLoading(false);
return; // Exit early, no need to fetch profile return; // Exit early, no need to fetch profile
} }
} else if (event === 'SIGNED_OUT') { } else if (event === 'SIGNED_OUT') {
@@ -287,30 +250,18 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) {
previousEmailRef.current = currentEmail; previousEmailRef.current = currentEmail;
} }
// Handle profile fetching for authenticated users // Handle profile fetching for authenticated users (async, doesn't block loading)
if (session?.user) { if (session?.user) {
// Clear any existing profile fetch timeout
if (profileFetchTimeoutRef.current) { if (profileFetchTimeoutRef.current) {
clearTimeout(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(() => { profileFetchTimeoutRef.current = setTimeout(() => {
fetchProfile(session.user.id, 0, () => { fetchProfile(session.user.id);
// Always set loading to false after profile fetch for authenticated users
authLog('[Auth] Profile fetch complete, setting loading to false');
setLoading(false);
});
profileFetchTimeoutRef.current = null; profileFetchTimeoutRef.current = null;
}, 0); }, 0);
} else { } else {
// No session/user - clear profile and resolve loading
setProfile(null); setProfile(null);
authLog('[Auth] No user, setting loading to false');
setLoading(false);
} }
}); });