'use client'; import { useState, useEffect, useRef } from 'react'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { z } from 'zod'; import api from '@/lib/api'; import { useUserStore } from '@/stores/userStore'; const profileSchema = z.object({ firstName: z.string().optional(), lastName: z.string().optional(), email: z.string().email('Invalid email format').optional().or(z.literal('')), phone: z.string().regex(/^1[3-9]\d{9}$/, 'Invalid phone format').optional().or(z.literal('')), }); type ProfileFormData = z.infer; export default function ProfilePage() { const { user, setUser } = useUserStore(); const [loading, setLoading] = useState(false); const [message, setMessage] = useState(null); const [error, setError] = useState(null); const fileInputRef = useRef(null); const { register, handleSubmit, reset, formState: { errors }, } = useForm({ resolver: zodResolver(profileSchema), }); useEffect(() => { if (user) { reset({ firstName: user.firstName || '', lastName: user.lastName || '', email: user.email || '', phone: user.phone || '', }); } }, [user, reset]); const onSubmit = async (data: ProfileFormData) => { try { setError(null); setMessage(null); setLoading(true); const response = await api.put('/users/me', { firstName: data.firstName || undefined, lastName: data.lastName || undefined, email: data.email || undefined, phone: data.phone || undefined, }); const updatedUser = response.data.data; setUser({ ...user, ...updatedUser, }); setMessage('Profile updated successfully'); } catch (err) { const error = err as { response?: { data?: { message?: string } } }; setError(error.response?.data?.message || 'Failed to update profile'); } finally { setLoading(false); } }; const handleAvatarUpload = async (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (!file) return; if (!file.type.startsWith('image/')) { setError('Please upload an image file'); return; } if (file.size > 5 * 1024 * 1024) { setError('Image size must be less than 5MB'); return; } try { setError(null); setLoading(true); const formData = new FormData(); formData.append('avatar', file); const response = await api.post('/users/me/avatar', formData, { headers: { 'Content-Type': 'multipart/form-data', }, }); const updatedUser = response.data.data; setUser({ ...user, avatar: updatedUser.avatar, }); setMessage('Avatar updated successfully'); } catch (err) { const error = err as { response?: { data?: { message?: string } } }; setError(error.response?.data?.message || 'Failed to upload avatar'); } finally { setLoading(false); } }; const handleLogout = () => { localStorage.removeItem('token'); setUser(null); window.location.href = '/auth/login'; }; if (!user) { return
Loading...
; } return (

Profile Settings

{user.avatar ? ( Avatar ) : ( {user.firstName?.[0] || user.username?.[0] || 'U'} )}

JPG, PNG, GIF or WebP (max 5MB)

{errors.firstName && (

{errors.firstName.message}

)}
{errors.lastName && (

{errors.lastName.message}

)}
{errors.email && (

{errors.email.message}

)}
{errors.phone && (

{errors.phone.message}

)}
{message && (
{message}
)} {error && (
{error}
)}
); }