Proyectos de Subversion LeadersLinked - SPA

Rev

Rev 2802 | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |

import React, { useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';
import { connect } from 'react-redux';
import { styled } from '@mui/material';

import { axios } from '@utils';
import { addNotification } from '@app/redux/notification/notification.actions';

import Spinner from '@components/UI/Spinner';
import FormErrorFeedback from '@components/UI/form/FormErrorFeedback';

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 ChangePassword = ({ addNotification }) => {
  const [loading, setLoading] = useState(false);
  const [isErrorPassword, setIsErrorPassword] = useState(false);
  const [isErrorConfirmation, setIsErrorConfirmation] = useState(false);

  const {
    register,
    handleSubmit,
    getValues,
    reset,
    setError,
    formState: { isSubmitSuccessful, errors }
  } = useForm();

  const handleOnSubmit = async (data) => {
    setLoading(true);

    let errorPassword = false;

    const validPassword = /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$^x%x*-]).{6,16}$/;

    if (!validPassword.test(data.password)) {
      setIsErrorPassword(true);
      setTimeout(() => {
        setIsErrorPassword(false);
      }, 10000);
      setLoading(false);
      errorPassword = true;
    }

    if (data.password !== data.confirmation) {
      setIsErrorConfirmation(true);
      setTimeout(() => {
        setIsErrorConfirmation(false);
      }, 10000);
      setLoading(false);
      errorPassword = true;
    }

    if (!errorPassword) {
      const formData = new FormData();
      Object.entries(data).forEach(([key, value]) => {
        formData.append(key, value);
      });
      await axios.post('/account-settings/password', formData).then((response) => {
        const resData = response.data;
        if (resData.success) {
          addNotification({
            style: 'success',
            msg: resData.data
          });
        } else {
          if (typeof resData.data === 'object') {
            Object.entries(resData.data).forEach(([key, value]) => {
              setError(key, { type: 'manual', message: value[0] });
            });
          } else {
            const errorMessage =
              typeof resData.data === 'string'
                ? resData.data
                : 'Ha ocurrido un error, Por favor intente mas tarde';
            addNotification({
              style: 'danger',
              msg: errorMessage
            });
          }
        }
      });
      setLoading(false);
    }

    errorPassword = false;
  };

  useEffect(() => {
    reset({ ...getValues });
  }, [isSubmitSuccessful]);

  return (
    <div className='settings-container'>
      <h2>Cambiar clave</h2>
      <div className='acc-setting_content'>
        <form onSubmit={handleSubmit(handleOnSubmit)}>
          <div className='d-flex flex-wrap' style={{ gap: '1rem' }}>
            <div className='cp-field'>
              <label htmlFor='password'>Clave</label>
              <div className='cpp-fiel'>
                <input
                  type='password'
                  name='password'
                  minLength='6'
                  maxLength='16'
                  id='password'
                  ref={register({
                    required: 'Por favor ingrese la contraseña'
                  })}
                  pattern='^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$^x%x*-]).{6,16}$'
                  title='La clave debe contener entre 6 y 16 caracteres, incluida una letra mayúscula, un número y un carácter especial #?!@$^%*-'
                />
                <i className='fa fa-lock'></i>
              </div>
              {isErrorPassword && (
                <p className='text-danger'>
                  Disculpe, La clave debe contener entre 6 y 16 caracteres, incluida una letra
                  mayúscula, un número y un carácter especial #?!@$^%*-
                </p>
              )}
              {<FormErrorFeedback>{errors?.password?.message}</FormErrorFeedback>}
            </div>
            <div className='cp-field'>
              <label htmlFor='confirmation'>Confirmación</label>
              <div className='cpp-fiel'>
                <input
                  type='password'
                  name='confirmation'
                  minLength='6'
                  maxLength='16'
                  id='confirmation'
                  ref={register({
                    required: 'Por favor ingrese la contraseña',
                    validate: (value) =>
                      value === getValues('password') || 'La contraseña no coincide'
                  })}
                  pattern='^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$^x%x*-]).{6,16}$'
                  title='La clave debe contener entre 6 y 16 caracteres, incluida una letra mayúscula, un número y un carácter especial #?!@$^%*-'
                />
                <i className='fa fa-lock'></i>
              </div>
              {isErrorConfirmation && (
                <p className='text-danger'>Disculpe, las claves tienen que coincidir</p>
              )}
              {<FormErrorFeedback>{errors?.confirmation?.message}</FormErrorFeedback>}
            </div>
          </div>
          <div className='pt-4 d-flex align-items-center justify-content-center'>
            <button type='submit' className='btn btn-secondary'>
              Guardar
            </button>
          </div>
        </form>
      </div>
      {loading && (
        <StyledSpinnerContainer>
          <Spinner />
        </StyledSpinnerContainer>
      )}
    </div>
  );
};

const mapDispatchToProps = {
  addNotification: (notification) => addNotification(notification)
};

export default connect(null, mapDispatchToProps)(ChangePassword);