Add the setup flow's confirm screen

What the answers switch on is read off the registry's derivation and
never computed here, so the list the person confirms is the list the
completion route writes. Units, language and time zone are shown once
beside it, changeable in Settings, never asked again.

The profile half keeps the baseline form and its per-field refusals:
the fields are seeded from the account so a value it holds is confirmed
rather than typed again, and a refused field still stops the flow. For
"someone I look after" the managed-profile form takes the profile's
place, because that record is created here, after the questions; an
account without a second factor can finish without it and create it
later under Settings.

Confirming posts the completion, passes the first-result step outright
when there is no task to offer, and goes where the step machine says.
This commit is contained in:
Marc-André Bombeck committed 2026-09-10 15:19:48 +02:00
1 parent 7b279aec72
commit 58bc91a0a3
8 files changed
+459 -57

No files matched your search

@@ -15,6 +15,7 @@ import { useTranslations } from "@/lib/i18n/context";
import {
useCreateManagedProfile,
type ManagedProfileGender,
type ManagedProfileView,
} from "@/lib/queries/use-managed-profiles";
import {
DEFAULT_TIMEZONE,
@@ -73,7 +74,19 @@ import {
* invitation form does, rather than the generic "could not be created", which
* would send somebody looking for a problem with what they typed.
*/
export function ManagedProfileCreateForm() {
export function ManagedProfileCreateForm({
submitLabel,
onCreated,
}: {
/** The button's label when the form sits somewhere other than the panel. */
submitLabel?: string;
/**
* v1.39 (C2) — fired after a successful creation, with the record. The
* setup flow's confirm screen mounts this form and continues from here;
* the sharing panel leaves it unset and shows the confirmation line.
*/
onCreated?: (profile: ManagedProfileView) => void;
} = {}) {
const { t, locale: actorLocale } = useTranslations();
const create = useCreateManagedProfile();
@@ -116,6 +129,7 @@ export function ManagedProfileCreateForm() {
setGender(null);
setTimezone(browserTimezone());
setCreated(profile.displayName ?? trimmedName);
onCreated?.(profile);
},
// Nothing is cleared here, on purpose: a refused creation is one the
// person is being asked to retry, and a form that emptied itself
@@ -258,7 +272,7 @@ export function ManagedProfileCreateForm() {
>
{create.isPending
? t("recordSharing.managed.creating")
: t("recordSharing.managed.create")}
: (submitLabel ?? t("recordSharing.managed.create"))}
</Button>
{error && (