Proyectos de Subversion LeadersLinked - SPA

Rev

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

import React, { useRef, useState, useEffect } from 'react'
import { Link } from 'react-router-dom'
import { useDispatch, useSelector } from 'react-redux'
import { useForm } from 'react-hook-form'
import { styled } from '@mui/material'
import { Mail } from '@mui/icons-material'
import Recaptcha from 'react-recaptcha'

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

import Input from '@components/UI/inputs/Input'
import Button from '@components/UI/buttons/Buttons'
import Spinner from '@components/UI/Spinner'
import AuthForm from '@components/auth/AuthForm'

const StyledCheck = styled('div')`
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  img {
    width: 100px !important;
    margin-bottom: 1rem !important;
  }
  p {
    text-align: center;
  }
`

const StyledSpinnerContainer = styled('div')`
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background: rgba(255, 255, 255, 0.4);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 300;
`

const ForgotPassword = () => {
  const { site_key, aes } = useSelector(({ auth }) => auth)
  const [forgotSent, setForgotSent] = useState(false)
  const [isLoading, setIsLoading] = useState(false)
  const [isVerified, setIsVerified] = useState(false)
  const reCaptchaInstance = useRef(null)
  const reCaptchaToken = useRef('')
  const dispatch = useDispatch()

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

  const forgotPasswordVerifyCallbackHandler = (response) => {
    if (response) {
      reCaptchaToken.current = response
      setIsVerified(true)
    }
  }

  const forgotPasswordExpiredCallbackHandler = () => {
    reCaptchaToken.current = ''
    setIsVerified(false)
  }

  const handleOnRecaptchaLoad = () => {
    reCaptchaToken.current = ''
  }

  const loginExpiredCallbackHandler = () => {
    reCaptchaToken.current = ''
    setIsVerified(false)
  }

  const onSubmitHandler = handleSubmit(async ({ email }) => {
    setIsLoading(true)
    const formData = new FormData()

    formData.append('email', CryptoJSAesJson.encrypt(email, aes))
    formData.append('captcha', reCaptchaToken.current)

    axios
      .post('/forgot-password', formData)
      .then(({ data: response }) => {
        const { success, data } = response

        if (!success) {
          throw new Error(data)
        }

        reCaptchaInstance.current.reset()
        forgotPasswordExpiredCallbackHandler()
        loginExpiredCallbackHandler()
        setForgotSent(true)
      })
      .catch((err) => {
        console.log(`Error: ${err}`)
        dispatch(addNotification({ style: 'danger', msg: err.message }))
      })
      .finally(() => setIsLoading(false))
  })

  useEffect(() => {
    reCaptchaInstance.current?.reset()
  }, [])

  if (forgotSent) {
    return (
      <StyledCheck>
        <img src='/images/check.png' alt='check' />

        <p>El enlace de recuperación fue enviado a su correo electrónico</p>

        <Link to='/signin'>
          <Button color='secondary' type='button'>
            Volver a Iniciar Sesión
          </Button>
        </Link>
      </StyledCheck>
    )
  }

  return (
    <AuthForm onSubmit={onSubmitHandler}>
      <h3>Olvide mi Clave</h3>

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

      <Recaptcha
        sitekey={site_key}
        verifyCallback={forgotPasswordVerifyCallbackHandler}
        verifyCallbackName='forgotPasswordVerifyCallbackHandler'
        expiredCallback={forgotPasswordExpiredCallbackHandler}
        expiredCallbackName='forgotPasswordExpiredCallbackHandler'
        ref={reCaptchaInstance}
        render='explicit'
        onloadCallback={handleOnRecaptchaLoad}
        hl='es'
      />

      <Button color='secondary' type='submit' disabled={!isVerified}>
        Nueva Clave
      </Button>

      {isLoading && (
        <StyledSpinnerContainer>
          <Spinner />
        </StyledSpinnerContainer>
      )}
    </AuthForm>
  )
}

export default ForgotPassword