Loading web/src/domain/useCase/usePlace.ts +9 −0 Original line number Diff line number Diff line Loading @@ -234,6 +234,14 @@ export const usePlace = ( }); }; // Delete a place const deletePlace = async (idPlace: number) => { await placeRepository.deletePlace(idPlace); if (forceRenderList) { forceRenderList(); } }; // Handle form submission for updating a place const onSubmitUpdate: SubmitHandler<Place> = (data: Place) => { const fetch = async () => { Loading Loading @@ -338,5 +346,6 @@ export const usePlace = ( setCategoriesId, getPlaceById, getValues, deletePlace, }; }; web/src/presentation/admin/admin_panel_places/admin_panel_place_list/admin_panel_place_list.tsx +77 −15 Original line number Diff line number Diff line Loading @@ -4,15 +4,18 @@ import { usePlace } from "../../../../domain/useCase/usePlace"; import "./assets/css/styles.css"; import { Place } from "../../../../data/datasource/api/entities/place"; import { LoadingSpinner } from "../../../components/loading_spinner/loading_spinner"; import { faEdit } from "@fortawesome/free-solid-svg-icons"; import { faEdit, faTrash } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Dispatch, SetStateAction, useEffect } from "react"; import { Dispatch, SetStateAction, useEffect, useState } from "react"; import { toast } from "react-toastify"; import { ConfirmationDialog } from "../../../components/confirmation_dialog_box/confirmation_dialog"; // Define the props interface for the component interface props { idTown: number; isWindowActive: boolean; setWindowVisibility: (visibility: boolean) => void; setIsWindowActiveDelete: Dispatch<SetStateAction<boolean>>; setActualPlace: Dispatch<SetStateAction<Place | undefined>>; setIsRegisterPane: Dispatch<SetStateAction<boolean>>; } Loading @@ -24,17 +27,58 @@ export const AdminPanelPlaceList = ({ setWindowVisibility, setActualPlace, setIsRegisterPane, setIsWindowActiveDelete, }: props) => { // Use the custom hook to fetch place data const { placeList, pending, updatePlacesByTown } = usePlace(); const { placeList, pending, updatePlacesByTown, deletePlace } = usePlace(); // State variables for managing dialog and deletion const [isDialogOpen, setIsDialogOpen] = useState(false); const [dialogMessage, setDialogMessage] = useState(""); const [placeDeleted, setPlaceDeleted] = useState<Place | null>(null); const [deletePlaceBool, setDeletePlaceBool] = useState(false); // Handle the edit action for a selected place const handleEditSelectedCategory = (place: Place) => { const handleEditSelectedPlace = (place: Place) => { setIsRegisterPane(false); setActualPlace(place); setWindowVisibility(true); }; // Function to delete the selected place with a toast notification const deleteSelectedPlace = (place: Place) => { toast.promise(deletePlace(place.idPlace || -1), { pending: "Eliminando categoría...", success: "La categoría se ha eliminado correctamente", error: "No se pudo eliminar la categoría", }); }; // Effect to handle Place deletion when deletePlaceBool changes useEffect(() => { if (deletePlaceBool && placeDeleted) { deleteSelectedPlace(placeDeleted); setDeletePlaceBool(false); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [deletePlaceBool]); // Function to close the confirmation dialog const handleToClose = () => { setIsWindowActiveDelete(false); setIsDialogOpen(false); }; // Function to handle the delete action and open the confirmation dialog const handleDeleteSelectedPlace = (place: Place) => { setDialogMessage( `¿Desea eliminar el lugar ${place.name}?\nEsto eliminará todos los datos relacionados a este lugar.` ); setPlaceDeleted(place); setIsDialogOpen(true); setIsWindowActiveDelete(true); }; // Fetch the places when the component mounts useEffect(() => { updatePlacesByTown(idTown); Loading @@ -50,7 +94,6 @@ export const AdminPanelPlaceList = ({ { name: "Nombre", selector: (row) => row.name, sortable: true, }, { name: "Estado", Loading @@ -60,15 +103,27 @@ export const AdminPanelPlaceList = ({ name: "Acciones", cell: (row) => { return ( <> <FontAwesomeIcon style={isWindowActive ? { color: "gray" } : { cursor: "pointer" }} icon={faTrash} onClick={() => { if (!isWindowActive) { handleDeleteSelectedPlace(row); } }} /> <span style={{ margin: "0 10px" }}></span> {/* Separation between icons */} <FontAwesomeIcon style={isWindowActive ? { color: "gray" } : { cursor: "pointer" }} icon={faEdit} onClick={() => { if (!isWindowActive) { handleEditSelectedCategory(row); handleEditSelectedPlace(row); } }} /> </> ); }, }, Loading @@ -85,6 +140,13 @@ export const AdminPanelPlaceList = ({ data={placeList} className="data_table" /> {isDialogOpen && ( <ConfirmationDialog handleToClose={handleToClose} setAnswer={setDeletePlaceBool} message={dialogMessage} /> )} </div> ); }; web/src/presentation/admin/admin_panel_places/admin_panel_place_screen/admin_panel_place_screen.tsx +1 −0 Original line number Diff line number Diff line Loading @@ -78,6 +78,7 @@ export const AdminPanelPlaceScreen = ({ setWindowVisibility={setWindowVisibility} setActualPlace={setActualPlace} setIsRegisterPane={setIsRegisterPane} setIsWindowActiveDelete={setIsWindowActive} /> </div> </div> Loading Loading
web/src/domain/useCase/usePlace.ts +9 −0 Original line number Diff line number Diff line Loading @@ -234,6 +234,14 @@ export const usePlace = ( }); }; // Delete a place const deletePlace = async (idPlace: number) => { await placeRepository.deletePlace(idPlace); if (forceRenderList) { forceRenderList(); } }; // Handle form submission for updating a place const onSubmitUpdate: SubmitHandler<Place> = (data: Place) => { const fetch = async () => { Loading Loading @@ -338,5 +346,6 @@ export const usePlace = ( setCategoriesId, getPlaceById, getValues, deletePlace, }; };
web/src/presentation/admin/admin_panel_places/admin_panel_place_list/admin_panel_place_list.tsx +77 −15 Original line number Diff line number Diff line Loading @@ -4,15 +4,18 @@ import { usePlace } from "../../../../domain/useCase/usePlace"; import "./assets/css/styles.css"; import { Place } from "../../../../data/datasource/api/entities/place"; import { LoadingSpinner } from "../../../components/loading_spinner/loading_spinner"; import { faEdit } from "@fortawesome/free-solid-svg-icons"; import { faEdit, faTrash } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Dispatch, SetStateAction, useEffect } from "react"; import { Dispatch, SetStateAction, useEffect, useState } from "react"; import { toast } from "react-toastify"; import { ConfirmationDialog } from "../../../components/confirmation_dialog_box/confirmation_dialog"; // Define the props interface for the component interface props { idTown: number; isWindowActive: boolean; setWindowVisibility: (visibility: boolean) => void; setIsWindowActiveDelete: Dispatch<SetStateAction<boolean>>; setActualPlace: Dispatch<SetStateAction<Place | undefined>>; setIsRegisterPane: Dispatch<SetStateAction<boolean>>; } Loading @@ -24,17 +27,58 @@ export const AdminPanelPlaceList = ({ setWindowVisibility, setActualPlace, setIsRegisterPane, setIsWindowActiveDelete, }: props) => { // Use the custom hook to fetch place data const { placeList, pending, updatePlacesByTown } = usePlace(); const { placeList, pending, updatePlacesByTown, deletePlace } = usePlace(); // State variables for managing dialog and deletion const [isDialogOpen, setIsDialogOpen] = useState(false); const [dialogMessage, setDialogMessage] = useState(""); const [placeDeleted, setPlaceDeleted] = useState<Place | null>(null); const [deletePlaceBool, setDeletePlaceBool] = useState(false); // Handle the edit action for a selected place const handleEditSelectedCategory = (place: Place) => { const handleEditSelectedPlace = (place: Place) => { setIsRegisterPane(false); setActualPlace(place); setWindowVisibility(true); }; // Function to delete the selected place with a toast notification const deleteSelectedPlace = (place: Place) => { toast.promise(deletePlace(place.idPlace || -1), { pending: "Eliminando categoría...", success: "La categoría se ha eliminado correctamente", error: "No se pudo eliminar la categoría", }); }; // Effect to handle Place deletion when deletePlaceBool changes useEffect(() => { if (deletePlaceBool && placeDeleted) { deleteSelectedPlace(placeDeleted); setDeletePlaceBool(false); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [deletePlaceBool]); // Function to close the confirmation dialog const handleToClose = () => { setIsWindowActiveDelete(false); setIsDialogOpen(false); }; // Function to handle the delete action and open the confirmation dialog const handleDeleteSelectedPlace = (place: Place) => { setDialogMessage( `¿Desea eliminar el lugar ${place.name}?\nEsto eliminará todos los datos relacionados a este lugar.` ); setPlaceDeleted(place); setIsDialogOpen(true); setIsWindowActiveDelete(true); }; // Fetch the places when the component mounts useEffect(() => { updatePlacesByTown(idTown); Loading @@ -50,7 +94,6 @@ export const AdminPanelPlaceList = ({ { name: "Nombre", selector: (row) => row.name, sortable: true, }, { name: "Estado", Loading @@ -60,15 +103,27 @@ export const AdminPanelPlaceList = ({ name: "Acciones", cell: (row) => { return ( <> <FontAwesomeIcon style={isWindowActive ? { color: "gray" } : { cursor: "pointer" }} icon={faTrash} onClick={() => { if (!isWindowActive) { handleDeleteSelectedPlace(row); } }} /> <span style={{ margin: "0 10px" }}></span> {/* Separation between icons */} <FontAwesomeIcon style={isWindowActive ? { color: "gray" } : { cursor: "pointer" }} icon={faEdit} onClick={() => { if (!isWindowActive) { handleEditSelectedCategory(row); handleEditSelectedPlace(row); } }} /> </> ); }, }, Loading @@ -85,6 +140,13 @@ export const AdminPanelPlaceList = ({ data={placeList} className="data_table" /> {isDialogOpen && ( <ConfirmationDialog handleToClose={handleToClose} setAnswer={setDeletePlaceBool} message={dialogMessage} /> )} </div> ); };
web/src/presentation/admin/admin_panel_places/admin_panel_place_screen/admin_panel_place_screen.tsx +1 −0 Original line number Diff line number Diff line Loading @@ -78,6 +78,7 @@ export const AdminPanelPlaceScreen = ({ setWindowVisibility={setWindowVisibility} setActualPlace={setActualPlace} setIsRegisterPane={setIsRegisterPane} setIsWindowActiveDelete={setIsWindowActive} /> </div> </div> Loading