File size: 6,328 Bytes
9853396 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | import { HTMLAttributes } from 'react';
import { z } from 'zod';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { useTranslation } from 'react-i18next';
import { cn } from '@/lib/utils';
import { Button } from '@/components/ui/button';
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form';
import { Input } from '@/components/ui/input';
import { PasswordInput } from '@/components/password-input';
import { useInitializeSystem } from '@/features/auth/data/initialization';
type InitializationFormProps = HTMLAttributes<HTMLFormElement>;
// Create form schema factory to support i18n
const createFormSchema = (t: (key: string) => string) =>
z.object({
ownerEmail: z
.string()
.min(1, { message: t('initialization.form.validation.ownerEmailRequired') })
.email({ message: t('initialization.form.validation.ownerEmailInvalid') }),
ownerPassword: z
.string()
.min(1, {
message: t('initialization.form.validation.ownerPasswordRequired'),
})
.min(8, {
message: t('initialization.form.validation.ownerPasswordMinLength'),
}),
ownerFirstName: z.string().min(1, { message: t('initialization.form.validation.ownerFirstNameRequired') }),
ownerLastName: z.string().min(1, { message: t('initialization.form.validation.ownerLastNameRequired') }),
brandName: z.string().min(1, { message: t('initialization.form.validation.brandNameRequired') }),
});
export function InitializationForm({ className, ...props }: InitializationFormProps) {
const { t } = useTranslation();
const initializeSystemMutation = useInitializeSystem();
const formSchema = createFormSchema(t);
type FormData = z.infer<typeof formSchema>;
const form = useForm<FormData>({
resolver: zodResolver(formSchema),
defaultValues: {
ownerEmail: '',
ownerPassword: '',
ownerFirstName: '',
ownerLastName: '',
brandName: '',
},
});
function onSubmit(data: FormData) {
const input = {
ownerEmail: data.ownerEmail,
ownerPassword: data.ownerPassword,
ownerFirstName: data.ownerFirstName,
ownerLastName: data.ownerLastName,
brandName: data.brandName,
};
initializeSystemMutation.mutate(input);
}
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className={cn('grid gap-4', className)} {...props}>
<FormField
control={form.control}
name='ownerFirstName'
render={({ field }) => (
<FormItem>
<FormLabel>{t('initialization.form.ownerFirstName')}</FormLabel>
<FormControl>
<Input placeholder={t('initialization.form.placeholders.ownerFirstName')} className='border-slate-300 !bg-white text-slate-800 transition-all duration-300 placeholder:text-slate-400 focus:border-slate-500 focus:!bg-white focus:ring-2 focus:ring-slate-200' {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name='ownerLastName'
render={({ field }) => (
<FormItem>
<FormLabel>{t('initialization.form.ownerLastName')}</FormLabel>
<FormControl>
<Input placeholder={t('initialization.form.placeholders.ownerLastName')} className='border-slate-300 !bg-white text-slate-800 transition-all duration-300 placeholder:text-slate-400 focus:border-slate-500 focus:!bg-white focus:ring-2 focus:ring-slate-200' {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name='ownerEmail'
render={({ field }) => (
<FormItem>
<FormLabel>{t('initialization.form.ownerEmail')}</FormLabel>
<FormControl>
<Input placeholder={t('initialization.form.placeholders.ownerEmail')} className='border-slate-300 !bg-white text-slate-800 transition-all duration-300 placeholder:text-slate-400 focus:border-slate-500 focus:!bg-white focus:ring-2 focus:ring-slate-200' {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name='ownerPassword'
render={({ field }) => (
<FormItem>
<FormLabel>{t('initialization.form.ownerPassword')}</FormLabel>
<FormControl>
<PasswordInput placeholder={t('initialization.form.placeholders.ownerPassword')} className='border-slate-300 bg-white text-slate-800 backdrop-blur-sm transition-all duration-300 placeholder:text-slate-400 focus:border-slate-500 focus:bg-white focus:ring-2 focus:ring-slate-200' {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name='brandName'
render={({ field }) => (
<FormItem>
<FormLabel>{t('initialization.form.brandName')}</FormLabel>
<FormControl>
<Input placeholder={t('initialization.form.placeholders.brandName')} className='border-slate-300 !bg-white text-slate-800 transition-all duration-300 placeholder:text-slate-400 focus:border-slate-500 focus:!bg-white focus:ring-2 focus:ring-slate-200' {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<Button
type='submit'
className='mt-6 w-full rounded-lg bg-slate-800 px-6 py-3 font-medium text-white shadow-lg transition-all duration-300 hover:bg-slate-700 hover:shadow-xl focus:ring-2 focus:ring-slate-500 focus:ring-offset-2 disabled:opacity-50'
disabled={initializeSystemMutation.isPending}
>
{initializeSystemMutation.isPending ? t('initialization.form.submitting') : t('initialization.form.submit')}
</Button>
</form>
</Form>
);
}
|