--
GitLab
From 73b45a0f328e11eceebbeccde3dc003afecad576 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Omar=20Luna=20Hern=C3=A1ndez?= <42101656@uaz.edu.mx>
Date: Wed, 13 Nov 2024 10:16:47 -0600
Subject: [PATCH 3/7] Se modifica para que no se vuelvan a insertar puntos
cuando se haya llegado al final
---
.../src/pointOfInterest/PointOfInterest.service.ts | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/backend/src/pointOfInterest/PointOfInterest.service.ts b/backend/src/pointOfInterest/PointOfInterest.service.ts
index 8ec12a18..c89cf494 100644
--- a/backend/src/pointOfInterest/PointOfInterest.service.ts
+++ b/backend/src/pointOfInterest/PointOfInterest.service.ts
@@ -40,6 +40,20 @@ export class PointOfInterestService {
if (!place) {
throw new BadRequestException('Place not found');
}
+
+ const idPlace = place.idPlace;
+ const points: getPointDto[] = await this.dataSource
+ .getRepository(PointOfInterestTraduction)
+ .createQueryBuilder('pointTrad')
+ .leftJoin('pointTrad.idPoint', 'point')
+ .select(['point.idPoint as idPoint', 'pointTrad.directions as directions', 'point.idPlace as idPlace'])
+ .where('point.idPlace = :idPlace', { idPlace })
+ .andWhere('pointTrad.directions IS NULL')
+ .getRawMany();
+ if (points.length > 0) {
+ throw new BadRequestException('El ultimo punto ha sido registrad');
+ }
+
const createPointDto: CreatePointDto = {
name: createPointAndTradDto.name,
imageName: createPointAndTradDto.image,
--
GitLab
From 47cdfcbbf4e29aa375c3d924deafec29dbe13b69 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Omar=20Luna=20Hern=C3=A1ndez?= <42101656@uaz.edu.mx>
Date: Wed, 13 Nov 2024 10:32:46 -0600
Subject: [PATCH 4/7] Se mejora el mensaje de error
---
backend/src/pointOfInterest/PointOfInterest.service.ts | 2 +-
web/src/domain/useCase/usePointOfInterest.ts | 5 +----
2 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/backend/src/pointOfInterest/PointOfInterest.service.ts b/backend/src/pointOfInterest/PointOfInterest.service.ts
index 836bde07..1be3ce47 100644
--- a/backend/src/pointOfInterest/PointOfInterest.service.ts
+++ b/backend/src/pointOfInterest/PointOfInterest.service.ts
@@ -51,7 +51,7 @@ export class PointOfInterestService {
.andWhere('pointTrad.directions IS NULL')
.getRawMany();
if (points.length > 0) {
- throw new BadRequestException('El ultimo punto ha sido registrad');
+ throw new BadRequestException('El ultimo punto ha sido registrado. Para agregar más, cambia el último punto');
}
const createPointDto: CreatePointDto = {
diff --git a/web/src/domain/useCase/usePointOfInterest.ts b/web/src/domain/useCase/usePointOfInterest.ts
index 2104b533..7042bc8d 100644
--- a/web/src/domain/useCase/usePointOfInterest.ts
+++ b/web/src/domain/useCase/usePointOfInterest.ts
@@ -159,14 +159,11 @@ export const usePointOfInterest = (
if (axios.isAxiosError(error)) {
error as AxiosError;
switch (error.code) {
- case axios.AxiosError.ERR_BAD_REQUEST:
- setErrorMessage("Acceso no autorizado");
- break;
case axios.AxiosError.ERR_NETWORK:
setErrorMessage("Conexión con el servidor fallida");
break;
default:
- setErrorMessage(error.message);
+ setErrorMessage(error.response?.data.message);
break;
}
}
--
GitLab
From 18f2378ecd790e6873302ac7d6787620c33743fe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Omar=20Luna=20Hern=C3=A1ndez?= <42101656@uaz.edu.mx>
Date: Wed, 13 Nov 2024 14:16:13 -0600
Subject: [PATCH 5/7] Se agrega el metodo para eliminar un lugar
---
web/src/data/datasource/api/place_datasource.ts | 9 +++++++++
web/src/data/datasource/place_datasource.ts | 7 +++++++
web/src/data/repository/place_repository.ts | 9 +++++++++
web/src/domain/repository/place_repository.ts | 7 +++++++
4 files changed, 32 insertions(+)
diff --git a/web/src/data/datasource/api/place_datasource.ts b/web/src/data/datasource/api/place_datasource.ts
index 88145c21..946b8bb5 100644
--- a/web/src/data/datasource/api/place_datasource.ts
+++ b/web/src/data/datasource/api/place_datasource.ts
@@ -125,4 +125,13 @@ export class PlaceDatasourceProd implements PlaceDatasourceInf {
headers,
});
}
+
+ /**
+ * Delete an existing place.
+ * @param idPlace - The place id to delete.
+ * @returns A promise that resolves when the place is deleted.
+ */
+ async deletePlace(idPlace: number): Promise
{
+ //await axios.patch(APIUrl + `/place/${idPlace}`)
+ }
}
diff --git a/web/src/data/datasource/place_datasource.ts b/web/src/data/datasource/place_datasource.ts
index 3b787935..9407136a 100644
--- a/web/src/data/datasource/place_datasource.ts
+++ b/web/src/data/datasource/place_datasource.ts
@@ -31,4 +31,11 @@ export interface PlaceDatasourceInf {
* @returns A promise that resolves when the update is complete.
*/
updatePlace(place: Place): Promise;
+
+ /**
+ * Delete an existing place.
+ * @param idPlace - The place id to delete.
+ * @returns A promise that resolves when the place is deleted.
+ */
+ deletePlace(idPlace: number): Promise;
}
diff --git a/web/src/data/repository/place_repository.ts b/web/src/data/repository/place_repository.ts
index aa120f13..f2c0c9dd 100644
--- a/web/src/data/repository/place_repository.ts
+++ b/web/src/data/repository/place_repository.ts
@@ -43,4 +43,13 @@ export class PlaceRepositoryProd implements PlaceRepositoryInf {
async updatePlace(place: Place): Promise {
return this.datasouce.updatePlace(place);
}
+
+ /**
+ * Delete an existing place.
+ * @param idPlace - The place id to delete.
+ * @returns A promise that resolves when the place is deleted.
+ */
+ async deletePlace(idPlace: number): Promise {
+ return this.datasouce.deletePlace(idPlace);
+ }
}
diff --git a/web/src/domain/repository/place_repository.ts b/web/src/domain/repository/place_repository.ts
index a89108d1..9ec6e750 100644
--- a/web/src/domain/repository/place_repository.ts
+++ b/web/src/domain/repository/place_repository.ts
@@ -31,4 +31,11 @@ export interface PlaceRepositoryInf {
* @returns A promise that resolves when the place is updated.
*/
updatePlace(place: Place): Promise;
+
+ /**
+ * Delete an existing place.
+ * @param idPlace - The place id to delete.
+ * @returns A promise that resolves when the place is deleted.
+ */
+ deletePlace(idPlace: number): Promise;
}
--
GitLab
From 1fa58b652df5b5ab1dfc32d8e0856390bc94d6f4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Omar=20Luna=20Hern=C3=A1ndez?= <42101656@uaz.edu.mx>
Date: Wed, 13 Nov 2024 14:37:44 -0600
Subject: [PATCH 6/7] Se ha agreado la funcion para eliminar un lugar
---
web/src/domain/useCase/usePlace.ts | 9 ++
.../admin_panel_place_list.tsx | 92 ++++++++++++++++---
.../admin_panel_place_screen.tsx | 1 +
3 files changed, 87 insertions(+), 15 deletions(-)
diff --git a/web/src/domain/useCase/usePlace.ts b/web/src/domain/useCase/usePlace.ts
index eec0430e..3f98a17b 100644
--- a/web/src/domain/useCase/usePlace.ts
+++ b/web/src/domain/useCase/usePlace.ts
@@ -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 = (data: Place) => {
const fetch = async () => {
@@ -338,5 +346,6 @@ export const usePlace = (
setCategoriesId,
getPlaceById,
getValues,
+ deletePlace,
};
};
diff --git a/web/src/presentation/admin/admin_panel_places/admin_panel_place_list/admin_panel_place_list.tsx b/web/src/presentation/admin/admin_panel_places/admin_panel_place_list/admin_panel_place_list.tsx
index e57c1a19..36ebe155 100644
--- a/web/src/presentation/admin/admin_panel_places/admin_panel_place_list/admin_panel_place_list.tsx
+++ b/web/src/presentation/admin/admin_panel_places/admin_panel_place_list/admin_panel_place_list.tsx
@@ -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>;
setActualPlace: Dispatch>;
setIsRegisterPane: Dispatch>;
}
@@ -24,21 +27,62 @@ 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(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);
- // eslint-disable-next-line react-hooks/exhaustive-deps
+ // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
// Define the columns for the data table
@@ -50,7 +94,6 @@ export const AdminPanelPlaceList = ({
{
name: "Nombre",
selector: (row) => row.name,
- sortable: true,
},
{
name: "Estado",
@@ -60,15 +103,27 @@ export const AdminPanelPlaceList = ({
name: "Acciones",
cell: (row) => {
return (
- {
- if (!isWindowActive) {
- handleEditSelectedCategory(row);
- }
- }}
- />
+ <>
+ {
+ if (!isWindowActive) {
+ handleDeleteSelectedPlace(row);
+ }
+ }}
+ />
+ {/* Separation between icons */}
+ {
+ if (!isWindowActive) {
+ handleEditSelectedPlace(row);
+ }
+ }}
+ />
+ >
);
},
},
@@ -85,6 +140,13 @@ export const AdminPanelPlaceList = ({
data={placeList}
className="data_table"
/>
+ {isDialogOpen && (
+
+ )}
);
};
diff --git a/web/src/presentation/admin/admin_panel_places/admin_panel_place_screen/admin_panel_place_screen.tsx b/web/src/presentation/admin/admin_panel_places/admin_panel_place_screen/admin_panel_place_screen.tsx
index d86bae58..21e0cd8d 100644
--- a/web/src/presentation/admin/admin_panel_places/admin_panel_place_screen/admin_panel_place_screen.tsx
+++ b/web/src/presentation/admin/admin_panel_places/admin_panel_place_screen/admin_panel_place_screen.tsx
@@ -78,6 +78,7 @@ export const AdminPanelPlaceScreen = ({
setWindowVisibility={setWindowVisibility}
setActualPlace={setActualPlace}
setIsRegisterPane={setIsRegisterPane}
+ setIsWindowActiveDelete={setIsWindowActive}
/>