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

Se modifican para que se pueda actualizar el lugar

parent b3c8cabc
Loading
Loading
Loading
Loading
+36 −4
Original line number Diff line number Diff line
@@ -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>[] = [
    {
@@ -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);
              }
            }}
          />
        );
      }
    }
  ];

@@ -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
+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 {
@@ -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;
@@ -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">
@@ -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">
@@ -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);
                  }}
                />
@@ -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);
                  }}
                />
@@ -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>
@@ -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>
@@ -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>
                      );
                    })
@@ -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>
  );
+13 −5
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@ import "./assets/css/styles.css";
import { AdminPanelPlaceList } from "../admin_panel_place_list/admin_panel_place_list";
import { Town } from "../../../infraestructure/entities/town";
import { useCategory } from "../../../hooks/useCategory";
import { LoadingScreen } from "../../loading_screen/loading_screen";
import { Place } from "../../../infraestructure/entities/place";

interface props {
  isWindowActive: boolean;
@@ -14,21 +14,22 @@ interface props {

export const AdminPanelPlaceScreen = ({isWindowActive,setIsWindowActive, town}: props) => {
  const [renderCount, setRenderCount] = useState(0);
  const [isRegisterPane, setIsRegisterPane] = useState(true);
  const [actualPlace, setActualPlace] = useState<Place | undefined>();
  const {
    categoriesList,
    updateCategoriesList,
    pending
  } = useCategory();

  const forceRenderList = () =>{
    setRenderCount(prevCount => prevCount + 1);
    setIsWindowActive(false);
  }

  useEffect(()=>{
    updateCategoriesList();
  },[]);

  if(pending) return <LoadingScreen/>

  return (
    <div className="admin_panel_place_content">
@@ -36,7 +37,10 @@ export const AdminPanelPlaceScreen = ({isWindowActive,setIsWindowActive, town}:
        Administrar lugares dentro de Pueblo Mágico
        <button className="place_add_btn"
          disabled={isWindowActive || !town}
          onClick={() => setIsWindowActive(true)}
          onClick={() => {
            setIsRegisterPane(true);
            setIsWindowActive(true);
          }}
        >
          Registrar lugar
        </button>
@@ -48,9 +52,13 @@ export const AdminPanelPlaceScreen = ({isWindowActive,setIsWindowActive, town}:
            idTown={town?.idTown || -1}
            categoriesList={categoriesList}
            forceRenderList={forceRenderList}
            isRegister={isRegisterPane}
            form={actualPlace}
            />
        }
        <AdminPanelPlaceList idTown={town?.idTown || -1} key={renderCount}/>
        <AdminPanelPlaceList idTown={town?.idTown || -1} key={renderCount}
        isWindowActive={isWindowActive} setIsWindowActive={setIsWindowActive}
        setActualPlace={setActualPlace} setIsRegisterPane={setIsRegisterPane}/>
      </div>
    </div>
  );
+39 −38
Original line number Diff line number Diff line
import { GoogleMap, Marker, useLoadScript } from "@react-google-maps/api";
import { useState, useMemo } from "react";
import { useState, Dispatch, SetStateAction, useEffect } from "react";
import { REACT_APP_GOOGLE_API_KEY } from "../../constants/api_keys";
import { LoadingScreen } from "../loading_screen/loading_screen";
import { UseFormSetValue } from "react-hook-form";
import { UseFormClearErrors, UseFormSetValue } from "react-hook-form";
import { Place } from "../../infraestructure/entities/place";
import { APIProvider, Map, Marker } from "@vis.gl/react-google-maps";

interface props{
  setValue: UseFormSetValue<Place>;
  setIsLoading: Dispatch<SetStateAction<boolean>>;
  clearErrors: UseFormClearErrors<Place>;
  latitude?: number;
  longitude?: number;
}

export const MapComponent = ({setValue}: props) => {
  const {isLoaded} = useLoadScript({
    googleMapsApiKey: REACT_APP_GOOGLE_API_KEY
  });
  const [marker, setMarker] = useState(false);
  const [latitude, setLatitude] = useState(0.0);
  const [longitude, setLongitude] = useState(0.0);
  const updateMarker = (event: google.maps.MapMouseEvent) => {
    if (event.latLng) {
      setMarker(true);
      setLatitude(event.latLng.lat());
      setLongitude(event.latLng.lng());
      setValue("latitude", event.latLng.lat(), {shouldValidate: true});
      setValue("longitude", event.latLng.lng(), {shouldValidate: true});
export interface Position{
  latitude: number;
  longitude: number;
}

export const MapComponent = ({setValue, setIsLoading, latitude, longitude, clearErrors}: props) => {
  const [position, setPosition] = useState<Position>({latitude: 0.0, longitude: 0.0});
  const center = {lat: 23.687, lng: -102.74};

  useEffect(() => {
    if(latitude && longitude){
      setPosition({latitude, longitude});
    }
  }, [latitude]);

  const center  = useMemo(() => (
    {lat: 23.687, lng: -102.74}
  ),[])
  useEffect(() => {
    setValue('latitude',position.latitude);
    setValue('longitude',position.longitude);
    clearErrors('latitude');
    clearErrors('longitude');
  },[position]);

  return (
    <APIProvider apiKey={REACT_APP_GOOGLE_API_KEY} onLoad={() => setIsLoading(false)}>
      <div style={{width: '100%', height: '100%'}}>
      {!isLoaded
      ?
        <LoadingScreen/>
      :
        <GoogleMap
          center={center}
          zoom={8}
          mapContainerStyle={{height: '100%'}}
          onClick={updateMarker}
        >
          {marker && <Marker position={{lat: latitude, lng: longitude}}/>}
        </GoogleMap>
      }
        <Map defaultCenter={center} defaultZoom={8} gestureHandling={'greedy'}
        disableDefaultUI={true} onClick={(event)=> {
          const lat = event.detail.latLng?.lat || 0.0;
          const lng = event.detail.latLng?.lng || 0.0;
          setPosition({latitude: lat, longitude: lng});
        }}>
          <Marker position={{lat: position.latitude, lng: position.longitude}}/>
        </Map>
      </div>
    </APIProvider>
  );
}
 No newline at end of file
+3 −6
Original line number Diff line number Diff line
@@ -7,15 +7,16 @@ import { faTimesCircle } from "@fortawesome/free-solid-svg-icons";

interface props{
  setValue: UseFormSetValue<Place>;
  imagesList?: File[] | string[];
}

export const MultipleImagesDropzone = ({setValue}:props) => {
export const MultipleImagesDropzone = ({setValue, imagesList}:props) => {
  const {
    getRootProps, 
    getInputProps,
    imagesFiles,
    removeImage,
  } = useDropzoneMultiplesImages(setValue);
  } = useDropzoneMultiplesImages(setValue, imagesList);

  return (
    <div className="multiple_images_dropzone_root">
@@ -25,14 +26,10 @@ export const MultipleImagesDropzone = ({setValue}:props) => {
      </div>
      <div className="previews_list_cnt">
        {
          imagesFiles &&
          imagesFiles.map((image, index) => {
            return (
              <div className="preview"
                key={index}
                onClick={() => {
                  
                }}
              >
                <div className="preview_inner">
                  <img
Loading