import { useState, type ReactNode } from 'react'; import { useQuery } from '@tanstack/react-query'; import { api } from '../api/client'; import { useI18n } from '../i18n'; import { useSession } from '../state/session'; import { goTo, workspacePath } from '../state/route'; /** * The other end of an invite link. * * Three cases, and the screen says which one it is rather than making the * person guess: they have no account yet and choose a password here; they have * one and are signed in, so it is a single confirmation; or they have one and * are not signed in, so they sign in first and come back. */ export function InviteScreen({ token }: { token: string }): ReactNode { const session = useSession(); const { t } = useI18n(); const [name, setName] = useState(''); const [password, setPassword] = useState(''); const [error, setError] = useState(null); const [busy, setBusy] = useState(false); const invite = useQuery({ queryKey: ['invite', token], queryFn: () => api.readInvite(token), retry: false, }); if (invite.isLoading) return ; if (invite.error) { return (

{invite.error instanceof Error ? invite.error.message : t('auth.inviteLinkExpired')}

{t('auth.goToWellformed')}
); } const info = invite.data!.invite; const signedInAsSomeoneElse = session.account && session.account.email !== info.email; async function accept() { setBusy(true); setError(null); try { const result = await api.acceptInvite( token, info.needsAccount ? { name: name.trim(), password } : {}, ); goTo(workspacePath(result.workspace.slug)); } catch (err) { setError(err instanceof Error ? err.message : t('auth.acceptFailed')); setBusy(false); } } return (

{t('auth.invitedAsBefore')} {info.email} {t('auth.invitedAsMiddle')} {t(`role.${info.role}`)} {t('auth.invitedAsAfter')}

{error && (
{error}
)} {signedInAsSomeoneElse && ( <>

{t('auth.wrongAccountBefore')} {session.account!.email} {t('auth.wrongAccountAfter')}

)} {!signedInAsSomeoneElse && info.needsAccount && (
{ e.preventDefault(); void accept(); }} >
)} {!signedInAsSomeoneElse && !info.needsAccount && session.account && ( )} {!signedInAsSomeoneElse && !info.needsAccount && !session.account && (

{info.email} {t('auth.alreadyAccountAfter')} {t('auth.signInLink')} {t('auth.thenOpenAgain')}

)}
); } function Card({ tagline, children }: { tagline: string; children?: ReactNode }): ReactNode { return (
Wellformed
{tagline}
{children}
); }