Select Git revision
Embruch, Gerd authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
Login.jsx 3.71 KiB
import React, { useEffect } from 'react';
import { Link, useLocation, useNavigate } from 'react-router-dom';
import { useAuth } from '../../contexts/Auth/AuthState';
import { FormProvider, useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from "zod";
import { toast } from 'react-toastify';
import { mergeBackendValidation, setFlashMsg } from '../../utils/ErrorHandling';
import Input from '../../components/form/Input';
import Submit from '../../components/form/Submit';
import { Helmet } from 'react-helmet-async';
import Heading from '../../components/font/Heading';
function Login() {
// #################################
// VALIDATION SCHEMA
// #################################
const schema = z.object({
email: z.string().email(),
password: z.string().min(1)
});
// #################################
// HOOKS
// #################################
// ### CONNECT AUTH CONTEXT
const { login } = useAuth();
// ### MAKE USE OF NAVIGATION
const redirect = useNavigate();
// ### MAKE USE OF location state to fetch former requested page
const { state } = useLocation();
// ### PREPARE FORM
const methods = useForm({
resolver: zodResolver(schema),
mode: 'onBlur',
defaultValues: {
email: '',
password: ''
}
});
// ### ON LOAD SHOW SOME INFOS
useEffect(() => {
// DEV TOASTS
if (import.meta.env.MODE === 'development') {
// Info for DevMode to accept self signed api cert to enable API connection
toast.warning(() => (
<>
<span className="sr-only">Info</span>
<p className="font-bold font-UhhSLC">DevMode: Making the API accessible</p>
<p>Connect the <a href={`${import.meta.env.VITE_BACKEND_URL}:${import.meta.env.VITE_BACKEND_PORT}`} target="_blank" className="underline">backend</a> & accept the security risk.</p>
</>
), {
autoClose: false,
closeOnClick: false,
toastId: 'api-connection-toast',
});
}
// dismiss dev toasts if unload
return () => {
if (import.meta.env.MODE === 'development') {
toast.dismiss('api-connection-toast');
}
};
}, []);
// #################################
// FUNCTIONS
// #################################
// ### HANDLE SUBMITTING LOGIN FORM
async function handleSendForm(record) {
try {
// send data to login function
const result = await login(record);
// if former page request was saved, redirect to this page
// otherwise redirect to default page
(state) ? redirect(`${state.redirectTo.pathname}${state.redirectTo.search}`) : redirect(import.meta.env.VITE_PAGE_AFTER_LOGIN);
// FIX: flash message not dislayed
setFlashMsg(result.data?.message);
} catch (err) {
// merge front & backend validation errors
mergeBackendValidation(err.response.status, err.response.data, methods.setError);
}
}
// #################################
// OUTPUT
// #################################
return (
<>
{/* render page title */}
<Helmet><title>[{import.meta.env.VITE_APP_NAME}]</title></Helmet>
<Heading level="1">ZBH-Portal LogIn</Heading>
<FormProvider {...methods} >
<form onSubmit={methods.handleSubmit(handleSendForm)}>
<Input name='email' type='mail' title='E-Mail' className='h-16' autoFocus={true} />
<Input name='password' type='password' title='password' className='h-16' />
<Submit value='LogIn' />
</form>
</FormProvider>
<div className="mt-4 flex justify-between">
<Link to="/reset_password">Reset Password</Link>
<Link to="/signup">Create an account</Link>
</div>
</>
);
}
export default Login;