This commit is contained in:
PxlLoewe
2025-10-16 11:17:52 +02:00
parent 1919227cd4
commit b5f07071a5
9 changed files with 76 additions and 34 deletions

View File

@@ -96,6 +96,7 @@ export const handleConnectPilot =
lastHeartbeat: debug ? nowPlus2h.toISOString() : undefined, lastHeartbeat: debug ? nowPlus2h.toISOString() : undefined,
posLat: randomPos?.lat, posLat: randomPos?.lat,
posLng: randomPos?.lng, posLng: randomPos?.lng,
posXplanePluginActive: debug ? true : undefined,
}, },
}); });

View File

@@ -108,6 +108,7 @@ export const MissionForm = () => {
hpgSelectedMissionString: null, hpgSelectedMissionString: null,
hpg: null, hpg: null,
missionLog: [], missionLog: [],
xPlaneObjects: [],
}) as MissionOptionalDefaults, }) as MissionOptionalDefaults,
[session.data?.user.id], [session.data?.user.id],
); );
@@ -415,6 +416,12 @@ export const MissionForm = () => {
In diesem Einsatz gibt es {form.watch("addressOSMways").length} Gebäude In diesem Einsatz gibt es {form.watch("addressOSMways").length} Gebäude
</p> </p>
<p
className={cn("text-sm text-gray-500", form.watch("addressOSMways").length && "text-info")}
>
In diesem Einsatz gibt es {form.watch("xPlaneObjects").length} Objekte
</p>
<div className="form-control min-h-[140px]"> <div className="form-control min-h-[140px]">
<div className="flex gap-2"> <div className="flex gap-2">
<button <button

View File

@@ -3,15 +3,32 @@ import { OSMWay } from "@repo/db";
import { useDispatchConnectionStore } from "_store/dispatch/connectionStore"; import { useDispatchConnectionStore } from "_store/dispatch/connectionStore";
import { useMapStore } from "_store/mapStore"; import { useMapStore } from "_store/mapStore";
import { usePannelStore } from "_store/pannelStore"; import { usePannelStore } from "_store/pannelStore";
import { MapPin, MapPinned, Radius, Ruler, Search, RulerDimensionLine, Scan } from "lucide-react"; import { XplaneObject } from "@repo/db";
import {
MapPin,
MapPinned,
Radius,
Search,
RulerDimensionLine,
Scan,
Car,
Ambulance,
} from "lucide-react";
import { getOsmAddress } from "_querys/osm"; import { getOsmAddress } from "_querys/osm";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import toast from "react-hot-toast"; import toast from "react-hot-toast";
import { Popup, useMap } from "react-leaflet"; import { Popup, useMap } from "react-leaflet";
import { findClosestPolygon } from "_helpers/findClosestPolygon"; import { findClosestPolygon } from "_helpers/findClosestPolygon";
import { xPlaneObjectsAvailable } from "_helpers/xPlaneObjectsAvailable";
import { useQuery } from "@tanstack/react-query";
import { getConnectedAircraftsAPI } from "_querys/aircrafts";
export const ContextMenu = () => { export const ContextMenu = () => {
const map = useMap(); const map = useMap();
const { data: aircrafts } = useQuery({
queryKey: ["connectedAircrafts"],
queryFn: getConnectedAircraftsAPI,
});
const { const {
contextMenu, contextMenu,
searchElements, searchElements,
@@ -150,9 +167,12 @@ export const ContextMenu = () => {
style={{ transform: "translateY(-50%)" }} style={{ transform: "translateY(-50%)" }}
onMouseEnter={() => setRulerHover(true)} onMouseEnter={() => setRulerHover(true)}
onMouseLeave={() => setRulerHover(false)} onMouseLeave={() => setRulerHover(false)}
disabled disabled={
!isPannelOpen ||
!xPlaneObjectsAvailable(missionFormValues?.missionStationIds, aircrafts)
}
> >
<Ruler size={20} /> <Car size={20} />
</button> </button>
{/* Bottom Button */} {/* Bottom Button */}
<button <button
@@ -181,40 +201,31 @@ export const ContextMenu = () => {
{/* Ruler Options - shown when Ruler button is hovered or options are hovered */} {/* Ruler Options - shown when Ruler button is hovered or options are hovered */}
{showRulerOptions && ( {showRulerOptions && (
<div <div
className="pointer-events-auto absolute flex flex-col items-center" className="pointer-events-auto absolute -left-[100px] top-1/2 z-10 flex h-[200px] w-[120px] -translate-y-1/2 flex-col items-center justify-center py-5"
style={{
left: "-100px", // position to the right of the left button
top: "50%",
transform: "translateY(-50%)",
zIndex: 10,
width: "120px", // Make the hover area wider
height: "200px", // Make the hover area taller
padding: "20px 0", // Add vertical padding
display: "flex",
justifyContent: "center",
pointerEvents: "auto",
}}
onMouseEnter={() => setRulerOptionsHover(true)} onMouseEnter={() => setRulerOptionsHover(true)}
onMouseLeave={() => setRulerOptionsHover(false)} onMouseLeave={() => setRulerOptionsHover(false)}
> >
<div <div className="flex w-full flex-col">
style={{
display: "flex",
flexDirection: "column",
width: "100%",
}}
>
<button <button
className="btn btn-circle bg-rescuetrack tooltip tooltip-left tooltip-accent mb-2 h-10 w-10 opacity-80" className="btn btn-circle bg-rescuetrack tooltip tooltip-left tooltip-accent mb-2 h-10 w-10 translate-x-full opacity-80"
data-tip="Strecke Messen" data-tip="Rettungswagen Platzieren"
style={{
transform: "translateX(100%)",
}}
onClick={() => { onClick={() => {
/* ... */ console.log("Add Ambulance");
setMissionFormValues({
...missionFormValues,
xPlaneObjects: [
...(missionFormValues?.xPlaneObjects ?? []),
{
objectName: "test",
alt: 0,
lat: contextMenu.lat,
lon: contextMenu.lng,
},
],
});
}} }}
> >
<RulerDimensionLine size={20} /> <Ambulance size={20} />
</button> </button>
<button <button
className="btn btn-circle bg-rescuetrack tooltip tooltip-left tooltip-accent mb-2 h-10 w-10 opacity-80" className="btn btn-circle bg-rescuetrack tooltip tooltip-left tooltip-accent mb-2 h-10 w-10 opacity-80"
@@ -226,11 +237,8 @@ export const ContextMenu = () => {
<Radius size={20} /> <Radius size={20} />
</button> </button>
<button <button
className="btn btn-circle bg-rescuetrack tooltip tooltip-left tooltip-accent h-10 w-10 opacity-80" className="btn btn-circle bg-rescuetrack tooltip tooltip-left tooltip-accent h-10 w-10 translate-x-full opacity-80"
data-tip="Fläche Messen" data-tip="Fläche Messen"
style={{
transform: "translateX(100%)",
}}
onClick={() => { onClick={() => {
/* ... */ /* ... */
}} }}

View File

@@ -0,0 +1,3 @@
export const XPlaneObjects = () => {
return <div>XPlaneObjects</div>;
};

View File

@@ -0,0 +1,12 @@
import { ConnectedAircraft } from "@repo/db";
export const xPlaneObjectsAvailable = (
missionStationIds?: number[],
aircrafts?: ConnectedAircraft[],
) => {
return missionStationIds?.some((id) => {
const aircraft = aircrafts?.find((a) => a.stationId === id);
return aircraft?.posXplanePluginActive;
});
};

View File

@@ -0,0 +1,7 @@
export interface XplaneObject {
objectName: string;
lat: number;
lon: number;
heading: number;
alt: number;
}

View File

@@ -3,3 +3,4 @@ export * from "./MissionVehicleLog";
export * from "./User"; export * from "./User";
export * from "./OSMway"; export * from "./OSMway";
export * from "./SocketEvents"; export * from "./SocketEvents";
export * from "./MissionXplaneObjects";

View File

@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Mission" ADD COLUMN "xPlaneObjects" JSONB[] DEFAULT ARRAY[]::JSONB[];

View File

@@ -19,6 +19,7 @@ model Mission {
missionStationIds Int[] @default([]) missionStationIds Int[] @default([])
missionStationUserIds String[] @default([]) missionStationUserIds String[] @default([])
missionLog Json[] @default([]) missionLog Json[] @default([])
xPlaneObjects Json[] @default([])
hpgMissionString String? hpgMissionString String?
hpgSelectedMissionString String? hpgSelectedMissionString String?
hpgAmbulanceState HpgState? @default(NOT_REQUESTED) hpgAmbulanceState HpgState? @default(NOT_REQUESTED)