import { useEffect, useRef, useState } from 'react'; import { api, type User } from '../api'; import { useI18n } from '../i18n/I18nProvider'; import { Avatar } from './Avatar'; // The signed-in account editing itself: picture, email, password. The API // re-verifies the current password and the login limiter caps guessing, so this // form holds no secret. Shared by the /admin settings drawer and /profile. export function Profile({ onSaved, onUser }: { onSaved: (note: string) => void; onUser?: (user: User) => void }) { const { t } = useI18n(); const [user, setUser] = useState(null); const [email, setEmail] = useState(''); const [current, setCurrent] = useState(''); const [password, setPassword] = useState(''); const [busy, setBusy] = useState(false); const [err, setErr] = useState(null); const filePick = useRef(null); useEffect(() => { api.me().then((r) => { setUser(r.user); setEmail(r.user?.email ?? ''); }).catch(() => undefined); }, []); const keep = (u: User) => { setUser(u); setEmail(u.email); onUser?.(u); }; const pick = async (file: File) => { setBusy(true); setErr(null); try { keep((await api.uploadAvatar(file)).user); onSaved(t('adm.saved')); } catch (e2) { setErr(e2 instanceof Error ? e2.message : String(e2)); } finally { setBusy(false); } }; const submit = async (e: React.FormEvent) => { e.preventDefault(); setBusy(true); setErr(null); try { const r = await api.updateProfile({ email: email.trim(), currentPassword: current, ...(password ? { password } : {}), }); keep(r.user); setPassword(''); setCurrent(''); onSaved(t('adm.saved')); } catch (e2) { setErr(e2 instanceof Error ? e2.message : String(e2)); } finally { setBusy(false); } }; return (

{t('adm.profileHint')}

{ const file = e.target.files?.[0]; e.target.value = ''; if (file) void pick(file); }} />
setEmail(e.target.value)} /> setCurrent(e.target.value)} /> setPassword(e.target.value)} /> {err ?

{err}

: null}
); }