From 1ca6007ac56f01d6e6fd33bf5b618cd795beb19c Mon Sep 17 00:00:00 2001 From: PxlLoewe <72106766+PxlLoewe@users.noreply.github.com> Date: Sat, 24 May 2025 12:46:11 -0700 Subject: [PATCH] added HPG VEhicles Mission, Audio settings; mission Context menu --- apps/dispatch-server/routes/mission.ts | 75 +++++-- .../socket-events/connect-desktop.ts | 2 +- apps/dispatch/app/_components/Audio.tsx | 49 ++--- .../app/_components/MicVolumeIndication.tsx | 75 +++++++ apps/dispatch/app/_components/Settings.tsx | 186 ++++++++++++++++++ .../app/_components/map/ContextMenu.tsx | 2 + .../app/_components/map/MissionMarkers.tsx | 5 - .../map/_components/MissionMarkerTabs.tsx | 46 ++++- apps/dispatch/app/_store/audioStore.ts | 34 ++-- .../app/_store/dispatch/connectionStore.ts | 12 +- .../app/_store/pilot/connectionStore.ts | 12 +- apps/dispatch/app/api/user/route.ts | 49 +++++ .../dispatch/_components/navbar/Navbar.tsx | 4 +- .../navbar/_components/Settings.tsx | 103 ---------- .../_components/pannel/MissionForm.tsx | 121 ++++++++---- .../app/helpers/hpgStateToFmsStatus.ts | 11 ++ apps/dispatch/app/helpers/radioAudio.ts | 62 ++++++ .../app/helpers/selectRandomHPGMission.ts | 28 +++ .../app/pilot/_components/navbar/Navbar.tsx | 4 +- .../app/pilot/_components/navbar/Settings.tsx | 103 ---------- .../navbar/{ => _components}/Connection.tsx | 0 .../navbar/{ => _components}/ThemeSwap.tsx | 0 apps/dispatch/app/querys/missions.ts | 23 +-- apps/dispatch/app/querys/user.ts | 12 ++ apps/dispatch/package.json | 1 + package-lock.json | 19 ++ .../database/prisma/schema/mission.prisma | 7 +- packages/database/prisma/schema/user.prisma | 4 +- 28 files changed, 680 insertions(+), 369 deletions(-) create mode 100644 apps/dispatch/app/_components/MicVolumeIndication.tsx create mode 100644 apps/dispatch/app/_components/Settings.tsx create mode 100644 apps/dispatch/app/api/user/route.ts delete mode 100644 apps/dispatch/app/dispatch/_components/navbar/_components/Settings.tsx create mode 100644 apps/dispatch/app/helpers/hpgStateToFmsStatus.ts create mode 100644 apps/dispatch/app/helpers/radioAudio.ts create mode 100644 apps/dispatch/app/helpers/selectRandomHPGMission.ts delete mode 100644 apps/dispatch/app/pilot/_components/navbar/Settings.tsx rename apps/dispatch/app/pilot/_components/navbar/{ => _components}/Connection.tsx (100%) rename apps/dispatch/app/pilot/_components/navbar/{ => _components}/ThemeSwap.tsx (100%) create mode 100644 apps/dispatch/app/querys/user.ts diff --git a/apps/dispatch-server/routes/mission.ts b/apps/dispatch-server/routes/mission.ts index 6a2996f6..5d1b4852 100644 --- a/apps/dispatch-server/routes/mission.ts +++ b/apps/dispatch-server/routes/mission.ts @@ -114,8 +114,48 @@ router.delete("/:id", async (req, res) => { router.post("/:id/send-alert", async (req, res) => { const { id } = req.params; - const { stationId } = req.body as { stationId?: number }; + const { stationId, vehicleName } = req.body as { + stationId?: number; + vehicleName?: "ambulance" | "police" | "firebrigade"; + }; + try { + if (vehicleName) { + const hpgAircrafts = await prisma.connectedAircraft.findMany({ + where: { + stationId: Number(id), + logoutTime: null, + posH145active: true, + }, + }); + + const newMission = await prisma.mission.update({ + where: { + id: Number(id), + }, + data: { + hpgAmbulanceState: vehicleName === "ambulance" ? "DISPATCHED" : undefined, + hpgFireEngineState: vehicleName === "firebrigade" ? "DISPATCHED" : undefined, + hpgPoliceState: vehicleName === "police" ? "DISPATCHED" : undefined, + }, + }); + hpgAircrafts.forEach((aircraft) => { + io.to(`desktop:${aircraft.userId}`).emit("hpg-vehicle-update", { + missionId: id, + vehicleData: { + ambulanceState: newMission.hpgAmbulanceState, + fireEngineState: newMission.hpgFireEngineState, + policeState: newMission.hpgPoliceState, + }, + }); + }); + + res.status(200).json({ + message: `Rettungsmittel disponiert (${hpgAircrafts.length} Nutzer)`, + }); + io.to("dispatchers").emit("update-mission", newMission); + return; + } const { connectedAircrafts, mission } = await sendAlert(Number(id), { stationId, }); @@ -153,7 +193,6 @@ router.post("/:id/send-sds", async (req, res) => { router.post("/:id/validate-hpg", async (req, res) => { try { - console.log(req.user); const { id } = req.params; const config = req.body as | { @@ -178,37 +217,39 @@ router.post("/:id/validate-hpg", async (req, res) => { Station: true, }, }); + const user = await prisma.user.findFirst({ + where: { + id: activeAircraftinMission?.userId, + }, + }); + const clients = await io.in(`desktop:${activeAircraftinMission?.userId}`).fetchSockets(); + if (!clients.length) { + res.status(400).json({ + error: `Keine Desktop Verbindung für ${user?.publicId} gefunden`, + }); + return; + } res.json({ message: "HPG validation started", }); - /* io.to(`desktop:${activeAircraftinMission}`).emit( + io.to(`desktop:${activeAircraftinMission}`).emit( "hpg-validation", { hpgMissionType: mission?.hpgMissionString, lat: mission?.addressLat, lng: mission?.addressLng, }, - async (result: { - state: HpgValidationState; - lat: number; - lng: number; - }) => { + async (result: { state: HpgValidationState; lat: number; lng: number }) => { console.log("response from user:", result); const newMission = await prisma.mission.update({ where: { id: Number(id) }, data: { // save position of new mission - addressLat: - result.state === "POSITION_AMANDED" - ? result.lat - : mission.addressLat, - addressLng: - result.state === "POSITION_AMANDED" - ? result.lng - : mission.addressLng, + addressLat: result.state === "POSITION_AMANDED" ? result.lat : mission.addressLat, + addressLng: result.state === "POSITION_AMANDED" ? result.lng : mission.addressLng, hpgLocationLat: result.lat, hpgLocationLng: result.lng, hpgValidationState: result.state, @@ -234,7 +275,7 @@ router.post("/:id/validate-hpg", async (req, res) => { } as NotificationPayload); } }, - ); */ + ); // TODO: remove this after testing setTimeout(() => { io.to(`user:${req.user?.id}`).emit("notification", { diff --git a/apps/dispatch-server/socket-events/connect-desktop.ts b/apps/dispatch-server/socket-events/connect-desktop.ts index 779eb341..9cddd34e 100644 --- a/apps/dispatch-server/socket-events/connect-desktop.ts +++ b/apps/dispatch-server/socket-events/connect-desktop.ts @@ -1,4 +1,4 @@ -import { getPublicUser, prisma, User } from "@repo/db"; +import { getPublicUser, HpgState, prisma, User } from "@repo/db"; import { Socket, Server } from "socket.io"; interface PTTData { diff --git a/apps/dispatch/app/_components/Audio.tsx b/apps/dispatch/app/_components/Audio.tsx index f3b5bc42..c19300f4 100644 --- a/apps/dispatch/app/_components/Audio.tsx +++ b/apps/dispatch/app/_components/Audio.tsx @@ -1,6 +1,6 @@ "use client"; -import { useEffect, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import { usePilotConnectionStore } from "_store/pilot/connectionStore"; import { Disc, @@ -18,10 +18,12 @@ import { useAudioStore } from "_store/audioStore"; import { cn } from "helpers/cn"; import { ConnectionQuality } from "livekit-client"; import { ROOMS } from "_data/livekitRooms"; +import { useSession } from "next-auth/react"; export const Audio = () => { const connection = usePilotConnectionStore(); const [showSource, setShowSource] = useState(false); + const serverSession = useSession(); const { isTalking, @@ -46,6 +48,7 @@ export const Audio = () => { clearTimeout(timeout); }; }, [source, isTalking]); + useEffect(() => { const joinRoom = async () => { if (connection.status != "connected") return; @@ -64,17 +67,12 @@ export const Audio = () => { return ( <>
+ Lautstärke sollte beim Sprechen in dem Grünen bereich bleiben +
+
+