super-fit-web-app / src / components / app / log-in-form.tsx
log-in-form.tsx
Raw
import React, {useEffect} from 'react';
import { useRouter } from 'next/router';
import { useForm } from 'react-hook-form'
import { toast } from 'react-toastify';
import { trpc } from '@/utils/trpc';
import { TextField, Paper, Stack, Box, Typography, Link, FormHelperText } from '@mui/material';
import { LoadingButton } from '@mui/lab';
import { useCustomTheme } from '@/themes/useCustomTheme';
import { useUserContext } from '@/context/UserContext';

interface LoginFormFields extends Record<string, string> {
  email: string;
  password: string;
}

export default function LogInForm() {
  const router = useRouter()
  const theme = useCustomTheme();
  const { userData, session_valid, userSessionDataLoading, setUserData, setSessionValid } = useUserContext();
  const { register, handleSubmit, formState: { errors } } = useForm<LoginFormFields>();

  const { 
    data: loginData,
    mutateAsync: loginQuery, 
    isLoading: isLoginLoading,
    isSuccess: isLogInSuccess,
    isError: isLoginError,
    error: loginError
  } = trpc.auth.login.useMutation();

  const onFormSubmit = async (data: LoginFormFields) => {
    if (session_valid) return;
    loginQuery(data)
  }

  useEffect(() => {
    if (loginData?.login_success) {
      setUserData(loginData.user);
      setSessionValid(loginData.login_success)
      if (loginData.email_verified !== null) {
        router.push('/dashboard');
      } else {
        router.push('/verify-email');
      }
    }
  }, [loginData]);

  return (
    <Box 
        sx={{
          display: 'flex',
          justifyContent: 'center',
          alignItems: 'center',
          minHeight: '80vh',
          px: theme.customProperties.sectionPaddingX
        }}
      >
        <Paper
          sx={{
            p: { xs: 2, md: 3, lg: 4 },
            width: '100%',
            maxWidth: '400px',
          }}
        >
          <Typography variant='h5'>
            LOGIN
          </Typography>
          <Box component={'form'} onSubmit={handleSubmit(onFormSubmit)} >
            <Stack spacing={2} sx={{ mt: 3 }}>
              <TextField
                label='Email'
                variant='outlined'
                autoFocus
                fullWidth
                helperText={errors.email ? 'this field is required' : null}
                {...register('email', { required: true, pattern: /^\S+@\S+$/i })}
                error={!!errors.email}
              />
              <TextField
                label='Password'
                variant='outlined'
                type='password'
                fullWidth
                helperText={errors.password ? 'this field is required' : null}
                {...register('password', { required: true })}
                error={!!errors.password}
              />
              <Link href='/forgot-password'>
                <Typography variant='subtitle2' sx={{ cursor: 'pointer', textDecoration: 'underline' }}>
                  Forgot password?
                </Typography>
              </Link>
              {isLoginError && loginError && (
                <FormHelperText error>{loginError.message}</FormHelperText>
              )}
              <LoadingButton
                fullWidth
                size='large'
                variant='contained'
                type='submit'
                loading={isLoginLoading}
              >
                Login
              </LoadingButton>
              <Typography variant='subtitle2'>
                Don&apos;t have an account? <Link href='/signup'> Sign up</Link>
              </Typography>
            </Stack>
          </Box>
        </Paper>
      </Box>
  )
}