From fffbe68dc29bf0165f6928aa1dc5a8b8efa5f2d1 Mon Sep 17 00:00:00 2001 From: Aaron Po Date: Tue, 13 Oct 2026 01:32:59 -0400 Subject: [PATCH] List the action's rejected fields above the register form --- .../features/auth/components/AuthErrorAlert.tsx | 14 ++++++++++++-- web/frontend/app/features/auth/routes/register.tsx | 13 +++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/web/frontend/app/features/auth/components/AuthErrorAlert.tsx b/web/frontend/app/features/auth/components/AuthErrorAlert.tsx index 4892d919..98f2b77d 100644 --- a/web/frontend/app/features/auth/components/AuthErrorAlert.tsx +++ b/web/frontend/app/features/auth/components/AuthErrorAlert.tsx @@ -1,10 +1,20 @@ interface AuthErrorAlertProps { message: string; + /** Per-field messages to list beneath the summary. */ + details?: readonly string[]; } -const AuthErrorAlert = ({ message }: AuthErrorAlertProps) => ( -
+const AuthErrorAlert = ({ message, details }: AuthErrorAlertProps) => ( +
{message} + + {details?.length ? ( +
    + {details.map((detail) => ( +
  • {detail}
  • + ))} +
+ ) : null}
); diff --git a/web/frontend/app/features/auth/routes/register.tsx b/web/frontend/app/features/auth/routes/register.tsx index fd6492b7..73cec5bd 100644 --- a/web/frontend/app/features/auth/routes/register.tsx +++ b/web/frontend/app/features/auth/routes/register.tsx @@ -51,6 +51,12 @@ const Register = ({ actionData }: Route.ComponentProps) => { 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 ( @@ -68,6 +74,13 @@ const Register = ({ actionData }: Route.ComponentProps) => { {actionData?.error && } + {rejectedFields.length > 0 && ( + + )} +