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 { useForm, Controller } from 'react-hook-form'; import { userEditProfileSchema, TUserEditProfileForm, useUpdateUserMe, useUploadAvatar, 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', ]; type ProfileModalProps = { open: boolean; onClose: () => void; }; const ProfilePage: FC = ({ open, onClose, }): ReactElement | null => { const [avatarFile, setAvatarFile] = useState(null); const [avatarPreview, setAvatarPreview] = useState(''); const { mutateAsync: updateUser, isPending: isUpdating } = useUpdateUserMe(); const { mutateAsync: uploadAvatar, isPending: isUploading } = useUploadAvatar(); const { session } = useAuthStore(); const form = useForm({ resolver: zodResolver(userEditProfileSchema), mode: 'all', defaultValues: { fullname: session?.user?.fullname || '', avatar: session?.user?.avatar || null, location: session?.user?.location || '', bio: session?.user?.bio || '', skills: session?.user?.skills || [], }, }); useEffect(() => { if (session?.user?.avatar && !avatarPreview) { setAvatarPreview(session.user.avatar); } if (session?.user?.fullname) { form.setValue('fullname', session.user.fullname); } if (session?.user?.location) { form.setValue('location', session.user.location); } if (session?.user?.bio) { form.setValue('bio', session.user.bio); } if (session?.user?.skills) { form.setValue('skills', session.user.skills); } }, [ session?.user?.avatar, session?.user?.fullname, session?.user?.location, session?.user?.bio, session?.user?.skills, avatarPreview, form, ]); const handleAvatarChange = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (file) { if (file.size > 2 * 1024 * 1024) { toast.error('The file is too large. Maximum size is 2MB.'); e.target.value = ''; return; } if (!file.type.startsWith('image/')) { toast.error('The file must be an image'); e.target.value = ''; return; } 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; if (avatarFile) { const uploadResult = await uploadAvatar(avatarFile); avatarUrl = uploadResult.data.url; } await updateUser({ fullname: data.fullname, avatar: avatarUrl, location: data.location, bio: data.bio, skills: data.skills, }); toast.success('Profile updated successfully!'); await new Promise((resolve) => setTimeout(resolve, 100)); onClose(); } catch (error) { console.error('Profile update failed:', error); toast.error( `Failed to update profile: ${ error instanceof Error ? error.message : 'Unknown error' }` ); } }); const isLoading = isUpdating || isUploading; return open ? (

Edit Profile

Update your photo and name

{avatarPreview ? ( Avatar preview ) : (
)}

Click the camera icon to change your photo
Format: JPG, PNG. Max 2MB

( )} />
(
{ROLE_OPTIONS.map((role) => ( ))}
)} />
(