Loading web/src/hooks/usePlace.tsx +132 −126 Original line number Diff line number Diff line import { FieldErrors, Resolver, SubmitHandler, useForm } from "react-hook-form" import { FieldErrors, Resolver, SubmitHandler, useForm } from "react-hook-form"; import { Place, AvailableDays } from "../infraestructure/entities/place"; import { toast } from "react-toastify"; import { useEffect, useState } from "react"; Loading @@ -18,56 +18,49 @@ const resolver: Resolver<Place> = async (data) => { if (!data.idTown) { errors.idTown = { type: "required", message : "Debe seleccionar el pueblo mágico al que pertenece el lugar" } message: "Debe seleccionar el pueblo mágico al que pertenece el lugar", }; } if (!data.openAt && data.openAt !== 0) { errors.openAt = { type: "required", message: "La hora de apertura es requerida" message: "La hora de apertura es requerida", }; } if (!data.closeAt && data.closeAt !== 0) { errors.closeAt = { type: "required", message: "La hora de cierre es requerida" message: "La hora de cierre es requerida", }; } if (data.openAt > data.closeAt) { errors.closeAt = { type: "required", message: "La hora de apertura debe ser antes que la hora de cierre" message: "La hora de apertura debe ser antes que la hora de cierre", }; } if (!data.name) { errors.name = { type: "required", message: "El nombre del lugar es requerido" message: "El nombre del lugar es requerido", }; } if (!data.categoriesId) { errors.categoriesId = { type: "required", message: "Debe seleccionar al menos una categoría" } message: "Debe seleccionar al menos una categoría", }; } else { if (data.categoriesId.length < 1) { errors.categoriesId = { type: "required", message: "Debe seleccionar al menos una categoría" } } } if(!data.address){ errors.address = { type: "required", message: "Debe de ingresar la dirección al lugar" message: "Debe seleccionar al menos una categoría", }; } } Loading @@ -75,7 +68,10 @@ const resolver: Resolver<Place> = async (data) => { if (!data.descriptions || !data.descriptions[index]) { errors.descriptions = { type: "required", message: "La descripción del lugar en "+languaguesList[index]+" es requerida" message: "La descripción del lugar en " + languaguesList[index] + " es requerida", }; } } Loading @@ -83,21 +79,21 @@ const resolver: Resolver<Place> = async (data) => { if (!data.available) { errors.available = { type: "required", message: "Se requieren los días que está disponible el lugar" message: "Se requieren los días que está disponible el lugar", }; } else { if (data.available === AvailableDays.CUSTOM) { if (!data.startDate) { errors.startDate = { type: "required", message: "Se requiere la fecha de inicio" message: "Se requiere la fecha de inicio", }; } if (!data.endDate) { errors.endDate = { type: "required", message: "Se requiere la fecha de cierre" message: "Se requiere la fecha de cierre", }; } Loading @@ -107,7 +103,8 @@ const resolver: Resolver<Place> = async (data) => { if (startDate.getTime() > endDate.getTime()) { errors.endDate = { type: "required", message: "La fecha de inicio no puede ser después de la fecha de cierre" message: "La fecha de inicio no puede ser después de la fecha de cierre", }; } } Loading @@ -117,25 +114,30 @@ const resolver: Resolver<Place> = async (data) => { if (!data.latitude || !data.longitude) { errors.latitude = { type: "required", message: "Debe de seleccionar la ubicación del lugar" } message: "Debe de seleccionar la ubicación del lugar", }; } if (!data.imagesList || data.imagesList.length < MIN_NUMBER_PLACE_IMAGES) { errors.imagesList = { type: "required", message: "Debe de haber al menos "+MIN_NUMBER_PLACE_IMAGES+" imagénes representativas del lugar" } message: "Debe de haber al menos " + MIN_NUMBER_PLACE_IMAGES + " imagénes representativas del lugar", }; } return { values: Object.keys(errors).length > 0 ? {} : data, errors: errors errors: errors, }; }; export const usePlace = (forceRenderList?: () => void, setIsWindowActive?: (visibility: boolean) => void) => { export const usePlace = ( forceRenderList?: () => void, setIsWindowActive?: (visibility: boolean) => void ) => { const { register, handleSubmit, Loading @@ -143,22 +145,30 @@ setIsWindowActive?: (visibility: boolean) => void) => { formState: { errors }, clearErrors, resetField, getValues getValues, } = useForm<Place>({ resolver }); const [languageDescriptionIndexSelected, setLanguageDescriptionIndexSelected] = useState(0); const [descriptions, setDescriptions] = useState<string[]>(new Array(languaguesList.length).fill("")); const [availableDays, setAvailableDays] = useState<AvailableDays>(AvailableDays.WEEKEND); const [ languageDescriptionIndexSelected, setLanguageDescriptionIndexSelected, ] = useState(0); const [descriptions, setDescriptions] = useState<string[]>( new Array(languaguesList.length).fill("") ); const [availableDays, setAvailableDays] = useState<AvailableDays>( AvailableDays.WEEKEND ); const [placeList, setPlaceList] = useState<Place[]>([]); const [pending, setPending] = useState(false); const [categoriesId, setCategoriesId] = useState<number[]>([]); const [updatedCategories, setUpdatedCategories] = useState(false); useEffect(() => { setValue('categoriesId',categoriesId,{shouldValidate: updatedCategories}); setValue("categoriesId", categoriesId, { shouldValidate: updatedCategories, }); setUpdatedCategories(true); }, [categoriesId]); const onSubmitRegister: SubmitHandler<Place> = (data: Place) => { const fetch = async () => { try { Loading @@ -173,29 +183,27 @@ setIsWindowActive?: (visibility: boolean) => void) => { if (axios.isAxiosError(error)) { error as AxiosError; switch (error.code) { case(axios.AxiosError.ERR_BAD_REQUEST): case axios.AxiosError.ERR_BAD_REQUEST: errorMessage = "Acceso no autorizado"; break; case(axios.AxiosError.ERR_NETWORK): case axios.AxiosError.ERR_NETWORK: errorMessage = "Conexión con el servidor fallida"; break; } } throw new Error(errorMessage); } } toast.promise( fetch(),{ }; toast.promise(fetch(), { pending: "Subiendo datos...", success: "Los datos se han subido correctamente", error: { render({ data }) { return (data as Error).message; } } } ) } }, }, }); }; const onSubmitUpdate: SubmitHandler<Place> = (data: Place) => { const fetch = async () => { Loading @@ -210,42 +218,40 @@ setIsWindowActive?: (visibility: boolean) => void) => { if (axios.isAxiosError(error)) { error as AxiosError; switch (error.code) { case(axios.AxiosError.ERR_BAD_REQUEST): case axios.AxiosError.ERR_BAD_REQUEST: errorMessage = "Acceso no autorizado"; break; case(axios.AxiosError.ERR_NETWORK): case axios.AxiosError.ERR_NETWORK: errorMessage = "Conexión con el servidor fallida"; break; } } throw new Error(errorMessage); } } toast.promise( fetch(),{ }; toast.promise(fetch(), { pending: "Subiendo datos...", success: "Los datos se han subido correctamente", error: { render({ data }) { return (data as Error).message; } } } ) } }, }, }); }; const updateTimeForm = (time: string, isOpeningHour: boolean) => { const timeSplitted = time.split(":"); let hours = Number(timeSplitted[0]); const minutes = Number(timeSplitted[1]); hours += (minutes/60); hours += minutes / 60; hours = Math.round(hours); if (isOpeningHour) { setValue("openAt", hours, { shouldValidate: true }); } else { setValue("closeAt", hours, { shouldValidate: true }); } } }; const updatePlacesByTown = async (idTown: number) => { setPending(true); Loading @@ -260,7 +266,7 @@ setIsWindowActive?: (visibility: boolean) => void) => { } setPending(false); } } }; const getPlaceById = async (idPlace: number): Promise<Place | null> => { try { Loading @@ -273,7 +279,7 @@ setIsWindowActive?: (visibility: boolean) => void) => { } } return null; } }; return { register, Loading @@ -297,6 +303,6 @@ setIsWindowActive?: (visibility: boolean) => void) => { categoriesId, setCategoriesId, getPlaceById, getValues getValues, }; }; } Loading
web/src/hooks/usePlace.tsx +132 −126 Original line number Diff line number Diff line import { FieldErrors, Resolver, SubmitHandler, useForm } from "react-hook-form" import { FieldErrors, Resolver, SubmitHandler, useForm } from "react-hook-form"; import { Place, AvailableDays } from "../infraestructure/entities/place"; import { toast } from "react-toastify"; import { useEffect, useState } from "react"; Loading @@ -18,56 +18,49 @@ const resolver: Resolver<Place> = async (data) => { if (!data.idTown) { errors.idTown = { type: "required", message : "Debe seleccionar el pueblo mágico al que pertenece el lugar" } message: "Debe seleccionar el pueblo mágico al que pertenece el lugar", }; } if (!data.openAt && data.openAt !== 0) { errors.openAt = { type: "required", message: "La hora de apertura es requerida" message: "La hora de apertura es requerida", }; } if (!data.closeAt && data.closeAt !== 0) { errors.closeAt = { type: "required", message: "La hora de cierre es requerida" message: "La hora de cierre es requerida", }; } if (data.openAt > data.closeAt) { errors.closeAt = { type: "required", message: "La hora de apertura debe ser antes que la hora de cierre" message: "La hora de apertura debe ser antes que la hora de cierre", }; } if (!data.name) { errors.name = { type: "required", message: "El nombre del lugar es requerido" message: "El nombre del lugar es requerido", }; } if (!data.categoriesId) { errors.categoriesId = { type: "required", message: "Debe seleccionar al menos una categoría" } message: "Debe seleccionar al menos una categoría", }; } else { if (data.categoriesId.length < 1) { errors.categoriesId = { type: "required", message: "Debe seleccionar al menos una categoría" } } } if(!data.address){ errors.address = { type: "required", message: "Debe de ingresar la dirección al lugar" message: "Debe seleccionar al menos una categoría", }; } } Loading @@ -75,7 +68,10 @@ const resolver: Resolver<Place> = async (data) => { if (!data.descriptions || !data.descriptions[index]) { errors.descriptions = { type: "required", message: "La descripción del lugar en "+languaguesList[index]+" es requerida" message: "La descripción del lugar en " + languaguesList[index] + " es requerida", }; } } Loading @@ -83,21 +79,21 @@ const resolver: Resolver<Place> = async (data) => { if (!data.available) { errors.available = { type: "required", message: "Se requieren los días que está disponible el lugar" message: "Se requieren los días que está disponible el lugar", }; } else { if (data.available === AvailableDays.CUSTOM) { if (!data.startDate) { errors.startDate = { type: "required", message: "Se requiere la fecha de inicio" message: "Se requiere la fecha de inicio", }; } if (!data.endDate) { errors.endDate = { type: "required", message: "Se requiere la fecha de cierre" message: "Se requiere la fecha de cierre", }; } Loading @@ -107,7 +103,8 @@ const resolver: Resolver<Place> = async (data) => { if (startDate.getTime() > endDate.getTime()) { errors.endDate = { type: "required", message: "La fecha de inicio no puede ser después de la fecha de cierre" message: "La fecha de inicio no puede ser después de la fecha de cierre", }; } } Loading @@ -117,25 +114,30 @@ const resolver: Resolver<Place> = async (data) => { if (!data.latitude || !data.longitude) { errors.latitude = { type: "required", message: "Debe de seleccionar la ubicación del lugar" } message: "Debe de seleccionar la ubicación del lugar", }; } if (!data.imagesList || data.imagesList.length < MIN_NUMBER_PLACE_IMAGES) { errors.imagesList = { type: "required", message: "Debe de haber al menos "+MIN_NUMBER_PLACE_IMAGES+" imagénes representativas del lugar" } message: "Debe de haber al menos " + MIN_NUMBER_PLACE_IMAGES + " imagénes representativas del lugar", }; } return { values: Object.keys(errors).length > 0 ? {} : data, errors: errors errors: errors, }; }; export const usePlace = (forceRenderList?: () => void, setIsWindowActive?: (visibility: boolean) => void) => { export const usePlace = ( forceRenderList?: () => void, setIsWindowActive?: (visibility: boolean) => void ) => { const { register, handleSubmit, Loading @@ -143,22 +145,30 @@ setIsWindowActive?: (visibility: boolean) => void) => { formState: { errors }, clearErrors, resetField, getValues getValues, } = useForm<Place>({ resolver }); const [languageDescriptionIndexSelected, setLanguageDescriptionIndexSelected] = useState(0); const [descriptions, setDescriptions] = useState<string[]>(new Array(languaguesList.length).fill("")); const [availableDays, setAvailableDays] = useState<AvailableDays>(AvailableDays.WEEKEND); const [ languageDescriptionIndexSelected, setLanguageDescriptionIndexSelected, ] = useState(0); const [descriptions, setDescriptions] = useState<string[]>( new Array(languaguesList.length).fill("") ); const [availableDays, setAvailableDays] = useState<AvailableDays>( AvailableDays.WEEKEND ); const [placeList, setPlaceList] = useState<Place[]>([]); const [pending, setPending] = useState(false); const [categoriesId, setCategoriesId] = useState<number[]>([]); const [updatedCategories, setUpdatedCategories] = useState(false); useEffect(() => { setValue('categoriesId',categoriesId,{shouldValidate: updatedCategories}); setValue("categoriesId", categoriesId, { shouldValidate: updatedCategories, }); setUpdatedCategories(true); }, [categoriesId]); const onSubmitRegister: SubmitHandler<Place> = (data: Place) => { const fetch = async () => { try { Loading @@ -173,29 +183,27 @@ setIsWindowActive?: (visibility: boolean) => void) => { if (axios.isAxiosError(error)) { error as AxiosError; switch (error.code) { case(axios.AxiosError.ERR_BAD_REQUEST): case axios.AxiosError.ERR_BAD_REQUEST: errorMessage = "Acceso no autorizado"; break; case(axios.AxiosError.ERR_NETWORK): case axios.AxiosError.ERR_NETWORK: errorMessage = "Conexión con el servidor fallida"; break; } } throw new Error(errorMessage); } } toast.promise( fetch(),{ }; toast.promise(fetch(), { pending: "Subiendo datos...", success: "Los datos se han subido correctamente", error: { render({ data }) { return (data as Error).message; } } } ) } }, }, }); }; const onSubmitUpdate: SubmitHandler<Place> = (data: Place) => { const fetch = async () => { Loading @@ -210,42 +218,40 @@ setIsWindowActive?: (visibility: boolean) => void) => { if (axios.isAxiosError(error)) { error as AxiosError; switch (error.code) { case(axios.AxiosError.ERR_BAD_REQUEST): case axios.AxiosError.ERR_BAD_REQUEST: errorMessage = "Acceso no autorizado"; break; case(axios.AxiosError.ERR_NETWORK): case axios.AxiosError.ERR_NETWORK: errorMessage = "Conexión con el servidor fallida"; break; } } throw new Error(errorMessage); } } toast.promise( fetch(),{ }; toast.promise(fetch(), { pending: "Subiendo datos...", success: "Los datos se han subido correctamente", error: { render({ data }) { return (data as Error).message; } } } ) } }, }, }); }; const updateTimeForm = (time: string, isOpeningHour: boolean) => { const timeSplitted = time.split(":"); let hours = Number(timeSplitted[0]); const minutes = Number(timeSplitted[1]); hours += (minutes/60); hours += minutes / 60; hours = Math.round(hours); if (isOpeningHour) { setValue("openAt", hours, { shouldValidate: true }); } else { setValue("closeAt", hours, { shouldValidate: true }); } } }; const updatePlacesByTown = async (idTown: number) => { setPending(true); Loading @@ -260,7 +266,7 @@ setIsWindowActive?: (visibility: boolean) => void) => { } setPending(false); } } }; const getPlaceById = async (idPlace: number): Promise<Place | null> => { try { Loading @@ -273,7 +279,7 @@ setIsWindowActive?: (visibility: boolean) => void) => { } } return null; } }; return { register, Loading @@ -297,6 +303,6 @@ setIsWindowActive?: (visibility: boolean) => void) => { categoriesId, setCategoriesId, getPlaceById, getValues getValues, }; }; }