diff --git a/src/contexts/UserContext.tsx b/src/contexts/UserContext.tsx index 1918a46..ecfec29 100644 --- a/src/contexts/UserContext.tsx +++ b/src/contexts/UserContext.tsx @@ -112,73 +112,59 @@ export const UserProvider = ({ children }: { children: React.ReactNode }) => { let profileRow: Record | null = null; - logger.debug('user-context', '🔧 Step 5: Querying profiles table...', { - userId: userInfo.id + // Fast-path: build profile from auth metadata + localStorage immediately. + // This clears the spinner before any network call so the page renders on refresh + // without waiting for the Supabase profiles query (~200ms). + const fastMetadata = userInfo.user_metadata as CCUserMetadata; + const fastStoredUserDb = DatabaseNameService.getStoredUserDatabase(); + const fastStoredSchoolDb = DatabaseNameService.getStoredSchoolDatabase(); + const fastUserDb = fastStoredUserDb || DatabaseNameService.getUserPrivateDB(fastMetadata?.user_type || '', userInfo.id); + const fastProfile: CCUser = { + id: userInfo.id, + email: userInfo.email, + user_type: fastMetadata?.user_type || '', + username: fastMetadata?.username || userInfo.email?.split('@')[0] || 'user', + display_name: String(fastMetadata?.display_name || ''), + user_db_name: String(fastUserDb || ''), + school_db_name: String(fastStoredSchoolDb || ''), + created_at: userInfo.created_at, + updated_at: userInfo.updated_at + }; + DatabaseNameService.rememberDatabaseNames({ + userDbName: fastProfile.user_db_name, + schoolDbName: fastProfile.school_db_name }); - - // Set loading state when we start the actual database query - setLoading(true); - - // Query profiles table without timeout to see actual error - logger.debug('user-context', '🔧 Step 5b: Starting profiles query...', { - userId: userInfo.id, - clientType: 'authenticated' - }); - - logger.debug('user-context', '🔧 Step 5b1: About to make profiles query...', { - userId: userInfo.id, - queryStarted: true - }); - + if (mountedRef.current && !isInitialized) { + setProfile(fastProfile); + setLoading(false); + setIsInitialized(true); + logger.debug('user-context', '⚡ Fast-path: profile initialized from auth metadata, no spinner'); + } + + // Background: query Supabase profiles for authoritative data (user_db_name, school_db_name, display_name). + // No setLoading toggles — spinner is already cleared above. const { data, error } = await supabase .from('profiles') .select('*') .eq('id', userInfo.id) .single(); - - logger.debug('user-context', '🔧 Step 5b2: Direct fetch completed...', { - userId: userInfo.id, - hasData: !!data, - hasError: !!error - }); - - logger.debug('user-context', '🔧 Step 5c: Profiles query completed', { - hasData: !!data, - hasError: !!error, - errorCode: error?.code, - errorMessage: error?.message - }); - - logger.debug('user-context', '🔧 Step 5a: Profiles query result', { - hasData: !!data, - hasError: !!error, - errorCode: error?.code, - errorMessage: error?.message - }); if (error && error.code !== 'PGRST116') { - logger.warn('user-context', '⚠️ Profiles query failed, using fallback', { + logger.warn('user-context', '⚠️ Profiles query failed, using fast-path profile', { error: error.message, code: error.code }); - // Don't throw error, just use fallback profile profileRow = null; } else if (data) { profileRow = data; - logger.debug('user-context', '✅ Found profile data in database', { + logger.debug('user-context', '✅ Supabase profile fetched', { userId: data.id, - userType: data.user_type, userDbName: data.user_db_name }); } else { - logger.debug('user-context', '⚠️ No profile data found - will create default'); profileRow = null; } - // Clear loading state after profiles query completes - setLoading(false); - logger.debug('user-context', '🔧 Step 5d: Loading state cleared'); - logger.debug('user-context', '🔧 Step 6: Processing profile data...', { userId: userInfo.id, hasProfileRow: !!profileRow,