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

Se crea el hook que guarda la lógica para crear, validar y obtener puntos de interes

parent d5e46ac9
Loading
Loading
Loading
Loading
+179 −0
Original line number Diff line number Diff line
import { FieldErrors, Resolver, SubmitHandler, useForm } from "react-hook-form";
import { POIDatasourceProd } from "../data/datasources/prod/poi_datasource";
import { POIRepositoryProd } from "../data/repositories/prod/poi_repository";
import { PointOfInterest } from "../infraestructure/entities/poi";
import { useState } from "react";
import axios, { AxiosError } from "axios";
import { toast } from "react-toastify";
import { languaguesList } from "../constants/languages";
import { showErrorAxios } from "../utils/Messages";

const POIDatasouce = new POIDatasourceProd();
const POIRepository = new POIRepositoryProd(POIDatasouce);

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

  if(!data.idPlace){
    errors.idPlace = {
      type : "required",
      message : "Debe seleccionar el lugar al que pertenece el punto de interés"
    }
  }

  if(!data.name){
    errors.name = {
      type: "required",
      message: "El nombre del punto de interés es requerido"
    };
  }

  if(!data.contentEN){
    errors.contentEN = {
      type: "required",
      message: "La descripción del punto de interés en inglés es requerida"
    };
  }

  if(!data.contentES){
    errors.contentES = {
      type: "required",
      message: "La descripción del punto de interés en español es requerida"
    };
  }

  if(!data.directionsEN){
    errors.directionsEN = {
      type: "required",
      message: "Las direcciones del punto de interés en inglés son requeridas"
    };
  }

  if(!data.directionsES){
    errors.directionsES = {
      type: "required",
      message: "Las direcciones del punto de interés en español son requeridas"
    };
  }


  if(!data.image){
    errors.image = {
      type: "required",
      message: "Debe de haber al menos 1 imagen representativa del lugar"
    }
  }

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

export const usePointOfInterest = (forceRenderList?: () => void, 
setIsWindowActive?: (visibility: boolean) => void) => {
  const {
    register, 
    handleSubmit,
    setValue,
    formState: {errors},
    clearErrors,
    resetField,
  } = useForm<PointOfInterest>({resolver});
  const [errorMessage, setErrorMessage] = useState("");
  const [languageDescriptionIndexSelected, setLanguageDescriptionIndexSelected] = useState(0);
  const [languageDirectionsIndexSelected, setLanguageDirectionsIndexSelected] = useState(0);
  const [descriptions, setDescriptions] = useState<string[]>(new Array(languaguesList.length).fill(""));
  const [directions, setDirections] = useState<string[]>(new Array(languaguesList.length).fill(""));
  const [poiList, setPoiList] = useState<PointOfInterest[]>([]);
  const [pending, setPending] = useState(false);


  const onSubmitRegister : SubmitHandler<PointOfInterest> = (data: PointOfInterest) => {
    const fetch = async () => {
      try{
        await POIRepository.registerPoint(data).then(() =>{
          if(forceRenderList && setIsWindowActive){
            setTimeout(() => {  
              forceRenderList();
              setIsWindowActive(false);
            }, 1000);
          }
        });
      }catch(error: any){
        if(axios.isAxiosError(error)){
          error as AxiosError;
          switch(error.code){
            case(axios.AxiosError.ERR_BAD_REQUEST):
              setErrorMessage("Acceso no autorizado");
              break;
            case(axios.AxiosError.ERR_NETWORK):
              setErrorMessage("Conexión con el servidor fallida");
              break;
            default:
              setErrorMessage(error.message);
              break;
          }
        }
        throw new Error();
      }
    }
    toast.promise(
      fetch(),{
        pending: "Subiendo datos...",
        success: "Los datos se han subido correctamente",
        error: errorMessage
      }
    )
  }

  const updatePOIByPlace = async (idPlace: number) => {
    setPending(true);
    try{
      const POIs = await POIRepository.getPOIsByPlace(idPlace);
      setPoiList(POIs);
      setPending(false);
    }catch(error: any){
      if(axios.isAxiosError(error)){
        error as AxiosError;
        showErrorAxios(error);
      }
      setPending(false);
    }
  }

  const getPointById = async (idPoint: number): Promise<PointOfInterest | null> => {
    try{
      const point = await POIRepository.getPOIById(idPoint);
      return point;
    }catch(error: any){
      if(axios.isAxiosError(error)){
        error as AxiosError;
        showErrorAxios(error);
      }
    }
    return null;
  }

  return {
    register, 
    handleSubmit, 
    errors, 
    onSubmitRegister,
    setValue,
    languageDescriptionIndexSelected,
    setLanguageDescriptionIndexSelected,
    languageDirectionsIndexSelected,
    setLanguageDirectionsIndexSelected,
    descriptions,
    directions,
    setDirections,
    setDescriptions,
    clearErrors,
    resetField,
    poiList,
    pending,
    getPointById,
    updatePOIByPlace
  };
}