import { useState, useEffect, useRef } from 'react'; import { UserCircle, AlertCircle, CheckCircle, Loader2, Eye, EyeOff, Pencil, X, KeyRound } from 'lucide-react'; import { DEFAULT_LOCALE } from '@archer/domain'; import { PageLayout } from '@/components/shared'; import { useProfile, useUpdateProfile, useChangePassword, useResendVerification } from './hooks/useProfile'; import type { ProfileFormData } from '@/infrastructure/http/api/profile'; import { useTranslation } from '@/i18n/TranslationProvider'; import { PersonalAddressSection } from './PersonalAddressSection'; import { BillingCurrencySection } from './BillingCurrencySection'; export function ProfilePage() { const { t } = useTranslation(); const { data: profile, isLoading, error } = useProfile(); const updateMutation = useUpdateProfile(); const passwordMutation = useChangePassword(); const resendMutation = useResendVerification(); const [editing, setEditing] = useState(false); const [formData, setFormData] = useState({ firstName: '', lastName: '', phone: '', locale: DEFAULT_LOCALE, timezone: 'Europe/Berlin', }); const [currentPassword, setCurrentPassword] = useState(''); const [newPassword, setNewPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); const [showPasswords, setShowPasswords] = useState(false); const [passwordError, setPasswordError] = useState(''); const passwordRef = useRef(null); useEffect(() => { if (profile) { setFormData(profile.toFormData()); } }, [profile]); const handleChange = (field: keyof ProfileFormData, value: string) => { setFormData((prev) => ({ ...prev, [field]: value })); }; const handleProfileSubmit = (e: React.FormEvent) => { e.preventDefault(); updateMutation.mutate(formData, { onSuccess: () => setEditing(false), }); }; const handleCancelEdit = () => { if (profile) setFormData(profile.toFormData()); setEditing(false); }; const scrollToPassword = () => { passwordRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' }); }; const handlePasswordSubmit = (e: React.FormEvent) => { e.preventDefault(); setPasswordError(''); if (newPassword.length < 8) { setPasswordError(t('profile.passwordMinLength')); return; } if (newPassword !== confirmPassword) { setPasswordError(t('profile.passwordsNoMatch')); return; } passwordMutation.mutate( { currentPassword, newPassword }, { onSuccess: () => { setCurrentPassword(''); setNewPassword(''); setConfirmPassword(''); }, }, ); }; return ( } gradient={true} > {error && (

{t('profile.errorLoading', { error: (error as Error).message })}

)} {profile?.emailNotVerified && (

{t('profile.emailNotVerified')}

)} {/* Personal Information */}

{t('profile.personalInfo')}

{!editing && !isLoading && ( )}
{isLoading ? (
{[1, 2, 3, 4].map((i) => (
))}
) : editing ? (
handleChange('firstName', e.target.value)} className="w-full px-3 py-2.5 border border-border rounded-lg bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-primary/50" autoFocus />
handleChange('lastName', e.target.value)} className="w-full px-3 py-2.5 border border-border rounded-lg bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-primary/50" />
{profile?.emailVerified && ( )}
handleChange('phone', e.target.value)} placeholder={t('profile.phonePlaceholder')} className="w-full px-3 py-2.5 border border-border rounded-lg bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-primary/50" />
{updateMutation.isError && ( {(updateMutation.error as Error).message || t('profile.updateFailed')} )}
) : (

{t('profile.firstName')}

{profile?.firstName || '-'}

{t('profile.lastName')}

{profile?.lastName || '-'}

{t('profile.email')}

{profile?.email || '-'}

{profile?.emailVerified ? ( ) : ( <> {t('profile.emailNotVerified')} {resendMutation.isError && ( {(resendMutation.error as Error).message || t('profile.updateFailed')} )} )}

{t('profile.phone')}

{profile?.phone || '-'}

{t('profile.language')}

{profile?.localeLabel}

{t('profile.timezone')}

{profile?.timezone || '-'}

)}
{/* Billing Address (PERSONAL accounts only — business users edit on /dashboard/company) */} {profile?.isPersonal && } {/* Billing currency — PERSONAL accounts only; BUSINESS see it on /dashboard/company */} {profile?.isPersonal && } {/* Change Password */}

{t('profile.changePasswordTitle')}

setCurrentPassword(e.target.value)} required className="w-full px-3 py-2.5 pr-10 border border-border rounded-lg bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-primary/50" />
setNewPassword(e.target.value)} required placeholder={t('profile.newPasswordPlaceholder')} className="w-full px-3 py-2.5 border border-border rounded-lg bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-primary/50" />
setConfirmPassword(e.target.value)} required className="w-full px-3 py-2.5 border border-border rounded-lg bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-primary/50" />
{(passwordError || passwordMutation.isError) && (

{passwordError || (passwordMutation.error as Error).message || t('profile.passwordChangeFailed')}

)}
{passwordMutation.isSuccess && ( {t('profile.passwordChanged')} )}
); }