Proyectos de Subversion LeadersLinked - SPA

Rev

Rev 3416 | Rev 3694 | Ir a la última revisión | Mostrar el archivo completo | | | Autoría | Ultima modificación | Ver Log |

Rev 3416 Rev 3432
Línea 1... Línea 1...
1
import React, { useRef, useState, useEffect } from "react";
1
import React, { useRef, useState, useEffect } from 'react'
2
import { Link } from "react-router-dom";
2
import { Link } from 'react-router-dom'
3
import { useForm } from "react-hook-form";
3
import { useForm } from 'react-hook-form'
4
import { useDispatch, useSelector } from "react-redux";
4
import { useDispatch, useSelector } from 'react-redux'
5
import { styled, Typography } from "@mui/material";
5
import { styled, Typography } from '@mui/material'
6
import { Mail, Lock, Person, CheckCircleOutline } from "@mui/icons-material";
6
import { Mail, Lock, Person, CheckCircleOutline } from '@mui/icons-material'
7
import Recaptcha from "react-recaptcha";
7
import Recaptcha from 'react-recaptcha'
8
 
8
 
9
import { axios } from "@utils";
9
import { axios } from '@utils'
10
import { useFetchHelper } from "@hooks";
10
import { useFetchHelper } from '@hooks'
11
import { addNotification } from "@store/notification/notification.actions";
11
import { addNotification } from '@store/notification/notification.actions'
12
import CryptoJSAesJson from "@utils/crypto-js/cryptojs-aes-format";
12
import CryptoJSAesJson from '@utils/crypto-js/cryptojs-aes-format'
13
 
13
 
14
import Input from "@components/UI/inputs/Input";
14
import Input from '@components/UI/inputs/Input'
15
import Button from "@components/UI/buttons/Buttons";
15
import Button from '@components/UI/buttons/Buttons'
16
import Select from "@components/UI/inputs/Select";
16
import Select from '@components/UI/inputs/Select'
17
import Spinner from "@components/UI/Spinner";
17
import Spinner from '@components/UI/Spinner'
18
import Form from "@components/common/form";
18
import Form from '@components/common/form'
19
import SwitchInput from "@components/UI/SwitchInput";
19
import SwitchInput from '@components/UI/SwitchInput'
20
import CheckboxInput from "@components/UI/inputs/Checkbox";
20
import CheckboxInput from '@components/UI/inputs/Checkbox'
Línea 21... Línea 21...
21
 
21
 
22
const StyledCheck = styled("div")`
22
const StyledCheck = styled('div')`
23
  display: flex;
23
  display: flex;
24
  flex-direction: column;
24
  flex-direction: column;
25
  justify-content: center;
25
  justify-content: center;
26
  align-items: center;
26
  align-items: center;
27
  gap: 0.5rem;
27
  gap: 0.5rem;
28
  p {
28
  p {
29
    text-align: center;
29
    text-align: center;
30
  }
30
  }
31
`;
31
`
32
const StyledSpinnerContainer = styled("div")`
32
const StyledSpinnerContainer = styled('div')`
33
  position: absolute;
33
  position: absolute;
34
  left: 0;
34
  left: 0;
35
  top: 0;
35
  top: 0;
36
  width: 100%;
36
  width: 100%;
37
  height: 100%;
37
  height: 100%;
38
  background: rgba(255, 255, 255, 0.4);
38
  background: rgba(255, 255, 255, 0.4);
39
  display: flex;
39
  display: flex;
40
  justify-content: center;
40
  justify-content: center;
41
  align-items: center;
41
  align-items: center;
42
  z-index: 300;
42
  z-index: 300;
Línea 43... Línea 43...
43
`;
43
`
44
 
44
 
45
const Signup = () => {
45
const Signup = () => {
46
  const [registered, setRegistered] = useState(false);
46
  const [registered, setRegistered] = useState(false)
47
  const [loading, setloading] = useState(false);
47
  const [isLoading, setIsLoading] = useState(false)
48
  const [isAdult, setIsAdult] = useState(false);
48
  const [isAdult, setIsAdult] = useState(false)
49
  const [isVerified, setIsVerified] = useState(false);
49
  const [isVerified, setIsVerified] = useState(false)
50
  const reCaptchaInstance = useRef(null);
50
  const reCaptchaInstance = useRef(null)
51
  const reCaptchaToken = useRef("");
51
  const reCaptchaToken = useRef('')
Línea 52... Línea 52...
52
  const dispatch = useDispatch();
52
  const dispatch = useDispatch()
Línea 53... Línea 53...
53
  const { site_key, aes } = useSelector(({ auth }) => auth);
53
  const { site_key, aes } = useSelector(({ auth }) => auth)
54
 
54
 
55
  const { data: timezones } = useFetchHelper("timezones");
55
  const { data: timezones } = useFetchHelper('timezones')
56
 
56
 
57
  const {
57
  const {
58
    control,
58
    control,
59
    handleSubmit,
59
    handleSubmit,
60
    setError,
60
    setError,
61
    watch,
61
    watch,
Línea 62... Línea 62...
62
    formState: { errors },
62
    formState: { errors }
63
  } = useForm({
63
  } = useForm({
64
    mode: "all",
64
    mode: 'all'
65
  });
65
  })
66
 
66
 
Línea 67... Línea 67...
67
  const signupVerifyCallbackHandler = (response) => {
67
  const signupVerifyCallbackHandler = (response) => {
68
    if (!response) return;
68
    if (!response) return
69
    reCaptchaToken.current = response;
69
    reCaptchaToken.current = response
70
    setIsVerified(true);
70
    setIsVerified(true)
Línea 71... Línea 71...
71
  };
71
  }
72
 
72
 
73
  const signupExpiredCallbackHandler = () => {
73
  const signupExpiredCallbackHandler = () => {
Línea 74... Línea 74...
74
    reCaptchaToken.current = "";
74
    reCaptchaToken.current = ''
75
    setIsVerified(false);
75
    setIsVerified(false)
76
  };
76
  }
77
 
77
 
78
  const handleOnRecaptchaLoad = () => {
78
  const handleOnRecaptchaLoad = () => {
79
    reCaptchaToken.current = "";
79
    reCaptchaToken.current = ''
80
  };
80
  }
81
 
81
 
82
  const onSubmitHandler = handleSubmit(
82
  const onSubmitHandler = handleSubmit(
83
    async ({
83
    async ({
84
      email,
84
      email,
85
      first_name,
85
      first_name,
86
      last_name,
86
      last_name,
87
      password,
87
      password,
88
      confirmation,
88
      confirmation,
89
      terms_and_conditions,
89
      terms_and_conditions
90
    }) => {
90
    }) => {
91
      setloading(true);
91
      setIsLoading(true)
92
      const formData = new FormData();
92
      const formData = new FormData()
93
      formData.append("first_name", first_name);
93
      formData.append('first_name', first_name)
Línea 94... Línea 94...
94
      formData.append("last_name", last_name);
94
      formData.append('last_name', last_name)
95
      formData.append("email", CryptoJSAesJson.encrypt(email, aes));
95
      formData.append('email', CryptoJSAesJson.encrypt(email, aes))
Línea 96... Línea 96...
96
      formData.append("password", CryptoJSAesJson.encrypt(password, aes));
96
      formData.append('password', CryptoJSAesJson.encrypt(password, aes))
97
      formData.append(
97
      formData.append(
98
        "confirmation",
98
        'confirmation',
99
        CryptoJSAesJson.encrypt(confirmation, aes)
99
        CryptoJSAesJson.encrypt(confirmation, aes)
100
      );
100
      )
101
      formData.append("terms_and_conditions", terms_and_conditions ? 1 : 0);
101
      formData.append('terms_and_conditions', terms_and_conditions ? 1 : 0)
102
 
102
 
103
      formData.append("captcha", reCaptchaToken.current);
103
      formData.append('captcha', reCaptchaToken.current)
104
      formData.append("is_adult", isAdult ? "y" : "n");
104
      formData.append('is_adult', isAdult ? 'y' : 'n')
105
 
105
 
106
      await axios
106
      await axios
107
        .post("/signup", formData)
107
        .post('/signup', formData)
108
        .then(({ data }) => {
108
        .then(({ data }) => {
Línea 109... Línea 109...
109
          if (!data.success) {
109
          if (!data.success) {
110
            if (typeof data.data !== "string") {
110
            if (typeof data.data !== 'string') {
111
              Object.entries(data.data).forEach(([key, value]) => {
111
              Object.entries(data.data).forEach(([key, value]) => {
112
                setError(key, {
112
                setError(key, {
113
                  type: "manual",
113
                  type: 'manual',
Línea 114... Línea 114...
114
                  message: Array.isArray(value) ? value[0] : value,
114
                  message: Array.isArray(value) ? value[0] : value
115
                });
115
                })
116
              });
116
              })
117
              return;
117
              return
118
            }
118
            }
119
 
119
 
120
            dispatch(addNotification({ style: "danger", msg: data.data }));
120
            dispatch(addNotification({ style: 'danger', msg: data.data }))
121
            reCaptchaInstance.current.reset();
121
            reCaptchaInstance.current.reset()
122
            signupVerifyCallbackHandler();
122
            signupVerifyCallbackHandler()
123
            return;
123
            return
124
          }
124
          }
125
 
125
 
126
          reCaptchaInstance.current.reset();
126
          reCaptchaInstance.current.reset()
127
          signupExpiredCallbackHandler();
127
          signupExpiredCallbackHandler()
128
          setRegistered(true);
128
          setRegistered(true)
129
        })
129
        })
Línea 130... Línea 130...
130
        .catch((err) => {
130
        .catch((err) => {
131
          console.log(`Error: ${err}`);
131
          console.log(`Error: ${err}`)
132
          dispatch(
132
          dispatch(
Línea 133... Línea 133...
133
            addNotification({
133
            addNotification({
134
              style: "danger",
134
              style: 'danger',
135
              msg: "Disculpe, ha ocurrido un error",
135
              msg: 'Disculpe, ha ocurrido un error'
136
            })
136
            })
Línea 137... Línea 137...
137
          );
137
          )
138
        })
138
        })
139
        .finally(() => setloading(false));
139
        .finally(() => setIsLoading(false))
140
    }
140
    }
Línea 141... Línea 141...
141
  );
141
  )
142
 
142
 
143
  useEffect(() => {
143
  useEffect(() => {
144
    reCaptchaInstance.current?.reset();
144
    reCaptchaInstance.current?.reset()
145
  }, []);
145
  }, [])
146
 
146
 
Línea 147... Línea 147...
147
  if (registered) {
147
  if (registered) {
148
    return (
148
    return (
149
      <StyledCheck>
149
      <StyledCheck>
Línea 150... Línea 150...
150
        <CheckCircleOutline sx={{ color: "#7FFF00", fontSize: "3rem" }} />
150
        <CheckCircleOutline sx={{ color: '#7FFF00', fontSize: '3rem' }} />
151
 
151
 
152
        <Typography>
152
        <Typography>
153
          Se ha registrado correctamente. Por favor, active la cuenta desde su
153
          Se ha registrado correctamente. Por favor, active la cuenta desde su
154
          correo
154
          correo
155
        </Typography>
155
        </Typography>
156
 
156
 
157
        <Link to="/signin">
157
        <Link to='/signin'>
158
          <button className="btn btn-primary">Entrar</button>
158
          <button className='btn btn-primary'>Entrar</button>
159
        </Link>
159
        </Link>
160
      </StyledCheck>
160
      </StyledCheck>
161
    );
161
    )
162
  }
162
  }
163
 
163
 
164
  return (
164
  return (
Línea 165... Línea 165...
165
    <Form onSubmit={onSubmitHandler}>
165
    <Form onSubmit={onSubmitHandler}>
166
      <Typography variant="h3">Registrarse</Typography>
166
      <Typography variant='h3'>Registrarse</Typography>
167
 
167
 
168
      <Input
168
      <Input
169
        type="email"
169
        type='email'
170
        name="email"
170
        name='email'
171
        placeholder="Correo electrónico"
171
        placeholder='Correo electrónico'
172
        icon={<Mail />}
172
        icon={<Mail />}
173
        control={control}
173
        control={control}
174
        rules={{
174
        rules={{
175
          required: "Este campo es requerido",
175
          required: 'Este campo es requerido',
176
          pattern: {
176
          pattern: {
177
            value: /^[\w-.]+@([\w-]+\.)+[\w-]{2,}$/i,
177
            value: /^[\w-.]+@([\w-]+\.)+[\w-]{2,}$/i,
178
            message: "Debe ser una dirección de correo electrónico valida",
178
            message: 'Debe ser una dirección de correo electrónico valida'
179
          },
179
          }
Línea 180... Línea 180...
180
        }}
180
        }}
181
        error={errors.email?.message}
181
        error={errors.email?.message}
182
      />
182
      />
183
 
183
 
184
      <Input
184
      <Input
185
        type="text"
185
        type='text'
186
        name="first_name"
186
        name='first_name'
187
        icon={<Person />}
187
        icon={<Person />}
188
        placeholder="Nombre"
188
        placeholder='Nombre'
189
        control={control}
189
        control={control}
190
        rules={{
190
        rules={{
191
          required: "Este campo es requerido",
191
          required: 'Este campo es requerido',
192
          maxLength: {
192
          maxLength: {
193
            value: 64,
193
            value: 64,
194
            message: "Limite de carateres superior al permitido",
194
            message: 'Limite de carateres superior al permitido'
Línea 195... Línea 195...
195
          },
195
          }
196
        }}
196
        }}
197
        error={errors.first_name?.message}
197
        error={errors.first_name?.message}
198
      />
198
      />
199
 
199
 
200
      <Input
200
      <Input
201
        type="text"
201
        type='text'
202
        name="last_name"
202
        name='last_name'
203
        icon={<Person />}
203
        icon={<Person />}
204
        placeholder="Apellido"
204
        placeholder='Apellido'
205
        control={control}
205
        control={control}
206
        rules={{
206
        rules={{
207
          required: "Este campo es requerido",
207
          required: 'Este campo es requerido',
208
          maxLength: {
208
          maxLength: {
209
            value: 64,
209
            value: 64,
210
            message: "Limite de carateres superior al permitido",
210
            message: 'Limite de carateres superior al permitido'
211
          },
211
          }
Línea 212... Línea 212...
212
        }}
212
        }}
213
        error={errors.last_name?.message}
213
        error={errors.last_name?.message}
214
      />
214
      />
215
 
215
 
216
      <Input
216
      <Input
217
        type="password"
217
        type='password'
218
        name="password"
218
        name='password'
219
        icon={<Lock />}
219
        icon={<Lock />}
220
        placeholder="Clave"
220
        placeholder='Clave'
221
        control={control}
221
        control={control}
222
        rules={{
222
        rules={{
223
          required: "Este campo es requerido",
223
          required: 'Este campo es requerido',
224
          pattern: {
224
          pattern: {
225
            value:
225
            value:
Línea 226... Línea 226...
226
              /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$^x%x*-]).{6,16}$/i,
226
              /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$^x%x*-]).{6,16}$/i,
227
            message:
227
            message:
228
              "Debe contener entre 6 y 16 caracteres, incluida una letra mayúscula, un número y un carácter especial #?!@$^%*-",
228
              'Debe contener entre 6 y 16 caracteres, incluida una letra mayúscula, un número y un carácter especial #?!@$^%*-'
229
          },
229
          }
230
        }}
230
        }}
231
        error={errors.password?.message}
231
        error={errors.password?.message}
232
      />
232
      />
233
 
233
 
234
      <Input
234
      <Input
235
        type="password"
235
        type='password'
236
        name="confirmation"
236
        name='confirmation'
Línea 237... Línea 237...
237
        icon={<Lock />}
237
        icon={<Lock />}
238
        placeholder="Confirme su clave"
238
        placeholder='Confirme su clave'
239
        control={control}
239
        control={control}
240
        rules={{
240
        rules={{
Línea 241... Línea 241...
241
          required: "Este campo es requerido",
241
          required: 'Este campo es requerido',
242
          validate: (v) =>
242
          validate: (v) =>
243
            v === watch("password") ||
243
            v === watch('password') ||
244
            "Disculpe, las claves tienen que coincidir",
244
            'Disculpe, las claves tienen que coincidir'
245
        }}
245
        }}
246
        error={errors.confirmation?.message}
246
        error={errors.confirmation?.message}
247
      />
247
      />
Línea 248... Línea 248...
248
 
248
 
249
      <Select
249
      <Select
250
        label="Zona horaria"
250
        label='Zona horaria'
251
        name="timezone"
251
        name='timezone'
252
        control={control}
252
        control={control}
253
        rules={{ required: "Este campo es requerido" }}
253
        rules={{ required: 'Este campo es requerido' }}
254
        error={errors.timezone?.message}
254
        error={errors.timezone?.message}
255
        options={Object.entries(timezones).map(([key, value]) => ({
255
        options={Object.entries(timezones).map(([key, value]) => ({
256
          name: key,
256
          name: key,
257
          value,
257
          value
258
        }))}
258
        }))}
Línea 259... Línea 259...
259
      />
259
      />
260
 
260
 
261
      <SwitchInput
261
      <SwitchInput
Línea 262... Línea 262...
262
        label="Eres mayor de 18"
262
        label='Eres mayor de 18'
263
        setValue={(value) => setIsAdult(value)}
263
        setValue={(value) => setIsAdult(value)}
264
      />
264
      />
Línea 265... Línea 265...
265
 
265
 
266
      <CheckboxInput
266
      <CheckboxInput
267
        name="terms_and_conditions"
267
        name='terms_and_conditions'
268
        control={control}
268
        control={control}
269
        label="Si, acepto los Términos y Condiciones."
269
        label='Si, acepto los Términos y Condiciones.'
270
        rules={{ required: "Este campo es requerido" }}
270
        rules={{ required: 'Este campo es requerido' }}
271
        error={errors.terms_and_conditions?.message}
271
        error={errors.terms_and_conditions?.message}
272
      />
272
      />
Línea 273... Línea 273...
273
 
273