diff --git a/apps/dispatch-server/package.json b/apps/dispatch-server/package.json index 35e57464..5471a6ed 100644 --- a/apps/dispatch-server/package.json +++ b/apps/dispatch-server/package.json @@ -12,6 +12,7 @@ "devDependencies": { "@repo/db": "workspace:*", "@repo/typescript-config": "workspace:*", + "@repo/shared-components": "workspace:*", "@types/cookie-parser": "^1.4.8", "@types/cors": "^2.8.18", "@types/express": "^5.0.2", diff --git a/apps/dispatch-server/socket-events/connect-dispatch.ts b/apps/dispatch-server/socket-events/connect-dispatch.ts index 7dfb6a5c..5bc654f1 100644 --- a/apps/dispatch-server/socket-events/connect-dispatch.ts +++ b/apps/dispatch-server/socket-events/connect-dispatch.ts @@ -1,5 +1,6 @@ import { getPublicUser, prisma, User } from "@repo/db"; import { addRolesToMember, removeRolesFromMember, renameMember } from "modules/discord"; +import { getNextDateWithTime } from "@repo/shared-components"; import { DISCORD_ROLES } from "@repo/db"; import { Server, Socket } from "socket.io"; @@ -45,30 +46,13 @@ export const handleConnectDispatch = } let parsedLogoffDate = null; - if (logoffTime.length > 0) { - const now = new Date(); - const [hours, minutes] = logoffTime.split(":").map(Number); - if (!hours || !minutes) { - throw new Error("Invalid logoffTime format"); - } - parsedLogoffDate = new Date(now); - parsedLogoffDate.setHours(hours, minutes, 0, 0); - - // If the calculated time is earlier than now, add one day to make it tomorrow - if (parsedLogoffDate <= now) { - parsedLogoffDate.setDate(parsedLogoffDate.getDate() + 1); - } - - // If the calculated time is in the past, add one day to make it in the future - if (parsedLogoffDate <= now) { - parsedLogoffDate.setDate(parsedLogoffDate.getDate() + 1); - } - } + const [logoffHours, logoffMinutes] = logoffTime.split(":").map(Number); const connectedDispatcherEntry = await prisma.connectedDispatcher.create({ data: { publicUser: getPublicUser(user) as any, - esimatedLogoutTime: parsedLogoffDate?.toISOString() || null, + esimatedLogoutTime: + logoffHours && logoffMinutes ? getNextDateWithTime(logoffHours, logoffMinutes) : null, lastHeartbeat: new Date().toISOString(), userId: user.id, zone: selectedZone, diff --git a/apps/dispatch-server/socket-events/connect-pilot.ts b/apps/dispatch-server/socket-events/connect-pilot.ts index 2aacc23a..4c1dbc1d 100644 --- a/apps/dispatch-server/socket-events/connect-pilot.ts +++ b/apps/dispatch-server/socket-events/connect-pilot.ts @@ -1,5 +1,6 @@ import { getPublicUser, prisma, User } from "@repo/db"; import { addRolesToMember, removeRolesFromMember, renameMember } from "modules/discord"; +import { getNextDateWithTime } from "@repo/shared-components"; import { DISCORD_ROLES } from "@repo/db"; import { Server, Socket } from "socket.io"; @@ -55,22 +56,6 @@ export const handleConnectPilot = }); } - let parsedLogoffDate = null; - if (logoffTime.length > 0) { - const now = new Date(); - const [hours, minutes] = logoffTime.split(":").map(Number); - if (!hours || !minutes) { - throw new Error("Invalid logoffTime format"); - } - parsedLogoffDate = new Date(now); - parsedLogoffDate.setHours(hours, minutes, 0, 0); - - // If the calculated time is earlier than now, add one day to make it tomorrow - if (parsedLogoffDate <= now) { - parsedLogoffDate.setDate(parsedLogoffDate.getDate() + 1); - } - } - // Set "now" to 2 hours in the future const nowPlus2h = new Date(); nowPlus2h.setHours(nowPlus2h.getHours() + 2); @@ -87,11 +72,13 @@ export const handleConnectPilot = } const randomPos = debug ? getRandomGermanPosition() : undefined; + const [logoffHours, logoffMinutes] = logoffTime.split(":").map(Number); const connectedAircraftEntry = await prisma.connectedAircraft.create({ data: { publicUser: getPublicUser(user) as any, - esimatedLogoutTime: parsedLogoffDate?.toISOString() || null, + esimatedLogoutTime: + logoffHours && logoffMinutes ? getNextDateWithTime(logoffHours, logoffMinutes) : null, userId: userId, stationId: parseInt(stationId), lastHeartbeat: debug ? nowPlus2h.toISOString() : undefined, diff --git a/apps/dispatch-server/tsconfig.json b/apps/dispatch-server/tsconfig.json index f3c1bbd3..b1087ac2 100644 --- a/apps/dispatch-server/tsconfig.json +++ b/apps/dispatch-server/tsconfig.json @@ -2,9 +2,10 @@ "extends": "@repo/typescript-config/base.json", "compilerOptions": { "outDir": "dist", - "allowImportingTsExtensions": false, - "baseUrl": ".", - "jsx": "react" + "module": "ESNext", + "moduleResolution": "bundler", + "noEmit": true, + "baseUrl": "." }, "include": ["**/*.ts", "./index.ts", "**/*.d.ts"], "exclude": ["node_modules", "dist"] 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 2496d489..66dea2af 100644 --- a/apps/dispatch/app/(app)/dispatch/_components/navbar/_components/Connection.tsx +++ b/apps/dispatch/app/(app)/dispatch/_components/navbar/_components/Connection.tsx @@ -6,6 +6,7 @@ import { toast } from "react-hot-toast"; import { useMutation } from "@tanstack/react-query"; import { Prisma } from "@repo/db"; import { changeDispatcherAPI } from "_querys/dispatcher"; +import { getNextDateWithTime } from "@repo/shared-components"; export const ConnectionBtn = () => { const modalRef = useRef(null); @@ -24,17 +25,19 @@ export const ConnectionBtn = () => { if (!uid) return null; // useEffect für die Logoff-Zeit + const [logoffHours, logoffMinutes] = form.logoffTime?.split(":").map(Number) || []; + useEffect(() => { + if (!logoffHours || !logoffMinutes) return; if (logoffDebounce) clearTimeout(logoffDebounce); const timeout = setTimeout(async () => { - if (!form.logoffTime || !connection.connectedDispatcher) return; + if (!logoffHours || !logoffMinutes || !connection.connectedDispatcher) return; await changeDispatcherMutation.mutateAsync({ id: connection.connectedDispatcher?.id, data: { - esimatedLogoutTime: new Date( - new Date().toDateString() + " " + form.logoffTime, - ).toISOString(), + esimatedLogoutTime: + logoffHours && logoffMinutes ? getNextDateWithTime(logoffHours, logoffMinutes) : null, }, }); toast.success("Änderung gespeichert!"); diff --git a/apps/dispatch/app/(app)/pilot/_components/navbar/_components/Connection.tsx b/apps/dispatch/app/(app)/pilot/_components/navbar/_components/Connection.tsx index 13ef94d3..b7e23776 100644 --- a/apps/dispatch/app/(app)/pilot/_components/navbar/_components/Connection.tsx +++ b/apps/dispatch/app/(app)/pilot/_components/navbar/_components/Connection.tsx @@ -8,6 +8,7 @@ import toast from "react-hot-toast"; import { editConnectedAircraftAPI } from "_querys/aircrafts"; import { Prisma } from "@repo/db"; import { debug } from "console"; +import { getNextDateWithTime } from "@repo/shared-components"; export const ConnectionBtn = () => { const modalRef = useRef(null); @@ -53,10 +54,10 @@ export const ConnectionBtn = () => { }; }, [connection.disconnect]); - const logoffTime = form.logoffTime; + const [logoffHours, logoffMinutes] = form.logoffTime?.split(":").map(Number) || []; useEffect(() => { - if (!logoffTime || !connection.connectedAircraft) return; + if (!logoffHours || !logoffMinutes || !connection.connectedAircraft) return; if (logoffDebounce) clearTimeout(logoffDebounce); @@ -65,9 +66,8 @@ export const ConnectionBtn = () => { await aircraftMutation.mutateAsync({ sessionId: connection.connectedAircraft.id, change: { - esimatedLogoutTime: logoffTime - ? new Date(new Date().toDateString() + " " + logoffTime).toISOString() - : null, + esimatedLogoutTime: + logoffHours && logoffMinutes ? getNextDateWithTime(logoffHours, logoffMinutes) : null, }, }); modalRef.current?.close(); @@ -80,7 +80,7 @@ export const ConnectionBtn = () => { return () => { if (logoffDebounce) clearTimeout(logoffDebounce); }; - }, [logoffTime, connection.connectedAircraft]); + }, [logoffHours, logoffMinutes, connection.connectedAircraft]); const session = useSession(); const uid = session.data?.user?.id; diff --git a/apps/dispatch/app/_components/map/_components/AircraftMarkerTabs.tsx b/apps/dispatch/app/_components/map/_components/AircraftMarkerTabs.tsx index 080c72ee..4f455050 100644 --- a/apps/dispatch/app/_components/map/_components/AircraftMarkerTabs.tsx +++ b/apps/dispatch/app/_components/map/_components/AircraftMarkerTabs.tsx @@ -1,7 +1,9 @@ "use client"; import React, { useEffect, useMemo, useState } from "react"; import { FMS_STATUS_COLORS, FMS_STATUS_TEXT_COLORS } from "_helpers/fmsStatusColors"; +import { Badge, cn } from "@repo/shared-components"; import { + BADGES, ConnectedAircraft, getPublicUser, Mission, @@ -16,7 +18,6 @@ import { toast } from "react-hot-toast"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { editConnectedAircraftAPI } from "_querys/aircrafts"; import { useDispatchConnectionStore } from "_store/dispatch/connectionStore"; -import { cn } from "@repo/shared-components"; import { PersonIcon } from "@radix-ui/react-icons"; import { Ban, @@ -42,6 +43,8 @@ import { useSession } from "next-auth/react"; import { sendSdsMessageAPI } from "_querys/missions"; import { getLivekitRooms } from "_querys/livekit"; import { findLeitstelleForPosition } from "_helpers/findLeitstelleinPoint"; +import { formatDistance } from "date-fns"; +import { de } from "date-fns/locale"; const FMSStatusHistory = ({ aircraft, @@ -63,9 +66,22 @@ const FMSStatusHistory = ({