mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-21 12:31:13 -05:00
Refactor: Simplify auth and profile handling
This commit is contained in:
@@ -8,12 +8,10 @@ import { authLog, authWarn, authError } from '@/lib/authLogger';
|
||||
interface AuthContextType {
|
||||
user: User | null;
|
||||
session: Session | null;
|
||||
profile: Profile | null;
|
||||
loading: boolean;
|
||||
pendingEmail: string | null;
|
||||
sessionError: string | null;
|
||||
signOut: () => Promise<void>;
|
||||
refreshProfile: () => Promise<void>;
|
||||
verifySession: () => Promise<boolean>;
|
||||
clearPendingEmail: () => void;
|
||||
}
|
||||
@@ -23,61 +21,16 @@ const AuthContext = createContext<AuthContextType | undefined>(undefined);
|
||||
function AuthProviderComponent({ children }: { children: React.ReactNode }) {
|
||||
const [user, setUser] = useState<User | null>(null);
|
||||
const [session, setSession] = useState<Session | null>(null);
|
||||
const [profile, setProfile] = useState<Profile | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [pendingEmail, setPendingEmail] = useState<string | null>(null);
|
||||
const [sessionError, setSessionError] = useState<string | null>(null);
|
||||
|
||||
// Refs for lifecycle and cleanup management
|
||||
const isMountedRef = useRef(true);
|
||||
const profileFetchTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
||||
const novuUpdateTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
||||
const fetchedUserIdRef = useRef<string | null>(null);
|
||||
const previousEmailRef = useRef<string | null>(null);
|
||||
|
||||
const fetchProfile = async (userId: string) => {
|
||||
console.log('[Auth] 📡 fetchProfile called for userId:', userId);
|
||||
try {
|
||||
const { data, error } = await supabase
|
||||
.from('profiles')
|
||||
.select(`*, location:locations(*)`)
|
||||
.eq('user_id', userId)
|
||||
.maybeSingle();
|
||||
|
||||
console.log('[Auth] 📦 Profile fetch result:', {
|
||||
hasData: !!data,
|
||||
hasError: !!error,
|
||||
avatar_url: data?.avatar_url
|
||||
});
|
||||
|
||||
if (error && error.code !== 'PGRST116') {
|
||||
authError('[Auth] ❌ Error fetching profile:', error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isMountedRef.current && data) {
|
||||
console.log('[Auth] ✅ Setting profile state with data:', {
|
||||
userId: data.user_id,
|
||||
username: data.username,
|
||||
avatar_url: data.avatar_url,
|
||||
});
|
||||
setProfile(data as Profile);
|
||||
} else {
|
||||
console.log('[Auth] ⚠️ NOT setting profile - mounted:', isMountedRef.current, 'hasData:', !!data);
|
||||
}
|
||||
} catch (error) {
|
||||
authError('[Auth] ❌ Exception in fetchProfile:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const refreshProfile = async () => {
|
||||
if (user) {
|
||||
await fetchProfile(user.id);
|
||||
}
|
||||
};
|
||||
|
||||
// Verify session is still valid - simplified
|
||||
const verifySession = async (updateLoadingState = false) => {
|
||||
const verifySession = async () => {
|
||||
try {
|
||||
const { data: { session }, error } = await supabase.auth.getSession();
|
||||
|
||||
@@ -95,7 +48,7 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) {
|
||||
authLog('[Auth] Session verified:', session.user.email);
|
||||
|
||||
// Update state if session was found but not set
|
||||
if (!user && isMountedRef.current) {
|
||||
if (!user) {
|
||||
setSession(session);
|
||||
setUser(session.user);
|
||||
}
|
||||
@@ -142,17 +95,13 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) {
|
||||
authLog('[Auth] INITIAL_SESSION - no user');
|
||||
setSession(null);
|
||||
setUser(null);
|
||||
setProfile(null);
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
} else if (event === 'SIGNED_OUT') {
|
||||
authLog('[Auth] SIGNED_OUT - clearing state');
|
||||
console.log('[Auth] 🔴 SIGNED_OUT - clearing profile and fetch tracking');
|
||||
fetchedUserIdRef.current = null;
|
||||
setSession(null);
|
||||
setUser(null);
|
||||
setProfile(null);
|
||||
setLoading(false);
|
||||
return;
|
||||
} else {
|
||||
@@ -222,24 +171,6 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) {
|
||||
if (currentEmail) {
|
||||
previousEmailRef.current = currentEmail;
|
||||
}
|
||||
|
||||
// Handle profile fetching for authenticated users (async, doesn't block loading)
|
||||
if (session?.user) {
|
||||
// Only fetch if we haven't fetched for this user yet
|
||||
if (fetchedUserIdRef.current !== session.user.id) {
|
||||
console.log('[Auth] 🔄 Fetching profile for user:', session.user.id);
|
||||
fetchedUserIdRef.current = session.user.id;
|
||||
|
||||
if (profileFetchTimeoutRef.current) {
|
||||
clearTimeout(profileFetchTimeoutRef.current);
|
||||
profileFetchTimeoutRef.current = null;
|
||||
}
|
||||
|
||||
fetchProfile(session.user.id);
|
||||
} else {
|
||||
console.log('[Auth] ✅ Profile already fetched for user:', session.user.id);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// THEN get initial session (this may trigger INITIAL_SESSION event)
|
||||
@@ -258,15 +189,9 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) {
|
||||
|
||||
return () => {
|
||||
authLog('[Auth] Cleaning up auth provider');
|
||||
isMountedRef.current = false;
|
||||
fetchedUserIdRef.current = null;
|
||||
subscription.unsubscribe();
|
||||
|
||||
// Clear any pending timeouts
|
||||
if (profileFetchTimeoutRef.current) {
|
||||
clearTimeout(profileFetchTimeoutRef.current);
|
||||
profileFetchTimeoutRef.current = null;
|
||||
}
|
||||
if (novuUpdateTimeoutRef.current) {
|
||||
clearTimeout(novuUpdateTimeoutRef.current);
|
||||
novuUpdateTimeoutRef.current = null;
|
||||
@@ -289,12 +214,10 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) {
|
||||
const value = {
|
||||
user,
|
||||
session,
|
||||
profile,
|
||||
loading,
|
||||
pendingEmail,
|
||||
sessionError,
|
||||
signOut,
|
||||
refreshProfile,
|
||||
verifySession,
|
||||
clearPendingEmail,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user