Proyectos de Subversion LeadersLinked - SPA

Rev

Rev 2802 | Rev 2888 | Ir a la última revisión | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
2630 stevensc 1
import React, { useRef, useState, useEffect } from 'react'
2
import { Link, useNavigate } from 'react-router-dom'
3
import { useForm } from 'react-hook-form'
4
import { useDispatch, useSelector } from 'react-redux'
5
import { styled } from '@mui/material'
6
import { Mail, Lock } from '@mui/icons-material'
7
import Recaptcha from 'react-recaptcha'
8
 
9
import { axios } from '../../utils'
10
import { login } from '../../redux/auth/auth.actions'
11
import { addNotification } from '../../redux/notification/notification.actions'
12
import CryptoJSAesJson from '../../utils/crypto-js/cryptojs-aes-format'
13
 
14
import XIcon from 'components/UI/icons/XIcon'
15
import FacebookIcon from 'components/UI/icons/FacebookIcon'
16
import GoogleIcon from 'components/UI/icons/GoogleIcon'
17
 
18
import AuthForm from '../../components/auth/AuthForm'
19
import Spinner from 'components/UI/Spinner'
20
import Input from 'components/UI/inputs/Input'
21
import Checkbox from 'components/UI/checkbox/Checkbox'
22
import Button from '@app/components/UI/buttons/Buttons'
23
 
24
const SocialButton = styled(Button)`
25
  background-color: white;
26
  border: 1px solid black;
27
  padding: 0.5rem 1rem;
28
  font-size: 1rem;
29
  color: #383838;
30
  width: 100%;
31
  box-sizing: border-box;
32
  margin-bottom: 10px;
33
  svg {
34
    width: 16px;
35
    height: 16px;
36
  }
37
`
38
 
39
const Login = ({
40
  facebookOauth = '/signin/facebook',
41
  twitterOauth = '/signin/twitter',
42
  googleOauth = '/signin/google'
43
}) => {
44
  const [isLoading, setIsLoading] = useState(false)
45
  const [isVerified, setIsVerified] = useState(false)
46
 
47
  const reCaptchaToken = useRef('')
48
  const reCaptchaInstance = useRef(null)
49
 
50
  const navigate = useNavigate()
51
 
52
  const dispatch = useDispatch()
53
  const { site_key, aes, access_usign_social_networks } = useSelector(
54
    ({ auth }) => auth
55
  )
56
  const rrssOptions = [
57
    { label: 'Facebook', icon: FacebookIcon, href: facebookOauth },
58
    { label: 'Twitter', icon: XIcon, href: twitterOauth },
59
    { label: 'Google', icon: GoogleIcon, href: googleOauth }
60
  ]
61
 
62
  const {
63
    handleSubmit,
64
    control,
65
    setError,
66
    getValues,
67
    setValue,
2802 stevensc 68
    reset,
69
    formState: { errors }
2630 stevensc 70
  } = useForm({ mode: 'all' })
71
 
72
  const onSubmitHandler = handleSubmit(
73
    async ({ email, password, remember }) => {
74
      const formData = new FormData()
75
      formData.append('email', CryptoJSAesJson.encrypt(email, aes))
76
      formData.append('password', CryptoJSAesJson.encrypt(password, aes))
77
      formData.append('remember', remember ? 1 : 0)
78
      formData.append('captcha', reCaptchaToken.current)
79
 
80
      await axios
81
        .post('/signin', formData)
82
        .then(({ data: response }) => {
83
          const { success, data } = response
84
 
85
          if (!success) {
86
            loginExpiredCallbackHandler()
87
            reCaptchaInstance.current.reset()
88
 
89
            if (data.constructor.name === 'Object') {
90
              Object.entries(data).forEach(([key, value]) => {
91
                if (key in getValues()) {
92
                  setError(key, {
93
                    type: 'manual',
94
                    message: Array.isArray(value) ? value[0] : value
95
                  })
96
                }
97
              })
98
              return
99
            }
100
 
101
            dispatch(addNotification({ style: 'danger', msg: data }))
102
            return
103
          }
104
 
105
          const url = data.redirect.split('.com')[1]
106
          reCaptchaInstance.current.reset()
107
          loginExpiredCallbackHandler()
108
          reset()
109
          dispatch(login())
110
          navigate(url)
111
        })
112
        .catch((err) => {
113
          console.log(err)
114
          reCaptchaInstance.current.reset()
115
 
116
          loginExpiredCallbackHandler()
117
          setValue('password', '')
118
 
119
          dispatch(
120
            addNotification({
121
              style: 'danger',
122
              msg: 'Disculpe, ha ocurrido un error'
123
            })
124
          )
125
        })
126
        .finally(() => setIsLoading(false))
127
    }
128
  )
129
 
130
  const loginVerifyCallbackHandler = (response) => {
131
    reCaptchaToken.current = response
132
    setIsVerified(true)
133
  }
134
 
135
  const loginExpiredCallbackHandler = () => {
136
    reCaptchaToken.current = ''
137
    setIsVerified(false)
138
  }
139
 
140
  const handleOnRecaptchaLoad = () => {
141
    reCaptchaToken.current = ''
142
  }
143
 
144
  const getRedirectUrl = async (endpoint) => {
145
    try {
146
      const res = await axios.get(endpoint)
147
      if (res.data && res.data.data) {
148
        window.location.href = res.data.data
149
      }
150
    } catch (error) {
151
      console.log('>>: error > ', error)
152
    }
153
  }
154
 
155
  useEffect(() => {
156
    reCaptchaInstance.current?.reset()
157
  }, [])
158
 
159
  return (
160
    <AuthForm onSubmit={onSubmitHandler}>
161
      <h3>Entrar</h3>
162
 
163
      <Input
164
        type='email'
165
        name='email'
2865 stevensc 166
        icon={<Mail />}
2630 stevensc 167
        placeholder='Correo electrónico'
2865 stevensc 168
        rules={{
2630 stevensc 169
          required: 'Este campo es requerido',
170
          pattern: {
171
            value: /^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$/i,
172
            message: 'Debe ser una dirección de correo electrónico valida'
173
          },
174
          maxLength: {
175
            value: 64,
176
            message: 'Debe ser menor a 64 caracteres'
177
          }
2865 stevensc 178
        }}
179
        control={control}
2630 stevensc 180
        error={errors.email?.message}
181
      />
182
 
183
      <Input
184
        type='password'
185
        name='password'
2865 stevensc 186
        icon={<Lock />}
2630 stevensc 187
        placeholder='Clave'
2865 stevensc 188
        control={control}
189
        rules={{
2630 stevensc 190
          required: 'Este campo es requerido',
191
          pattern: {
192
            value:
193
              /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$^x%x*-]).{6,16}$/i,
194
            message:
195
              'Debe contener entre 6 y 16 caracteres, incluida una letra mayúscula, un número y un carácter especial #?!@$^%*-'
196
          }
2865 stevensc 197
        }}
2630 stevensc 198
        error={errors.password?.message}
199
      />
200
 
201
      <Checkbox control={control} name='remember' label='Recuerdame' />
202
 
203
      {site_key && (
204
        <Recaptcha
205
          sitekey={site_key}
206
          verifyCallback={loginVerifyCallbackHandler}
207
          verifyCallbackName='loginVerifyCallbackHandler'
208
          expiredCallback={loginExpiredCallbackHandler}
209
          expiredCallbackName='loginExpiredCallbackHandler'
210
          ref={reCaptchaInstance}
211
          render='explicit'
212
          onloadCallback={handleOnRecaptchaLoad}
213
          hl='es'
214
        />
215
      )}
216
 
217
      <div className='links'>
218
        <Link to='/forgot-password'>¿Has olvidado tu contraseña?</Link>
219
        <Link to='/signup'>¿No tienes cuenta?</Link>
220
      </div>
221
 
222
      <Button variant='secondary' type='submit' disabled={!isVerified}>
223
        Entrar
224
      </Button>
225
 
226
      {access_usign_social_networks === 'y' && (
227
        <>
228
          <h4>Entrar usando su red social</h4>
229
          <ul>
230
            {rrssOptions.map(({ label, icon: Icon, href }) => (
231
              <li key={label}>
232
                <SocialButton onClick={() => getRedirectUrl(href)}>
233
                  <Icon />
234
                  {`Iniciar sesión con ${label}`}
235
                </SocialButton>
236
              </li>
237
            ))}
238
          </ul>
239
        </>
240
      )}
241
 
242
      {isLoading && <Spinner />}
243
    </AuthForm>
244
  )
245
}
246
 
247
export default Login