diff --git a/apps/dispatch-server/routes/aircraft.ts b/apps/dispatch-server/routes/aircraft.ts
index c3ff5d44..fa665438 100644
--- a/apps/dispatch-server/routes/aircraft.ts
+++ b/apps/dispatch-server/routes/aircraft.ts
@@ -2,6 +2,7 @@ import {
AdminMessage,
getPublicUser,
MissionLog,
+ MissionSdsStatusLog,
NotificationPayload,
Prisma,
prisma,
@@ -130,6 +131,44 @@ router.patch("/:id", async (req, res) => {
}
});
+router.post("/:id/send-sds-message", async (req, res) => {
+ const { id } = req.params;
+ const { sdsMessage } = req.body as { sdsMessage: MissionSdsStatusLog };
+
+ if (!sdsMessage.data.stationId || !id) {
+ res.status(400).json({ error: "Missing aircraftId or stationId" });
+ return;
+ }
+
+ await prisma.mission.updateMany({
+ where: {
+ state: "running",
+ missionStationIds: {
+ has: sdsMessage.data.stationId,
+ },
+ },
+ data: {
+ missionLog: {
+ push: sdsMessage as unknown as Prisma.InputJsonValue,
+ },
+ },
+ });
+
+ io.to(
+ sdsMessage.data.direction === "to-lst" ? "dispatchers" : `station:${sdsMessage.data.stationId}`,
+ ).emit(sdsMessage.data.direction === "to-lst" ? "notification" : "sds-status", {
+ type: "station-status",
+ status: sdsMessage.data.status,
+ message: "SDS Status Message",
+ data: {
+ aircraftId: parseInt(id),
+ stationId: sdsMessage.data.stationId,
+ },
+ } as NotificationPayload);
+
+ res.sendStatus(204);
+});
+
// Kick a connectedAircraft by ID
router.delete("/:id", async (req, res) => {
const { id } = req.params;
diff --git a/apps/dispatch/app/(app)/dispatch/_components/navbar/_components/Connection.tsx b/apps/dispatch/app/(app)/dispatch/_components/navbar/_components/Connection.tsx
index f1450f19..039d7ac2 100644
--- a/apps/dispatch/app/(app)/dispatch/_components/navbar/_components/Connection.tsx
+++ b/apps/dispatch/app/(app)/dispatch/_components/navbar/_components/Connection.tsx
@@ -14,7 +14,7 @@ export const ConnectionBtn = () => {
const connection = useDispatchConnectionStore((state) => state);
const [form, setForm] = useState({
logoffTime: "",
- selectedZone: "LST_01",
+ selectedZone: "VAR_LST_RD_01",
ghostMode: false,
});
const changeDispatcherMutation = useMutation({
diff --git a/apps/dispatch/app/(app)/pilot/_components/mrt/Base.tsx b/apps/dispatch/app/(app)/pilot/_components/mrt/Base.tsx
new file mode 100644
index 00000000..7624c177
--- /dev/null
+++ b/apps/dispatch/app/(app)/pilot/_components/mrt/Base.tsx
@@ -0,0 +1,15 @@
+import { useMrtStore } from "_store/pilot/MrtStore";
+import Image from "next/image";
+import DAY_BASE_IMG from "./images/Base_NoScreen_Day.png";
+import NIGHT_BASE_IMG from "./images/Base_NoScreen_Night.png";
+
+export const MrtBase = () => {
+ const { nightMode } = useMrtStore((state) => state);
+ return (
+
+ );
+};
diff --git a/apps/dispatch/app/(app)/pilot/_components/mrt/MRT.png b/apps/dispatch/app/(app)/pilot/_components/mrt/MRT.png
deleted file mode 100644
index a9c552b1..00000000
Binary files a/apps/dispatch/app/(app)/pilot/_components/mrt/MRT.png and /dev/null differ
diff --git a/apps/dispatch/app/(app)/pilot/_components/mrt/MRT_MESSAGE.png b/apps/dispatch/app/(app)/pilot/_components/mrt/MRT_MESSAGE.png
deleted file mode 100644
index a0e80ae6..00000000
Binary files a/apps/dispatch/app/(app)/pilot/_components/mrt/MRT_MESSAGE.png and /dev/null differ
diff --git a/apps/dispatch/app/(app)/pilot/_components/mrt/Mrt.tsx b/apps/dispatch/app/(app)/pilot/_components/mrt/Mrt.tsx
index 5d271921..0fda6281 100644
--- a/apps/dispatch/app/(app)/pilot/_components/mrt/Mrt.tsx
+++ b/apps/dispatch/app/(app)/pilot/_components/mrt/Mrt.tsx
@@ -1,22 +1,9 @@
import { CSSProperties } from "react";
-import MrtImage from "./MRT.png";
-import MrtMessageImage from "./MRT_MESSAGE.png";
-import { useButtons } from "./useButtons";
-import { useSounds } from "./useSounds";
import "./mrt.css";
-import Image from "next/image";
-import { useMrtStore } from "_store/pilot/MrtStore";
-
-const MRT_BUTTON_STYLES: CSSProperties = {
- cursor: "pointer",
- zIndex: "9999",
- backgroundColor: "transparent",
- border: "none",
-};
-const MRT_DISPLAYLINE_STYLES: CSSProperties = {
- color: "white",
- zIndex: 1,
-};
+import { MrtBase } from "./Base";
+import { MrtDisplay } from "./MrtDisplay";
+import { MrtButtons } from "./MrtButtons";
+import { MrtPopups } from "./MrtPopups";
export interface DisplayLineProps {
lineStyle?: CSSProperties;
@@ -27,45 +14,7 @@ export interface DisplayLineProps {
textSize: "1" | "2" | "3" | "4";
}
-const DisplayLine = ({
- style = {},
- textLeft,
- textMid,
- textRight,
- textSize,
- lineStyle,
-}: DisplayLineProps) => {
- const INNER_TEXT_PARTS: CSSProperties = {
- fontFamily: "Melder",
- flex: "1",
- flexBasis: "auto",
- overflowWrap: "break-word",
- ...lineStyle,
- };
-
- return (
-
- {textLeft}
- {textMid}
- {textRight}
-
- );
-};
-
export const Mrt = () => {
- useSounds();
- const { handleButton } = useButtons();
- const { lines, page } = useMrtStore((state) => state);
-
return (
{
maxHeight: "100%",
maxWidth: "100%",
color: "white",
- gridTemplateColumns: "21.83% 4.43% 24.42% 18.08% 5.93% 1.98% 6.00% 1.69% 6.00% 9.35%",
- gridTemplateRows: "21.58% 11.87% 3.55% 5.00% 6.84% 0.53% 3.03% 11.84% 3.55% 11.84% 20.39%",
+ gridTemplateColumns:
+ "9.75% 4.23% 8.59% 7.30% 1.16% 7.30% 1.23% 7.16% 1.09% 7.30% 3.68% 4.23% 5.59% 6.07% 1.91% 6.07% 1.84% 6.21% 9.28%",
+ gridTemplateRows:
+ "21.55% 11.83% 3.55% 2.50% 9.46% 2.76% 0.66% 4.99% 6.83% 3.55% 1.97% 9.99% 4.20% 11.04% 5.12%",
}}
>
- {page !== "sds" && (
-
- )}
- {page === "sds" && (
-
- )}
-
-
-
-
-
-
-
-
-
-
-
-
-
- {lines[0] && (
-
- )}
- {lines[1] && (
-
- )}
- {lines[2] && (
-
- )}
- {lines[3] && (
-
- )}
+
+
+
+
);
};
diff --git a/apps/dispatch/app/(app)/pilot/_components/mrt/MrtButtons.tsx b/apps/dispatch/app/(app)/pilot/_components/mrt/MrtButtons.tsx
new file mode 100644
index 00000000..d6e67f59
--- /dev/null
+++ b/apps/dispatch/app/(app)/pilot/_components/mrt/MrtButtons.tsx
@@ -0,0 +1,110 @@
+import { CSSProperties, useRef } from "react";
+import { useButtons } from "./useButtons";
+import { useSounds } from "./useSounds";
+
+const MRT_BUTTON_STYLES: CSSProperties = {
+ cursor: "pointer",
+ zIndex: "9999",
+ backgroundColor: "transparent",
+ border: "none",
+};
+
+interface MrtButtonProps {
+ onClick: () => void;
+ onHold?: () => void;
+ style: CSSProperties;
+}
+
+const MrtButton = ({ onClick, onHold, style }: MrtButtonProps) => {
+ const timeoutRef = useRef(null);
+
+ const handleMouseDown = () => {
+ if (!onHold) return;
+ timeoutRef.current = setTimeout(onHold, 500);
+ };
+
+ const handleMouseUp = () => {
+ if (timeoutRef.current) {
+ clearTimeout(timeoutRef.current);
+ onClick();
+ }
+ };
+
+ return (
+