From 79d08e785f49bcb1c54ee7b2ae347fc85e04e0e6 Mon Sep 17 00:00:00 2001 From: Hanka8 Date: Mon, 4 Nov 2024 19:19:27 +0100 Subject: [PATCH] Make the map modal a separate component Clicking on a map marker now opens a modal with the map and a close button --- src/components/InteractiveMap.tsx | 40 +++++++++++++++++++++++++++---- src/components/MapModal.tsx | 24 +++++++++++++++++++ src/types.tsx | 8 ++++++- 3 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 src/components/MapModal.tsx diff --git a/src/components/InteractiveMap.tsx b/src/components/InteractiveMap.tsx index 40118e4..b01c792 100644 --- a/src/components/InteractiveMap.tsx +++ b/src/components/InteractiveMap.tsx @@ -1,4 +1,5 @@ -import { useEffect, useRef } from "react"; +import { useState, useEffect, useRef } from "react"; +import MapModal from "./MapModal"; import Map from "ol/Map.js"; import OSM from "ol/source/OSM.js"; import TileLayer from "ol/layer/Tile.js"; @@ -22,6 +23,10 @@ const InteractiveMap: React.FC = ({ setLongitude, data, }) => { + + const [modalOpen, setModalOpen] = useState(false); + const [modalContent, setModalContent] = useState(""); + const mapRef = useRef(null); useEffect(() => { @@ -95,6 +100,7 @@ const InteractiveMap: React.FC = ({ }) ); + birdMarker.set("description", `Bird Name: ${bird.comName}`); vectorSource.addFeature(birdMarker); }); @@ -106,15 +112,39 @@ const InteractiveMap: React.FC = ({ // Add click event listener to the map map.on("singleclick", (event) => { - const clickedCoordinate = toLonLat(event.coordinate); // Convert to longitude/latitude - setLatitude(clickedCoordinate[1].toFixed(2)); - setLongitude(clickedCoordinate[0].toFixed(2)); + const clickedFeature = map.forEachFeatureAtPixel( + event.pixel, + (feature) => { + return feature; + } + ); + + if (clickedFeature) { + const description = clickedFeature.get("description"); + if (description) { + setModalContent(description); // Set the content for the modal + setModalOpen(true); // Open the modal + } + } else { + const clickedCoordinate = toLonLat(event.coordinate); // Convert to longitude/latitude + setLatitude(clickedCoordinate[1].toFixed(2)); + setLongitude(clickedCoordinate[0].toFixed(2)); + } }); return () => map.setTarget(undefined); }, [latitude, longitude, data, setLatitude, setLongitude]); - return
; + return ( +
+
+ setModalOpen(false)} + content={modalContent} + /> +
+ ); }; export default InteractiveMap; diff --git a/src/components/MapModal.tsx b/src/components/MapModal.tsx new file mode 100644 index 0000000..553dbb9 --- /dev/null +++ b/src/components/MapModal.tsx @@ -0,0 +1,24 @@ + + +import { MapModalProps } from "../types"; + +const MapModal: React.FC = ({ isOpen, onClose, content }) => { + if (!isOpen) return null; + + return ( +
+
+

Info

+

{content}

+ +
+
+ ); +}; + +export default MapModal; diff --git a/src/types.tsx b/src/types.tsx index a5e3c5a..ba3a8fd 100644 --- a/src/types.tsx +++ b/src/types.tsx @@ -96,4 +96,10 @@ export type InteractiveMapProps = { setLatitude: (value: string) => void; setLongitude: (value: string) => void; data: Bird[] | undefined; -}; \ No newline at end of file +}; + +export type MapModalProps = { + isOpen: boolean; + onClose: () => void; + content: string; +} \ No newline at end of file