'use client' import { useState } from 'react' import { useRouter } from 'next/navigation' import { signOut } from 'next-auth/react' import { trpc } from '@/lib/trpc/client' import { toast } from 'sonner' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { Textarea } from '@/components/ui/textarea' import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from '@/components/ui/card' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select' import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from '@/components/ui/dialog' import { Skeleton } from '@/components/ui/skeleton' import { AvatarUpload } from '@/components/shared/avatar-upload' import { UserAvatar } from '@/components/shared/user-avatar' import { Loader2, Save, Camera, Lock, Bell, Trash2, User, } from 'lucide-react' export default function ProfileSettingsPage() { const router = useRouter() const { data: user, isLoading, refetch } = trpc.user.me.useQuery() const { data: avatarUrl } = trpc.avatar.getUrl.useQuery() const updateProfile = trpc.user.updateProfile.useMutation() const changePassword = trpc.user.changePassword.useMutation() const deleteAccount = trpc.user.deleteAccount.useMutation() // Profile form state const [name, setName] = useState('') const [bio, setBio] = useState('') const [phoneNumber, setPhoneNumber] = useState('') const [notificationPreference, setNotificationPreference] = useState('EMAIL') const [profileLoaded, setProfileLoaded] = useState(false) // Password form state const [currentPassword, setCurrentPassword] = useState('') const [newPassword, setNewPassword] = useState('') const [confirmNewPassword, setConfirmNewPassword] = useState('') // Delete account state const [deletePassword, setDeletePassword] = useState('') const [deleteDialogOpen, setDeleteDialogOpen] = useState(false) // Populate form when user data loads if (user && !profileLoaded) { setName(user.name || '') const meta = (user.metadataJson as Record) || {} setBio((meta.bio as string) || '') setPhoneNumber(user.phoneNumber || '') setNotificationPreference(user.notificationPreference || 'EMAIL') setProfileLoaded(true) } const handleSaveProfile = async () => { try { await updateProfile.mutateAsync({ name: name || undefined, bio, phoneNumber: phoneNumber || null, notificationPreference: notificationPreference as 'EMAIL' | 'WHATSAPP' | 'BOTH' | 'NONE', }) toast.success('Profile updated successfully') refetch() } catch (error) { toast.error(error instanceof Error ? error.message : 'Failed to update profile') } } const handleChangePassword = async () => { if (newPassword !== confirmNewPassword) { toast.error('New passwords do not match') return } try { await changePassword.mutateAsync({ currentPassword, newPassword, confirmNewPassword, }) toast.success('Password changed successfully') setCurrentPassword('') setNewPassword('') setConfirmNewPassword('') } catch (error) { toast.error(error instanceof Error ? error.message : 'Failed to change password') } } const handleDeleteAccount = async () => { try { await deleteAccount.mutateAsync({ password: deletePassword }) toast.success('Account deleted') setDeleteDialogOpen(false) signOut({ callbackUrl: '/login' }) } catch (error) { toast.error(error instanceof Error ? error.message : 'Failed to delete account') } } if (isLoading) { return (
) } if (!user) return null return (

Profile Settings

Manage your personal information and preferences

{/* Profile Photo */} Profile Photo Click your avatar to upload a new profile picture refetch()} >
{/* Personal Information */} Personal Information Update your name, bio, and contact information

Email cannot be changed

setName(e.target.value)} placeholder="Your full name" />