Loading web/package-lock.json +17 −69 Original line number Diff line number Diff line Loading @@ -11,7 +11,6 @@ "@fortawesome/free-solid-svg-icons": "^6.5.1", "@fortawesome/react-fontawesome": "^0.2.0", "@hookform/resolvers": "^3.3.4", "@react-google-maps/api": "^2.19.3", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", Loading @@ -19,6 +18,7 @@ "@types/node": "^16.18.87", "@types/react": "^18.2.64", "@types/react-dom": "^18.2.21", "@vis.gl/react-google-maps": "^1.1.0", "axios": "^1.6.8", "react": "^18.2.0", "react-data-table-component": "^7.6.2", Loading Loading @@ -2599,23 +2599,6 @@ "react": ">=16.3" } }, "node_modules/@googlemaps/js-api-loader": { "version": "1.16.2", "resolved": "https://registry.npmjs.org/@googlemaps/js-api-loader/-/js-api-loader-1.16.2.tgz", "integrity": "sha512-psGw5u0QM6humao48Hn4lrChOM2/rA43ZCm3tKK9qQsEj1/VzqkCqnvGfEOshDbBQflydfaRovbKwZMF4AyqbA==", "dependencies": { "fast-deep-equal": "^3.1.3" } }, "node_modules/@googlemaps/markerclusterer": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/@googlemaps/markerclusterer/-/markerclusterer-2.5.3.tgz", "integrity": "sha512-x7lX0R5yYOoiNectr10wLgCBasNcXFHiADIBdmn7jQllF2B5ENQw5XtZK+hIw4xnV0Df0xhN4LN98XqA5jaiOw==", "dependencies": { "fast-deep-equal": "^3.1.3", "supercluster": "^8.0.1" } }, "node_modules/@hookform/resolvers": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.3.4.tgz", Loading Loading @@ -3590,33 +3573,6 @@ "url": "https://opencollective.com/popperjs" } }, "node_modules/@react-google-maps/api": { "version": "2.19.3", "resolved": "https://registry.npmjs.org/@react-google-maps/api/-/api-2.19.3.tgz", "integrity": "sha512-jiLqvuOt5lOowkLeq7d077AByTyJp+s6hZVlLhlq7SBacBD37aUNpXBz2OsazfeR6Aw4a+9RRhAEjEFvrR1f5A==", "dependencies": { "@googlemaps/js-api-loader": "1.16.2", "@googlemaps/markerclusterer": "2.5.3", "@react-google-maps/infobox": "2.19.2", "@react-google-maps/marker-clusterer": "2.19.2", "@types/google.maps": "3.55.2", "invariant": "2.2.4" }, "peerDependencies": { "react": "^16.8 || ^17 || ^18", "react-dom": "^16.8 || ^17 || ^18" } }, "node_modules/@react-google-maps/infobox": { "version": "2.19.2", "resolved": "https://registry.npmjs.org/@react-google-maps/infobox/-/infobox-2.19.2.tgz", "integrity": "sha512-6wvBqeJsQ/eFSvoxg+9VoncQvNoVCdmxzxRpLvmjPD+nNC6mHM0vJH1xSqaKijkMrfLJT0nfkTGpovrF896jwg==" }, "node_modules/@react-google-maps/marker-clusterer": { "version": "2.19.2", "resolved": "https://registry.npmjs.org/@react-google-maps/marker-clusterer/-/marker-clusterer-2.19.2.tgz", "integrity": "sha512-x9ibmsP0ZVqzyCo1Pitbw+4b6iEXRw/r1TCy3vOUR3eKrzWLnHYZMR325BkZW2r8fnuWE/V3Fp4QZOP9qYORCw==" }, "node_modules/@remix-run/router": { "version": "1.15.3", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.3.tgz", Loading Loading @@ -4383,9 +4339,9 @@ } }, "node_modules/@types/google.maps": { "version": "3.55.2", "resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.55.2.tgz", "integrity": "sha512-JcTwzkxskR8DN/nnX96Pie3gGN3WHiPpuxzuQ9z3516o1bB243d8w8DHUJ8BohuzoT1o3HUFta2ns/mkZC8KRw==" "version": "3.55.11", "resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.55.11.tgz", "integrity": "sha512-F3VuPtjKj4UGuyym75pqmgPBOHbT/i7I6/D+4DdtSzbeu2aWZG1ENwpbZOd46uO+PSAz9flJEhxxi+b4MVb4gQ==" }, "node_modules/@types/graceful-fs": { "version": "4.1.9", Loading Loading @@ -4845,6 +4801,19 @@ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" }, "node_modules/@vis.gl/react-google-maps": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@vis.gl/react-google-maps/-/react-google-maps-1.1.0.tgz", "integrity": "sha512-MxDIhCfPRzTQY1c6sS0GFg8Ukl40o13fkIKEaCN0cR1BIrV4LPo+EuCov9WElbe0bOo8MApx5qAbqBKOmLQyKg==", "dependencies": { "@types/google.maps": "^3.54.10", "fast-deep-equal": "^3.1.3" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "node_modules/@webassemblyjs/ast": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", Loading Loading @@ -9727,14 +9696,6 @@ "node": ">= 0.4" } }, "node_modules/invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "dependencies": { "loose-envify": "^1.0.0" } }, "node_modules/ipaddr.js": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", Loading Loading @@ -12452,11 +12413,6 @@ "node": ">=4.0" } }, "node_modules/kdbush": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz", "integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==" }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", Loading Loading @@ -16913,14 +16869,6 @@ "url": "https://github.com/sponsors/isaacs" } }, "node_modules/supercluster": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-8.0.1.tgz", "integrity": "sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==", "dependencies": { "kdbush": "^4.0.2" } }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", web/package.json +1 −1 Original line number Diff line number Diff line Loading @@ -6,7 +6,6 @@ "@fortawesome/free-solid-svg-icons": "^6.5.1", "@fortawesome/react-fontawesome": "^0.2.0", "@hookform/resolvers": "^3.3.4", "@react-google-maps/api": "^2.19.3", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", Loading @@ -14,6 +13,7 @@ "@types/node": "^16.18.87", "@types/react": "^18.2.64", "@types/react-dom": "^18.2.21", "@vis.gl/react-google-maps": "^1.1.0", "axios": "^1.6.8", "react": "^18.2.0", "react-data-table-component": "^7.6.2", Loading web/src/components/admin_panel_places/admin_panel_place_list/admin_panel_place_list.tsx +36 −4 Original line number Diff line number Diff line Loading @@ -3,16 +3,34 @@ import { usePlace } from '../../../hooks/usePlace'; import './assets/css/styles.css'; import { Place } from '../../../infraestructure/entities/place'; import { LoadingSpinner } from '../../loading_spinner/loading_spinner'; import { faEdit } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Dispatch, SetStateAction, useEffect } from 'react'; interface props{ idTown: number; isWindowActive: boolean; setIsWindowActive: Dispatch<SetStateAction<boolean>>; setActualPlace: Dispatch<SetStateAction<Place | undefined>>; setIsRegisterPane: Dispatch<SetStateAction<boolean>>; } export const AdminPanelPlaceList = ({idTown}: props) => { export const AdminPanelPlaceList = ({idTown, isWindowActive, setIsWindowActive, setActualPlace, setIsRegisterPane}: props) => { const { placeList, pending } = usePlace(idTown); pending, updatePlacesByTown } = usePlace(); const handleEditSelectedCategory = (place: Place) => { setIsRegisterPane(false); setActualPlace(place); setIsWindowActive(true); } useEffect(() => { updatePlacesByTown(idTown); },[]); const columns : TableColumn<Place>[] = [ { Loading @@ -27,6 +45,20 @@ export const AdminPanelPlaceList = ({idTown}: props) => { { name: "Estado", selector: row => row.available }, { name: "Acciones", cell: (row) => { return ( <FontAwesomeIcon style={isWindowActive ? {color: 'gray'}: {cursor: 'pointer'}} icon={faEdit} onClick={() => { if(!isWindowActive){ handleEditSelectedCategory(row); } }} /> ); } } ]; Loading @@ -36,7 +68,7 @@ export const AdminPanelPlaceList = ({idTown}: props) => { progressComponent={ <LoadingSpinner style={{display: 'flex'}}/> } columns={columns} data={placeList} selectableRows className="data_table"/> columns={columns} data={placeList} className="data_table"/> </div> ); } No newline at end of file web/src/components/admin_panel_places/admin_panel_place_register/admin_panel_place_register.tsx +196 −142 Original line number Diff line number Diff line import { faWindowClose } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Dispatch, SetStateAction, useState} from "react"; import { Dispatch, SetStateAction, useEffect, useState} from "react"; import "./assets/css/styles.css"; import { MapComponent } from "../../map/map"; import { usePlace } from "../../../hooks/usePlace"; import { languaguesList } from "../../../constants/languages"; import { LoadingScreen } from "../../loading_screen/loading_screen"; import { MultipleImagesDropzone } from "../../multiple_images_dropzone/multiple_images_dropzone"; import { AvailableDays, availableDaysList } from "../../../infraestructure/entities/place"; import { AvailableDays, availableDaysList, EmptyPlace, Place } from "../../../infraestructure/entities/place"; import { Category } from "../../../infraestructure/entities/category"; interface props { Loading @@ -15,31 +15,40 @@ interface props { categoriesList: Category[]; idTown: number; forceRenderList: () => void; isRegister: boolean; form?: Place; } export const AdminPanelPlaceRegister = ({setIsWindowActive, idTown, categoriesList, forceRenderList}: props) => { export const AdminPanelPlaceRegister = ({setIsWindowActive, idTown, categoriesList, forceRenderList, isRegister, form}: props) => { const { register, handleSubmit, errors, onSubmit, setValue, languageDescriptionIndexSelected, descriptions, setDescriptions, setLanguageDescriptionIndexSelected, isLoading, updateTimeForm, availableDays, setAvailableDays, resetField, categoriesId, setCategoriesId, } = usePlace(idTown, forceRenderList, setIsWindowActive); getPlaceById, onSubmitRegister, onSubmitUpdate, clearErrors } = usePlace(forceRenderList, setIsWindowActive); const [clickedCategories, setClickedCategories] = useState<boolean[]>(new Array(categoriesList.length).fill(false)); const [isLoading, setIsLoading] = useState(false); const [actualPlace, setActualPlace] = useState<Place>(EmptyPlace); const [openHourInput, setOpenHourInput] = useState(''); const [closeHourInput, setCloseHourInput] = useState(''); const onClickCategory = (idCategory: number, indexList: number) => { const onClickCategory = (idCategory: number) => { const index = categoriesId.indexOf(idCategory); const indexList = categoriesList.findIndex(category => category.idCategory === idCategory); const clickedCategoriesBackup = clickedCategories.map((clickedCategory, index)=> { if(index === indexList){ return !clickedCategory; Loading @@ -61,6 +70,43 @@ export const AdminPanelPlaceRegister = ({setIsWindowActive, idTown, categoriesLi setClickedCategories(clickedCategoriesBackup); } useEffect(() => { setIsLoading(true); const fetchData = async () => { setValue('idTown', idTown); if (!isRegister && form) { const placeGetted = await getPlaceById(form.idPlace || 0); if(placeGetted){ setActualPlace(placeGetted); setValue('idPlace', placeGetted.idPlace); setValue('name', placeGetted.name); setValue('descriptions', placeGetted.descriptions); setDescriptions(placeGetted.descriptions || ['', '']); setValue('openAt', placeGetted.openAt); setOpenHourInput(placeGetted.openAt < 10 ? `0${placeGetted.openAt}:00` : `${placeGetted.openAt}:00`); setCloseHourInput(placeGetted.closeAt < 10 ? `0${placeGetted.closeAt}:00` : `${placeGetted.closeAt}:00`); setValue('closeAt', placeGetted.closeAt); setValue('available', placeGetted.available); setAvailableDays(placeGetted.available); const clickedCategoriesBackup : boolean[] = []; categoriesList.forEach((category) => { if(placeGetted.categoriesId.indexOf(category.idCategory) > -1){ clickedCategoriesBackup.push(true); }else{ clickedCategoriesBackup.push(false); } }); setClickedCategories(clickedCategoriesBackup); setCategoriesId(placeGetted.categoriesId); } } else { setValue('available', availableDays, { shouldValidate: true }); } }; fetchData(); setIsLoading(false); },[]); return ( <div className="place_register_wrap"> <div className="place_register_header"> Loading @@ -69,12 +115,11 @@ export const AdminPanelPlaceRegister = ({setIsWindowActive, idTown, categoriesLi onClick={() => setIsWindowActive(false)}/> </div> <div className="place_register_body"> <form onSubmit={handleSubmit(onSubmit)}> { isLoading {isLoading ? <LoadingScreen/> : <form onSubmit={handleSubmit(isRegister ? onSubmitRegister : onSubmitUpdate)}> <div className="inputs_container"> <div className="input"> <div className="input_header"> Loading Loading @@ -131,7 +176,9 @@ export const AdminPanelPlaceRegister = ({setIsWindowActive, idTown, categoriesLi <input type="time" autoComplete="off" value={openHourInput} onChange={(event) => { setOpenHourInput(event.target.value); updateTimeForm(event.target.value, true); }} /> Loading @@ -142,7 +189,9 @@ export const AdminPanelPlaceRegister = ({setIsWindowActive, idTown, categoriesLi <input type="time" autoComplete="off" value={closeHourInput} onChange={(event) => { setCloseHourInput(event.target.value); updateTimeForm(event.target.value, false); }} /> Loading @@ -163,7 +212,7 @@ export const AdminPanelPlaceRegister = ({setIsWindowActive, idTown, categoriesLi > {availableDaysList.map((option, index) => { return ( <option key={index} value={index}>{option.name}</option> <option key={index} selected={option.option===actualPlace.available} value={index}>{option.name}</option> ); })} </select> Loading @@ -177,11 +226,13 @@ export const AdminPanelPlaceRegister = ({setIsWindowActive, idTown, categoriesLi Inicio <input type="date" defaultValue={actualPlace.startDate?.toString().substring(0,10)} {...register('startDate')} /> Cierre <input type="date" defaultValue={actualPlace.endDate?.toString().substring(0,10)} {...register('endDate')} /> </div> Loading @@ -202,10 +253,10 @@ export const AdminPanelPlaceRegister = ({setIsWindowActive, idTown, categoriesLi categoriesList.map((category, index) => { return ( <div className="category_item" onClick={() => onClickCategory(category.idCategory, index)} onClick={() => onClickCategory(category.idCategory)} style={clickedCategories[index] ? {border: '2px solid blue'} : {border: '1px solid black'}} > {category.nameES} {category.nameES + " " + category.idCategory} </div> ); }) Loading @@ -215,21 +266,24 @@ export const AdminPanelPlaceRegister = ({setIsWindowActive, idTown, categoriesLi <p className="error">{errors.categoriesId?.message}</p> </div> <MultipleImagesDropzone setValue={setValue}/> <MultipleImagesDropzone setValue={setValue} imagesList={actualPlace.imagesList}/> <p className="error">{errors.imagesList?.message}</p> <input type="submit"/> </div> } <div className="map_container"> <div className="map"> <MapComponent setValue={setValue}/> <MapComponent setValue={setValue} setIsLoading={setIsLoading} latitude={actualPlace.latitude} longitude={actualPlace.longitude} clearErrors={clearErrors}/> </div> <div className="map_error_cnt"> <p className="error">{errors.latitude?.message}</p> </div> </div> </form> } </div> </div> ); Loading web/src/components/admin_panel_places/admin_panel_place_register/assets/css/styles.css +1 −1 Original line number Diff line number Diff line Loading @@ -95,7 +95,7 @@ } .place_description{ height: 130px; height: 100px; padding: 5px; overflow-y: auto; resize: none; Loading Loading
web/package-lock.json +17 −69 Original line number Diff line number Diff line Loading @@ -11,7 +11,6 @@ "@fortawesome/free-solid-svg-icons": "^6.5.1", "@fortawesome/react-fontawesome": "^0.2.0", "@hookform/resolvers": "^3.3.4", "@react-google-maps/api": "^2.19.3", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", Loading @@ -19,6 +18,7 @@ "@types/node": "^16.18.87", "@types/react": "^18.2.64", "@types/react-dom": "^18.2.21", "@vis.gl/react-google-maps": "^1.1.0", "axios": "^1.6.8", "react": "^18.2.0", "react-data-table-component": "^7.6.2", Loading Loading @@ -2599,23 +2599,6 @@ "react": ">=16.3" } }, "node_modules/@googlemaps/js-api-loader": { "version": "1.16.2", "resolved": "https://registry.npmjs.org/@googlemaps/js-api-loader/-/js-api-loader-1.16.2.tgz", "integrity": "sha512-psGw5u0QM6humao48Hn4lrChOM2/rA43ZCm3tKK9qQsEj1/VzqkCqnvGfEOshDbBQflydfaRovbKwZMF4AyqbA==", "dependencies": { "fast-deep-equal": "^3.1.3" } }, "node_modules/@googlemaps/markerclusterer": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/@googlemaps/markerclusterer/-/markerclusterer-2.5.3.tgz", "integrity": "sha512-x7lX0R5yYOoiNectr10wLgCBasNcXFHiADIBdmn7jQllF2B5ENQw5XtZK+hIw4xnV0Df0xhN4LN98XqA5jaiOw==", "dependencies": { "fast-deep-equal": "^3.1.3", "supercluster": "^8.0.1" } }, "node_modules/@hookform/resolvers": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.3.4.tgz", Loading Loading @@ -3590,33 +3573,6 @@ "url": "https://opencollective.com/popperjs" } }, "node_modules/@react-google-maps/api": { "version": "2.19.3", "resolved": "https://registry.npmjs.org/@react-google-maps/api/-/api-2.19.3.tgz", "integrity": "sha512-jiLqvuOt5lOowkLeq7d077AByTyJp+s6hZVlLhlq7SBacBD37aUNpXBz2OsazfeR6Aw4a+9RRhAEjEFvrR1f5A==", "dependencies": { "@googlemaps/js-api-loader": "1.16.2", "@googlemaps/markerclusterer": "2.5.3", "@react-google-maps/infobox": "2.19.2", "@react-google-maps/marker-clusterer": "2.19.2", "@types/google.maps": "3.55.2", "invariant": "2.2.4" }, "peerDependencies": { "react": "^16.8 || ^17 || ^18", "react-dom": "^16.8 || ^17 || ^18" } }, "node_modules/@react-google-maps/infobox": { "version": "2.19.2", "resolved": "https://registry.npmjs.org/@react-google-maps/infobox/-/infobox-2.19.2.tgz", "integrity": "sha512-6wvBqeJsQ/eFSvoxg+9VoncQvNoVCdmxzxRpLvmjPD+nNC6mHM0vJH1xSqaKijkMrfLJT0nfkTGpovrF896jwg==" }, "node_modules/@react-google-maps/marker-clusterer": { "version": "2.19.2", "resolved": "https://registry.npmjs.org/@react-google-maps/marker-clusterer/-/marker-clusterer-2.19.2.tgz", "integrity": "sha512-x9ibmsP0ZVqzyCo1Pitbw+4b6iEXRw/r1TCy3vOUR3eKrzWLnHYZMR325BkZW2r8fnuWE/V3Fp4QZOP9qYORCw==" }, "node_modules/@remix-run/router": { "version": "1.15.3", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.3.tgz", Loading Loading @@ -4383,9 +4339,9 @@ } }, "node_modules/@types/google.maps": { "version": "3.55.2", "resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.55.2.tgz", "integrity": "sha512-JcTwzkxskR8DN/nnX96Pie3gGN3WHiPpuxzuQ9z3516o1bB243d8w8DHUJ8BohuzoT1o3HUFta2ns/mkZC8KRw==" "version": "3.55.11", "resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.55.11.tgz", "integrity": "sha512-F3VuPtjKj4UGuyym75pqmgPBOHbT/i7I6/D+4DdtSzbeu2aWZG1ENwpbZOd46uO+PSAz9flJEhxxi+b4MVb4gQ==" }, "node_modules/@types/graceful-fs": { "version": "4.1.9", Loading Loading @@ -4845,6 +4801,19 @@ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" }, "node_modules/@vis.gl/react-google-maps": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@vis.gl/react-google-maps/-/react-google-maps-1.1.0.tgz", "integrity": "sha512-MxDIhCfPRzTQY1c6sS0GFg8Ukl40o13fkIKEaCN0cR1BIrV4LPo+EuCov9WElbe0bOo8MApx5qAbqBKOmLQyKg==", "dependencies": { "@types/google.maps": "^3.54.10", "fast-deep-equal": "^3.1.3" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "node_modules/@webassemblyjs/ast": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", Loading Loading @@ -9727,14 +9696,6 @@ "node": ">= 0.4" } }, "node_modules/invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "dependencies": { "loose-envify": "^1.0.0" } }, "node_modules/ipaddr.js": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", Loading Loading @@ -12452,11 +12413,6 @@ "node": ">=4.0" } }, "node_modules/kdbush": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz", "integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==" }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", Loading Loading @@ -16913,14 +16869,6 @@ "url": "https://github.com/sponsors/isaacs" } }, "node_modules/supercluster": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-8.0.1.tgz", "integrity": "sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==", "dependencies": { "kdbush": "^4.0.2" } }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
web/package.json +1 −1 Original line number Diff line number Diff line Loading @@ -6,7 +6,6 @@ "@fortawesome/free-solid-svg-icons": "^6.5.1", "@fortawesome/react-fontawesome": "^0.2.0", "@hookform/resolvers": "^3.3.4", "@react-google-maps/api": "^2.19.3", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", Loading @@ -14,6 +13,7 @@ "@types/node": "^16.18.87", "@types/react": "^18.2.64", "@types/react-dom": "^18.2.21", "@vis.gl/react-google-maps": "^1.1.0", "axios": "^1.6.8", "react": "^18.2.0", "react-data-table-component": "^7.6.2", Loading
web/src/components/admin_panel_places/admin_panel_place_list/admin_panel_place_list.tsx +36 −4 Original line number Diff line number Diff line Loading @@ -3,16 +3,34 @@ import { usePlace } from '../../../hooks/usePlace'; import './assets/css/styles.css'; import { Place } from '../../../infraestructure/entities/place'; import { LoadingSpinner } from '../../loading_spinner/loading_spinner'; import { faEdit } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Dispatch, SetStateAction, useEffect } from 'react'; interface props{ idTown: number; isWindowActive: boolean; setIsWindowActive: Dispatch<SetStateAction<boolean>>; setActualPlace: Dispatch<SetStateAction<Place | undefined>>; setIsRegisterPane: Dispatch<SetStateAction<boolean>>; } export const AdminPanelPlaceList = ({idTown}: props) => { export const AdminPanelPlaceList = ({idTown, isWindowActive, setIsWindowActive, setActualPlace, setIsRegisterPane}: props) => { const { placeList, pending } = usePlace(idTown); pending, updatePlacesByTown } = usePlace(); const handleEditSelectedCategory = (place: Place) => { setIsRegisterPane(false); setActualPlace(place); setIsWindowActive(true); } useEffect(() => { updatePlacesByTown(idTown); },[]); const columns : TableColumn<Place>[] = [ { Loading @@ -27,6 +45,20 @@ export const AdminPanelPlaceList = ({idTown}: props) => { { name: "Estado", selector: row => row.available }, { name: "Acciones", cell: (row) => { return ( <FontAwesomeIcon style={isWindowActive ? {color: 'gray'}: {cursor: 'pointer'}} icon={faEdit} onClick={() => { if(!isWindowActive){ handleEditSelectedCategory(row); } }} /> ); } } ]; Loading @@ -36,7 +68,7 @@ export const AdminPanelPlaceList = ({idTown}: props) => { progressComponent={ <LoadingSpinner style={{display: 'flex'}}/> } columns={columns} data={placeList} selectableRows className="data_table"/> columns={columns} data={placeList} className="data_table"/> </div> ); } No newline at end of file
web/src/components/admin_panel_places/admin_panel_place_register/admin_panel_place_register.tsx +196 −142 Original line number Diff line number Diff line import { faWindowClose } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Dispatch, SetStateAction, useState} from "react"; import { Dispatch, SetStateAction, useEffect, useState} from "react"; import "./assets/css/styles.css"; import { MapComponent } from "../../map/map"; import { usePlace } from "../../../hooks/usePlace"; import { languaguesList } from "../../../constants/languages"; import { LoadingScreen } from "../../loading_screen/loading_screen"; import { MultipleImagesDropzone } from "../../multiple_images_dropzone/multiple_images_dropzone"; import { AvailableDays, availableDaysList } from "../../../infraestructure/entities/place"; import { AvailableDays, availableDaysList, EmptyPlace, Place } from "../../../infraestructure/entities/place"; import { Category } from "../../../infraestructure/entities/category"; interface props { Loading @@ -15,31 +15,40 @@ interface props { categoriesList: Category[]; idTown: number; forceRenderList: () => void; isRegister: boolean; form?: Place; } export const AdminPanelPlaceRegister = ({setIsWindowActive, idTown, categoriesList, forceRenderList}: props) => { export const AdminPanelPlaceRegister = ({setIsWindowActive, idTown, categoriesList, forceRenderList, isRegister, form}: props) => { const { register, handleSubmit, errors, onSubmit, setValue, languageDescriptionIndexSelected, descriptions, setDescriptions, setLanguageDescriptionIndexSelected, isLoading, updateTimeForm, availableDays, setAvailableDays, resetField, categoriesId, setCategoriesId, } = usePlace(idTown, forceRenderList, setIsWindowActive); getPlaceById, onSubmitRegister, onSubmitUpdate, clearErrors } = usePlace(forceRenderList, setIsWindowActive); const [clickedCategories, setClickedCategories] = useState<boolean[]>(new Array(categoriesList.length).fill(false)); const [isLoading, setIsLoading] = useState(false); const [actualPlace, setActualPlace] = useState<Place>(EmptyPlace); const [openHourInput, setOpenHourInput] = useState(''); const [closeHourInput, setCloseHourInput] = useState(''); const onClickCategory = (idCategory: number, indexList: number) => { const onClickCategory = (idCategory: number) => { const index = categoriesId.indexOf(idCategory); const indexList = categoriesList.findIndex(category => category.idCategory === idCategory); const clickedCategoriesBackup = clickedCategories.map((clickedCategory, index)=> { if(index === indexList){ return !clickedCategory; Loading @@ -61,6 +70,43 @@ export const AdminPanelPlaceRegister = ({setIsWindowActive, idTown, categoriesLi setClickedCategories(clickedCategoriesBackup); } useEffect(() => { setIsLoading(true); const fetchData = async () => { setValue('idTown', idTown); if (!isRegister && form) { const placeGetted = await getPlaceById(form.idPlace || 0); if(placeGetted){ setActualPlace(placeGetted); setValue('idPlace', placeGetted.idPlace); setValue('name', placeGetted.name); setValue('descriptions', placeGetted.descriptions); setDescriptions(placeGetted.descriptions || ['', '']); setValue('openAt', placeGetted.openAt); setOpenHourInput(placeGetted.openAt < 10 ? `0${placeGetted.openAt}:00` : `${placeGetted.openAt}:00`); setCloseHourInput(placeGetted.closeAt < 10 ? `0${placeGetted.closeAt}:00` : `${placeGetted.closeAt}:00`); setValue('closeAt', placeGetted.closeAt); setValue('available', placeGetted.available); setAvailableDays(placeGetted.available); const clickedCategoriesBackup : boolean[] = []; categoriesList.forEach((category) => { if(placeGetted.categoriesId.indexOf(category.idCategory) > -1){ clickedCategoriesBackup.push(true); }else{ clickedCategoriesBackup.push(false); } }); setClickedCategories(clickedCategoriesBackup); setCategoriesId(placeGetted.categoriesId); } } else { setValue('available', availableDays, { shouldValidate: true }); } }; fetchData(); setIsLoading(false); },[]); return ( <div className="place_register_wrap"> <div className="place_register_header"> Loading @@ -69,12 +115,11 @@ export const AdminPanelPlaceRegister = ({setIsWindowActive, idTown, categoriesLi onClick={() => setIsWindowActive(false)}/> </div> <div className="place_register_body"> <form onSubmit={handleSubmit(onSubmit)}> { isLoading {isLoading ? <LoadingScreen/> : <form onSubmit={handleSubmit(isRegister ? onSubmitRegister : onSubmitUpdate)}> <div className="inputs_container"> <div className="input"> <div className="input_header"> Loading Loading @@ -131,7 +176,9 @@ export const AdminPanelPlaceRegister = ({setIsWindowActive, idTown, categoriesLi <input type="time" autoComplete="off" value={openHourInput} onChange={(event) => { setOpenHourInput(event.target.value); updateTimeForm(event.target.value, true); }} /> Loading @@ -142,7 +189,9 @@ export const AdminPanelPlaceRegister = ({setIsWindowActive, idTown, categoriesLi <input type="time" autoComplete="off" value={closeHourInput} onChange={(event) => { setCloseHourInput(event.target.value); updateTimeForm(event.target.value, false); }} /> Loading @@ -163,7 +212,7 @@ export const AdminPanelPlaceRegister = ({setIsWindowActive, idTown, categoriesLi > {availableDaysList.map((option, index) => { return ( <option key={index} value={index}>{option.name}</option> <option key={index} selected={option.option===actualPlace.available} value={index}>{option.name}</option> ); })} </select> Loading @@ -177,11 +226,13 @@ export const AdminPanelPlaceRegister = ({setIsWindowActive, idTown, categoriesLi Inicio <input type="date" defaultValue={actualPlace.startDate?.toString().substring(0,10)} {...register('startDate')} /> Cierre <input type="date" defaultValue={actualPlace.endDate?.toString().substring(0,10)} {...register('endDate')} /> </div> Loading @@ -202,10 +253,10 @@ export const AdminPanelPlaceRegister = ({setIsWindowActive, idTown, categoriesLi categoriesList.map((category, index) => { return ( <div className="category_item" onClick={() => onClickCategory(category.idCategory, index)} onClick={() => onClickCategory(category.idCategory)} style={clickedCategories[index] ? {border: '2px solid blue'} : {border: '1px solid black'}} > {category.nameES} {category.nameES + " " + category.idCategory} </div> ); }) Loading @@ -215,21 +266,24 @@ export const AdminPanelPlaceRegister = ({setIsWindowActive, idTown, categoriesLi <p className="error">{errors.categoriesId?.message}</p> </div> <MultipleImagesDropzone setValue={setValue}/> <MultipleImagesDropzone setValue={setValue} imagesList={actualPlace.imagesList}/> <p className="error">{errors.imagesList?.message}</p> <input type="submit"/> </div> } <div className="map_container"> <div className="map"> <MapComponent setValue={setValue}/> <MapComponent setValue={setValue} setIsLoading={setIsLoading} latitude={actualPlace.latitude} longitude={actualPlace.longitude} clearErrors={clearErrors}/> </div> <div className="map_error_cnt"> <p className="error">{errors.latitude?.message}</p> </div> </div> </form> } </div> </div> ); Loading
web/src/components/admin_panel_places/admin_panel_place_register/assets/css/styles.css +1 −1 Original line number Diff line number Diff line Loading @@ -95,7 +95,7 @@ } .place_description{ height: 130px; height: 100px; padding: 5px; overflow-y: auto; resize: none; Loading