import { useEffect, useState } from 'react'; import { api } from '@/lib/api'; import { useAuthStore } from '@/stores/auth'; import type { Profile } from '@/types'; import { Save, User, Lock, Mail, CheckCircle2, AlertCircle } from 'lucide-react'; import LoadingSpinner, { PageLoader } from '@/components/LoadingSpinner'; function StatusMessage({ type, message }: { type: 'success' | 'error'; message: string }) { return (
{type === 'success' ? : } {message}
); } export default function SettingsPage() { const { checkSession } = useAuthStore(); const [profile, setProfile] = useState(null); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); const [profileStatus, setProfileStatus] = useState<{ type: 'success' | 'error'; message: string } | null>(null); // Email change const [newEmail, setNewEmail] = useState(''); const [emailSaving, setEmailSaving] = useState(false); const [emailStatus, setEmailStatus] = useState<{ type: 'success' | 'error'; message: string } | null>(null); // Password change const [currentPassword, setCurrentPassword] = useState(''); const [newPassword, setNewPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); const [passwordSaving, setPasswordSaving] = useState(false); const [passwordStatus, setPasswordStatus] = useState<{ type: 'success' | 'error'; message: string } | null>(null); useEffect(() => { api.getProfile().then((p) => { setProfile(p); setNewEmail(p.email || ''); setLoading(false); }).catch(() => setLoading(false)); }, []); const handleSaveProfile = async (e: React.FormEvent) => { e.preventDefault(); if (!profile) return; setSaving(true); setProfileStatus(null); try { const updated = await api.updateProfile(profile); setProfile(updated); setProfileStatus({ type: 'success', message: 'Profile saved' }); setTimeout(() => setProfileStatus(null), 3000); } catch (err: any) { setProfileStatus({ type: 'error', message: err.message || 'Failed to save' }); } finally { setSaving(false); } }; const handleChangeEmail = async (e: React.FormEvent) => { e.preventDefault(); if (!newEmail || newEmail === profile?.email) return; setEmailSaving(true); setEmailStatus(null); try { await api.changeEmail(newEmail); await checkSession(); setProfile(prev => prev ? { ...prev, email: newEmail } : prev); setEmailStatus({ type: 'success', message: 'Email updated' }); setTimeout(() => setEmailStatus(null), 3000); } catch (err: any) { setEmailStatus({ type: 'error', message: err.message || 'Failed to update email' }); } finally { setEmailSaving(false); } }; const handleChangePassword = async (e: React.FormEvent) => { e.preventDefault(); setPasswordStatus(null); if (newPassword !== confirmPassword) { setPasswordStatus({ type: 'error', message: 'Passwords do not match' }); return; } if (newPassword.length < 8) { setPasswordStatus({ type: 'error', message: 'Password must be at least 8 characters' }); return; } setPasswordSaving(true); try { await api.changePassword(currentPassword, newPassword); setCurrentPassword(''); setNewPassword(''); setConfirmPassword(''); setPasswordStatus({ type: 'success', message: 'Password changed' }); setTimeout(() => setPasswordStatus(null), 3000); } catch (err: any) { setPasswordStatus({ type: 'error', message: err.message || 'Failed to change password' }); } finally { setPasswordSaving(false); } }; if (loading) return ; const inputClass = 'w-full px-3.5 py-2.5 border border-slate-300 dark:border-slate-600 rounded-lg text-sm text-slate-900 dark:text-slate-100 bg-white dark:bg-slate-800 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent'; const labelClass = 'block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1.5'; return (

Settings

Manage your profile, email, and password

{/* Profile Information */}

Profile Information

Your public-facing details

setProfile({ ...profile!, name: e.target.value })} className={inputClass} />
setProfile({ ...profile!, title: e.target.value })} placeholder="e.g., Account Executive" className={inputClass} />
setProfile({ ...profile!, company: e.target.value })} className={inputClass} />
setProfile({ ...profile!, phone: e.target.value })} className={inputClass} />
{/* Signature */}