shoc-frontend-new/src/app/invite/_components/invite-password-step.tsx

101 lines
2.8 KiB
TypeScript

import { useForm, useWatch } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { Box } from "@mui/material";
import { PasswordChecklist } from "@/components/auth/password-checklist";
import { Button } from "@/components/ui/button";
import { Text } from "@/components/ui/text";
import { FormField } from "@/components/ui/form-field";
import { PasswordField } from "@/components/ui/password-field";
import {
invitePasswordStepSchema,
type InvitePasswordStepValues,
} from "@/domain/team-member-invite/schemas/invite-registration-schema";
import { InviteStepHeader } from "./invite-step-header";
export type InvitePasswordStepProps = {
name: string;
defaultPassword: string;
isSubmitting: boolean;
error: string | null;
onContinue: (password: string) => void;
};
export function InvitePasswordStep({
name,
defaultPassword,
isSubmitting,
error,
onContinue,
}: InvitePasswordStepProps) {
const {
register,
handleSubmit,
control,
formState: { errors },
} = useForm<InvitePasswordStepValues>({
resolver: zodResolver(invitePasswordStepSchema),
defaultValues: { password: defaultPassword, confirmPassword: defaultPassword },
mode: "onTouched",
});
const values = useWatch({ control });
const canContinue = invitePasswordStepSchema.safeParse(values).success;
return (
<Box
component="form"
aria-label="Create your password"
onSubmit={handleSubmit((form) => onContinue(form.password))}
className="flex flex-col gap-4"
>
<InviteStepHeader
step={1}
title="Create your password"
subtitle={`Setting up the account for ${name}`}
/>
<FormField label="Password" htmlFor="invite-password" required appearance="auth">
<PasswordField
{...register("password")}
id="invite-password"
autoComplete="new-password"
slotProps={{ htmlInput: { "aria-describedby": "invite-password-rules" } }}
/>
<PasswordChecklist id="invite-password-rules" password={values.password ?? ""} />
</FormField>
<FormField
label="Confirm password"
htmlFor="invite-confirm-password"
required
appearance="auth"
error={Boolean(errors.confirmPassword)}
helperText={errors.confirmPassword?.message}
>
<PasswordField
{...register("confirmPassword")}
id="invite-confirm-password"
autoComplete="new-password"
error={Boolean(errors.confirmPassword)}
/>
</FormField>
<Text variant="error" when={error !== null}>
{error}
</Text>
<Button
type="submit"
fullWidth
size="lg"
disabled={!canContinue}
loading={isSubmitting}
loadingText="Sending code…"
>
Continue
</Button>
</Box>
);
}