169 lines
5.1 KiB
TypeScript
169 lines
5.1 KiB
TypeScript
"use client";
|
|
import { usePannelStore } from "_store/pannelStore";
|
|
import { Marker, useMap } from "react-leaflet";
|
|
import L from "leaflet";
|
|
import { useQuery } from "@tanstack/react-query";
|
|
import { getMissionsAPI } from "_querys/missions";
|
|
import { HPGValidationRequired } from "_helpers/hpgValidationRequired";
|
|
import { getConnectedAircraftsAPI } from "_querys/aircrafts";
|
|
import { useMapStore } from "_store/mapStore";
|
|
import { useDispatchConnectionStore } from "_store/dispatch/connectionStore";
|
|
import { XplaneObject } from "@repo/db";
|
|
import { useEffect, useState } from "react";
|
|
|
|
export const MapAdditionals = () => {
|
|
const { isOpen, missionFormValues, setMissionFormValues } = usePannelStore((state) => state);
|
|
const dispatcherConnectionState = useDispatchConnectionStore((state) => state.status);
|
|
const { openMissionMarker } = useMapStore((state) => state);
|
|
|
|
const { data: missions = [] } = useQuery({
|
|
queryKey: ["missions"],
|
|
queryFn: () =>
|
|
getMissionsAPI({
|
|
OR: [{ state: "draft" }, { state: "running" }],
|
|
}),
|
|
refetchInterval: 10_000,
|
|
});
|
|
const { setOpenMissionMarker } = useMapStore((state) => state);
|
|
const [showDetailedAdditionals, setShowDetailedAdditionals] = useState(false);
|
|
|
|
const { data: aircrafts } = useQuery({
|
|
queryKey: ["aircrafts"],
|
|
queryFn: () => getConnectedAircraftsAPI(),
|
|
refetchInterval: 10000,
|
|
});
|
|
const leafletMap = useMap();
|
|
|
|
useEffect(() => {
|
|
const handleZoomEnd = () => {
|
|
const currentZoom = leafletMap.getZoom();
|
|
setShowDetailedAdditionals(currentZoom > 10);
|
|
};
|
|
|
|
leafletMap.on("zoomend", handleZoomEnd);
|
|
|
|
return () => {
|
|
leafletMap.off("zoomend", handleZoomEnd);
|
|
};
|
|
}, [leafletMap]);
|
|
|
|
const markersNeedingAttention = missions.filter(
|
|
(m) =>
|
|
HPGValidationRequired(m.missionStationIds, aircrafts, m.hpgMissionString) &&
|
|
m.hpgValidationState === "POSITION_AMANDED" &&
|
|
m.state === "draft" &&
|
|
m.hpgLocationLat &&
|
|
dispatcherConnectionState === "connected" &&
|
|
m.hpgLocationLng &&
|
|
openMissionMarker.find((openMission) => openMission.id === m.id),
|
|
);
|
|
|
|
return (
|
|
<>
|
|
{missionFormValues?.addressLat && missionFormValues?.addressLng && isOpen && (
|
|
<Marker
|
|
position={[missionFormValues.addressLat, missionFormValues.addressLng]}
|
|
icon={L.icon({
|
|
iconUrl: "/icons/mapMarker.png",
|
|
iconSize: [40, 40],
|
|
iconAnchor: [20, 35],
|
|
})}
|
|
draggable={true}
|
|
eventHandlers={{
|
|
dragend: (e) => {
|
|
const marker = e.target;
|
|
const position = marker.getLatLng();
|
|
setMissionFormValues({
|
|
...missionFormValues,
|
|
addressLat: position.lat,
|
|
addressLng: position.lng,
|
|
});
|
|
},
|
|
}}
|
|
/>
|
|
)}
|
|
{showDetailedAdditionals &&
|
|
openMissionMarker.map((mission) => {
|
|
if (missionFormValues?.id === mission.id) return null;
|
|
const missionData = missions.find((m) => m.id === mission.id);
|
|
if (!missionData?.addressLat || !missionData?.addressLng) return null;
|
|
return (missionData.xPlaneObjects as unknown as XplaneObject[]).map((obj, index) => (
|
|
<Marker
|
|
key={`${mission.id}-additional-${index}`}
|
|
position={[obj.lat, obj.lon]}
|
|
icon={L.icon({
|
|
iconUrl: `/icons/${obj.objectName}.png`,
|
|
iconSize: [40, 40],
|
|
iconAnchor: [20, 35],
|
|
})}
|
|
interactive={false}
|
|
/>
|
|
));
|
|
})}
|
|
{isOpen &&
|
|
missionFormValues?.xPlaneObjects &&
|
|
(missionFormValues.xPlaneObjects as unknown as XplaneObject[]).map((obj, index) => (
|
|
<Marker
|
|
key={index}
|
|
position={[obj.lat, obj.lon]}
|
|
icon={L.icon({
|
|
iconUrl: `/icons/${obj.objectName}.png`,
|
|
iconSize: [40, 40],
|
|
iconAnchor: [20, 35],
|
|
})}
|
|
draggable={true}
|
|
eventHandlers={{
|
|
dragend: (e) => {
|
|
const marker = e.target;
|
|
const position = marker.getLatLng();
|
|
console.log("Marker dragged to:", position);
|
|
setMissionFormValues({
|
|
...missionFormValues,
|
|
xPlaneObjects: (missionFormValues.xPlaneObjects as unknown as XplaneObject[]).map(
|
|
(obj, objIndex) =>
|
|
objIndex === index ? { ...obj, lat: position.lat, lon: position.lng } : obj,
|
|
),
|
|
});
|
|
},
|
|
|
|
contextmenu: (e) => {
|
|
e.originalEvent.preventDefault();
|
|
const updatedObjects = (
|
|
missionFormValues.xPlaneObjects as unknown as XplaneObject[]
|
|
).filter((_, objIndex) => objIndex !== index);
|
|
setMissionFormValues({
|
|
...missionFormValues,
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
xPlaneObjects: updatedObjects as unknown as any[],
|
|
});
|
|
},
|
|
}}
|
|
/>
|
|
))}
|
|
{markersNeedingAttention.map((mission) => (
|
|
<Marker
|
|
key={mission.id}
|
|
position={[mission.hpgLocationLat!, mission.hpgLocationLng!]}
|
|
icon={L.icon({
|
|
iconUrl: "/icons/mapMarkerAttention.png",
|
|
iconSize: [40, 40],
|
|
iconAnchor: [20, 35],
|
|
})}
|
|
eventHandlers={{
|
|
click: () =>
|
|
setOpenMissionMarker({
|
|
open: [
|
|
{
|
|
id: mission.id,
|
|
tab: "home",
|
|
},
|
|
],
|
|
close: [],
|
|
}),
|
|
}}
|
|
/>
|
|
))}
|
|
</>
|
|
);
|
|
};
|