feat: Implement OAuth profile enhancement

This commit is contained in:
gpt-engineer-app[bot]
2025-10-11 23:56:44 +00:00
parent b8c9bf1784
commit d6f9f4d9a3
4 changed files with 391 additions and 1 deletions

154
src/pages/AuthCallback.tsx Normal file
View File

@@ -0,0 +1,154 @@
import { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { supabase } from '@/integrations/supabase/client';
import { useToast } from '@/hooks/use-toast';
import { Loader2 } from 'lucide-react';
import { Header } from '@/components/layout/Header';
export default function AuthCallback() {
const navigate = useNavigate();
const { toast } = useToast();
const [status, setStatus] = useState<'processing' | 'success' | 'error'>('processing');
useEffect(() => {
const processOAuthCallback = async () => {
try {
// Get the current session
const { data: { session }, error: sessionError } = await supabase.auth.getSession();
if (sessionError) {
console.error('[AuthCallback] Session error:', sessionError);
throw sessionError;
}
if (!session) {
console.log('[AuthCallback] No session found, redirecting to auth');
navigate('/auth');
return;
}
const user = session.user;
console.log('[AuthCallback] User authenticated:', user.id);
// Check if this is a new OAuth user (created within last minute)
const createdAt = new Date(user.created_at);
const now = new Date();
const isNewUser = (now.getTime() - createdAt.getTime()) < 60000; // 1 minute
// Check if user has an OAuth provider
const provider = user.app_metadata?.provider;
const isOAuthUser = provider === 'google' || provider === 'discord';
console.log('[AuthCallback] User info:', {
isNewUser,
isOAuthUser,
provider,
createdAt: user.created_at,
});
// If new OAuth user, process profile
if (isNewUser && isOAuthUser) {
setStatus('processing');
try {
console.log('[AuthCallback] Processing OAuth profile...');
const { data, error } = await supabase.functions.invoke('process-oauth-profile', {
headers: {
Authorization: `Bearer ${session.access_token}`,
},
});
if (error) {
console.error('[AuthCallback] Profile processing error:', error);
// Don't throw - allow sign-in to continue even if profile processing fails
} else {
console.log('[AuthCallback] Profile processed:', data);
}
} catch (error) {
console.error('[AuthCallback] Failed to process profile:', error);
// Continue anyway - don't block sign-in
}
}
setStatus('success');
// Show success message
toast({
title: 'Welcome to ThrillWiki!',
description: isNewUser
? 'Your account has been created successfully.'
: 'You have been signed in successfully.',
});
// Redirect to home after a short delay
setTimeout(() => {
navigate('/');
}, 500);
} catch (error: any) {
console.error('[AuthCallback] Error:', error);
setStatus('error');
toast({
variant: 'destructive',
title: 'Sign in error',
description: error.message || 'An error occurred during sign in. Please try again.',
});
// Redirect to auth page after error
setTimeout(() => {
navigate('/auth');
}, 2000);
}
};
processOAuthCallback();
}, [navigate, toast]);
return (
<div className="min-h-screen bg-background">
<Header />
<main className="container mx-auto px-4 py-16">
<div className="max-w-md mx-auto text-center">
<div className="flex flex-col items-center gap-4">
{status === 'processing' && (
<>
<Loader2 className="h-8 w-8 animate-spin text-primary" />
<h2 className="text-2xl font-bold">Setting up your profile...</h2>
<p className="text-muted-foreground">
We're preparing your ThrillWiki experience
</p>
</>
)}
{status === 'success' && (
<>
<div className="h-8 w-8 rounded-full bg-green-500 flex items-center justify-center">
<span className="text-white text-xl">✓</span>
</div>
<h2 className="text-2xl font-bold">Welcome!</h2>
<p className="text-muted-foreground">
Redirecting you to ThrillWiki...
</p>
</>
)}
{status === 'error' && (
<>
<div className="h-8 w-8 rounded-full bg-destructive flex items-center justify-center">
<span className="text-destructive-foreground text-xl"></span>
</div>
<h2 className="text-2xl font-bold">Something went wrong</h2>
<p className="text-muted-foreground">
Redirecting you to sign in...
</p>
</>
)}
</div>
</div>
</main>
</div>
);
}