Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

Rev 6510 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
6509 stevensc 1
import React, { useRef, useState, useEffect } from 'react'
2
import { axios } from '../../../../utils'
3
import { Link } from 'react-router-dom'
4
import { useForm } from 'react-hook-form'
6511 stevensc 5
import { useDispatch, useSelector } from 'react-redux'
6509 stevensc 6
import { addNotification } from '../../../redux/notification/notification.actions'
7
import styled from 'styled-components'
8
import Recaptcha from 'react-recaptcha'
6510 stevensc 9
import CryptoJSAesJson from '../../../utils/crypto-js/cryptojs-aes-format'
6509 stevensc 10
 
6510 stevensc 11
import Spinner from '../../UI/Spinner'
6509 stevensc 12
import SwitchInput from '../../UI/SwitchInput'
13
import FormErrorFeedback from '../../UI/FormErrorFeedback'
14
 
15
const StyledCheck = styled.div`
16
  display: flex;
17
  flex-direction: column;
18
  justify-content: center;
19
  align-items: center;
20
  img {
21
    width: 100px;
22
    margin-bottom: 1rem;
23
  }
24
  p {
25
    text-align: center;
26
  }
27
`
28
const StyledSpinnerContainer = styled.div`
29
  position: absolute;
30
  left: 0;
31
  top: 0;
32
  width: 100%;
33
  height: 100%;
34
  background: rgba(255, 255, 255, 0.4);
35
  display: flex;
36
  justify-content: center;
37
  align-items: center;
38
  z-index: 300;
39
`
40
const Signup = () => {
41
  const { site_key, aes } = useSelector(({ auth }) => auth)
42
  const { register, handleSubmit, setError, errors, watch } = useForm({
43
    mode: 'onBlur',
44
  })
45
  const [termsChecked, setTermsChecked] = useState(false)
46
  const [registered, setRegistered] = useState(false)
47
  const [isLoading, setIsLoading] = useState(false)
48
  const [isAdult, setIsAdult] = useState(false)
49
  const [isVerified, setIsVerified] = useState(false)
50
 
51
  const reCaptchaInstance = useRef(null)
52
  const reCaptchaToken = useRef('')
53
 
6511 stevensc 54
  const dispatch = useDispatch()
55
 
6509 stevensc 56
  const signupVerifyCallbackHandler = (response) => {
57
    if (!response) return
58
    reCaptchaToken.current = response
59
    setIsVerified(true)
60
  }
61
 
62
  const signupExpiredCallbackHandler = () => {
63
    reCaptchaToken.current = ''
64
    setIsVerified(false)
65
  }
66
 
67
  const onSubmitHandler = async (data) => {
68
    setIsLoading(true)
69
    const formData = new FormData()
70
 
71
    Object.entries(data).map(([key, value]) => {
72
      if (key === 'email' || key === 'password' || key === 'confirmation')
73
        return formData.append(key, CryptoJSAesJson.encrypt(value, aes))
74
      return formData.append(key, value)
75
    })
76
    formData.append('captcha', reCaptchaToken.current)
77
    formData.append('is_adult', isAdult ? 'y' : 'n')
78
 
79
    await axios
80
      .post('/signup', formData)
81
      .then(({ data }) => {
82
        if (!data.success) {
83
          if (typeof data.data !== 'string') {
84
            Object.entries(data.data).map(([key, value]) => {
85
              setError(key, {
86
                type: 'manual',
87
                message: Array.isArray(value) ? value[0] : value,
88
              })
89
            })
90
          }
6511 stevensc 91
 
92
          dispatch(addNotification({ style: 'danger', msg: data.data }))
6509 stevensc 93
          reCaptchaInstance.current.reset()
94
          signupVerifyCallbackHandler()
95
          return
96
        }
97
 
98
        reCaptchaInstance.current.reset()
99
        signupExpiredCallbackHandler()
100
        setRegistered(true)
101
      })
102
      .catch((err) => {
6511 stevensc 103
        dispatch(
104
          addNotification({
105
            style: 'danger',
106
            msg: 'Disculpe, ha ocurrido un error',
107
          })
108
        )
6509 stevensc 109
        console.log(`Error: ${err}`)
6511 stevensc 110
        throw new Error(err)
6509 stevensc 111
      })
112
      .finally(() => setIsLoading(false))
113
  }
114
 
115
  const handleOnRecaptchaLoad = () => {
116
    reCaptchaToken.current = ''
117
  }
118
 
6510 stevensc 119
  useEffect(() => {
120
    reCaptchaInstance.current?.reset()
121
  }, [])
122
 
6509 stevensc 123
  if (registered) {
124
    return (
125
      <StyledCheck>
126
        <img src="/images/check.png" alt="check" />
127
        <p>
128
          Se ha registrado correctamente. Por favor, active la cuenta desde su
129
          correo
130
        </p>
131
        <Link to="/signin">
132
          <button id="btn-submit" className="sign_in_sec_button">
133
            Entrar
134
          </button>
135
        </Link>
136
      </StyledCheck>
137
    )
138
  }
139
 
140
  return (
6510 stevensc 141
    <>
6509 stevensc 142
      <h3>Registrarse</h3>
143
      <form onSubmit={handleSubmit(onSubmitHandler)}>
6510 stevensc 144
        <div className="inputContainer">
145
          <div className="sn-field">
146
            <input
147
              type="email"
148
              name="email"
149
              ref={register({
150
                required: 'Este campo es requerido',
151
                pattern: {
152
                  value: /^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$/i,
153
                  message:
154
                    'Debe ser una dirección de correo electrónico valida',
155
                },
156
              })}
157
              maxLength="64"
158
              placeholder="Correo electrónico"
159
            />
160
            <i className="la la-envelope"></i>
6509 stevensc 161
          </div>
6510 stevensc 162
          {errors.email && (
163
            <FormErrorFeedback>{errors.email.message}</FormErrorFeedback>
164
          )}
165
        </div>
6509 stevensc 166
 
6510 stevensc 167
        <div className="inputContainer">
168
          <div className="sn-field">
169
            <input
170
              type="text"
171
              name="first_name"
172
              ref={register({
173
                required: 'Este campo es requerido',
174
                maxLength: {
175
                  value: 64,
176
                  message: 'Limite de carateres superior al permitido',
177
                },
178
              })}
179
              placeholder="Nombre"
180
            />
181
            <i className="la la-user"></i>
6509 stevensc 182
          </div>
6510 stevensc 183
          {errors.first_name && (
184
            <FormErrorFeedback>{errors.first_name.message}</FormErrorFeedback>
185
          )}
186
        </div>
187
 
188
        <div className="inputContainer">
189
          <div className="sn-field">
190
            <input
191
              type="text"
192
              name="last_name"
193
              ref={register({
194
                required: 'Este campo es requerido',
195
                maxLength: {
196
                  value: 64,
197
                  message: 'Limite de carateres superior al permitido',
198
                },
199
              })}
200
              placeholder="Apellido"
201
            />
202
            <i className="la la-user"></i>
6509 stevensc 203
          </div>
6510 stevensc 204
          {errors.last_name && (
205
            <FormErrorFeedback>{errors.last_name.message}</FormErrorFeedback>
206
          )}
207
        </div>
6509 stevensc 208
 
6510 stevensc 209
        <div className="inputContainer">
210
          <div className="sn-field">
211
            <input
212
              type="password"
213
              name="password"
214
              ref={register({
215
                required: 'Este campo es requerido',
216
                pattern: {
217
                  value:
218
                    /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$^x%x*-]).{6,16}$/i,
219
                  message:
220
                    'Debe contener entre 6 y 16 caracteres, incluida una letra mayúscula, un número y un carácter especial #?!@$^%*-',
221
                },
222
              })}
223
              title="La clave debe contener entre 6 y 16 caracteres, incluida una letra mayúscula, un número y un carácter especial #?!@$^%*-"
224
              placeholder="Clave"
225
            />
226
            <i className="la la-lock"></i>
6509 stevensc 227
          </div>
6510 stevensc 228
          {errors.password && (
229
            <FormErrorFeedback>{errors.password.message}</FormErrorFeedback>
230
          )}
231
        </div>
6509 stevensc 232
 
6510 stevensc 233
        <div className="inputContainer">
234
          <div className="sn-field">
235
            <input
236
              type="password"
237
              name="confirmation"
238
              ref={register({
239
                required: 'Este campo es requerido',
240
                validate: (v) =>
241
                  v === watch('password') ||
242
                  'Disculpe, las claves tienen que coincidir',
243
              })}
244
              placeholder="Confirme su clave"
245
            />
246
            <i className="la la-lock" />
6509 stevensc 247
          </div>
6510 stevensc 248
          {errors.confirmation && (
249
            <FormErrorFeedback>{errors.confirmation.message}</FormErrorFeedback>
250
          )}
251
        </div>
6509 stevensc 252
 
6510 stevensc 253
        <div className="d-flex flex-column" style={{ gap: '.5rem' }}>
254
          <label>Eres mayor de 18</label>
255
          <SwitchInput setValue={(value) => setIsAdult(value)} />
256
        </div>
257
 
258
        <div className="inputContainer">
259
          <div className="checky-sec st2">
260
            <div className="sn-field fgt-sec">
261
              <input
262
                type="checkbox"
263
                name="terms_and_conditions"
264
                id="terms_and_conditions"
265
                checked={termsChecked}
266
                ref={register({
267
                  required: 'Este campo es requerido',
268
                })}
269
                value="1"
270
                readOnly
6509 stevensc 271
              />
6510 stevensc 272
              <label
273
                htmlFor="terms_and_conditions"
274
                onClick={() => setTermsChecked(!termsChecked)}
275
              >
276
                <span></span>
277
              </label>
278
              <small onClick={() => setTermsChecked(!termsChecked)}>
279
                Si, acepto los{' '}
280
                <a href="/terms-and-conditions">Términos y Condiciones.</a>
281
              </small>
6509 stevensc 282
            </div>
283
          </div>
6510 stevensc 284
          {errors.terms_and_conditions && (
285
            <FormErrorFeedback>
286
              {errors.terms_and_conditions.message}
287
            </FormErrorFeedback>
288
          )}
289
        </div>
6509 stevensc 290
 
6510 stevensc 291
        <div className="sn-field">
292
          <Recaptcha
293
            sitekey={site_key}
294
            verifyCallback={signupVerifyCallbackHandler}
295
            verifyCallbackName="signupVerifyCallbackHandler"
296
            expiredCallback={signupExpiredCallbackHandler}
297
            expiredCallbackName="signupExpiredCallbackHandler"
298
            ref={reCaptchaInstance}
299
            render="explicit"
300
            onloadCallback={handleOnRecaptchaLoad}
301
            hl="es"
302
          />
6509 stevensc 303
        </div>
6510 stevensc 304
 
305
        <button
306
          type="submit"
307
          value="submit"
308
          id="btn-submit"
309
          disabled={!isVerified}
310
        >
311
          Registrarse
312
        </button>
6509 stevensc 313
      </form>
314
      {isLoading && (
315
        <StyledSpinnerContainer>
316
          <Spinner />
317
        </StyledSpinnerContainer>
318
      )}
6510 stevensc 319
    </>
6509 stevensc 320
  )
321
}
322
 
323
export default Signup