Files
myeasycms-v2/packages/features/auth/src/components/password-sign-up-form.tsx
Giancarlo Buomprisco 001903ddac Refactor password sign-up flow and improve form usability (#131)
- Extracted sign-up logic into a new `usePasswordSignUpFlow` hook
- Simplified `EmailPasswordSignUpContainer` component
- Added `autoComplete="new-password"` to password input for better UX
- Converted `PasswordSignUpForm` props to a TypeScript interface
2025-02-03 12:34:26 +08:00

171 lines
4.1 KiB
TypeScript

'use client';
import { zodResolver } from '@hookform/resolvers/zod';
import { ArrowRight } from 'lucide-react';
import { useForm } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { Button } from '@kit/ui/button';
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@kit/ui/form';
import { If } from '@kit/ui/if';
import { Input } from '@kit/ui/input';
import { Trans } from '@kit/ui/trans';
import { PasswordSignUpSchema } from '../schemas/password-sign-up.schema';
import { TermsAndConditionsFormField } from './terms-and-conditions-form-field';
interface PasswordSignUpFormProps {
defaultValues?: {
email: string;
};
displayTermsCheckbox?: boolean;
onSubmit: (params: {
email: string;
password: string;
repeatPassword: string;
}) => unknown;
loading: boolean;
}
export function PasswordSignUpForm({
defaultValues,
displayTermsCheckbox,
onSubmit,
loading,
}: PasswordSignUpFormProps) {
const { t } = useTranslation();
const form = useForm({
resolver: zodResolver(PasswordSignUpSchema),
defaultValues: {
email: defaultValues?.email ?? '',
password: '',
repeatPassword: '',
},
});
return (
<Form {...form}>
<form
className={'flex w-full flex-col gap-y-4'}
onSubmit={form.handleSubmit(onSubmit)}
>
<FormField
control={form.control}
name={'email'}
render={({ field }) => (
<FormItem>
<FormLabel>
<Trans i18nKey={'common:emailAddress'} />
</FormLabel>
<FormControl>
<Input
data-test={'email-input'}
required
type="email"
placeholder={t('emailPlaceholder')}
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name={'password'}
render={({ field }) => (
<FormItem>
<FormLabel>
<Trans i18nKey={'common:password'} />
</FormLabel>
<FormControl>
<Input
required
data-test={'password-input'}
type="password"
autoComplete="new-password"
placeholder={''}
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name={'repeatPassword'}
render={({ field }) => (
<FormItem>
<FormLabel>
<Trans i18nKey={'auth:repeatPassword'} />
</FormLabel>
<FormControl>
<Input
required
data-test={'repeat-password-input'}
type="password"
placeholder={''}
{...field}
/>
</FormControl>
<FormMessage />
<FormDescription className={'pb-2 text-xs'}>
<Trans i18nKey={'auth:repeatPasswordHint'} />
</FormDescription>
</FormItem>
)}
/>
<If condition={displayTermsCheckbox}>
<TermsAndConditionsFormField />
</If>
<Button
data-test={'auth-submit-button'}
className={'w-full'}
type="submit"
disabled={loading}
>
<If
condition={loading}
fallback={
<>
<Trans i18nKey={'auth:signUpWithEmail'} />
<ArrowRight
className={
'zoom-in animate-in slide-in-from-left-2 fill-mode-both h-4 delay-500 duration-500'
}
/>
</>
}
>
<Trans i18nKey={'auth:signingUp'} />
</If>
</Button>
</form>
</Form>
);
}