Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 60 additions & 10 deletions app/complete-profile/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';

import { useState, useEffect, useCallback, useRef } from 'react';
import { useState, useEffect, useCallback, useRef, Suspense } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
import Link from 'next/link';
import { createClient } from '@/lib/supabase/client';
Expand All @@ -22,7 +22,7 @@ interface User {
};
}

export default function CompleteProfile() {
function CompleteProfileContent() {
const router = useRouter();
const searchParams = useSearchParams();
const returnUrl = searchParams.get('returnUrl') || '/protected/dashboard';
Expand All @@ -36,6 +36,7 @@ export default function CompleteProfile() {
const [usernameError, setUsernameError] = useState<string>('');
const [user, setUser] = useState<User | null>(null);
const [isValidating, setIsValidating] = useState(true);
const [oauthProvider, setOauthProvider] = useState<string>('');
const usernameCheckTimeout = useRef<ReturnType<typeof setTimeout> | null>(null);

const getSupabaseClient = () => {
Expand Down Expand Up @@ -82,15 +83,40 @@ export default function CompleteProfile() {
// Continue with the form - profileService will handle creation if needed
}

// Pre-fill from OAuth provider data if available
// Pre-fill from OAuth provider data if available (prioritize OAuth data over existing profile data)
if (user.user_metadata) {
const metadata = user.user_metadata;
if (!firstName && (metadata.first_name || metadata.given_name)) {
setFirstName(metadata.first_name || metadata.given_name || '');

// Extract first name from various OAuth provider formats
const oauthFirstName = metadata.first_name ||
metadata.given_name ||
metadata.name?.split(' ')[0] ||
'';

// Extract last name from various OAuth provider formats
const oauthLastName = metadata.last_name ||
metadata.family_name ||
metadata.name?.split(' ').slice(1).join(' ') ||
'';

// Use OAuth data if available, otherwise keep existing profile data
if (oauthFirstName) {
setFirstName(oauthFirstName);
}
if (!lastName && (metadata.last_name || metadata.family_name)) {
setLastName(metadata.last_name || metadata.family_name || '');
if (oauthLastName) {
setLastName(oauthLastName);
}

// Set OAuth provider for UI display
setOauthProvider(metadata.provider || 'unknown');

console.log('OAuth provider data:', {
provider: metadata.provider || 'unknown',
firstName: oauthFirstName,
lastName: oauthLastName,
fullName: metadata.name,
metadata: metadata
});
}

} catch (error) {
Expand All @@ -99,7 +125,7 @@ export default function CompleteProfile() {
} finally {
setIsValidating(false);
}
}, [router, firstName, lastName]);
}, [router, returnUrl]);

useEffect(() => {
checkUser();
Expand Down Expand Up @@ -287,7 +313,11 @@ export default function CompleteProfile() {
{/* First Name */}
<div className="space-y-2">
<label className="block text-sm font-semibold text-gray-700">
First Name *
First Name * {oauthProvider && firstName && (
<span className="text-xs text-green-600 font-normal">
(pre-filled from {oauthProvider})
</span>
)}
</label>
<input
type="text"
Expand All @@ -302,7 +332,11 @@ export default function CompleteProfile() {
{/* Last Name */}
<div className="space-y-2">
<label className="block text-sm font-semibold text-gray-700">
Last Name *
Last Name * {oauthProvider && lastName && (
<span className="text-xs text-green-600 font-normal">
(pre-filled from {oauthProvider})
</span>
)}
</label>
<input
type="text"
Expand Down Expand Up @@ -456,3 +490,19 @@ export default function CompleteProfile() {
</div>
);
}

export default function CompleteProfile() {
return (
<Suspense fallback={
<div className="min-h-screen flex items-center justify-center bg-gradient-to-br from-background via-muted/30 to-muted/50">
<div className="relative">
<div className="animate-spin rounded-full h-12 w-12 border-4 border-primary border-t-transparent"></div>
<div className="absolute inset-0 rounded-full border-4 border-primary/20 animate-ping"></div>
</div>
<span className="ml-4 text-lg text-muted-foreground">Loading...</span>
</div>
}>
<CompleteProfileContent />
</Suspense>
);
}
19 changes: 17 additions & 2 deletions lib/services/profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,25 @@ export class ProfileService {
// Generate a simple codeunia_id if needed
const codeuniaId = `CU-${userId.slice(-8).toUpperCase()}-${Date.now().toString(36).toUpperCase()}`

// Extract name data from OAuth provider metadata
const metadata = user.user?.user_metadata || {};

// Extract first name from various OAuth provider formats
const firstName = metadata.first_name ||
metadata.given_name ||
metadata.name?.split(' ')[0] ||
'';

// Extract last name from various OAuth provider formats
const lastName = metadata.last_name ||
metadata.family_name ||
metadata.name?.split(' ').slice(1).join(' ') ||
'';

const profileData = {
id: userId,
first_name: user.user?.user_metadata?.first_name || '',
last_name: user.user?.user_metadata?.last_name || '',
first_name: firstName,
last_name: lastName,
is_public: true,
email_notifications: true,
profile_completion_percentage: 0,
Expand Down
Loading