Skip to content
Snippets Groups Projects
Select Git revision
  • 048eb4e58521dfc950f8ca33d81ab8d1f220431a
  • main default protected
  • userHandling
  • snuggle
4 results

Login.jsx

Blame
  • 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;