Rev 3156 | Rev 3230 | 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, useNavigate } from 'react-router-dom'import { useForm } from 'react-hook-form'import { useDispatch, useSelector } from 'react-redux'import { Button, styled, Typography } from '@mui/material'import { Mail, Lock } from '@mui/icons-material'import Recaptcha from 'react-recaptcha'import { useMobile } from '@hooks'import CryptoJSAesJson from '@utils/crypto-js/cryptojs-aes-format'import FacebookIcon from '@components/UI/icons/FacebookIcon'import XIcon from '@components/UI/icons/XIcon'import GoogleIcon from '@components/UI/icons/GoogleIcon'import { axios } from '@utils'import { addNotification } from '@store/notification/notification.actions'import { login } from '@store/auth/auth.actions'import Form from '@components/common/form'import Input from '@components/UI/inputs/Input'import CheckboxInput from '@components/UI/inputs/Checkbox'import Spinner from '@components/UI/Spinner'const SocialButton = styled(Button)`background-color: white;border: 1px solid black;padding: 0.5rem 1rem;font-size: 1rem;color: #383838;width: 100%;box-sizing: border-box;margin-bottom: 10px;svg {width: 16px;height: 16px;}`const Login = ({facebookOauth = '/signin/facebook',twitterOauth = '/signin/twitter',googleOauth = '/signin/google'}) => {const [isLoading, setIsLoading] = useState(false)const [isVerified, setIsVerified] = useState(false)const isMobile = useMobile()const reCaptchaToken = useRef('')const reCaptchaInstance = useRef(null)const navigate = useNavigate()const dispatch = useDispatch()const { site_key, aes, access_usign_social_networks } = useSelector(({ auth }) => auth)const rrssOptions = [{ label: 'Facebook', icon: FacebookIcon, href: facebookOauth },{ label: 'Twitter', icon: XIcon, href: twitterOauth },{ label: 'Google', icon: GoogleIcon, href: googleOauth }]const {handleSubmit,control,setError,getValues,setValue,reset,formState: { errors }} = useForm({ mode: 'all' })const onSubmitHandler = handleSubmit(async ({ email, password, remember }) => {const formData = new FormData()formData.append('email', CryptoJSAesJson.encrypt(email, aes))formData.append('password', CryptoJSAesJson.encrypt(password, aes))formData.append('remember', remember ? 1 : 0)formData.append('captcha', reCaptchaToken.current)await axios.post('/signin', formData).then(({ data: response }) => {const { success, data } = responseif (!success) {loginExpiredCallbackHandler()reCaptchaInstance.current.reset()if (data.constructor.name === 'Object') {Object.entries(data).forEach(([key, value]) => {if (key in getValues()) {setError(key, {type: 'manual',message: Array.isArray(value) ? value[0] : value})}})return}dispatch(addNotification({ style: 'danger', msg: data }))return}const url = data.redirect.split('.com')[1]reCaptchaInstance.current.reset()loginExpiredCallbackHandler()reset()dispatch(login())isMobile ? navigate('/apps-navigation') : navigate(url)}).catch((err) => {console.log(err)reCaptchaInstance.current.reset()loginExpiredCallbackHandler()setValue('password', '')dispatch(addNotification({style: 'danger',msg: 'Disculpe, ha ocurrido un error'}))}).finally(() => setIsLoading(false))})const loginVerifyCallbackHandler = (response) => {reCaptchaToken.current = responsesetIsVerified(true)}const loginExpiredCallbackHandler = () => {reCaptchaToken.current = ''setIsVerified(false)}const handleOnRecaptchaLoad = () => {reCaptchaToken.current = ''}const getRedirectUrl = async (endpoint) => {try {const res = await axios.get(endpoint)if (res.data && res.data.data) {window.location.href = res.data.data}} catch (error) {console.log('>>: error > ', error)}}useEffect(() => {reCaptchaInstance.current?.reset()}, [])return (<Form onSubmit={onSubmitHandler}>{isLoading && <Spinner absolute />}<Typography variant='h3'>Entrar</Typography><Inputtype='email'name='email'icon={<Mail />}placeholder='Correo electrónico'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'},maxLength: {value: 64,message: 'Debe ser menor a 64 caracteres'}}}control={control}error={errors.email?.message}/><Inputtype='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' />{site_key && (<Recaptchasitekey={site_key}verifyCallback={loginVerifyCallbackHandler}verifyCallbackName='loginVerifyCallbackHandler'expiredCallback={loginExpiredCallbackHandler}expiredCallbackName='loginExpiredCallbackHandler'ref={reCaptchaInstance}render='explicit'onloadCallback={handleOnRecaptchaLoad}hl='es'/>)}<div className='links'><Link to='/forgot-password'>¿Has olvidado tu contraseña?</Link><Link to='/signup'>¿No tienes cuenta?</Link></div><Button color='secondary' type='submit' disabled={!isVerified}>Entrar</Button>{access_usign_social_networks === 'y' && (<><h4>Entrar usando su red social</h4><ul>{rrssOptions.map(({ label, icon: Icon, href }) => (<li key={label}><SocialButton onClick={() => getRedirectUrl(href)}><Icon />{`Iniciar sesión con ${label}`}</SocialButton></li>))}</ul></>)}</Form>)}export default Login