ShowAddStationPopup.js Komponent erstellt statt in MapComponent für bessere Organisation in das Projekt

This commit is contained in:
ISA
2024-05-02 12:37:59 +02:00
parent c4e70564ec
commit 7465069e44
5 changed files with 238 additions and 132 deletions

View File

@@ -1,5 +1,6 @@
// components/MapComponent.js
import React, { useEffect, useRef, useState } from "react";
import ReactDOM from "react-dom/client"; // Import from 'react-dom/client'
import L, { marker } from "leaflet";
import "leaflet/dist/leaflet.css";
import "leaflet-contextmenu/dist/leaflet.contextmenu.css";
@@ -8,16 +9,19 @@ import * as config from "../config/config.js";
import dynamic from "next/dynamic";
import "leaflet.smooth_marker_bouncing";
import OverlappingMarkerSpiderfier from "overlapping-marker-spiderfier-leaflet";
import DataSheet from "../components/DataSheet";
import { useRecoilState, useRecoilValue } from "recoil";
import { gisStationsStaticDistrictState } from "../store/gisStationState";
import { gisSystemStaticState } from "../store/gisSystemState";
import { mapLayersState } from "../store/mapLayersState";
import { selectedAreaState } from "../store/selectedAreaState";
import { zoomTriggerState } from "../store/zoomTriggerState";
import { poiTypState } from "../store/poiTypState";
import DataSheet from "./DataSheet.js";
import { useRecoilState, useRecoilValue, RecoilRoot } from "recoil";
import { gisStationsStaticDistrictState } from "../store/gisStationState.js";
import { gisSystemStaticState } from "../store/gisSystemState.js";
import { mapLayersState } from "../store/mapLayersState.js";
import { selectedAreaState } from "../store/selectedAreaState.js";
import { zoomTriggerState } from "../store/zoomTriggerState.js";
import { poiTypState } from "../store/poiTypState.js";
import ShowAddStationPopup from "./ShowAddStationPopup";
//import { createRoot } from "react-dom/client";
const MapComponent = ({ locations, onLocationUpdate }) => {
const [poiTypData, setPoiTypData] = useRecoilState(poiTypState); // Recoil State verwenden
const poiLayerRef = useRef(null); // Referenz auf die Layer-Gruppe für Datenbank-Marker
const mapRef = useRef(null); // Referenz auf das DIV-Element der Karte
const [map, setMap] = useState(null); // Zustand der Karteninstanz
@@ -322,6 +326,29 @@ const MapComponent = ({ locations, onLocationUpdate }) => {
}
}
//----------------------------------
//------------------------------------------
// Funktion zum Abrufen der poiTyp Daten
useEffect(() => {
const fetchPoiTypData = async () => {
try {
const response = await fetch("/api/poiTyp");
const data = await response.json();
setPoiTypData(data); // Daten im Recoil State speichern
} catch (error) {
console.error("Fehler beim Abrufen der poiTyp Daten:", error);
}
};
fetchPoiTypData();
}, []);
// Effekt zum Loggen der poiTypData, wenn sie sich ändern
useEffect(() => {
console.log("poiTypData aktualisiert:", poiTypData);
}, [poiTypData]);
//----------------------------------------------------
//-----Kontextmenu----------------
const newLink = (e) => {
try {
@@ -382,99 +409,39 @@ const MapComponent = ({ locations, onLocationUpdate }) => {
};
//-----Kontextmenu----ende------------
// Ensure this function is only called when map is initialized and available
const showAddStationPopup = (e) => {
if (!initMap) {
return;
}
const showAddStationPopup = (e, map) => {
const container = L.DomUtil.create("div");
const popupContent = L.DomUtil.create("div");
popupContent.innerHTML = `
<form id="addStationForm" class="m-0 p-2 w-full">
<!-- Kommantar von hier
<div class="flex items-center mb-4">
// Create a root container for the React component inside the popup
const root = ReactDOM.createRoot(container);
<label for="idPoi" class="block mr-2 flex-none">ID Poi:</label>
<input
type="text"
id="idPoi"
name="idPoi"
value="2"
class="block p-2 flex-grow border-2 border-gray-200 rounded-md text-sm"
/>
</div>
<div class="flex items-center mb-4">
<label for="idPoiTyp" class="block mr-2 flex-none">ID idPoiTyp:</label>
<input
type="text"
id="idPoiTyp"
name="idPoiTyp"
value="2"
class="block p-2 flex-grow border-2 border-gray-200 rounded-md text-sm"
/>
</div>
Kommantar bis hier-->
<div class="flex items-center mb-4">
<label for="name" class="block mr-2 flex-none">Name:</label>
<input
type="text"
id="name"
name="name"
placeholder="Name der Station"
class="block p-2 flex-grow border-2 border-gray-200 rounded-md text-sm"
/>
</div>
root.render(
<RecoilRoot>
<ShowAddStationPopup map={map} latlng={e.latlng} />
</RecoilRoot>
);
<div class="flex items-center mb-4">
<label for="idPoi" class="block mr-3 flex-none">Type:</label>
<input
type="text"
id="type"
name="type"
placeholder="Typ der Station"
class="block p-2 flex-grow border-2 border-gray-200 rounded-md text-sm"
/>
</div>
// Create and configure the popup
L.popup().setLatLng(e.latlng).setContent(container).openOn(initMap);
<div class="flex items-center mb-4">
<label for="lat" class="block mr-2 flex-none">Breitengrad:</label>
<input
type="text"
id="lat"
name="lat"
value="${e.latlng.lat.toFixed(5)}"
readonly
class="block p-2 flex-grow border-2 border-gray-200 rounded-md text-sm"
/>
</div>
<div class="flex items-center mb-4">
<label for="lng" class="block mr-2 flex-none">Längengrad:</label>
<input
type="text"
id="lng"
name="lng"
value="${e.latlng.lng.toFixed(5)}"
readonly
class="block p-2 flex-grow border-2 border-gray-200 rounded-md text-sm"
/>
</div>
<button
type="submit"
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded w-full"
>
Station hinzufügen
</button>
</form>
`;
L.popup().setLatLng(e.latlng).setContent(popupContent).openOn(initMap);
// Attach event listener here
L.DomEvent.on(popupContent, "submit", handleSubmit);
// Cleanup when the popup is closed
initMap.on("popupclose", () => {
root.unmount(); // Use unmount method from the root
});
};
// Inside your ShowAddStationPopup component
useEffect(() => {
// Cleanup function to unmount React component
return () => {
if (container._reactRoot) {
container._reactRoot.unmount();
}
};
}, []);
//------------------------------------------
// Hinzufügen eines neuen Standorts (Marker) in MySQL-DB-Tabelle (poi)
async function handleSubmit(event) {
event.preventDefault();
@@ -1507,30 +1474,8 @@ const MapComponent = ({ locations, onLocationUpdate }) => {
} // Ihre bereits existierende Funktion, die Zoom-Out ausführt
}
}, [map, zoomTrigger]);
//------------------------------------------
// Funktion zum Abrufen der poiTyp Daten
const [poiTypData, setPoiTypData] = useRecoilState(poiTypState); // Recoil State verwenden
useEffect(() => {
const fetchPoiTypData = async () => {
try {
const response = await fetch("/api/poiTyp");
const data = await response.json();
setPoiTypData(data); // Daten im Recoil State speichern
} catch (error) {
console.error("Fehler beim Abrufen der poiTyp Daten:", error);
}
};
fetchPoiTypData();
}, []);
// Effekt zum Loggen der poiTypData, wenn sie sich ändern
useEffect(() => {
console.log("poiTypData aktualisiert:", poiTypData);
}, [poiTypData]);
//----------------------------------------------------
//---------------------------------------------------------
return (
<>

View File

@@ -0,0 +1,95 @@
// components/ShowAddStationPopup.js:
import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
import { useRecoilState } from "recoil";
import { poiTypState } from "../store/poiTypState";
const ShowAddStationPopup = ({ map, latlng }) => {
const [poiTypData, setPoiTypData] = useRecoilState(poiTypState);
const [name, setName] = useState("");
const [poiTypeId, setPoiTypeId] = useState("");
const [latitude] = useState(latlng.lat.toFixed(5));
const [longitude] = useState(latlng.lng.toFixed(5));
// Effekt zum Ausgeben von poiTypData in der Konsole
useEffect(() => {
console.log("poiTypData in ShowAddStationPopup.js :", poiTypData);
}, [poiTypData]);
const handleSubmit = (event) => {
event.preventDefault();
console.log({ name, poiTypeId, latitude, longitude });
map.closePopup();
};
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" // Use w-full for full width
/>
</div>
<div className="flex items-center mb-4">
<label htmlFor="idPoiTyp" className="block mr-2 flex-none">
Typ:
</label>
<select
id="idPoiTyp"
name="idPoiTyp"
value={poiTypeId}
onChange={(e) => setPoiTypeId(e.target.value)}
className="block p-2 w-full border-2 border-gray-200 rounded-md text-sm" // Adjusted width
>
{poiTypData.map((poiTyp) => (
<option key={poiTyp.id} value={poiTyp.id}>
{poiTyp.name}
</option>
))}
</select>
</div>
<div className="flex items-center mb-4">
<label htmlFor="lat" className="block mr-2 flex-none">
Breitengrad:
</label>
<input
type="text"
id="lat"
name="lat"
value={latitude}
readOnly
className="block p-2 w-full border-2 border-gray-200 rounded-md text-sm" // Adjusted width
/>
</div>
<div className="flex items-center mb-4">
<label htmlFor="lng" className="block mr-2 flex-none">
Längengrad:
</label>
<input
type="text"
id="lng"
name="lng"
value={longitude}
readOnly
className="block p-2 w-full border-2 border-gray-200 rounded-md text-sm" // Adjusted width
/>
</div>
<button
type="submit"
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded w-full"
>
Station hinzufügen
</button>
</form>
);
};
export default ShowAddStationPopup;

85
package-lock.json generated
View File

@@ -1,5 +1,5 @@
{
"name": "OpenStreetMapProject-26.04.2024",
"name": "OpenStreetMapProject-02.05.2024",
"lockfileVersion": 3,
"requires": true,
"packages": {
@@ -13,11 +13,15 @@
"next": "^14.2.0",
"overlapping-marker-spiderfier-leaflet": "^0.2.7",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-dom": "^18.3.1",
"react-leaflet": "^4.2.1",
"recoil": "^0.7.7"
},
"devDependencies": {
"@types/leaflet": "^1.9.12",
"@types/leaflet-contextmenu": "^1.4.3",
"@types/react": "^18.3.1",
"@types/react-dom": "^18.3.0",
"autoprefixer": "^10.4.19",
"postcss": "^8.4.38",
"prettier": "^3.2.5",
@@ -310,6 +314,12 @@
"tslib": "^2.4.0"
}
},
"node_modules/@types/geojson": {
"version": "7946.0.14",
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz",
"integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==",
"dev": true
},
"node_modules/@types/http-proxy": {
"version": "1.17.14",
"resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz",
@@ -318,6 +328,24 @@
"@types/node": "*"
}
},
"node_modules/@types/leaflet": {
"version": "1.9.12",
"resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.12.tgz",
"integrity": "sha512-BK7XS+NyRI291HIo0HCfE18Lp8oA30H1gpi1tf0mF3TgiCEzanQjOqNZ4x126SXzzi2oNSZhZ5axJp1k0iM6jg==",
"dev": true,
"dependencies": {
"@types/geojson": "*"
}
},
"node_modules/@types/leaflet-contextmenu": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/@types/leaflet-contextmenu/-/leaflet-contextmenu-1.4.3.tgz",
"integrity": "sha512-S2FCwMDtgyuykW9tZ0Wg99FDDdtpoMhmoqGgbrqXvMlQ2Yfl7ZuHJqcmvLZznr48pZjfPuvdkeGzcGkIM3ihYg==",
"dev": true,
"dependencies": {
"@types/leaflet": "*"
}
},
"node_modules/@types/node": {
"version": "20.12.7",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz",
@@ -326,6 +354,31 @@
"undici-types": "~5.26.4"
}
},
"node_modules/@types/prop-types": {
"version": "15.7.12",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz",
"integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==",
"dev": true
},
"node_modules/@types/react": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.1.tgz",
"integrity": "sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw==",
"dev": true,
"dependencies": {
"@types/prop-types": "*",
"csstype": "^3.0.2"
}
},
"node_modules/@types/react-dom": {
"version": "18.3.0",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz",
"integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==",
"dev": true,
"dependencies": {
"@types/react": "*"
}
},
"node_modules/ansi-regex": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
@@ -628,6 +681,12 @@
"node": ">=4"
}
},
"node_modules/csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
"dev": true
},
"node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -1531,9 +1590,9 @@
]
},
"node_modules/react": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
"integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
"dependencies": {
"loose-envify": "^1.1.0"
},
@@ -1542,15 +1601,15 @@
}
},
"node_modules/react-dom": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
"integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
"dependencies": {
"loose-envify": "^1.1.0",
"scheduler": "^0.23.0"
"scheduler": "^0.23.2"
},
"peerDependencies": {
"react": "^18.2.0"
"react": "^18.3.1"
}
},
"node_modules/react-leaflet": {
@@ -1681,9 +1740,9 @@
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"node_modules/scheduler": {
"version": "0.23.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
"integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
"version": "0.23.2",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
"integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
"dependencies": {
"loose-envify": "^1.1.0"
}

View File

@@ -8,7 +8,7 @@
"next": "^14.2.0",
"overlapping-marker-spiderfier-leaflet": "^0.2.7",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-dom": "^18.3.1",
"react-leaflet": "^4.2.1",
"recoil": "^0.7.7"
},
@@ -19,6 +19,10 @@
"export": "next export"
},
"devDependencies": {
"@types/leaflet": "^1.9.12",
"@types/leaflet-contextmenu": "^1.4.3",
"@types/react": "^18.3.1",
"@types/react-dom": "^18.3.0",
"autoprefixer": "^10.4.19",
"postcss": "^8.4.38",
"prettier": "^3.2.5",

View File

@@ -7,3 +7,6 @@
.tooltip-tailwind .leaflet-tooltip {
@apply bg-white text-black p-2 border border-gray-300 rounded shadow !important;
}
.leaflet-popup-content {
min-width: 250px; /* Adjust the width based on your requirements */
}