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
if (loading || (user && !profile)) {
// Show loading skeleton only during initial auth check
if (loading) {
return (
<div className="flex gap-2 items-center">
<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 lastVisibilityVerificationRef = useRef<number>(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?.();
}
}
}
};
@@ -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);
}
});