added Callback and custon notification Toast, client notification event handler
This commit is contained in:
168
apps/dispatch/app/_components/map/SearchElements.tsx
Normal file
168
apps/dispatch/app/_components/map/SearchElements.tsx
Normal file
@@ -0,0 +1,168 @@
|
||||
import { useMapStore } from "_store/mapStore";
|
||||
import { Marker as LMarker } from "leaflet";
|
||||
import { Fragment, useEffect, useRef } from "react";
|
||||
import { Marker, Polygon, Popup } from "react-leaflet";
|
||||
import L from "leaflet";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { getMissionsAPI } from "querys/missions";
|
||||
import { OSMWay } from "@repo/db";
|
||||
|
||||
export const SearchElements = () => {
|
||||
const {
|
||||
searchElements,
|
||||
searchPopup,
|
||||
setSearchPopup,
|
||||
setContextMenu,
|
||||
openMissionMarker,
|
||||
} = useMapStore();
|
||||
const missions = useQuery({
|
||||
queryKey: ["missions"],
|
||||
queryFn: () =>
|
||||
getMissionsAPI({
|
||||
OR: [
|
||||
{
|
||||
state: "draft",
|
||||
},
|
||||
{
|
||||
state: "running",
|
||||
},
|
||||
],
|
||||
}),
|
||||
});
|
||||
const poppupRef = useRef<LMarker>(null);
|
||||
const searchPopupElement = searchElements.find(
|
||||
(element) => element.wayID === searchPopup?.elementId,
|
||||
);
|
||||
|
||||
const SearchElement = ({
|
||||
element,
|
||||
isActive = false,
|
||||
}: {
|
||||
element: (typeof searchElements)[1];
|
||||
isActive?: boolean;
|
||||
}) => {
|
||||
const ref = useRef<L.Polygon>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (ref.current) {
|
||||
ref.current.on("click", () => {
|
||||
const center = ref.current?.getBounds().getCenter();
|
||||
if (center && searchPopup?.elementId !== element.wayID) {
|
||||
setSearchPopup({
|
||||
lat: center.lat,
|
||||
lng: center.lng,
|
||||
elementId: element.wayID,
|
||||
});
|
||||
} else {
|
||||
setSearchPopup(null);
|
||||
}
|
||||
setContextMenu(null);
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
if (!element.nodes) return null;
|
||||
return (
|
||||
<Polygon
|
||||
positions={element.nodes.map((node) => [node.lat, node.lon])}
|
||||
color={
|
||||
searchPopup?.elementId === element.wayID || isActive
|
||||
? "#ff4500"
|
||||
: "#46b7a3"
|
||||
}
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const SearchElementPopup = ({
|
||||
element,
|
||||
}: {
|
||||
element: (typeof searchElements)[1];
|
||||
}) => {
|
||||
if (!searchPopup) return null;
|
||||
return (
|
||||
<Popup
|
||||
autoPan={false}
|
||||
position={[searchPopup.lat, searchPopup.lng]}
|
||||
autoClose={false}
|
||||
closeOnClick={false}
|
||||
>
|
||||
<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}
|
||||
{!element.tags?.building && "unbekannt"}
|
||||
</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>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{openMissionMarker.map(({ id }) => {
|
||||
const mission = missions.data?.find((m) => m.id === id);
|
||||
if (!mission) return null;
|
||||
return (
|
||||
<Fragment key={`mission-osm-${mission.id}`}>
|
||||
{(mission.addressOSMways as (OSMWay | null)[])
|
||||
.filter((element): element is OSMWay => element !== null)
|
||||
.map((element: OSMWay, i) => (
|
||||
<SearchElement
|
||||
key={`mission-elem-${element.wayID}-${i}`}
|
||||
element={element}
|
||||
isActive
|
||||
/>
|
||||
))}
|
||||
</Fragment>
|
||||
);
|
||||
})}
|
||||
{searchElements.map((element, i) => {
|
||||
if (
|
||||
missions.data?.some(
|
||||
(mission) =>
|
||||
(mission.addressOSMways as (OSMWay | null)[])
|
||||
.filter((e): e is OSMWay => e !== null)
|
||||
.some((e) => e.wayID === element.wayID) &&
|
||||
openMissionMarker.some((m) => m.id === mission.id),
|
||||
)
|
||||
)
|
||||
return null;
|
||||
return (
|
||||
<SearchElement
|
||||
key={`mission-elem-${element.wayID}-${i}`}
|
||||
element={element}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
{searchPopup && (
|
||||
<Marker
|
||||
position={[searchPopup.lat, searchPopup.lng]}
|
||||
ref={poppupRef}
|
||||
icon={new L.DivIcon()}
|
||||
opacity={0}
|
||||
>
|
||||
{!searchPopupElement && (
|
||||
<div className="w-20 border border-rescuetrack"></div>
|
||||
)}
|
||||
</Marker>
|
||||
)}
|
||||
{searchPopupElement && (
|
||||
<SearchElementPopup element={searchPopupElement} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user