Fix bug in auth provider

This commit is contained in:
2025-06-04 10:36:02 -05:00
parent e2f291e707
commit bfb6e9e648

View File

@ -1,5 +1,4 @@
'use client'; 'use client';
import React, { import React, {
type ReactNode, type ReactNode,
createContext, createContext,
@ -44,14 +43,17 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => {
const [avatarUrl, setAvatarUrl] = useState<string | null>(null); const [avatarUrl, setAvatarUrl] = useState<string | null>(null);
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
const [isInitialized, setIsInitialized] = useState(false); const [isInitialized, setIsInitialized] = useState(false);
const fetchingRef = useRef(false); const fetchingRef = useRef(false);
const fetchUserData = useCallback(async () => { const fetchUserData = useCallback(async (showLoading = true) => {
if (fetchingRef.current) return; if (fetchingRef.current) return;
fetchingRef.current = true; fetchingRef.current = true;
try { try {
// Only show loading for initial load or manual refresh
if (showLoading) {
setIsLoading(true); setIsLoading(true);
}
const userResponse = await getUser(); const userResponse = await getUser();
const profileResponse = await getProfile(); const profileResponse = await getProfile();
@ -62,6 +64,7 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => {
setAvatarUrl(null); setAvatarUrl(null);
return; return;
} }
setUser(userResponse.data); setUser(userResponse.data);
setProfile(profileResponse.data); setProfile(profileResponse.data);
@ -71,12 +74,14 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => {
bucket: 'avatars', bucket: 'avatars',
url: profileResponse.data.avatar_url, url: profileResponse.data.avatar_url,
}); });
if (avatarResponse.success) { if (avatarResponse.success) {
setAvatarUrl(avatarResponse.data); setAvatarUrl(avatarResponse.data);
} else setAvatarUrl(null); } else {
setAvatarUrl(null);
}
} else {
setAvatarUrl(null);
} }
} catch (error) { } catch (error) {
console.error( console.error(
'Auth fetch error: ', 'Auth fetch error: ',
@ -88,7 +93,9 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => {
toast.error('Failed to load user data!'); toast.error('Failed to load user data!');
} }
} finally { } finally {
if (showLoading) {
setIsLoading(false); setIsLoading(false);
}
setIsInitialized(true); setIsInitialized(true);
fetchingRef.current = false; fetchingRef.current = false;
} }
@ -97,20 +104,27 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => {
useEffect(() => { useEffect(() => {
const supabase = createClient(); const supabase = createClient();
fetchUserData().catch((error) => { // Initial fetch with loading
fetchUserData(true).catch((error) => {
console.error('💥 Initial fetch error:', error); console.error('💥 Initial fetch error:', error);
}); });
const { const {
data: { subscription }, data: { subscription },
} = supabase.auth.onAuthStateChange(async (event, session) => { } = supabase.auth.onAuthStateChange(async (event, session) => {
console.log('Auth state change:', event); // Debug log
if (event === 'SIGNED_IN') { if (event === 'SIGNED_IN') {
await fetchUserData(); // Background refresh without loading state
await fetchUserData(false);
} else if (event === 'SIGNED_OUT') { } else if (event === 'SIGNED_OUT') {
setUser(null); setUser(null);
setProfile(null); setProfile(null);
setAvatarUrl(null); setAvatarUrl(null);
setIsLoading(false); setIsLoading(false);
} else if (event === 'TOKEN_REFRESHED') {
// Silent refresh - don't show loading
await fetchUserData(false);
} }
}); });
@ -129,7 +143,6 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => {
if (!result.success) { if (!result.success) {
throw new Error(result.error ?? 'Failed to update profile'); throw new Error(result.error ?? 'Failed to update profile');
} }
setProfile(result.data); setProfile(result.data);
// If avatar was updated, refresh the avatar URL // If avatar was updated, refresh the avatar URL
@ -139,12 +152,10 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => {
url: result.data.avatar_url, url: result.data.avatar_url,
transform: { width: 128, height: 128 }, transform: { width: 128, height: 128 },
}); });
if (avatarResponse.success) { if (avatarResponse.success) {
setAvatarUrl(avatarResponse.data); setAvatarUrl(avatarResponse.data);
} }
} }
toast.success('Profile updated successfully!'); toast.success('Profile updated successfully!');
return { success: true, data: result.data }; return { success: true, data: result.data };
} catch (error) { } catch (error) {
@ -155,7 +166,7 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => {
}, []); }, []);
const refreshUserData = useCallback(async () => { const refreshUserData = useCallback(async () => {
await fetchUserData(); await fetchUserData(true); // Manual refresh shows loading
}, [fetchUserData]); }, [fetchUserData]);
const value = { const value = {
@ -173,7 +184,7 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => {
{children} {children}
</AuthContext.Provider> </AuthContext.Provider>
); );
} };
export const useAuth = () => { export const useAuth = () => {
const context = useContext(AuthContext); const context = useContext(AuthContext);
@ -181,4 +192,4 @@ export const useAuth = () => {
throw new Error('useAuth must be used within an AuthProvider'); throw new Error('useAuth must be used within an AuthProvider');
} }
return context; return context;
} };