import { redirect, useNavigation, useSubmit } from 'react-router'; import { z } from 'zod'; import { createAuthSession, getOptionalAuth, register } from '../auth.server'; import AuthCardHeading from '../components/AuthCardHeading'; import AuthErrorAlert from '../components/AuthErrorAlert'; import AuthSplitLayout from '../components/AuthSplitLayout'; import AuthSwitchPrompt from '../components/AuthSwitchPrompt'; import RegisterForm from '../components/RegisterForm'; import RegisterStepProgress from '../components/RegisterStepProgress'; import { useActionErrorToast } from '../hooks/useActionErrorToast'; import { useRegisterWizard } from '../hooks/useRegisterWizard'; import { registerSchema } from '../schemas'; import type { Route } from './+types/register'; export const meta = ({}: Route.MetaArgs) => { return [{ title: 'Register | The Biergarten App' }]; }; export const loader = async ({ request }: Route.LoaderArgs) => { const auth = await getOptionalAuth(request); if (auth) throw redirect('/dashboard'); return null; }; export const action = async ({ request }: Route.ActionArgs) => { const formData = await request.formData(); const result = registerSchema.safeParse(Object.fromEntries(formData)); if (!result.success) { return { error: null, fieldErrors: z.flattenError(result.error).fieldErrors }; } try { const { confirmPassword: _confirmPassword, ...body } = result.data; const payload = await register(body); return createAuthSession(payload, '/dashboard'); } catch (err) { return { error: err instanceof Error ? err.message : 'Registration failed.', fieldErrors: null, }; } }; const Register = ({ actionData }: Route.ComponentProps) => { const navigation = useNavigation(); const submit = useSubmit(); const isSubmitting = navigation.state === 'submitting'; const wizard = useRegisterWizard((data) => { submit(data, { method: 'post' }); }); // A request that reached the action without passing client validation, so the // rejected fields may well sit on a step other than the one on screen. const rejectedFields = Object.values(actionData?.fieldErrors ?? {}).flatMap( (messages) => messages ?? [], ); useActionErrorToast(actionData?.error); return ( {actionData?.error && } {rejectedFields.length > 0 && ( )} ); }; export default Register;