150 lines
4.9 KiB
TypeScript
150 lines
4.9 KiB
TypeScript
import { Container, FormTextField } from "@/components";
|
|
import { FormSubmitButton } from "@/components/Forms/FormSubmitButton";
|
|
import { UeckoLogo } from "@/components/UeckoLogo/UeckoLogo";
|
|
import { useLogin } from "@/lib/hooks";
|
|
import {
|
|
Alert,
|
|
AlertDescription,
|
|
AlertTitle,
|
|
Card,
|
|
CardContent,
|
|
CardDescription,
|
|
CardHeader,
|
|
CardTitle,
|
|
Form,
|
|
} from "@/ui";
|
|
import { joiResolver } from "@hookform/resolvers/joi";
|
|
import { ILogin_DTO } from "@shared/contexts";
|
|
import { t } from "i18next";
|
|
import Joi from "joi";
|
|
import { AlertCircleIcon } from "lucide-react";
|
|
import { SubmitHandler, useForm } from "react-hook-form";
|
|
import { Trans } from "react-i18next";
|
|
import { Link } from "react-router-dom";
|
|
import SpanishJoiMessages from "../../spanish-joi-messages.json";
|
|
|
|
type LoginDataForm = ILogin_DTO;
|
|
|
|
export const LoginPage = () => {
|
|
const { mutate: login } = useLogin({
|
|
onSuccess: (data) => {
|
|
const { success, error } = data;
|
|
if (!success && error) {
|
|
form.setError("root", error);
|
|
}
|
|
},
|
|
});
|
|
|
|
const form = useForm<LoginDataForm>({
|
|
mode: "onBlur",
|
|
defaultValues: {
|
|
email: "",
|
|
password: "",
|
|
},
|
|
resolver: joiResolver(
|
|
Joi.object({
|
|
email: Joi.string()
|
|
.email({ tlds: { allow: false } })
|
|
.required(),
|
|
password: Joi.string().min(4).alphanum().required(),
|
|
}),
|
|
{
|
|
messages: SpanishJoiMessages,
|
|
}
|
|
),
|
|
});
|
|
|
|
const onSubmit: SubmitHandler<LoginDataForm> = async (data) => {
|
|
login({ email: data.email, password: data.password }, {});
|
|
};
|
|
|
|
return (
|
|
<Container
|
|
variant={"full"}
|
|
className='p-0 lg:grid lg:min-h-[600px] lg:grid-cols-2 xl:min-h-[800px] h-screen'
|
|
>
|
|
<div className='flex items-center justify-center py-12'>
|
|
<div className='mx-auto grid w-[650px] gap-6'>
|
|
<Card className='px-12 py-6'>
|
|
<CardHeader>
|
|
<UeckoLogo className='inline-block m-auto mb-6 align-middle max-w-32' />
|
|
<CardTitle>
|
|
<Trans i18nKey='login_page.title' />
|
|
</CardTitle>
|
|
<CardDescription>
|
|
<Trans i18nKey='login_page.description' />
|
|
</CardDescription>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<Form {...form}>
|
|
<form onSubmit={form.handleSubmit(onSubmit)}>
|
|
<div className='grid items-start gap-6'>
|
|
<div className='grid gap-6'>
|
|
<FormTextField
|
|
required
|
|
name='email'
|
|
label={t("login_page.email_label")}
|
|
type='email'
|
|
placeholder={t("login_page.email_placeholder")}
|
|
/>
|
|
</div>
|
|
<div className='grid gap-6'>
|
|
<FormTextField
|
|
required
|
|
name='password'
|
|
label={t("login_page.password_label")}
|
|
type='password'
|
|
/>
|
|
<div className='mb-4 -mt-2 text-sm'>
|
|
<Trans i18nKey='login_page.forgotten_password' />
|
|
<br />
|
|
<Link to='https://uecko.com/distribuidores' className='underline'>
|
|
<Trans i18nKey='login_page.contact_us' />
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
|
|
{form.formState.errors.root?.message && (
|
|
<Alert variant='destructive'>
|
|
<AlertCircleIcon className='w-4 h-4' />
|
|
<AlertTitle>
|
|
<Trans i18nKey='common.error' />
|
|
</AlertTitle>
|
|
<AlertDescription>{form.formState.errors.root?.message}</AlertDescription>
|
|
</Alert>
|
|
)}
|
|
|
|
<FormSubmitButton className='w-full' label={t("login_page.login")} />
|
|
|
|
<div className='mt-4 text-sm text-center'>
|
|
<Trans i18nKey='login_page.become_dealer' />
|
|
<br />
|
|
<Link to='https://uecko.com/distribuidores' className='underline'>
|
|
<Trans i18nKey='login_page.contact_us' />
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</Form>
|
|
</CardContent>
|
|
</Card>
|
|
<img
|
|
className='block w-11/12 mx-auto aspect-auto'
|
|
src='https://uecko.com/assets/img/uecko-footer_logos.jpg'
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div className='hidden bg-muted lg:block'>
|
|
<img
|
|
src='https://uecko.com/assets/img/021/nara2.jpg'
|
|
alt='Image'
|
|
width='1920'
|
|
height='1080'
|
|
className='h-full w-full object-cover dark:brightness-[0.2] dark:grayscale'
|
|
/>
|
|
</div>
|
|
</Container>
|
|
);
|
|
};
|