Fix Pilot-conenction
This commit is contained in:
@@ -3,11 +3,10 @@
|
|||||||
import { useSession } from "next-auth/react";
|
import { useSession } from "next-auth/react";
|
||||||
import { useDispatchConnectionStore } from "../../../../../_store/dispatch/connectionStore";
|
import { useDispatchConnectionStore } from "../../../../../_store/dispatch/connectionStore";
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import { toast } from "react-hot-toast";
|
|
||||||
import { useMutation } from "@tanstack/react-query";
|
import { useMutation } from "@tanstack/react-query";
|
||||||
import { Prisma } from "@repo/db";
|
import { Prisma } from "@repo/db";
|
||||||
import { changeDispatcherAPI } from "_querys/dispatcher";
|
import { changeDispatcherAPI } from "_querys/dispatcher";
|
||||||
import { getNextDateWithTime } from "@repo/shared-components";
|
import { Button, getNextDateWithTime } from "@repo/shared-components";
|
||||||
|
|
||||||
export const ConnectionBtn = () => {
|
export const ConnectionBtn = () => {
|
||||||
const modalRef = useRef<HTMLDialogElement>(null);
|
const modalRef = useRef<HTMLDialogElement>(null);
|
||||||
@@ -20,44 +19,19 @@ export const ConnectionBtn = () => {
|
|||||||
mutationFn: ({ id, data }: { id: number; data: Prisma.ConnectedDispatcherUpdateInput }) =>
|
mutationFn: ({ id, data }: { id: number; data: Prisma.ConnectedDispatcherUpdateInput }) =>
|
||||||
changeDispatcherAPI(id, data),
|
changeDispatcherAPI(id, data),
|
||||||
});
|
});
|
||||||
const [logoffDebounce, setLogoffDebounce] = useState<NodeJS.Timeout | null>(null);
|
|
||||||
const session = useSession();
|
const session = useSession();
|
||||||
const uid = session.data?.user?.id;
|
const uid = session.data?.user?.id;
|
||||||
|
|
||||||
// useEffect für die Logoff-Zeit
|
// useEffect für die Logoff-Zeit
|
||||||
const [logoffHours, logoffMinutes] = form.logoffTime?.split(":").map(Number) || [];
|
const [logoffHours, logoffMinutes] = form.logoffTime?.split(":").map(Number) || [];
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!logoffHours || !logoffMinutes) return;
|
|
||||||
if (logoffDebounce) clearTimeout(logoffDebounce);
|
|
||||||
|
|
||||||
const timeout = setTimeout(async () => {
|
|
||||||
if (!logoffHours || !logoffMinutes || !connection.connectedDispatcher) return;
|
|
||||||
await changeDispatcherMutation.mutateAsync({
|
|
||||||
id: connection.connectedDispatcher?.id,
|
|
||||||
data: {
|
|
||||||
esimatedLogoutTime:
|
|
||||||
logoffHours && logoffMinutes ? getNextDateWithTime(logoffHours, logoffMinutes) : null,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
toast.success("Änderung gespeichert!");
|
|
||||||
modalRef.current?.close();
|
|
||||||
}, 2000);
|
|
||||||
|
|
||||||
setLogoffDebounce(timeout);
|
|
||||||
|
|
||||||
// Cleanup function
|
|
||||||
return () => {
|
|
||||||
if (logoffDebounce) clearTimeout(logoffDebounce);
|
|
||||||
};
|
|
||||||
}, [form.logoffTime, connection.connectedDispatcher]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Disconnect the socket when the component unmounts
|
// Disconnect the socket when the component unmounts
|
||||||
return () => {
|
return () => {
|
||||||
connection.disconnect();
|
connection.disconnect();
|
||||||
};
|
};
|
||||||
}, [connection.disconnect]);
|
}, [connection.disconnect]);
|
||||||
|
|
||||||
if (!uid) return null;
|
if (!uid) return null;
|
||||||
return (
|
return (
|
||||||
<div className="rounded-box bg-base-200 flex justify-center items-center gap-2 p-1">
|
<div className="rounded-box bg-base-200 flex justify-center items-center gap-2 p-1">
|
||||||
@@ -122,6 +96,25 @@ export const ConnectionBtn = () => {
|
|||||||
<form method="dialog" className="w-full flex justify-between">
|
<form method="dialog" className="w-full flex justify-between">
|
||||||
<button className="btn btn-soft">Zurück</button>
|
<button className="btn btn-soft">Zurück</button>
|
||||||
{connection.status == "connected" ? (
|
{connection.status == "connected" ? (
|
||||||
|
<>
|
||||||
|
<Button
|
||||||
|
className="btn"
|
||||||
|
onClick={async () => {
|
||||||
|
if (!connection.connectedDispatcher?.id) return;
|
||||||
|
await changeDispatcherMutation.mutateAsync({
|
||||||
|
id: connection.connectedDispatcher?.id,
|
||||||
|
data: {
|
||||||
|
esimatedLogoutTime:
|
||||||
|
logoffHours && logoffMinutes
|
||||||
|
? getNextDateWithTime(logoffHours, logoffMinutes)
|
||||||
|
: null,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
modalRef.current?.close();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Logoff-Zeit speichern
|
||||||
|
</Button>
|
||||||
<button
|
<button
|
||||||
className="btn btn-soft btn-error"
|
className="btn btn-soft btn-error"
|
||||||
type="submit"
|
type="submit"
|
||||||
@@ -132,6 +125,7 @@ export const ConnectionBtn = () => {
|
|||||||
>
|
>
|
||||||
Verbindung Trennen
|
Verbindung Trennen
|
||||||
</button>
|
</button>
|
||||||
|
</>
|
||||||
) : (
|
) : (
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
|
|||||||
@@ -4,10 +4,9 @@ import { usePilotConnectionStore } from "_store/pilot/connectionStore";
|
|||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
import { getStationsAPI } from "_querys/stations";
|
import { getStationsAPI } from "_querys/stations";
|
||||||
import toast from "react-hot-toast";
|
|
||||||
import { editConnectedAircraftAPI, getConnectedAircraftsAPI } from "_querys/aircrafts";
|
import { editConnectedAircraftAPI, getConnectedAircraftsAPI } from "_querys/aircrafts";
|
||||||
import { Prisma } from "@repo/db";
|
import { Prisma } from "@repo/db";
|
||||||
import { getNextDateWithTime } from "@repo/shared-components";
|
import { Button, getNextDateWithTime } from "@repo/shared-components";
|
||||||
import { Select } from "_components/Select";
|
import { Select } from "_components/Select";
|
||||||
import { Radio } from "lucide-react";
|
import { Radio } from "lucide-react";
|
||||||
|
|
||||||
@@ -23,7 +22,6 @@ export const ConnectionBtn = () => {
|
|||||||
selectedStationId: null,
|
selectedStationId: null,
|
||||||
debugPosition: false,
|
debugPosition: false,
|
||||||
});
|
});
|
||||||
const [logoffDebounce, setLogoffDebounce] = useState<NodeJS.Timeout | null>(null);
|
|
||||||
|
|
||||||
const { data: stations } = useQuery({
|
const { data: stations } = useQuery({
|
||||||
queryKey: ["stations"],
|
queryKey: ["stations"],
|
||||||
@@ -53,7 +51,8 @@ export const ConnectionBtn = () => {
|
|||||||
return () => {
|
return () => {
|
||||||
connection.disconnect();
|
connection.disconnect();
|
||||||
};
|
};
|
||||||
}, [connection, connection.disconnect]);
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [connection.disconnect]);
|
||||||
|
|
||||||
const [logoffHours, logoffMinutes] = form.logoffTime?.split(":").map(Number) || [];
|
const [logoffHours, logoffMinutes] = form.logoffTime?.split(":").map(Number) || [];
|
||||||
|
|
||||||
@@ -62,32 +61,6 @@ export const ConnectionBtn = () => {
|
|||||||
queryFn: () => getConnectedAircraftsAPI(),
|
queryFn: () => getConnectedAircraftsAPI(),
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!logoffHours || !logoffMinutes || !connection.connectedAircraft) return;
|
|
||||||
|
|
||||||
if (logoffDebounce) clearTimeout(logoffDebounce);
|
|
||||||
|
|
||||||
const timeout = setTimeout(async () => {
|
|
||||||
if (!connection.connectedAircraft?.id) return;
|
|
||||||
await aircraftMutation.mutateAsync({
|
|
||||||
sessionId: connection.connectedAircraft.id,
|
|
||||||
change: {
|
|
||||||
esimatedLogoutTime:
|
|
||||||
logoffHours && logoffMinutes ? getNextDateWithTime(logoffHours, logoffMinutes) : null,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
modalRef.current?.close();
|
|
||||||
toast.success("Änderung gespeichert!");
|
|
||||||
}, 2000);
|
|
||||||
|
|
||||||
setLogoffDebounce(timeout);
|
|
||||||
|
|
||||||
// Cleanup function to clear timeout
|
|
||||||
return () => {
|
|
||||||
if (logoffDebounce) clearTimeout(logoffDebounce);
|
|
||||||
};
|
|
||||||
}, [logoffHours, logoffMinutes, connection.connectedAircraft, aircraftMutation, logoffDebounce]);
|
|
||||||
|
|
||||||
const session = useSession();
|
const session = useSession();
|
||||||
const uid = session.data?.user?.id;
|
const uid = session.data?.user?.id;
|
||||||
if (!uid) return null;
|
if (!uid) return null;
|
||||||
@@ -185,7 +158,8 @@ export const ConnectionBtn = () => {
|
|||||||
)}
|
)}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
{session.data?.user.permissions.includes("ADMIN_STATION") && (
|
{session.data?.user.permissions.includes("ADMIN_STATION") &&
|
||||||
|
connection.status === "disconnected" && (
|
||||||
<fieldset className="fieldset bg-base-100 border-base-300 rounded-box w-full border p-4">
|
<fieldset className="fieldset bg-base-100 border-base-300 rounded-box w-full border p-4">
|
||||||
<legend className="fieldset-legend">Debug-optionen</legend>
|
<legend className="fieldset-legend">Debug-optionen</legend>
|
||||||
<label className="label">
|
<label className="label">
|
||||||
@@ -203,6 +177,25 @@ export const ConnectionBtn = () => {
|
|||||||
<form method="dialog" className="w-full flex justify-between">
|
<form method="dialog" className="w-full flex justify-between">
|
||||||
<button className="btn btn-soft">Zurück</button>
|
<button className="btn btn-soft">Zurück</button>
|
||||||
{connection.status == "connected" ? (
|
{connection.status == "connected" ? (
|
||||||
|
<>
|
||||||
|
<Button
|
||||||
|
className="btn"
|
||||||
|
onClick={async () => {
|
||||||
|
if (!connection.connectedAircraft) return;
|
||||||
|
await aircraftMutation.mutateAsync({
|
||||||
|
sessionId: connection.connectedAircraft.id,
|
||||||
|
change: {
|
||||||
|
esimatedLogoutTime:
|
||||||
|
logoffHours && logoffMinutes
|
||||||
|
? getNextDateWithTime(logoffHours, logoffMinutes)
|
||||||
|
: null,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
modalRef.current?.close();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Logoff-Zeit speichern
|
||||||
|
</Button>
|
||||||
<button
|
<button
|
||||||
className="btn btn-soft btn-error"
|
className="btn btn-soft btn-error"
|
||||||
type="submit"
|
type="submit"
|
||||||
@@ -213,17 +206,18 @@ export const ConnectionBtn = () => {
|
|||||||
>
|
>
|
||||||
Verbindung Trennen
|
Verbindung Trennen
|
||||||
</button>
|
</button>
|
||||||
|
</>
|
||||||
) : (
|
) : (
|
||||||
<button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
onSubmit={() => false}
|
onSubmit={() => false}
|
||||||
onClick={() => {
|
onClick={async () => {
|
||||||
const selectedStation = stations?.find(
|
const selectedStation = stations?.find(
|
||||||
(station) =>
|
(station) =>
|
||||||
station.id === parseInt(form.selectedStationId?.toString() || ""),
|
station.id === parseInt(form.selectedStationId?.toString() || ""),
|
||||||
);
|
);
|
||||||
if (selectedStation) {
|
if (selectedStation) {
|
||||||
connection.connect(
|
await connection.connect(
|
||||||
uid,
|
uid,
|
||||||
form.selectedStationId?.toString() || "",
|
form.selectedStationId?.toString() || "",
|
||||||
form.logoffTime || "",
|
form.logoffTime || "",
|
||||||
@@ -232,11 +226,12 @@ export const ConnectionBtn = () => {
|
|||||||
form.debugPosition,
|
form.debugPosition,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
modalRef.current?.close();
|
||||||
}}
|
}}
|
||||||
className="btn btn-soft btn-info"
|
className="btn btn-soft btn-info"
|
||||||
>
|
>
|
||||||
{connection.status == "disconnected" ? "Verbinden" : connection.status}
|
{connection.status == "disconnected" ? "Verbinden" : connection.status}
|
||||||
</button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
43
packages/shared-components/components/Button.tsx
Normal file
43
packages/shared-components/components/Button.tsx
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
"use client";
|
||||||
|
import React, {
|
||||||
|
ButtonHTMLAttributes,
|
||||||
|
DetailedHTMLProps,
|
||||||
|
useEffect,
|
||||||
|
useState,
|
||||||
|
forwardRef,
|
||||||
|
} from "react";
|
||||||
|
import { cn } from "@repo/shared-components";
|
||||||
|
|
||||||
|
export const Button = forwardRef<
|
||||||
|
HTMLButtonElement,
|
||||||
|
DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement> & {
|
||||||
|
isLoading?: boolean;
|
||||||
|
}
|
||||||
|
>(({ isLoading, ...props }, ref) => {
|
||||||
|
const [isLoadingState, setIsLoadingState] = useState(isLoading);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setIsLoadingState(isLoading);
|
||||||
|
}, [isLoading]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
{...props}
|
||||||
|
ref={ref}
|
||||||
|
className={cn("btn", props.className)}
|
||||||
|
disabled={isLoadingState || props.disabled}
|
||||||
|
onClick={async (e) => {
|
||||||
|
if (props.onClick) {
|
||||||
|
setIsLoadingState(true);
|
||||||
|
await props.onClick(e);
|
||||||
|
setIsLoadingState(false);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{isLoadingState && <span className="loading loading-spinner loading-sm"></span>}
|
||||||
|
{props.children}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
Button.displayName = "Button";
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
export * from "./Badge";
|
export * from "./Badge";
|
||||||
export * from "./PenaltyDropdown";
|
export * from "./PenaltyDropdown";
|
||||||
export * from "./Maintenance";
|
export * from "./Maintenance";
|
||||||
|
export * from "./Button";
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
"tailwind-merge": "^3.3.0"
|
"tailwind-merge": "^3.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react": "^19.1.6",
|
"@types/react": "^19.1.8",
|
||||||
"@types/react-dom": "^19.1.5",
|
"@types/react-dom": "^19.1.5",
|
||||||
"react": "^19.1.0",
|
"react": "^19.1.0",
|
||||||
"react-dom": "^19.1.0"
|
"react-dom": "^19.1.0"
|
||||||
|
|||||||
10
pnpm-lock.yaml
generated
10
pnpm-lock.yaml
generated
@@ -630,11 +630,11 @@ importers:
|
|||||||
version: 3.3.0
|
version: 3.3.0
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@types/react':
|
'@types/react':
|
||||||
specifier: ^19.1.6
|
specifier: ^19.1.8
|
||||||
version: 19.1.6
|
version: 19.1.8
|
||||||
'@types/react-dom':
|
'@types/react-dom':
|
||||||
specifier: ^19.1.5
|
specifier: ^19.1.5
|
||||||
version: 19.1.5(@types/react@19.1.6)
|
version: 19.1.5(@types/react@19.1.8)
|
||||||
react:
|
react:
|
||||||
specifier: ^19.1.0
|
specifier: ^19.1.0
|
||||||
version: 19.1.0
|
version: 19.1.0
|
||||||
@@ -8668,9 +8668,9 @@ snapshots:
|
|||||||
|
|
||||||
'@types/range-parser@1.2.7': {}
|
'@types/range-parser@1.2.7': {}
|
||||||
|
|
||||||
'@types/react-dom@19.1.5(@types/react@19.1.6)':
|
'@types/react-dom@19.1.5(@types/react@19.1.8)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/react': 19.1.6
|
'@types/react': 19.1.8
|
||||||
|
|
||||||
'@types/react-dom@19.1.6(@types/react@19.1.8)':
|
'@types/react-dom@19.1.6(@types/react@19.1.8)':
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|||||||
Reference in New Issue
Block a user