import { FC, ReactElement, useState, useEffect } from 'react'; import { ControlledInputField } from '@imphnen-frontend-service/ui/organisms'; import { Button, Textarea } from '@imphnen-frontend-service/ui/atoms'; import { useNavigate } from 'react-router'; import { useForm, Controller } from 'react-hook-form'; import { userOnboardingSchema, TUserOnboardingForm, useUpdateUserMe, useUploadAvatar, useUserMe, useAuthStore, } from '@imphnen-frontend-service/service'; import { zodResolver } from '@hookform/resolvers/zod'; import { toast } from 'sonner'; import { CitySelect } from '../../../components/city-select'; import { Icon } from '@iconify/react'; const ROLE_OPTIONS = [ 'Frontend Developer', 'Backend Developer', 'Full Stack Developer', 'DevOps Engineer', 'UI/UX Designer', 'Product Manager', 'Data Scientist', 'Mobile Developer', ]; const UserOnboardingPage: FC = (): ReactElement => { const navigate = useNavigate(); const [avatarFile, setAvatarFile] = useState(null); const [avatarPreview, setAvatarPreview] = useState(''); const { data: userData } = useUserMe(); const { mutateAsync: updateUser, isPending: isUpdating } = useUpdateUserMe(); const { mutateAsync: uploadAvatar, isPending: isUploading } = useUploadAvatar(); const { session } = useAuthStore(); const form = useForm({ resolver: zodResolver(userOnboardingSchema), mode: 'all', defaultValues: { fullname: session?.user?.fullname || userData?.data?.fullname || '', location: session?.user?.location || '', bio: session?.user?.bio || '', skills: session?.user?.skills || [], }, }); // Set initial avatar preview from GitHub avatar if available useEffect(() => { if (session?.user?.avatar && !avatarPreview) { setAvatarPreview(session.user.avatar); } }, [session?.user?.avatar, avatarPreview]); const handleAvatarChange = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (file) { setAvatarFile(file); const reader = new FileReader(); reader.onloadend = () => { setAvatarPreview(reader.result as string); }; reader.readAsDataURL(file); } }; const onSubmit = form.handleSubmit(async (data) => { try { let avatarUrl = session?.user?.avatar || null; // Upload avatar if a new file was selected if (avatarFile) { const uploadResult = await uploadAvatar(avatarFile); avatarUrl = uploadResult.data.url; } // Update user in Supabase await updateUser({ fullname: data.fullname, avatar: avatarUrl, location: data.location, bio: data.bio, skills: data.skills, }); // Wait a bit for the onSuccess handler to update localStorage // The updateUser mutation's onSuccess handler updates the Zustand store and localStorage await new Promise((resolve) => setTimeout(resolve, 100)); // Use window.location for a full page reload to ensure middleware sees updated localStorage globalThis.location.href = '/dashboard'; } catch (error) { toast.error( error instanceof Error ? error.message : 'Onboarding failed. Please try again.' ); } }); return (

Complete Your Profile

Tell us more about yourself to get started

{/* Avatar Upload */}
{avatarPreview ? ( Avatar preview ) : (
)}

Optional, but highly recommended

{/* Full Name */} {/* City */}
( )} />
{/* Role/Skills */}
(
{ROLE_OPTIONS.map((role) => ( ))}
)} />
{/* Bio */}
(