Dispatch Router-Struktur; AddPenalty Layout gefixed
This commit is contained in:
BIN
apps/dispatch/app/(app)/pilot/_components/mrt/MRT.png
Normal file
BIN
apps/dispatch/app/(app)/pilot/_components/mrt/MRT.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 194 KiB |
BIN
apps/dispatch/app/(app)/pilot/_components/mrt/MRT_MESSAGE.png
Normal file
BIN
apps/dispatch/app/(app)/pilot/_components/mrt/MRT_MESSAGE.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 322 KiB |
227
apps/dispatch/app/(app)/pilot/_components/mrt/Mrt.tsx
Normal file
227
apps/dispatch/app/(app)/pilot/_components/mrt/Mrt.tsx
Normal file
@@ -0,0 +1,227 @@
|
||||
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,
|
||||
};
|
||||
|
||||
export interface DisplayLineProps {
|
||||
lineStyle?: CSSProperties;
|
||||
style?: CSSProperties;
|
||||
textLeft?: string;
|
||||
textMid?: string;
|
||||
textRight?: string;
|
||||
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 (
|
||||
<div
|
||||
className={`text-${textSize}`}
|
||||
style={{
|
||||
fontFamily: "Famirids",
|
||||
display: "flex",
|
||||
flexWrap: "wrap",
|
||||
|
||||
...style,
|
||||
}}
|
||||
>
|
||||
<span style={INNER_TEXT_PARTS}>{textLeft}</span>
|
||||
<span style={{ textAlign: "center", ...INNER_TEXT_PARTS }}>{textMid}</span>
|
||||
<span style={{ textAlign: "end", ...INNER_TEXT_PARTS }}>{textRight}</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const Mrt = () => {
|
||||
useSounds();
|
||||
const { handleButton } = useButtons();
|
||||
const { lines, page } = useMrtStore((state) => state);
|
||||
|
||||
return (
|
||||
<div
|
||||
id="mrt-container"
|
||||
style={{
|
||||
containerName: "mrtContainer",
|
||||
display: "grid",
|
||||
aspectRatio: "1466 / 760",
|
||||
height: "auto",
|
||||
width: "auto",
|
||||
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%",
|
||||
}}
|
||||
>
|
||||
{page !== "sds" && (
|
||||
<Image
|
||||
src={MrtImage}
|
||||
alt="MrtImage"
|
||||
style={{
|
||||
zIndex: 0,
|
||||
height: "100%",
|
||||
width: "100%",
|
||||
gridArea: "1 / 1 / 13 / 13",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{page === "sds" && (
|
||||
<Image
|
||||
src={MrtMessageImage}
|
||||
alt="MrtImage-Message"
|
||||
style={{
|
||||
zIndex: 0,
|
||||
height: "100%",
|
||||
width: "100%",
|
||||
gridArea: "1 / 1 / 13 / 13",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
<button
|
||||
onClick={handleButton("home")}
|
||||
style={{ gridArea: "2 / 4 / 3 / 5", ...MRT_BUTTON_STYLES }}
|
||||
/>
|
||||
<button
|
||||
onClick={handleButton("1")}
|
||||
style={{ gridArea: "2 / 5 / 3 / 6", ...MRT_BUTTON_STYLES }}
|
||||
/>
|
||||
<button
|
||||
onClick={handleButton("2")}
|
||||
style={{ gridArea: "2 / 7 / 3 / 7", ...MRT_BUTTON_STYLES }}
|
||||
/>
|
||||
<button
|
||||
onClick={handleButton("3")}
|
||||
style={{ gridArea: "2 / 9 / 3 / 10", ...MRT_BUTTON_STYLES }}
|
||||
/>
|
||||
<button
|
||||
onClick={handleButton("4")}
|
||||
style={{ gridArea: "4 / 5 / 6 / 6", ...MRT_BUTTON_STYLES }}
|
||||
/>
|
||||
<button
|
||||
onClick={handleButton("5")}
|
||||
style={{ gridArea: "4 / 7 / 6 / 7", ...MRT_BUTTON_STYLES }}
|
||||
/>
|
||||
<button
|
||||
onClick={handleButton("6")}
|
||||
style={{ gridArea: "4 / 9 / 6 / 10", ...MRT_BUTTON_STYLES }}
|
||||
/>
|
||||
<button
|
||||
onClick={handleButton("7")}
|
||||
style={{ gridArea: "8 / 5 / 9 / 6", ...MRT_BUTTON_STYLES }}
|
||||
/>
|
||||
<button
|
||||
onClick={handleButton("8")}
|
||||
style={{ gridArea: "8 / 7 / 9 / 7", ...MRT_BUTTON_STYLES }}
|
||||
/>
|
||||
<button
|
||||
onClick={handleButton("9")}
|
||||
style={{ gridArea: "8 / 9 / 9 / 10", ...MRT_BUTTON_STYLES }}
|
||||
/>
|
||||
<button
|
||||
onClick={handleButton("0")}
|
||||
style={{ gridArea: "10 / 7 / 11 / 8", ...MRT_BUTTON_STYLES }}
|
||||
/>
|
||||
|
||||
{lines[0] && (
|
||||
<DisplayLine
|
||||
{...lines[0]}
|
||||
style={
|
||||
page === "sds"
|
||||
? {
|
||||
gridArea: "2 / 3 / 3 / 4",
|
||||
marginLeft: "9px",
|
||||
marginTop: "auto",
|
||||
|
||||
...MRT_DISPLAYLINE_STYLES,
|
||||
...lines[0]?.style,
|
||||
}
|
||||
: {
|
||||
gridArea: "4 / 3 / 5 / 4",
|
||||
marginLeft: "9px",
|
||||
marginTop: "auto",
|
||||
...MRT_DISPLAYLINE_STYLES,
|
||||
...lines[0]?.style,
|
||||
}
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{lines[1] && (
|
||||
<DisplayLine
|
||||
lineStyle={{
|
||||
overflowX: "hidden",
|
||||
maxHeight: "100%",
|
||||
overflowY: "auto",
|
||||
}}
|
||||
{...lines[1]}
|
||||
style={
|
||||
page === "sds"
|
||||
? {
|
||||
gridArea: "4 / 2 / 10 / 4",
|
||||
marginLeft: "3px",
|
||||
...MRT_DISPLAYLINE_STYLES,
|
||||
...lines[1].style,
|
||||
}
|
||||
: {
|
||||
gridArea: "5 / 3 / 7 / 4",
|
||||
marginLeft: "3px",
|
||||
marginTop: "auto",
|
||||
...MRT_DISPLAYLINE_STYLES,
|
||||
...lines[1].style,
|
||||
}
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{lines[2] && (
|
||||
<DisplayLine
|
||||
{...lines[2]}
|
||||
style={{
|
||||
gridArea: "8 / 2 / 9 / 4",
|
||||
...MRT_DISPLAYLINE_STYLES,
|
||||
...lines[2]?.style,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{lines[3] && (
|
||||
<DisplayLine
|
||||
{...lines[3]}
|
||||
style={{
|
||||
gridArea: "9 / 2 / 10 / 4",
|
||||
marginRight: "10px",
|
||||
...MRT_DISPLAYLINE_STYLES,
|
||||
...lines[3]?.style,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
32
apps/dispatch/app/(app)/pilot/_components/mrt/mrt.css
Normal file
32
apps/dispatch/app/(app)/pilot/_components/mrt/mrt.css
Normal file
@@ -0,0 +1,32 @@
|
||||
#mrt-container {
|
||||
container-name: mrtContainer;
|
||||
}
|
||||
|
||||
@container mrtContainer (inline-size < 600px) {
|
||||
#mrt-container .text-1 {
|
||||
font-size: 12px;
|
||||
color: red;
|
||||
}
|
||||
#mrt-container .text-2 {
|
||||
font-size: 99px;
|
||||
}
|
||||
#mrt-container .text-3 {
|
||||
font-size: 25px;
|
||||
}
|
||||
#mrt-container .text-4 {
|
||||
font-size: 45px;
|
||||
}
|
||||
}
|
||||
|
||||
#mrt-container .text-1 {
|
||||
font-size: 10px;
|
||||
}
|
||||
#mrt-container .text-2 {
|
||||
font-size: 12px;
|
||||
}
|
||||
#mrt-container .text-3 {
|
||||
font-size: 15px;
|
||||
}
|
||||
#mrt-container .text-4 {
|
||||
font-size: 25px;
|
||||
}
|
||||
76
apps/dispatch/app/(app)/pilot/_components/mrt/useButtons.ts
Normal file
76
apps/dispatch/app/(app)/pilot/_components/mrt/useButtons.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import { ConnectedAircraft, Prisma } from "@repo/db";
|
||||
import { usePilotConnectionStore } from "_store/pilot/connectionStore";
|
||||
import { useMrtStore } from "_store/pilot/MrtStore";
|
||||
import { pilotSocket } from "(app)/pilot/socket";
|
||||
import { editConnectedAircraftAPI } from "_querys/aircrafts";
|
||||
import { useEffect } from "react";
|
||||
import { useMutation } from "@tanstack/react-query";
|
||||
|
||||
export const useButtons = () => {
|
||||
const station = usePilotConnectionStore((state) => state.selectedStation);
|
||||
const connectedAircraft = usePilotConnectionStore((state) => state.connectedAircraft);
|
||||
const connectionStatus = usePilotConnectionStore((state) => state.status);
|
||||
const updateAircraftMutation = useMutation({
|
||||
mutationKey: ["edit-pilot-connected-aircraft"],
|
||||
mutationFn: ({
|
||||
aircraftId,
|
||||
data,
|
||||
}: {
|
||||
aircraftId: number;
|
||||
data: Prisma.ConnectedAircraftUpdateInput;
|
||||
}) => editConnectedAircraftAPI(aircraftId, data),
|
||||
});
|
||||
|
||||
const { page, setPage } = useMrtStore((state) => state);
|
||||
|
||||
const handleButton =
|
||||
(button: "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "0" | "home") => () => {
|
||||
if (connectionStatus !== "connected") return;
|
||||
if (!station) return;
|
||||
if (!connectedAircraft?.id) return;
|
||||
if (
|
||||
button === "1" ||
|
||||
button === "2" ||
|
||||
button === "3" ||
|
||||
button === "4" ||
|
||||
button === "5" ||
|
||||
button === "6" ||
|
||||
button === "7" ||
|
||||
button === "8" ||
|
||||
button === "9" ||
|
||||
button === "0"
|
||||
) {
|
||||
setPage({ page: "sending-status", station });
|
||||
|
||||
setTimeout(async () => {
|
||||
await updateAircraftMutation.mutateAsync({
|
||||
aircraftId: connectedAircraft.id,
|
||||
data: {
|
||||
fmsStatus: button,
|
||||
},
|
||||
});
|
||||
setPage({
|
||||
page: "home",
|
||||
station,
|
||||
fmsStatus: button,
|
||||
});
|
||||
}, 1000);
|
||||
} else {
|
||||
setPage({ page: "home", fmsStatus: connectedAircraft.fmsStatus || "6", station });
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
pilotSocket.on("connect", () => {
|
||||
if (!station) return;
|
||||
setPage({ page: "home", fmsStatus: "6", station });
|
||||
});
|
||||
|
||||
pilotSocket.on("aircraft-update", () => {
|
||||
if (!station) return;
|
||||
setPage({ page: "new-status", station });
|
||||
});
|
||||
}, [setPage, station]);
|
||||
|
||||
return { handleButton };
|
||||
};
|
||||
52
apps/dispatch/app/(app)/pilot/_components/mrt/useSounds.ts
Normal file
52
apps/dispatch/app/(app)/pilot/_components/mrt/useSounds.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
"use client";
|
||||
import { usePilotConnectionStore } from "_store/pilot/connectionStore";
|
||||
import { useMrtStore } from "_store/pilot/MrtStore";
|
||||
import { useEffect, useRef } from "react";
|
||||
|
||||
export const useSounds = () => {
|
||||
const mrtState = useMrtStore((state) => state);
|
||||
const { connectedAircraft, selectedStation } = usePilotConnectionStore((state) => state);
|
||||
|
||||
const setPage = useMrtStore((state) => state.setPage);
|
||||
const MRTstatusSoundRef = useRef<HTMLAudioElement>(null);
|
||||
const MrtMessageReceivedSoundRef = useRef<HTMLAudioElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window !== "undefined") {
|
||||
MRTstatusSoundRef.current = new Audio("/sounds/MRT-status.mp3");
|
||||
MrtMessageReceivedSoundRef.current = new Audio("/sounds/MRT-message-received.mp3");
|
||||
MRTstatusSoundRef.current.onended = () => {
|
||||
if (!selectedStation || !connectedAircraft?.fmsStatus) return;
|
||||
setPage({
|
||||
page: "home",
|
||||
station: selectedStation,
|
||||
fmsStatus: connectedAircraft?.fmsStatus,
|
||||
});
|
||||
};
|
||||
MrtMessageReceivedSoundRef.current.onended = () => {
|
||||
if (!selectedStation || !connectedAircraft?.fmsStatus) return;
|
||||
if (mrtState.page === "sds") return;
|
||||
setPage({
|
||||
page: "home",
|
||||
station: selectedStation,
|
||||
fmsStatus: connectedAircraft?.fmsStatus,
|
||||
});
|
||||
};
|
||||
}
|
||||
}, [connectedAircraft?.fmsStatus, selectedStation, setPage, mrtState.page]);
|
||||
|
||||
const fmsStatus = connectedAircraft?.fmsStatus || "NaN";
|
||||
|
||||
useEffect(() => {
|
||||
if (!connectedAircraft) return;
|
||||
if (mrtState.page === "new-status") {
|
||||
if (fmsStatus === "J" || fmsStatus === "c") {
|
||||
MrtMessageReceivedSoundRef.current?.play();
|
||||
} else {
|
||||
MRTstatusSoundRef.current?.play();
|
||||
}
|
||||
} else if (mrtState.page === "sds") {
|
||||
MrtMessageReceivedSoundRef.current?.play();
|
||||
}
|
||||
}, [mrtState, fmsStatus, connectedAircraft, selectedStation]);
|
||||
};
|
||||
Reference in New Issue
Block a user