Modal für Poi zu updaten und zu löschen
This commit is contained in:
@@ -20,6 +20,7 @@ import { poiTypState } from "../store/atoms/poiTypState.js";
|
|||||||
import ShowAddStationPopup from "./ShowAddStationPopup";
|
import ShowAddStationPopup from "./ShowAddStationPopup";
|
||||||
import { poiReadFromDbTriggerAtom } from "../store/atoms/poiReadFromDbTriggerAtom";
|
import { poiReadFromDbTriggerAtom } from "../store/atoms/poiReadFromDbTriggerAtom";
|
||||||
import { InformationCircleIcon } from "@heroicons/react/20/solid"; // oder 'outline'
|
import { InformationCircleIcon } from "@heroicons/react/20/solid"; // oder 'outline'
|
||||||
|
import PoiUpdateModal from "./PoiUpdateModal.js";
|
||||||
|
|
||||||
//import { createRoot } from "react-dom/client";
|
//import { createRoot } from "react-dom/client";
|
||||||
|
|
||||||
@@ -32,6 +33,22 @@ const plusRoundIcon = L.icon({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const MapComponent = ({ locations, onLocationUpdate }) => {
|
const MapComponent = ({ locations, onLocationUpdate }) => {
|
||||||
|
const openPoiUpdateModal = () => setShowPoiUpdateModal(true);
|
||||||
|
const closePoiUpdateModal = () => setShowPoiUpdateModal(false);
|
||||||
|
const [showPoiUpdateModal, setShowPoiUpdateModal] = useState(false);
|
||||||
|
const [currentPoiData, setCurrentPoiData] = useState(null);
|
||||||
|
|
||||||
|
const handleEditPoi = (marker) => {
|
||||||
|
console.log("Gewählte Marker ID (idPoi):", marker.options.id);
|
||||||
|
// Setzen der aktuellen POI-Daten für die Übergabe an das Modal
|
||||||
|
setCurrentPoiData({
|
||||||
|
idPoi: marker.options.id,
|
||||||
|
//name: marker.options.name, // Angenommen, name ist ebenfalls in options gespeichert
|
||||||
|
// Weitere relevante Markerdaten können hier hinzugefügt werden
|
||||||
|
});
|
||||||
|
setShowPoiUpdateModal(true);
|
||||||
|
};
|
||||||
|
|
||||||
const [showVersionInfoModal, setShowVersionInfoModal] = useState(false);
|
const [showVersionInfoModal, setShowVersionInfoModal] = useState(false);
|
||||||
const zoomTrigger = useRecoilValue(zoomTriggerState);
|
const zoomTrigger = useRecoilValue(zoomTriggerState);
|
||||||
const offlineTileLayer = "/mapTiles/{z}/{x}/{y}.png";
|
const offlineTileLayer = "/mapTiles/{z}/{x}/{y}.png";
|
||||||
@@ -245,6 +262,7 @@ const MapComponent = ({ locations, onLocationUpdate }) => {
|
|||||||
className: "background-red",
|
className: "background-red",
|
||||||
callback: addStationCallback,
|
callback: addStationCallback,
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
text: "Koordinaten anzeigen",
|
text: "Koordinaten anzeigen",
|
||||||
icon: "img/not_listed_location.png",
|
icon: "img/not_listed_location.png",
|
||||||
@@ -835,6 +853,15 @@ const MapComponent = ({ locations, onLocationUpdate }) => {
|
|||||||
};
|
};
|
||||||
console.log("trigger in MapComponent.js:", poiReadTrigger);
|
console.log("trigger in MapComponent.js:", poiReadTrigger);
|
||||||
}, [map, locations, poiReadTrigger]); // Dieser Effekt läuft nur, wenn sich `map` ändert
|
}, [map, locations, poiReadTrigger]); // Dieser Effekt läuft nur, wenn sich `map` ändert
|
||||||
|
//------------------------------------------
|
||||||
|
function editPoi(marker) {
|
||||||
|
// Zugriff auf die Markerdaten
|
||||||
|
const markerId = marker.options.id;
|
||||||
|
console.log("Bearbeiten des POI mit ID:", markerId);
|
||||||
|
|
||||||
|
// Hier könnte ein Modal mit Formular geöffnet werden
|
||||||
|
// Beispiel: openEditModal(markerId);
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------
|
//------------------------------------------
|
||||||
// poiLayerRef(poiDbLayer) POI hinzufügen
|
// poiLayerRef(poiDbLayer) POI hinzufügen
|
||||||
@@ -861,7 +888,19 @@ const MapComponent = ({ locations, onLocationUpdate }) => {
|
|||||||
}),
|
}),
|
||||||
draggable: true,
|
draggable: true,
|
||||||
id: location.idPoi,
|
id: location.idPoi,
|
||||||
|
}).bindContextMenu({
|
||||||
|
contextmenu: true,
|
||||||
|
contextmenuWidth: 140,
|
||||||
|
contextmenuItems: [
|
||||||
|
{
|
||||||
|
text: "POI Bearbeiten", //git stash save "POI Bearbeiten"
|
||||||
|
|
||||||
|
icon: "/img/edit_icon.png",
|
||||||
|
callback: () => handleEditPoi(marker),
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
//console.log("location.idPoi:", location.idPoi);
|
||||||
|
|
||||||
// Popup konfigurieren
|
// Popup konfigurieren
|
||||||
marker.bindPopup(`
|
marker.bindPopup(`
|
||||||
@@ -891,16 +930,6 @@ const MapComponent = ({ locations, onLocationUpdate }) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
marker.addTo(poiLayerRef.current);
|
marker.addTo(poiLayerRef.current);
|
||||||
/* //--------------
|
|
||||||
const plusMarker = L.marker([latitude, longitude], {
|
|
||||||
icon: plusRoundIcon,
|
|
||||||
zIndexOffset: 1000, // Higher z-index for visibility
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add to the poiLayer
|
|
||||||
plusMarker.addTo(poiLayerRef.current);
|
|
||||||
console.log("Adding plus icon marker at", [latitude, longitude]);
|
|
||||||
//------------ */
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [map, locations, onLocationUpdate, poiReadTrigger, isPoiTypLoaded]);
|
}, [map, locations, onLocationUpdate, poiReadTrigger, isPoiTypLoaded]);
|
||||||
@@ -1670,6 +1699,52 @@ const MapComponent = ({ locations, onLocationUpdate }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<div>
|
||||||
|
{/* Zeigt das Popup-Fenster nur, wenn `showPopup` wahr ist */}
|
||||||
|
{showPoiUpdateModal && (
|
||||||
|
<div
|
||||||
|
className="fixed inset-0 bg-black bg-opacity-10 flex justify-center items-center z-[1000]"
|
||||||
|
onClick={closePoiUpdateModal} // Schließt das Popup bei einem Klick außerhalb
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="relative bg-white p-6 rounded-lg shadow-lg"
|
||||||
|
onClick={(e) => e.stopPropagation()} // Verhindert das Schließen innerhalb des Fensters
|
||||||
|
>
|
||||||
|
{/* Schließen-Button oben rechts */}
|
||||||
|
<button
|
||||||
|
onClick={closePoiUpdateModal}
|
||||||
|
className="absolute top-0 right-0 mt-2 mr-2 p-1 text-gray-700 hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-gray-600"
|
||||||
|
aria-label="Close"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
className="h-6 w-6"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth={2}
|
||||||
|
d="M6 18L18 6M6 6l12 12"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* Formular-Komponente zum Hinzufügen einer Station */}
|
||||||
|
<PoiUpdateModal
|
||||||
|
onClose={() => setShowPoiUpdateModal(false)}
|
||||||
|
poiData={currentPoiData}
|
||||||
|
onSubmit={handleAddStation}
|
||||||
|
latlng={popupCoordinates}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Rest of your component */}
|
||||||
<div>
|
<div>
|
||||||
{/* Zeigt das Popup-Fenster nur, wenn `showPopup` wahr ist */}
|
{/* Zeigt das Popup-Fenster nur, wenn `showPopup` wahr ist */}
|
||||||
{showPopup && (
|
{showPopup && (
|
||||||
|
|||||||
225
components/PoiUpdateModal.js
Normal file
225
components/PoiUpdateModal.js
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
// components/PoiUpdate.js
|
||||||
|
import React, { useState, useEffect, use } from "react";
|
||||||
|
import ReactDOM from "react-dom";
|
||||||
|
import { useRecoilValue, useRecoilState, useSetRecoilState } from "recoil";
|
||||||
|
import { readPoiMarkersStore } from "../store/selectors/readPoiMarkersStore";
|
||||||
|
import { poiReadFromDbTriggerAtom } from "../store/atoms/poiReadFromDbTriggerAtom";
|
||||||
|
|
||||||
|
const PoiUpdateModal = ({ onClose, map, poiData }) => {
|
||||||
|
const [poiId, setPoiId] = useState(poiData ? poiData.id : "");
|
||||||
|
const [poiTypData, setpoiTypData] = useState(); // Recoil State verwenden
|
||||||
|
|
||||||
|
const [name, setName] = useState("");
|
||||||
|
const [poiTypeId, setPoiTypeId] = useState(""); // Initialize as string
|
||||||
|
const [poiTypeName, setPoiTypeName] = useState(""); // Initialize as string
|
||||||
|
//const [latitude] = useState(latlng.lat.toFixed(5));
|
||||||
|
//const [longitude] = useState(latlng.lng.toFixed(5));
|
||||||
|
const setLoadData = useSetRecoilState(readPoiMarkersStore);
|
||||||
|
const setTrigger = useSetRecoilState(poiReadFromDbTriggerAtom);
|
||||||
|
const [locationDeviceData, setLocationDeviceData] = useState([]);
|
||||||
|
const [deviceName, setDeviceName] = useState("");
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchpoiData = async () => {
|
||||||
|
try {
|
||||||
|
const response = await fetch("/api/readLocation");
|
||||||
|
const data = await response.json();
|
||||||
|
console.log("data in PoiUpdateModal: ", data[0].idPoiTyp);
|
||||||
|
setpoiTypData(data);
|
||||||
|
if (data && data.length > 0) {
|
||||||
|
setPoiTypeId(data[0].idPoiTyp); // Set initial poiTypeId to the id of the first poiType
|
||||||
|
setPoiTypeName(data[1].name); // Set initial poiTypeName to the name of the first poiType
|
||||||
|
/* console.log(
|
||||||
|
"Initial poiTypeId set in ShowAddStationPopup.js :",
|
||||||
|
data[0].idPoiTyp
|
||||||
|
); */
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Fehler beim Abrufen der poi Tabelle Daten:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchpoiData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchpoiTypData = async () => {
|
||||||
|
try {
|
||||||
|
const response = await fetch("/api/readPoiTyp");
|
||||||
|
const data = await response.json();
|
||||||
|
setpoiTypData(data);
|
||||||
|
if (data && data.length > 0) {
|
||||||
|
setPoiTypeId(data[0].idPoiTyp); // Set initial poiTypeId to the id of the first poiType
|
||||||
|
setPoiTypeName(data[1].name); // Set initial poiTypeName to the name of the first poiType
|
||||||
|
/* console.log(
|
||||||
|
"Initial poiTypeId set in ShowAddStationPopup.js :",
|
||||||
|
data[0].idPoiTyp
|
||||||
|
); */
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Fehler beim Abrufen der poiTyp Daten:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchpoiTypData();
|
||||||
|
}, []);
|
||||||
|
//------------------------------------------------------------------------------------------
|
||||||
|
useEffect(() => {
|
||||||
|
// Funktion zum Abrufen der Daten von der API -> DB talas_v5.location_device
|
||||||
|
const fetchData = async () => {
|
||||||
|
try {
|
||||||
|
const response = await fetch("/api/talas_v5/location_device");
|
||||||
|
const data = await response.json();
|
||||||
|
setLocationDeviceData(data);
|
||||||
|
if (data.length > 0) {
|
||||||
|
setDeviceName(data[0].name); // Setzen des anfänglichen Gerätenamens
|
||||||
|
}
|
||||||
|
//console.log("Abgerufene Standort- und Gerätedaten:", data);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(
|
||||||
|
"Fehler beim Abrufen der Standort- und Gerätedaten:",
|
||||||
|
error
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//-----------------handleSubmit-------------------
|
||||||
|
const handleSubmit = async (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
const formData = {
|
||||||
|
name,
|
||||||
|
poiTypeId,
|
||||||
|
latitude,
|
||||||
|
longitude,
|
||||||
|
idLD: locationDeviceData.find((device) => device.name === deviceName)
|
||||||
|
.idLD,
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await fetch("/api/addLocation", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify(formData),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
setTrigger((trigger) => {
|
||||||
|
console.log("Aktueller Trigger-Wert:", trigger); // Vorheriger Wert
|
||||||
|
const newTrigger = trigger + 1;
|
||||||
|
console.log("Neuer Trigger-Wert:", newTrigger); // Aktualisierter Wert
|
||||||
|
onClose();
|
||||||
|
return newTrigger;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.error("Fehler beim Hinzufügen des POI");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (map && typeof map.closePopup === "function") {
|
||||||
|
map.closePopup();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//-----------------handleSubmit-------------------
|
||||||
|
useEffect(() => {
|
||||||
|
if (poiData) {
|
||||||
|
console.log("poiData in PoiUpdateModal: ", poiData);
|
||||||
|
console.log("poiData.name in PoiUpdateModal: ", poiData.name);
|
||||||
|
setName(poiData.name);
|
||||||
|
console.log("poiData.idPoi in PoiUpdateModal: ", poiData.idPoi);
|
||||||
|
setPoiId(poiData.idPoi);
|
||||||
|
}
|
||||||
|
}, [poiData]);
|
||||||
|
//------------------------------------------------------------------------------------------
|
||||||
|
return (
|
||||||
|
<form onSubmit={handleSubmit} className="m-0 p-2 w-full ">
|
||||||
|
<div className="flex items-center mb-4">
|
||||||
|
<label htmlFor="name" className="block mr-2 flex-none">
|
||||||
|
Name :
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="name"
|
||||||
|
name="name"
|
||||||
|
value={name}
|
||||||
|
onChange={(e) => setName(e.target.value)}
|
||||||
|
placeholder="Name der Station"
|
||||||
|
className="block p-2 w-full border-2 border-gray-200 rounded-md text-sm"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* {locationDeviceData.----------------------------------------------*/}
|
||||||
|
<div className="flex items-center mb-4">
|
||||||
|
<label htmlFor="deviceName" className="block mr-2 flex-none">
|
||||||
|
Gerät :
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
id="deviceName"
|
||||||
|
name="deviceName"
|
||||||
|
value={deviceName}
|
||||||
|
onChange={(e) => setDeviceName(e.target.value)}
|
||||||
|
className="block p-2 w-full border-2 border-gray-200 rounded-md text-sm"
|
||||||
|
>
|
||||||
|
{locationDeviceData.map((device, index) => (
|
||||||
|
<option key={index} value={device.name}>
|
||||||
|
{device.name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{/* {locationDeviceData.----------------------------------------------*/}
|
||||||
|
<div className="flex items-center mb-4">
|
||||||
|
<label htmlFor="idPoiTyp2" className="block mr-2 flex-none">
|
||||||
|
Typ:
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
id="idPoiTyp2"
|
||||||
|
name="idPoiTyp2"
|
||||||
|
value={poiTypeId}
|
||||||
|
onChange={(e) => setPoiTypeId(e.target.value)}
|
||||||
|
className="block p-2 w-full border-2 border-gray-200 rounded-md text-sm"
|
||||||
|
>
|
||||||
|
{poiTypData &&
|
||||||
|
poiTypData.map((poiTyp, index) => (
|
||||||
|
<option key={poiTyp.idPoiTyp || index} value={poiTyp.idPoiTyp}>
|
||||||
|
{poiTyp.name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-row items-center justify-center">
|
||||||
|
<div className="flex items-center mb-4">
|
||||||
|
<label htmlFor="lat" className="block mr-2 flex-none text-xs">
|
||||||
|
{/* Lat : {latitude} */}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center mb-4">
|
||||||
|
<label htmlFor="lng" className="block mr-2 flex-none text-xs">
|
||||||
|
{/* Lng : {longitude} */}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="bg-red-400 hover:bg-red-600 text-white font-bold py-2 px-4 rounded w-full mb-4"
|
||||||
|
>
|
||||||
|
POI löschen
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded w-full"
|
||||||
|
>
|
||||||
|
POI aktualisieren
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PoiUpdateModal;
|
||||||
39
pages/api/updatePoi.js
Normal file
39
pages/api/updatePoi.js
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
// pages/api/updateLocation.js
|
||||||
|
import mysql from "mysql";
|
||||||
|
import util from "util";
|
||||||
|
|
||||||
|
const dbConfig = {
|
||||||
|
host: process.env.DB_HOST,
|
||||||
|
user: process.env.DB_USER,
|
||||||
|
password: process.env.DB_PASSWORD,
|
||||||
|
database: process.env.DB_NAME,
|
||||||
|
port: process.env.DB_PORT,
|
||||||
|
charset: "utf8mb4",
|
||||||
|
};
|
||||||
|
|
||||||
|
export default async function handler(req, res) {
|
||||||
|
if (req.method !== "POST") {
|
||||||
|
res.setHeader("Allow", ["POST"]);
|
||||||
|
return res.status(405).end(`Method ${req.method} Not Allowed`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { id, latitude, longitude } = req.body;
|
||||||
|
|
||||||
|
const connection = mysql.createConnection(dbConfig);
|
||||||
|
// Promisify the query method
|
||||||
|
const query = util.promisify(connection.query).bind(connection);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await query("UPDATE poi SET position = POINT(?, ?) WHERE idPoi = ?", [
|
||||||
|
longitude,
|
||||||
|
latitude,
|
||||||
|
id,
|
||||||
|
]);
|
||||||
|
res.status(200).json({ success: true });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
res.status(500).json({ error: "Ein Fehler ist aufgetreten" });
|
||||||
|
} finally {
|
||||||
|
connection.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user