import { useState, type ReactNode } from 'react'; import { useI18n } from '../i18n'; import { useSession } from '../state/session'; import { currentVoiceId } from '../state/voice'; import { goTo } from '../state/route'; /** * Signup asks for three things because that is what an account is: a person, * an address, a password. The workspace is deliberately not one of them — * naming a workspace before ever having seen one produced names like "test" — * so a fresh account lands in the picker, and the picker creates the first * workspace with the choices that belong to it: the name, and whether to * start from the demo. */ export function SignupScreen(): ReactNode { const session = useSession(); const { t } = useI18n(); const [email, setEmail] = useState(''); const [name, setName] = useState(''); const [password, setPassword] = useState(''); const [error, setError] = useState(null); const [busy, setBusy] = useState(false); const ready = email.trim() && name.trim() && password.length >= 10; async function submit(event: React.FormEvent) { event.preventDefault(); setBusy(true); setError(null); try { await session.signUp({ email: email.trim(), name: name.trim(), password, // Which landing page produced this, if any. Read at submit rather than // held in state so arriving here straight from a bookmark — with no // impression in the tab — simply omits it. ...(currentVoiceId() ? { voice: currentVoiceId() } : {}), }); // No workspaces yet, so the router lands on the picker, mid-creation. goTo('/'); } catch (err) { setError(err instanceof Error ? err.message : t('auth.signupFailed')); setBusy(false); } } return (
Wellformed
{t('auth.signupTagline')}
void submit(e)}> {error && (
{error}
)}

{t('auth.haveAccountBefore')} {t('auth.signInLink')}.

); }