122 lines
3.0 KiB
TypeScript
122 lines
3.0 KiB
TypeScript
import { useMapStore } from "_store/mapStore";
|
|
import { Marker as LMarker } from "leaflet";
|
|
import { useEffect, useRef } from "react";
|
|
import { Marker, Polygon, Polyline, Popup } from "react-leaflet";
|
|
import L from "leaflet";
|
|
|
|
export const SearchElements = () => {
|
|
const { searchElements, searchPopup, setSearchPopup, setPopup } =
|
|
useMapStore();
|
|
const poppupRef = useRef<LMarker>(null);
|
|
const intervalRef = useRef<NodeJS.Timeout>(null);
|
|
const searchPopupElement = searchElements.find(
|
|
(element) => element.id === searchPopup?.elementId,
|
|
);
|
|
|
|
useEffect(() => {
|
|
intervalRef.current = setInterval(() => {
|
|
if (searchPopup?.isOpen) {
|
|
poppupRef.current?.openPopup();
|
|
} else {
|
|
poppupRef.current?.closePopup();
|
|
}
|
|
}, 100);
|
|
poppupRef.current?.on("popupclose", () => {
|
|
setSearchPopup(undefined);
|
|
});
|
|
return () => {
|
|
if (poppupRef.current) {
|
|
poppupRef.current.off("popupclose");
|
|
}
|
|
if (intervalRef.current) {
|
|
clearInterval(intervalRef.current);
|
|
}
|
|
};
|
|
}, [searchPopup, searchPopupElement]);
|
|
|
|
const SearchElement = ({
|
|
element,
|
|
}: {
|
|
element: (typeof searchElements)[1];
|
|
}) => {
|
|
const ref = useRef<any>(null);
|
|
|
|
useEffect(() => {
|
|
if (ref.current) {
|
|
ref.current.on("click", () => {
|
|
const center = ref.current.getBounds().getCenter();
|
|
setSearchPopup({
|
|
isOpen: true,
|
|
lat: center.lat,
|
|
lng: center.lng,
|
|
elementId: element.id,
|
|
});
|
|
setPopup(null);
|
|
});
|
|
}
|
|
}, []);
|
|
|
|
return (
|
|
<Polygon
|
|
key={element.id}
|
|
positions={element.nodes.map((node) => [node.lat, node.lon])}
|
|
color={searchPopup?.elementId === element.id ? "#ff4500" : "#46b7a3"}
|
|
ref={ref}
|
|
/>
|
|
);
|
|
};
|
|
|
|
const SearchElementPopup = ({
|
|
element,
|
|
}: {
|
|
element: (typeof searchElements)[1];
|
|
}) => {
|
|
return (
|
|
<Popup>
|
|
<div className="bg-base-100/70 border border-rescuetrack w-[250px] text-white pointer-events-auto p-2">
|
|
<h3 className="text-lg font-bold">
|
|
{element.tags?.building === "yes"
|
|
? "Gebäude"
|
|
: element.tags?.building}
|
|
</h3>
|
|
<p className="">
|
|
{element.tags?.["addr:street"]} {element.tags?.["addr:housenumber"]}
|
|
</p>
|
|
<p className="">
|
|
{element.tags?.["addr:suburb"]} {element.tags?.["addr:postcode"]}
|
|
</p>
|
|
<div className="flex flex-col gap-2 mt-2">
|
|
<button className="btn bg-rescuetrack-highlight">
|
|
Zum Einsatz Hinzufügen
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</Popup>
|
|
);
|
|
};
|
|
|
|
console.log("searchPopupElement", searchPopupElement, searchPopup);
|
|
return (
|
|
<>
|
|
{searchElements.map((element) => {
|
|
return <SearchElement key={element.id} element={element} />;
|
|
})}
|
|
{searchPopup && (
|
|
<Marker
|
|
position={[searchPopup.lat, searchPopup.lng]}
|
|
ref={poppupRef}
|
|
icon={new L.DivIcon()}
|
|
opacity={0}
|
|
>
|
|
{searchPopupElement && (
|
|
<SearchElementPopup element={searchPopupElement} />
|
|
)}
|
|
{!searchPopupElement && (
|
|
<div className="w-20 border border-rescuetrack"></div>
|
|
)}
|
|
</Marker>
|
|
)}
|
|
</>
|
|
);
|
|
};
|