diff --git a/apps/dispatch/app/_store/mapStore.ts b/apps/dispatch/app/_store/mapStore.ts index c2b1bbf4..46a75180 100644 --- a/apps/dispatch/app/_store/mapStore.ts +++ b/apps/dispatch/app/_store/mapStore.ts @@ -58,6 +58,13 @@ interface MapStore { aircraftId: string, tab: MapStore["aircraftTabs"][string], ) => void; + missionTabs: { + [missionId: string]: "home" | "details" | "chat"; + }; + setMissionTab: ( + missionId: string, + tab: MapStore["missionTabs"][string], + ) => void; } export const useMapStore = create((set, get) => ({ @@ -106,4 +113,12 @@ export const useMapStore = create((set, get) => ({ [aircraftId]: tab, }, })), + missionTabs: {}, + setMissionTab: (missionId, tab) => + set((state) => ({ + missionTabs: { + ...state.missionTabs, + [missionId]: tab, + }, + })), })); diff --git a/apps/dispatch/app/_store/missionsStore.ts b/apps/dispatch/app/_store/missionsStore.ts index 19ac8c5f..1ae05a1e 100644 --- a/apps/dispatch/app/_store/missionsStore.ts +++ b/apps/dispatch/app/_store/missionsStore.ts @@ -4,6 +4,7 @@ import { create } from "zustand"; interface MissionStore { missions: MissionOptionalDefaults[]; setMissions: (missions: MissionOptionalDefaults[]) => void; + setMission: (mission: MissionOptionalDefaults) => void; } export const useMissionsStore = create((set) => ({ @@ -24,4 +25,17 @@ export const useMissionsStore = create((set) => ({ }, ], setMissions: (missions) => set({ missions }), + setMission: (mission) => + set((state) => { + const existingMissionIndex = state.missions.findIndex( + (m) => m.id === mission.id, + ); + if (existingMissionIndex !== -1) { + const updatedMissions = [...state.missions]; + updatedMissions[existingMissionIndex] = mission; + return { missions: updatedMissions }; + } else { + return { missions: [...state.missions, mission] }; + } + }), })); diff --git a/apps/dispatch/app/dispatch/_components/map/MissionMarkers.tsx b/apps/dispatch/app/dispatch/_components/map/MissionMarkers.tsx index 869e990c..55e7ed85 100644 --- a/apps/dispatch/app/dispatch/_components/map/MissionMarkers.tsx +++ b/apps/dispatch/app/dispatch/_components/map/MissionMarkers.tsx @@ -2,11 +2,19 @@ import { useMissionsStore } from "_store/missionsStore"; import { Marker, Popup, useMap } from "react-leaflet"; import { DivIcon, Marker as LMarker, Popup as LPopup } from "leaflet"; import { useMapStore } from "_store/mapStore"; -import { Fragment, useCallback, useEffect, useRef, useState } from "react"; +import { + Fragment, + useCallback, + useEffect, + useMemo, + useRef, + useState, +} from "react"; import { cn } from "helpers/cn"; import { Cross, House, Minimize2, Route } from "lucide-react"; import { SmartPopup, useConflict, useSmartPopup } from "_components/SmartPopup"; import { Mission, MissionState } from "@repo/db"; +import FMSStatusHistory from "./_components/MissionMarkerTabs"; export const MISSION_STATUS_COLORS: Record = { draft: "#0092b8", @@ -21,10 +29,38 @@ export const MISSION_STATUS_TEXT_COLORS: Record = { }; const MissionPopupContent = ({ mission }: { mission: Mission }) => { + const setMissionTab = useMapStore((state) => state.setMissionTab); + const currentTab = useMapStore( + (state) => state.missionTabs[mission.id] || "home", + ); + + const handleTabChange = useCallback( + (tab: "home" | "details" | "chat") => { + if (currentTab !== tab) { + setMissionTab(mission.id, tab); + } + }, + [currentTab, mission.id, setMissionTab], + ); + + const renderTabContent = useMemo(() => { + switch (currentTab) { + case "home": + return ; + case "details": + return
Details Content
; + case "chat": + return
Chat Content
; + default: + return Error; + } + }, [currentTab]); + const setOpenMissionMarker = useMapStore( (state) => state.setOpenMissionMarker, ); const { anchor } = useSmartPopup(); + return ( <>
{ }); }} > - +
{ }} >
handleTabChange("home")} > - +
handleTabChange("details")} > - +
handleTabChange("chat")} > - {mission.state} -
-
- Einsatz 250411 +
+
{renderTabContent}
); }; @@ -231,9 +274,11 @@ const MissionMarker = ({ mission }: { mission: Mission }) => { closeOnClick={false} autoPan={false} wrapperClassName="relative" - className="w-[300px] h-[150px]" + className="w-[502px]" > - +
+ +
)} diff --git a/apps/dispatch/app/dispatch/_components/map/_components/MissionMarkerTabs.tsx b/apps/dispatch/app/dispatch/_components/map/_components/MissionMarkerTabs.tsx new file mode 100644 index 00000000..4c55daf4 --- /dev/null +++ b/apps/dispatch/app/dispatch/_components/map/_components/MissionMarkerTabs.tsx @@ -0,0 +1,58 @@ +"use client"; +import React from "react"; +import { FMS_STATUS_TEXT_COLORS } from "../AircraftMarker"; + +const FMSStatusHistory = () => { + const dummyData = [ + { status: "3", time: "12:00", unit: "RTW", unitshort: "RTW" }, + { status: "3", time: "12:01", unit: "Christoph 31", unitshort: "CHX31" }, + { status: "4", time: "12:09", unit: "RTW", unitshort: "RTW" }, + { status: "4", time: "12:11", unit: "Christoph 31", unitshort: "CHX31" }, + { status: "7", time: "12:34", unit: "RTW", unitshort: "RTW" }, + { status: "1", time: "12:38", unit: "Christoph 31", unitshort: "CHX31" }, + ]; + + return ( +
+
+ {[ + ...new Map(dummyData.map((entry) => [entry.unit, entry])).values(), + ].map((entry, index, array) => ( + +
+ + {entry.status} + + {entry.unitshort} +
+ {index < array.length - 1 && |} +
+ ))} +
+
+
    + {dummyData.map((entry, index) => ( +
  • + {entry.time} + + {entry.status} + + {entry.unit} +
  • + ))} +
+
+ ); +}; + +export default FMSStatusHistory;