Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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