diff --git a/components/MapComponent.js b/components/MapComponent.js index eede305c8..ed39dc167 100644 --- a/components/MapComponent.js +++ b/components/MapComponent.js @@ -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 = ` -
- -
- - -
- -
- - -
- -
- - -
- -
- - -
+ root.render( + + + + ); - - -
- `; + // Create and configure the popup + L.popup().setLatLng(e.latlng).setContent(container).openOn(initMap); - 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 ( <> diff --git a/components/ShowAddStationPopup.js b/components/ShowAddStationPopup.js new file mode 100644 index 000000000..c1095f6d5 --- /dev/null +++ b/components/ShowAddStationPopup.js @@ -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 ( +
+
+ + 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 + /> +
+
+ + +
+
+ + +
+
+ + +
+ +
+ ); +}; + +export default ShowAddStationPopup; diff --git a/package-lock.json b/package-lock.json index b462c6155..716d39a55 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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" } diff --git a/package.json b/package.json index ddc42823b..77d4233e5 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/styles/global.css b/styles/global.css index d1c492ca3..dae0f46b0 100644 --- a/styles/global.css +++ b/styles/global.css @@ -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 */ +}