import React, { useCallback, useEffect, useState } from 'react'; import { ArrowLeft, ChevronRight, LogOut } from 'lucide-react'; import ProfileLogo from '../../Logos/ProfileLogo'; import { useAuth } from '../../../contexts/AuthContext'; import { useSetIsSettingsModalOpen } from '../../../contexts/UIContext'; import { useAppRoute } from '../../../hooks/useAppRoute'; import { Button, Panel, StatusBadge } from '../../ui'; import { Field, PasswordField } from './SettingsFields'; import type { SettingsMessage } from './types'; type AccountView = 'summary' | 'email' | 'password' | 'verify-email'; interface AccountSettingsSectionProps { isOpen: boolean; onMessageChange: (message: SettingsMessage | null) => void; } const sourceBadge = (label: string) => ( {label} ); const AccountSettingsSection: React.FC = ({ isOpen, onMessageChange, }) => { const { userInfo, logout, updateEmail, updatePassword, requestVerification, verifyCode } = useAuth(); const setIsSettingsModalOpen = useSetIsSettingsModalOpen(); const { setRoute } = useAppRoute(); const [accountView, setAccountView] = useState('summary'); const [newEmail, setNewEmail] = useState(''); const [emailPassword, setEmailPassword] = useState(''); const [verificationCode, setVerificationCode] = useState(''); const [pendingEmailChange, setPendingEmailChange] = useState<{ newEmail: string; currentPassword: string } | null>(null); const [currentPassword, setCurrentPassword] = useState(''); const [newPassword, setNewPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); const [isSubmitting, setIsSubmitting] = useState(false); const resetAccountForms = useCallback(() => { setNewEmail(''); setEmailPassword(''); setVerificationCode(''); setPendingEmailChange(null); setCurrentPassword(''); setNewPassword(''); setConfirmPassword(''); onMessageChange(null); }, [onMessageChange]); useEffect(() => { if (!isOpen) { setAccountView('summary'); resetAccountForms(); } }, [isOpen, resetAccountForms]); const submitEmailChange = async (event: React.FormEvent) => { event.preventDefault(); setIsSubmitting(true); onMessageChange(null); try { const result = await updateEmail(newEmail, emailPassword); if (result.requiresVerification) { await requestVerification(newEmail, 'email_change'); setPendingEmailChange({ newEmail, currentPassword: emailPassword }); setAccountView('verify-email'); } else { onMessageChange({ tone: 'success', text: 'Email updated.' }); setAccountView('summary'); } } catch (error) { onMessageChange({ tone: 'danger', text: error instanceof Error ? error.message : 'Failed to update email.' }); } finally { setIsSubmitting(false); } }; const submitVerification = async (event: React.FormEvent) => { event.preventDefault(); setIsSubmitting(true); onMessageChange(null); try { if (!pendingEmailChange) throw new Error('Missing email change request.'); await verifyCode(pendingEmailChange.newEmail, verificationCode); onMessageChange({ tone: 'success', text: 'Email verified.' }); resetAccountForms(); setAccountView('summary'); } catch (error) { onMessageChange({ tone: 'danger', text: error instanceof Error ? error.message : 'Verification failed.' }); } finally { setIsSubmitting(false); } }; const submitPasswordChange = async (event: React.FormEvent) => { event.preventDefault(); onMessageChange(null); if (newPassword.length < 8) { onMessageChange({ tone: 'danger', text: 'Password must be at least 8 characters long.' }); return; } if (newPassword !== confirmPassword) { onMessageChange({ tone: 'danger', text: 'New passwords do not match.' }); return; } setIsSubmitting(true); try { await updatePassword(currentPassword, newPassword); onMessageChange({ tone: 'success', text: 'Password updated.' }); resetAccountForms(); setAccountView('summary'); } catch (error) { onMessageChange({ tone: 'danger', text: error instanceof Error ? error.message : 'Failed to update password.' }); } finally { setIsSubmitting(false); } }; const handleLogout = async () => { setIsSettingsModalOpen(false); setRoute({ name: 'home' }, { replace: true }); await logout(); }; if (!userInfo) { return ( Account Sign in to manage account settings and saved preferences. {sourceBadge('Account')} ); } if (accountView === 'email') { return ( setAccountView('summary')}> Back setNewEmail(event.target.value)} required /> setEmailPassword(event.target.value)} required /> Send verification ); } if (accountView === 'verify-email') { return ( setAccountView('summary')}> Back Enter the verification code sent to {pendingEmailChange?.newEmail}. setVerificationCode(event.target.value)} required /> Verify email ); } if (accountView === 'password') { return ( setAccountView('summary')}> Back setCurrentPassword(event.target.value)} required /> setNewPassword(event.target.value)} required /> setConfirmPassword(event.target.value)} required /> Update password ); } return ( {userInfo.name} {userInfo.email} {([ { label: 'Change email', onClick: () => setAccountView('email') }, { label: 'Change password', onClick: () => setAccountView('password') }, ] as const).map(row => ( {row.label} ))} Log out ); }; export default AccountSettingsSection;
Sign in to manage account settings and saved preferences.
{userInfo.email}