import React, { useState } from 'react'; import { User, Mail, Save, Trash2, AlertTriangle, X, Loader2, CheckCircle, Lock, ChevronDown, ChevronUp, Eye, EyeOff } from 'lucide-react'; import { useTheme } from '../contexts/ThemeContext'; const AccountModal = ({ user, authToken, onClose, onAccountUpdated, onAccountDeleted }) => { const { isDark } = useTheme(); const [firstName, setFirstName] = useState(user?.firstName || ''); const [lastName, setLastName] = useState(user?.lastName || ''); const [email, setEmail] = useState(user?.email || ''); const [saving, setSaving] = useState(false); const [saved, setSaved] = useState(false); const [error, setError] = useState(null); const [showPassword, setShowPassword] = useState(false); const [currentPassword, setCurrentPassword] = useState(''); const [newPassword, setNewPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); const [changingPw, setChangingPw] = useState(false); const [pwSuccess, setPwSuccess] = useState(false); const [pwError, setPwError] = useState(null); const [showCurrent, setShowCurrent] = useState(false); const [showNew, setShowNew] = useState(false); const [showDeleteConfirm, setShowDeleteConfirm] = useState(false); const [deleting, setDeleting] = useState(false); const [deleteInput, setDeleteInput] = useState(''); const hasChanges = firstName !== (user?.firstName || '') || lastName !== (user?.lastName || '') || email !== (user?.email || ''); const handleSave = async () => { if (!firstName.trim() || !email.trim()) { setError('First name and email are required.'); return; } setSaving(true); setError(null); try { const resp = await fetch(`${process.env.REACT_APP_API_URL}/auth/me`, { method: 'PATCH', headers: { 'Authorization': `Bearer ${authToken}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ firstName: firstName.trim(), lastName: lastName.trim(), email: email.trim() }), }); if (resp.ok) { const updated = await resp.json(); setSaved(true); if (onAccountUpdated) onAccountUpdated(updated); setTimeout(() => setSaved(false), 2000); } else { const data = await resp.json().catch(() => ({})); setError(data.detail || 'Failed to update account.'); } } catch { setError('Network error.'); } finally { setSaving(false); } }; const handleChangePassword = async () => { setPwError(null); if (!currentPassword) { setPwError('Enter your current password.'); return; } if (newPassword.length < 6) { setPwError('New password must be at least 6 characters.'); return; } if (newPassword !== confirmPassword) { setPwError('New passwords do not match.'); return; } setChangingPw(true); try { const resp = await fetch(`${process.env.REACT_APP_API_URL}/auth/me/password`, { method: 'POST', headers: { 'Authorization': `Bearer ${authToken}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ current_password: currentPassword, new_password: newPassword }), }); if (resp.ok) { setPwSuccess(true); setCurrentPassword(''); setNewPassword(''); setConfirmPassword(''); setTimeout(() => { setPwSuccess(false); setShowPassword(false); }, 2000); } else { const data = await resp.json().catch(() => ({})); setPwError(data.detail || 'Failed to change password.'); } } catch { setPwError('Network error.'); } finally { setChangingPw(false); } }; const handleDelete = async () => { setDeleting(true); try { const resp = await fetch(`${process.env.REACT_APP_API_URL}/auth/me`, { method: 'DELETE', headers: { 'Authorization': `Bearer ${authToken}` }, }); if (resp.ok) { if (onAccountDeleted) onAccountDeleted(); } else { setError('Failed to delete account.'); setShowDeleteConfirm(false); } } catch { setError('Network error.'); setShowDeleteConfirm(false); } finally { setDeleting(false); } }; const overlay = { position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.5)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 9999, }; const modal = { background: isDark ? '#1f2937' : '#fff', borderRadius: 16, padding: 28, width: 420, maxWidth: '92vw', boxShadow: '0 20px 60px rgba(0,0,0,0.3)', color: isDark ? '#f3f4f6' : '#111827', }; const inputStyle = { width: '100%', padding: '10px 12px', borderRadius: 10, fontSize: 14, border: `1px solid ${isDark ? '#374151' : '#e5e7eb'}`, background: isDark ? '#111827' : '#f9fafb', color: isDark ? '#f3f4f6' : '#111827', outline: 'none', boxSizing: 'border-box', }; const labelStyle = { display: 'block', fontSize: 12, fontWeight: 600, color: isDark ? '#9ca3af' : '#6b7280', marginBottom: 5, }; if (showDeleteConfirm) { return (
setShowDeleteConfirm(false)}>
e.stopPropagation()}>

Delete Account?

This will permanently delete your account and all associated data (profile, chats, canvas). This action cannot be undone.

Type DELETE to confirm:

setDeleteInput(e.target.value)} placeholder="DELETE" style={{ ...inputStyle, textAlign: 'center', maxWidth: 200, margin: '0 auto 18px' }} />
); } return (
e.stopPropagation()}> {/* Header */}

Account

{/* Fields */}
setFirstName(e.target.value)} style={inputStyle} />
setLastName(e.target.value)} style={inputStyle} />
setEmail(e.target.value)} type="email" style={{ ...inputStyle, paddingLeft: 36 }} />
{/* Change Password */}
{showPassword && (
setCurrentPassword(e.target.value)} type={showCurrent ? 'text' : 'password'} style={inputStyle} placeholder="Enter current password" />
setNewPassword(e.target.value)} type={showNew ? 'text' : 'password'} style={inputStyle} placeholder="At least 6 characters" />
setConfirmPassword(e.target.value)} type={showNew ? 'text' : 'password'} style={inputStyle} placeholder="Re-enter new password" />
{pwError && (
{pwError}
)}
)}
{error && (
{error}
)} {/* Save */}
); }; export default AccountModal;