Commit 1b9535cb authored by Omar Luna Hernández's avatar Omar Luna Hernández
Browse files

Se crea el hook para validar los campos cuando se reinicia la contraseña

parent 9f186cce
Loading
Loading
Loading
Loading
+196 −0
Original line number Diff line number Diff line
import { useState } from "react";
import { ResetPasswordValues } from "../infraestructure/entities/reset_password_values";
import { FieldErrors, Resolver, SubmitHandler, useForm } from "react-hook-form";
import { AdminDatasourceProd } from "../data/datasources/prod/admin_datasource";
import { AdminRepositoryProd } from "../data/repositories/prod/admin_repository";
import axios, { AxiosError } from "axios";
import { toast } from "react-toastify";
import { usePasswoordVisibility } from "./usePasswordVisibility";

const adminDatasource = new AdminDatasourceProd();
const adminRepository = new AdminRepositoryProd(adminDatasource);

const resolver: Resolver<ResetPasswordValues> = async (data) => {
  const errors: FieldErrors<ResetPasswordValues> = {};

  if (!data.email) {
    errors.email = {
      type: "required",
      message: "El correo electronico es requerido",
    };
  } else {
    const emailPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
    if (!emailPattern.test(data.email)) {
      errors.email = {
        type: "validate",
        message: "El correo electronico no es válido",
      };
    }
  }

  if (!data.code) {
    errors.code = {
      type: "required",
      message: "El código es requerido",
    };
  } else {
    if (data.code.toString().length !== 6) {
      errors.code = {
        type: "required",
        message: "El código debe ser de 6 dígitos",
      };
    } else {
      const numberPattern = /^[0-9]+$/;
      if (!numberPattern.test(data.code.toString())) {
        errors.code = {
          type: "validate",
          message: "El código debe contener solo números",
        };
      }
    }
  }

  if (!data.newPassword) {
    errors.newPassword = {
      type: "required",
      message: "Se requiere una nueva contraseña",
    };
  } else if (data.confirmNewPassword !== data.newPassword) {
    errors.confirmNewPassword = {
      type: "validate",
      message: "Las contraseñas deben coincidir",
    };
  }

  if (!data.confirmNewPassword) {
    errors.confirmNewPassword = {
      type: "required",
      message: "Se requiere confirmar la nueva contraseña",
    };
  }

  return {
    values: Object.keys(errors).length > 0 ? {} : data,
    errors: errors,
  };
};

export const useResetPassword = (handleClickToClose?: () => void) => {
  const [step, setStep] = useState(1);
  const [isChanging, setIsChanging] = useState(false);
  const {
    register,
    formState: { errors },
    handleSubmit,
    getValues,
    setError,
  } = useForm<ResetPasswordValues>({ resolver: resolver });
  const {
    values: valuesNewPassword,
    handleClickShowPassword: handleClickShowNewPassword,
    handleMouseDownPassword: handleMouseDownNewPassword,
  } = usePasswoordVisibility();
  const {
    values: valuesNewPasswordConfirm,
    handleClickShowPassword: handleClickShowNewPasswordConfirm,
    handleMouseDownPassword: handleMouseDownNewPasswordConfirm,
  } = usePasswoordVisibility();
  const [animating, setAnimating] = useState(false);

  const handleSubmitEmail = () => {
    const fetch = async () => {
      try {
        await adminRepository.generateResetCode(getValues("email")).then(() => {
          setAnimating(true);
          setIsChanging(true);
          setTimeout(() => {
            setStep(2);
            setIsChanging(false);
            setAnimating(false);
          }, 500);
        });
      } catch (error: any) {
        let errorMessage: string = "Ha ocurrido un error";
        if (axios.isAxiosError(error)) {
          error as AxiosError;
          switch (error.code) {
            case axios.AxiosError.ERR_BAD_REQUEST:
              errorMessage = "Acceso no autorizado";
              break;
            case axios.AxiosError.ERR_NETWORK:
              errorMessage = "Conexión con el servidor fallida";
              break;
          }
        }
        throw new Error(errorMessage);
      }
    };
    toast.promise(fetch(), {
      pending: "Enviando correo...",
      success: "Se ha enviado el correo",
      error: {
        render({ data }) {
          return (data as Error).message;
        },
      },
    });
  };

  const onSubmitPassword: SubmitHandler<ResetPasswordValues> = (
    data: ResetPasswordValues
  ) => {
    const fetch = async () => {
      try {
        await adminRepository.resetPassword(data).then(() => {
          if (handleClickToClose) {
            handleClickToClose();
          }
        });
      } catch (error: any) {
        let errorMessage: string = "Ha ocurrido un error";
        if (axios.isAxiosError(error)) {
          error as AxiosError;
          switch (error.code) {
            case axios.AxiosError.ERR_BAD_REQUEST:
              errorMessage = "Acceso no autorizado";
              setError("code", {
                type: "validate",
                message: "El código no es correcto",
              });
              break;
            case axios.AxiosError.ERR_NETWORK:
              errorMessage = "Conexión con el servidor fallida";
              break;
          }
        }
        throw new Error(errorMessage);
      }
    };
    toast.promise(fetch(), {
      pending: "Subiendo datos...",
      success: "La contraseña se ha cambiado",
      error: {
        render({ data }) {
          return (data as Error).message;
        },
      },
    });
  };

  return {
    step,
    animating,
    handleSubmitEmail,
    onSubmitPassword,
    isChanging,
    register,
    errors,
    handleSubmit,
    valuesNewPassword,
    valuesNewPasswordConfirm,
    handleClickShowNewPassword,
    handleClickShowNewPasswordConfirm,
    handleMouseDownNewPassword,
    handleMouseDownNewPasswordConfirm,
  };
};