shared library hinzugefügt
@@ -15,7 +15,7 @@ import {
|
||||
ZapOff,
|
||||
} from "lucide-react";
|
||||
import { useAudioStore } from "_store/audioStore";
|
||||
import { cn } from "_helpers/cn";
|
||||
import { cn } from "@repo/shared-components";
|
||||
import { ConnectionQuality } from "livekit-client";
|
||||
import { ROOMS } from "_data/livekitRooms";
|
||||
import { useDispatchConnectionStore } from "_store/dispatch/connectionStore";
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
import { BADGES } from "@repo/db";
|
||||
import P1 from "./p-1.png";
|
||||
import P2 from "./p-2.png";
|
||||
import P3 from "./p-3.png";
|
||||
import D1 from "./d-1.png";
|
||||
import D2 from "./d-2.png";
|
||||
import D3 from "./d-3.png";
|
||||
import DAY1 from "./day-1-member.png";
|
||||
import { cn } from "_helpers/cn";
|
||||
|
||||
const BadgeImage = {
|
||||
[BADGES.P1]: P1,
|
||||
[BADGES.P2]: P2,
|
||||
[BADGES.P3]: P3,
|
||||
[BADGES.D1]: D1,
|
||||
[BADGES.D2]: D2,
|
||||
[BADGES.D3]: D3,
|
||||
[BADGES.DAY1]: DAY1,
|
||||
[BADGES.V1Veteran]: DAY1,
|
||||
};
|
||||
|
||||
export const Badge = ({ name, className }: { name: BADGES; className?: string }) => {
|
||||
const image = BadgeImage[name];
|
||||
|
||||
return (
|
||||
<span className={cn("flex h-fit p-1", className)}>
|
||||
<img src={image.src} alt={name} width={100} />
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 1.7 MiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 29 KiB |
@@ -1,6 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import { cn } from "_helpers/cn";
|
||||
import { cn } from "@repo/shared-components";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
type MicrophoneLevelProps = {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
import { FieldValues, Path, RegisterOptions, UseFormReturn } from "react-hook-form";
|
||||
import SelectTemplate, { Props as SelectTemplateProps, StylesConfig } from "react-select";
|
||||
import { cn } from "_helpers/cn";
|
||||
import { cn } from "@repo/shared-components";
|
||||
import dynamic from "next/dynamic";
|
||||
import { CSSProperties } from "react";
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { cn } from "_helpers/cn";
|
||||
import { cn } from "@repo/shared-components";
|
||||
import { RefAttributes, useCallback, useEffect, useImperativeHandle } from "react";
|
||||
import { createContext, Ref, useContext, useState } from "react";
|
||||
import { Popup, PopupProps, useMap } from "react-leaflet";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { AdminMessage } from "@repo/db";
|
||||
import { BaseNotification } from "_components/customToasts/BaseNotification";
|
||||
import { cn } from "_helpers/cn";
|
||||
import { cn } from "@repo/shared-components";
|
||||
import { TriangleAlert } from "lucide-react";
|
||||
import toast, { Toast } from "react-hot-toast";
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { cn } from "_helpers/cn";
|
||||
import { cn } from "@repo/shared-components";
|
||||
|
||||
export const BaseNotification = ({
|
||||
children,
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ChatBubbleIcon, PaperPlaneIcon } from "@radix-ui/react-icons";
|
||||
import { useLeftMenuStore } from "_store/leftMenuStore";
|
||||
import { useSession } from "next-auth/react";
|
||||
import { Fragment, useEffect, useState } from "react";
|
||||
import { cn } from "_helpers/cn";
|
||||
import { cn } from "@repo/shared-components";
|
||||
import { asPublicUser } from "@repo/db";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { getConnectedDispatcherAPI } from "_querys/dispatcher";
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { ExclamationTriangleIcon, PaperPlaneIcon } from "@radix-ui/react-icons";
|
||||
import { useSession } from "next-auth/react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { cn } from "_helpers/cn";
|
||||
import { cn } from "@repo/shared-components";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { useLeftMenuStore } from "_store/leftMenuStore";
|
||||
import { asPublicUser } from "@repo/db";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
import { useLeftMenuStore } from "_store/leftMenuStore";
|
||||
import { cn } from "_helpers/cn";
|
||||
import { cn } from "@repo/shared-components";
|
||||
import { ListCollapse, Plane } from "lucide-react";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { getMissionsAPI } from "_querys/missions";
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Marker, Polyline, useMap } from "react-leaflet";
|
||||
import { DivIcon, Marker as LMarker, Popup as LPopup } from "leaflet";
|
||||
import { useMapStore } from "_store/mapStore";
|
||||
import { Fragment, useCallback, useEffect, useRef, useState, useMemo } from "react";
|
||||
import { cn } from "_helpers/cn";
|
||||
import { cn } from "@repo/shared-components";
|
||||
import { ChevronsRightLeft, House, MessageSquareText, Minimize2 } from "lucide-react";
|
||||
import { SmartPopup, calculateAnchor, useSmartPopup } from "_components/SmartPopup";
|
||||
import FMSStatusHistory, {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { DivIcon, LatLngExpression, Marker as LMarker, Popup as LPopup } from "l
|
||||
import { useMapStore } from "_store/mapStore";
|
||||
import { usePannelStore } from "_store/pannelStore";
|
||||
import { Fragment, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { cn } from "_helpers/cn";
|
||||
import { cn } from "@repo/shared-components";
|
||||
import { ClipboardList, Cross, House, Minimize2, SmartphoneNfc, PencilLine } from "lucide-react";
|
||||
import { calculateAnchor, SmartPopup, useSmartPopup } from "_components/SmartPopup";
|
||||
import { Mission, MissionState } from "@repo/db";
|
||||
|
||||
@@ -16,7 +16,7 @@ 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 "_helpers/cn";
|
||||
import { cn } from "@repo/shared-components";
|
||||
import { PersonIcon } from "@radix-ui/react-icons";
|
||||
import {
|
||||
Ban,
|
||||
|
||||
@@ -5,7 +5,7 @@ import { useDispatchConnectionStore } from "_store/dispatch/connectionStore";
|
||||
import { useMapStore } from "_store/mapStore";
|
||||
import { FMS_STATUS_COLORS, FMS_STATUS_TEXT_COLORS } from "_helpers/fmsStatusColors";
|
||||
import { MISSION_STATUS_COLORS, MISSION_STATUS_TEXT_COLORS } from "_components/map/MissionMarkers";
|
||||
import { cn } from "_helpers/cn";
|
||||
import { cn } from "@repo/shared-components";
|
||||
import { getConnectedAircraftsAPI } from "_querys/aircrafts";
|
||||
import { getMissionsAPI } from "_querys/missions";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
|
||||
@@ -47,7 +47,7 @@ import { useDispatchConnectionStore } from "_store/dispatch/connectionStore";
|
||||
import { HPGValidationRequired } from "_helpers/hpgValidationRequired";
|
||||
import { getOsmAddress } from "_querys/osm";
|
||||
import { hpgStateToFMSStatus } from "_helpers/hpgStateToFmsStatus";
|
||||
import { cn } from "_helpers/cn";
|
||||
import { cn } from "@repo/shared-components";
|
||||
|
||||
const Einsatzdetails = ({
|
||||
mission,
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
"use client";
|
||||
import { PublicUser } from "@repo/db";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { cn } from "_helpers/cn";
|
||||
import { cn, PenaltyDropdown } from "@repo/shared-components";
|
||||
import { getConnectedAircraftsAPI, kickAircraftAPI } from "_querys/aircrafts";
|
||||
import { getConnectedDispatcherAPI, kickDispatcherAPI } from "_querys/dispatcher";
|
||||
import { getLivekitRooms, kickLivekitParticipant } from "_querys/livekit";
|
||||
import { editUserAPI } from "_querys/user";
|
||||
import { ParticipantInfo } from "livekit-server-sdk";
|
||||
import {
|
||||
Eye,
|
||||
@@ -21,112 +20,6 @@ import {
|
||||
import { ReactNode, useRef, useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
|
||||
const PenaltyDropdown = ({
|
||||
onClick,
|
||||
btnClassName,
|
||||
showDatePicker,
|
||||
btnTip,
|
||||
Icon,
|
||||
}: {
|
||||
onClick: (data: { reason: string; until: Date | null }) => void;
|
||||
showDatePicker?: boolean;
|
||||
btnClassName?: string;
|
||||
btnTip?: string;
|
||||
Icon: ReactNode;
|
||||
}) => {
|
||||
const [reason, setReason] = useState("");
|
||||
const [until, setUntil] = useState<string>("default");
|
||||
return (
|
||||
<details className="dropdown dropdown-left dropdown-center">
|
||||
<summary className={cn("btn btn-xs btn-square btn-soft", btnClassName)}>{Icon}</summary>
|
||||
<div className="dropdown-content flex gap-3 bg-base-100 rounded-box z-1 p-2 mr-3 shadow-sm">
|
||||
<input
|
||||
value={reason}
|
||||
onChange={(e) => setReason(e.target.value)}
|
||||
type="text"
|
||||
className="input min-w-[250px]"
|
||||
placeholder="Begründung"
|
||||
/>
|
||||
{showDatePicker && (
|
||||
<select
|
||||
className="select min-w-[150px] select-bordered"
|
||||
value={until}
|
||||
onChange={(e) => setUntil(e.target.value)}
|
||||
>
|
||||
<option value="default" disabled>
|
||||
Unbegrenzt
|
||||
</option>
|
||||
<option value="1h">1 Stunde</option>
|
||||
<option value="6h">6 Stunden</option>
|
||||
<option value="12h">12 Stunden</option>
|
||||
<option value="24h">24 Stunden</option>
|
||||
<option value="72h">72 Stunden</option>
|
||||
<option value="1w">1 Woche</option>
|
||||
<option value="2w">2 Wochen</option>
|
||||
<option value="1m">1 Monat</option>
|
||||
<option value="3m">3 Monate</option>
|
||||
<option value="6m">6 Monate</option>
|
||||
<option value="1y">1 Jahr</option>
|
||||
</select>
|
||||
)}
|
||||
<button
|
||||
className={cn(
|
||||
"btn btn-square btn-soft tooltip tooltip-bottom tooltip-warning",
|
||||
btnClassName,
|
||||
)}
|
||||
data-tip={btnTip}
|
||||
onClick={() => {
|
||||
let untilDate: Date | null = null;
|
||||
if (until !== "default") {
|
||||
const now = new Date();
|
||||
switch (until) {
|
||||
case "1h":
|
||||
untilDate = new Date(now.getTime() + 1 * 60 * 60 * 1000);
|
||||
break;
|
||||
case "6h":
|
||||
untilDate = new Date(now.getTime() + 6 * 60 * 60 * 1000);
|
||||
break;
|
||||
case "12h":
|
||||
untilDate = new Date(now.getTime() + 12 * 60 * 60 * 1000);
|
||||
break;
|
||||
case "24h":
|
||||
untilDate = new Date(now.getTime() + 24 * 60 * 60 * 1000);
|
||||
break;
|
||||
case "72h":
|
||||
untilDate = new Date(now.getTime() + 72 * 60 * 60 * 1000);
|
||||
break;
|
||||
case "1w":
|
||||
untilDate = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000);
|
||||
break;
|
||||
case "2w":
|
||||
untilDate = new Date(now.getTime() + 14 * 24 * 60 * 60 * 1000);
|
||||
break;
|
||||
case "1m":
|
||||
untilDate = new Date(now.setMonth(now.getMonth() + 1));
|
||||
break;
|
||||
case "3m":
|
||||
untilDate = new Date(now.setMonth(now.getMonth() + 3));
|
||||
break;
|
||||
case "6m":
|
||||
untilDate = new Date(now.setMonth(now.getMonth() + 6));
|
||||
break;
|
||||
case "1y":
|
||||
untilDate = new Date(now.setFullYear(now.getFullYear() + 1));
|
||||
break;
|
||||
default:
|
||||
untilDate = null;
|
||||
}
|
||||
}
|
||||
onClick({ reason, until: untilDate });
|
||||
}}
|
||||
>
|
||||
{Icon}
|
||||
</button>
|
||||
</div>
|
||||
</details>
|
||||
);
|
||||
};
|
||||
|
||||
export default function AdminPanel() {
|
||||
const queryClient = useQueryClient();
|
||||
const { data: pilots } = useQuery({
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { cn } from "_helpers/cn";
|
||||
import { cn } from "@repo/shared-components";
|
||||
import { ArrowLeftRight, Plane, Radar, Workflow } from "lucide-react";
|
||||
import { useSession } from "next-auth/react";
|
||||
import Link from "next/link";
|
||||
|
||||