Proyectos de Subversion LeadersLinked - SPA

Rev

Rev 3402 | Rev 3694 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |

import React from 'react'
import { useNavigate, Link } from 'react-router-dom'
import { useDispatch, useSelector } from 'react-redux'
import { Controller, useForm } from 'react-hook-form'
import { Button, Typography } from '@mui/material'
import { Mail, Lock } from '@mui/icons-material'

import { useMobile } from '@hooks'
import { asyncLogin } from '@store/auth/auth.actions'
import { addNotification } from '@store/notification/notification.actions'
import CryptoJSAesJson from '@utils/crypto-js/cryptojs-aes-format'

import Captcha from './captcha'
import Row from '@components/common/Row'
import Form from '@components/common/form'
import Input from '@components/UI/inputs/Input'
import CheckboxInput from '@components/UI/inputs/Checkbox'
import LoadingWrapper from '@components/common/loading-wrapper'
import FormErrorFeedback from '@components/UI/form/FormErrorFeedback'

export default function LoginForm() {
  const navigate = useNavigate()
  const dispatch = useDispatch()

  const { aes, jwt } = useSelector((state) => state.auth)
  const isMobile = useMobile()

  const {
    formState: { errors, isSubmitting, isValid },
    control,
    handleSubmit,
    reset
  } = useForm({ mode: 'all' })

  const onSubmitHandler = handleSubmit(
    async ({ email, password, remember, captcha }) => {
      try {
        const response = await dispatch(
          asyncLogin({
            email: CryptoJSAesJson.encrypt(email, aes),
            password: CryptoJSAesJson.encrypt(password, aes),
            captcha,
            remember: remember ? 1 : 0
          })
        )
        reset()

        isMobile ? navigate('/apps-navigation') : navigate(response.redirect)
      } catch (error) {
        dispatch(addNotification({ style: 'danger', msg: error.message }))
      }
    }
  )

  return (
    <Form onSubmit={onSubmitHandler}>
      <LoadingWrapper loading={isSubmitting} displayChildren></LoadingWrapper>

      <Typography variant='h3'>Entrar</Typography>

      <Input
        type='email'
        name='email'
        icon={<Mail />}
        placeholder='Correo electrónico'
        rules={{
          required: 'Este campo es requerido',
          pattern: {
            value: /^[\w-.]+@([\w-]+\.)+[\w-]{2,}$/i,
            message: 'Debe ser una dirección de correo electrónico valida'
          },
          maxLength: {
            value: 64,
            message: 'Debe ser menor a 64 caracteres'
          }
        }}
        control={control}
        error={errors.email?.message}
      />

      <Input
        type='password'
        name='password'
        icon={<Lock />}
        placeholder='Clave'
        control={control}
        rules={{
          required: 'Este campo es requerido',
          pattern: {
            value:
              /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$^x%x*-]).{6,16}$/i,
            message:
              'Debe contener entre 6 y 16 caracteres, incluida una letra mayúscula, un número y un carácter especial #?!@$^%*-'
          }
        }}
        error={errors.password?.message}
      />

      <CheckboxInput control={control} name='remember' label='Recuerdame' />

      <Controller
        name='captcha'
        rules={{ required: 'Este campo es requerido' }}
        control={control}
        render={({ field: { ref, onChange } }) => (
          <>
            <Captcha
              instanceRef={ref}
              onVerify={onChange}
              onExpired={onChange}
            />
            {errors.captcha && (
              <FormErrorFeedback>{errors.captcha.message}</FormErrorFeedback>
            )}
          </>
        )}
      />

      <Row>
        <Link to='/forgot-password'>¿Has olvidado tu contraseña?</Link>
        <Link to='/signup'>¿No tienes cuenta?</Link>
      </Row>

      <Button color='secondary' type='submit' disabled={!isValid}>
        Entrar
      </Button>
    </Form>
  )
}