diff --git a/src/components/settings/settings-overview.tsx b/src/components/settings/settings-overview.tsx index fff559a..2b61cf8 100644 --- a/src/components/settings/settings-overview.tsx +++ b/src/components/settings/settings-overview.tsx @@ -135,7 +135,7 @@ export function SettingsOverview({ return () => { cancelled = true; }; - }, [user, accountId, canManageMembers]); + }, [user?.id, accountId, canManageMembers]); const displayName = profile?.full_name || profile?.email || 'Your account'; const initial = (profile?.full_name || profile?.email || 'U').charAt(0).toUpperCase(); diff --git a/src/components/settings/whatsapp-config.tsx b/src/components/settings/whatsapp-config.tsx index de77125..713670d 100644 --- a/src/components/settings/whatsapp-config.tsx +++ b/src/components/settings/whatsapp-config.tsx @@ -178,7 +178,7 @@ export function WhatsAppConfig() { if (loadedAccountIdRef.current === accountId) return; loadedAccountIdRef.current = accountId; fetchConfig(accountId); - }, [authLoading, profileLoading, user, accountId, fetchConfig]); + }, [authLoading, profileLoading, user?.id, accountId, fetchConfig]); async function handleSave() { if (!phoneNumberId.trim()) { diff --git a/src/hooks/use-auth.tsx b/src/hooks/use-auth.tsx index 47284dd..c14434b 100644 --- a/src/hooks/use-auth.tsx +++ b/src/hooks/use-auth.tsx @@ -7,6 +7,7 @@ import { useState, useCallback, useMemo, + useRef, type ReactNode, } from "react"; import { createClient } from "@/lib/supabase/client"; @@ -121,12 +122,18 @@ export function AuthProvider({ children }: { children: ReactNode }) { // window they're in — see the type doc above. const [profileLoading, setProfileLoading] = useState(true); + // Tracks the user ID we've successfully initiated/completed fetching + // a profile for. This prevents redundant re-fetches and toggling + // profileLoading back to true on window focus events/token refresh. + const lastFetchedUserIdRef = useRef(null); + // Shared across init, auth-state-change listener, and the exposed // refreshProfile() callback. Reads the current session's user id and // pulls the matching profile row along with its account summary. const fetchProfile = useCallback(async (userId: string) => { const supabase = createClient(); setProfileLoading(true); + lastFetchedUserIdRef.current = userId; try { const { data, error } = await supabase .from("profiles") @@ -143,6 +150,7 @@ export function AuthProvider({ children }: { children: ReactNode }) { hint: error.hint, code: error.code, }); + lastFetchedUserIdRef.current = null; return; } @@ -206,9 +214,12 @@ export function AuthProvider({ children }: { children: ReactNode }) { account_role: accountRole, }); setAccount(accountRow); + } else { + lastFetchedUserIdRef.current = null; } } catch (err) { console.error("[AuthProvider] fetchProfile threw:", err); + lastFetchedUserIdRef.current = null; } finally { setProfileLoading(false); } @@ -269,8 +280,11 @@ export function AuthProvider({ children }: { children: ReactNode }) { setUser(currentUser); if (currentUser) { - fetchProfile(currentUser.id); + if (currentUser.id !== lastFetchedUserIdRef.current) { + fetchProfile(currentUser.id); + } } else { + lastFetchedUserIdRef.current = null; setProfile(null); setAccount(null); setProfileLoading(false);