Loading web/src/components/admin_panel_places/admin_panel_place_register/admin_panel_place_register.tsx +156 −7 Original line number Diff line number Diff line Loading @@ -3,13 +3,36 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Dispatch, SetStateAction} from "react"; import "./assets/css/styles.css"; import { MapComponent } from "../../map/map"; import { usePlaceRegister } from "../../../hooks/usePlaceRegister"; import { languaguesList } from "../../../constants/languages"; import { ToastContainer, toast } from "react-toastify"; import { LoadingScreen } from "../../loading_screen/loading_screen"; import { MultipleImagesDropzone } from "../../multiple_images_dropzone/multiple_images_dropzone"; interface props { setIsWindowActive: Dispatch<SetStateAction<boolean>>; } export const AdminPanelPlaceRegister = ({setIsWindowActive}: props) => { const { register, handleSubmit, errors, onSubmit, setValue, languageNameIndexSelected, setLanguageNameIndexSelected, languageDescriptionIndexSelected, setNames, names, descriptions, setDescriptions, setLanguageDescriptionIndexSelected, isLoading, statesList, updateTownsList, townsList, } = usePlaceRegister(); return ( <div className="place_register_wrap"> Loading @@ -19,18 +42,144 @@ export const AdminPanelPlaceRegister = ({setIsWindowActive}: props) => { onClick={() => setIsWindowActive(false)}/> </div> <div className="place_register_body"> <form> <form onSubmit={handleSubmit(onSubmit)}> { isLoading ? <LoadingScreen/> : <div className="inputs_container"> <div className="input"> <div className="input_header"> Nombre del lugar <select onChange={(e) => setLanguageNameIndexSelected(Number(e.target.value))}> {languaguesList.map((language, index) => { return ( <option key={index} value={index}>{language}</option> ); })} </select> </div> { languaguesList.map((language, index) => { if(index===languageNameIndexSelected){ return ( <input type="text" value={names[index]} onChange={(e) => { const updatedNamesList = [...names]; updatedNamesList[index] = e.target.value; setNames(updatedNamesList); setValue("names", updatedNamesList, {shouldValidate: true}); }} /> ); } }) } <p className="error">{errors.names?.message}</p> </div> <div className="input"> <div className="input_header"> Descripción del lugar <select onChange={(e) => setLanguageDescriptionIndexSelected(Number(e.target.value))}> {languaguesList.map((language, index) => { return ( <option key={index} value={index}>{language}</option> ); })} </select> </div> { languaguesList.map((language, index) => { if(index===languageDescriptionIndexSelected){ return ( <textarea id={index.toString()} className="place_description" value={descriptions[index]} onChange={(e) => { const updatedDescriptionsList = [...descriptions]; updatedDescriptionsList[index] = e.target.value; setDescriptions(updatedDescriptionsList); setValue("descriptions", updatedDescriptionsList, {shouldValidate: true}); }} /> ); } }) } <p className="error">{errors.descriptions?.message}</p> </div> <div className="input"> <div className="input_header"> Pueblo mágico al que pertenece el lugar </div> <div className="town_select_cnt"> <div> Estado <select onChange={(event) => { updateTownsList(Number(event.target.value), event.target.options[event.target.selectedIndex].text); }} > {statesList === null || statesList.length===0 ? <option disabled selected value="">No hay estados</option> : <> <option disabled selected value="">Selecciona el estado</option> {statesList.map((state, index) => { return ( <option key={state.stateId} value={state.stateId}>{state.name}</option> ); })} </> } </select> </div> <div> Pueblo mágico <select {...register("idTown")}> { townsList === null || townsList.length===0 ? <option disabled selected value="">No hay pueblos</option> : townsList.map((towns) => { return ( <option key={towns.idTown} value={towns.idTown}>{towns.name}</option> ); }) } </select> </div> </div> <p className="error">{errors.idTown?.message}</p> </div> <MultipleImagesDropzone setValue={setValue}/> <p className="error">{errors.imagesList?.message}</p> <input type="submit"/> </div> } <div className="map_container"> <div className="map"> <MapComponent/> <MapComponent setValue={setValue}/> </div> <div className="map_error_cnt"> <p className="error">{errors.latitude?.message}</p> </div> </div> <ToastContainer position='bottom-right' autoClose = {1000} hideProgressBar = {true} closeOnClick rtl={false} pauseOnFocusLoss /> </form> </div> </div> Loading web/src/components/admin_panel_places/admin_panel_place_register/assets/css/styles.css +50 −0 Original line number Diff line number Diff line Loading @@ -67,3 +67,53 @@ height: 5%; width: 100%; } .input{ width: 100%; display: flex; flex-direction: column; } .input_header{ display: flex; align-items: center; justify-content: center; position: relative; } .input .input_header select{ position: absolute; right: 5px; } .error{ color: red; font-size: 12px; padding: 0; margin: 0; } .place_description{ height: 200px; padding: 5px; overflow-y: auto; resize: none; } .town_select_cnt{ display: flex; width: 100%; } .town_select_cnt div{ width: 50%; height: 100%; display: flex; flex-direction: row; justify-content: center; align-items: center; } .town_select_cnt div select{ width: 50%; } No newline at end of file Loading
web/src/components/admin_panel_places/admin_panel_place_register/admin_panel_place_register.tsx +156 −7 Original line number Diff line number Diff line Loading @@ -3,13 +3,36 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Dispatch, SetStateAction} from "react"; import "./assets/css/styles.css"; import { MapComponent } from "../../map/map"; import { usePlaceRegister } from "../../../hooks/usePlaceRegister"; import { languaguesList } from "../../../constants/languages"; import { ToastContainer, toast } from "react-toastify"; import { LoadingScreen } from "../../loading_screen/loading_screen"; import { MultipleImagesDropzone } from "../../multiple_images_dropzone/multiple_images_dropzone"; interface props { setIsWindowActive: Dispatch<SetStateAction<boolean>>; } export const AdminPanelPlaceRegister = ({setIsWindowActive}: props) => { const { register, handleSubmit, errors, onSubmit, setValue, languageNameIndexSelected, setLanguageNameIndexSelected, languageDescriptionIndexSelected, setNames, names, descriptions, setDescriptions, setLanguageDescriptionIndexSelected, isLoading, statesList, updateTownsList, townsList, } = usePlaceRegister(); return ( <div className="place_register_wrap"> Loading @@ -19,18 +42,144 @@ export const AdminPanelPlaceRegister = ({setIsWindowActive}: props) => { onClick={() => setIsWindowActive(false)}/> </div> <div className="place_register_body"> <form> <form onSubmit={handleSubmit(onSubmit)}> { isLoading ? <LoadingScreen/> : <div className="inputs_container"> <div className="input"> <div className="input_header"> Nombre del lugar <select onChange={(e) => setLanguageNameIndexSelected(Number(e.target.value))}> {languaguesList.map((language, index) => { return ( <option key={index} value={index}>{language}</option> ); })} </select> </div> { languaguesList.map((language, index) => { if(index===languageNameIndexSelected){ return ( <input type="text" value={names[index]} onChange={(e) => { const updatedNamesList = [...names]; updatedNamesList[index] = e.target.value; setNames(updatedNamesList); setValue("names", updatedNamesList, {shouldValidate: true}); }} /> ); } }) } <p className="error">{errors.names?.message}</p> </div> <div className="input"> <div className="input_header"> Descripción del lugar <select onChange={(e) => setLanguageDescriptionIndexSelected(Number(e.target.value))}> {languaguesList.map((language, index) => { return ( <option key={index} value={index}>{language}</option> ); })} </select> </div> { languaguesList.map((language, index) => { if(index===languageDescriptionIndexSelected){ return ( <textarea id={index.toString()} className="place_description" value={descriptions[index]} onChange={(e) => { const updatedDescriptionsList = [...descriptions]; updatedDescriptionsList[index] = e.target.value; setDescriptions(updatedDescriptionsList); setValue("descriptions", updatedDescriptionsList, {shouldValidate: true}); }} /> ); } }) } <p className="error">{errors.descriptions?.message}</p> </div> <div className="input"> <div className="input_header"> Pueblo mágico al que pertenece el lugar </div> <div className="town_select_cnt"> <div> Estado <select onChange={(event) => { updateTownsList(Number(event.target.value), event.target.options[event.target.selectedIndex].text); }} > {statesList === null || statesList.length===0 ? <option disabled selected value="">No hay estados</option> : <> <option disabled selected value="">Selecciona el estado</option> {statesList.map((state, index) => { return ( <option key={state.stateId} value={state.stateId}>{state.name}</option> ); })} </> } </select> </div> <div> Pueblo mágico <select {...register("idTown")}> { townsList === null || townsList.length===0 ? <option disabled selected value="">No hay pueblos</option> : townsList.map((towns) => { return ( <option key={towns.idTown} value={towns.idTown}>{towns.name}</option> ); }) } </select> </div> </div> <p className="error">{errors.idTown?.message}</p> </div> <MultipleImagesDropzone setValue={setValue}/> <p className="error">{errors.imagesList?.message}</p> <input type="submit"/> </div> } <div className="map_container"> <div className="map"> <MapComponent/> <MapComponent setValue={setValue}/> </div> <div className="map_error_cnt"> <p className="error">{errors.latitude?.message}</p> </div> </div> <ToastContainer position='bottom-right' autoClose = {1000} hideProgressBar = {true} closeOnClick rtl={false} pauseOnFocusLoss /> </form> </div> </div> Loading
web/src/components/admin_panel_places/admin_panel_place_register/assets/css/styles.css +50 −0 Original line number Diff line number Diff line Loading @@ -67,3 +67,53 @@ height: 5%; width: 100%; } .input{ width: 100%; display: flex; flex-direction: column; } .input_header{ display: flex; align-items: center; justify-content: center; position: relative; } .input .input_header select{ position: absolute; right: 5px; } .error{ color: red; font-size: 12px; padding: 0; margin: 0; } .place_description{ height: 200px; padding: 5px; overflow-y: auto; resize: none; } .town_select_cnt{ display: flex; width: 100%; } .town_select_cnt div{ width: 50%; height: 100%; display: flex; flex-direction: row; justify-content: center; align-items: center; } .town_select_cnt div select{ width: 50%; } No newline at end of file