Rev 3410 | Rev 3432 | 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 } from "react-router-dom";import { useForm } from "react-hook-form";import { useDispatch, useSelector } from "react-redux";import { styled, Typography } from "@mui/material";import { Mail, Lock, Person, CheckCircleOutline } from "@mui/icons-material";import Recaptcha from "react-recaptcha";import { axios } from "@utils";import { useFetchHelper } from "@hooks";import { addNotification } from "@store/notification/notification.actions";import CryptoJSAesJson from "@utils/crypto-js/cryptojs-aes-format";import Input from "@components/UI/inputs/Input";import Button from "@components/UI/buttons/Buttons";import Select from "@components/UI/inputs/Select";import Spinner from "@components/UI/Spinner";import Form from "@components/common/form";import SwitchInput from "@components/UI/SwitchInput";import CheckboxInput from "@components/UI/inputs/Checkbox";const StyledCheck = styled("div")`display: flex;flex-direction: column;justify-content: center;align-items: center;gap: 0.5rem;p {text-align: center;}`;const StyledSpinnerContainer = styled("div")`position: absolute;left: 0;top: 0;width: 100%;height: 100%;background: rgba(255, 255, 255, 0.4);display: flex;justify-content: center;align-items: center;z-index: 300;`;const Signup = () => {const [registered, setRegistered] = useState(false);const [loading, setloading] = useState(false);const [isAdult, setIsAdult] = useState(false);const [isVerified, setIsVerified] = useState(false);const reCaptchaInstance = useRef(null);const reCaptchaToken = useRef("");const dispatch = useDispatch();const { site_key, aes } = useSelector(({ auth }) => auth);const { data: timezones } = useFetchHelper("timezones");const {control,handleSubmit,setError,watch,formState: { errors },} = useForm({mode: "all",});const signupVerifyCallbackHandler = (response) => {if (!response) return;reCaptchaToken.current = response;setIsVerified(true);};const signupExpiredCallbackHandler = () => {reCaptchaToken.current = "";setIsVerified(false);};const handleOnRecaptchaLoad = () => {reCaptchaToken.current = "";};const onSubmitHandler = handleSubmit(async ({email,first_name,last_name,password,confirmation,terms_and_conditions,}) => {setloading(true);const formData = new FormData();formData.append("first_name", first_name);formData.append("last_name", last_name);formData.append("email", CryptoJSAesJson.encrypt(email, aes));formData.append("password", CryptoJSAesJson.encrypt(password, aes));formData.append("confirmation",CryptoJSAesJson.encrypt(confirmation, aes));formData.append("terms_and_conditions", terms_and_conditions ? 1 : 0);formData.append("captcha", reCaptchaToken.current);formData.append("is_adult", isAdult ? "y" : "n");await axios.post("/signup", formData).then(({ data }) => {if (!data.success) {if (typeof data.data !== "string") {Object.entries(data.data).forEach(([key, value]) => {setError(key, {type: "manual",message: Array.isArray(value) ? value[0] : value,});});return;}dispatch(addNotification({ style: "danger", msg: data.data }));reCaptchaInstance.current.reset();signupVerifyCallbackHandler();return;}reCaptchaInstance.current.reset();signupExpiredCallbackHandler();setRegistered(true);}).catch((err) => {console.log(`Error: ${err}`);dispatch(addNotification({style: "danger",msg: "Disculpe, ha ocurrido un error",}));}).finally(() => setloading(false));});useEffect(() => {reCaptchaInstance.current?.reset();}, []);if (registered) {return (<StyledCheck><CheckCircleOutline sx={{ color: "#7FFF00", fontSize: "3rem" }} /><Typography>Se ha registrado correctamente. Por favor, active la cuenta desde sucorreo</Typography><Link to="/signin"><button className="btn btn-primary">Entrar</button></Link></StyledCheck>);}return (<Form onSubmit={onSubmitHandler}><Typography variant="h3">Registrarse</Typography><Inputtype="email"name="email"placeholder="Correo electrónico"icon={<Mail />}control={control}rules={{required: "Este campo es requerido",pattern: {value: /^[\w-.]+@([\w-]+\.)+[\w-]{2,}$/i,message: "Debe ser una dirección de correo electrónico valida",},}}error={errors.email?.message}/><Inputtype="text"name="first_name"icon={<Person />}placeholder="Nombre"control={control}rules={{required: "Este campo es requerido",maxLength: {value: 64,message: "Limite de carateres superior al permitido",},}}error={errors.first_name?.message}/><Inputtype="text"name="last_name"icon={<Person />}placeholder="Apellido"control={control}rules={{required: "Este campo es requerido",maxLength: {value: 64,message: "Limite de carateres superior al permitido",},}}error={errors.last_name?.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}/><Inputtype="password"name="confirmation"icon={<Lock />}placeholder="Confirme su clave"control={control}rules={{required: "Este campo es requerido",validate: (v) =>v === watch("password") ||"Disculpe, las claves tienen que coincidir",}}error={errors.confirmation?.message}/><Selectlabel="Zona horaria"name="timezone"control={control}rules={{ required: "Este campo es requerido" }}error={errors.timezone?.message}options={Object.entries(timezones).map(([key, value]) => ({name: key,value,}))}/><SwitchInputlabel="Eres mayor de 18"setValue={(value) => setIsAdult(value)}/><CheckboxInputname="terms_and_conditions"control={control}label="Si, acepto los Términos y Condiciones."rules={{ required: "Este campo es requerido" }}error={errors.terms_and_conditions?.message}/><Recaptchasitekey={site_key}verifyCallback={signupVerifyCallbackHandler}verifyCallbackName="signupVerifyCallbackHandler"expiredCallback={signupExpiredCallbackHandler}expiredCallbackName="signupExpiredCallbackHandler"ref={reCaptchaInstance}render="explicit"onloadCallback={handleOnRecaptchaLoad}hl="es"/><div className="links"><Link to="/signin">¿Ya tienes cuenta?</Link></div><Button color="secondary" type="submit" disabled={!isVerified}>Registrarse</Button>{loading && (<StyledSpinnerContainer><Spinner /></StyledSpinnerContainer>)}</Form>);};export default Signup;