diff --git a/.vscode/settings.json b/.vscode/settings.json index 07bb728a..7265ca71 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,6 +2,7 @@ "editor.formatOnSave": true, "files.autoSave": "off", "editor.defaultFormatter": "esbenp.prettier-vscode", + "eslint.workingDirectories": [{ "mode": "auto" }], "editor.codeActionsOnSave": ["source.formatDocument", "source.fixAll.eslint"], "typescript.validate.enable": true, "typescript.tsserver.experimental.enableProjectDiagnostics": true, diff --git a/apps/dispatch/app/(app)/dispatch/_components/StationSelect.tsx b/apps/dispatch/app/(app)/dispatch/_components/StationSelect.tsx index dec6274a..53038bdb 100644 --- a/apps/dispatch/app/(app)/dispatch/_components/StationSelect.tsx +++ b/apps/dispatch/app/(app)/dispatch/_components/StationSelect.tsx @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { HpgState } from "@repo/db"; import { cn } from "@repo/shared-components"; import { useQuery } from "@tanstack/react-query"; @@ -6,7 +7,6 @@ import { getConnectedAircraftsAPI } from "_querys/aircrafts"; import { getStationsAPI } from "_querys/stations"; import { Ambulance, FireExtinguisher, Radio, Siren } from "lucide-react"; import { useEffect, useState } from "react"; -import { FieldValues } from "react-hook-form"; type MissionStationsSelectProps = { selectedStations?: number[]; @@ -54,7 +54,6 @@ export function StationsSelect({ ...(vehicleStates.hpgFireEngineState !== HpgState.NOT_REQUESTED || undefined ? ["FW"] : []), ...(vehicleStates.hpgPoliceState !== HpgState.NOT_REQUESTED || undefined ? ["POL"] : []), ]); - // eslint-disable-next-line react-hooks/exhaustive-deps }, [selectedStations, vehicleStates]); // Helper to check if a station is a vehicle and its state is NOT_REQUESTED 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 66dea2af..3ec4a56a 100644 --- a/apps/dispatch/app/(app)/dispatch/_components/navbar/_components/Connection.tsx +++ b/apps/dispatch/app/(app)/dispatch/_components/navbar/_components/Connection.tsx @@ -1,3 +1,4 @@ +/* eslint-disable react-hooks/exhaustive-deps */ "use client"; import { useSession } from "next-auth/react"; import { useDispatchConnectionStore } from "../../../../../_store/dispatch/connectionStore"; @@ -22,7 +23,6 @@ export const ConnectionBtn = () => { const [logoffDebounce, setLogoffDebounce] = useState(null); const session = useSession(); const uid = session.data?.user?.id; - if (!uid) return null; // useEffect für die Logoff-Zeit const [logoffHours, logoffMinutes] = form.logoffTime?.split(":").map(Number) || []; @@ -58,7 +58,7 @@ export const ConnectionBtn = () => { connection.disconnect(); }; }, [connection.disconnect]); - + if (!uid) return null; return (
{connection.message.length > 0 && ( diff --git a/apps/dispatch/app/(app)/dispatch/_components/pannel/MissionForm.tsx b/apps/dispatch/app/(app)/dispatch/_components/pannel/MissionForm.tsx index 3ae8f2e0..df0baa41 100644 --- a/apps/dispatch/app/(app)/dispatch/_components/pannel/MissionForm.tsx +++ b/apps/dispatch/app/(app)/dispatch/_components/pannel/MissionForm.tsx @@ -1,8 +1,9 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ "use client"; import React, { useEffect } from "react"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; -import { BellRing, BookmarkPlus, Radio } from "lucide-react"; +import { BellRing, BookmarkPlus } from "lucide-react"; import { KEYWORD_CATEGORY, Mission, missionType, Prisma } from "@repo/db"; import { JsonValueType, diff --git a/apps/dispatch/app/(app)/dispatch/_components/pannel/Pannel.tsx b/apps/dispatch/app/(app)/dispatch/_components/pannel/Pannel.tsx index cb98c919..4515fce0 100644 --- a/apps/dispatch/app/(app)/dispatch/_components/pannel/Pannel.tsx +++ b/apps/dispatch/app/(app)/dispatch/_components/pannel/Pannel.tsx @@ -26,7 +26,14 @@ export const Pannel = () => { setOpen(false); } } - }, [missions, setMissionFormValues, setEditingMission, setOpen, missionFormValues]); + }, [ + missions, + setMissionFormValues, + setEditingMission, + setOpen, + missionFormValues, + editingMissionId, + ]); return (
diff --git a/apps/dispatch/app/(app)/pilot/_components/mrt/useButtons.ts b/apps/dispatch/app/(app)/pilot/_components/mrt/useButtons.ts index dfaad039..8718295f 100644 --- a/apps/dispatch/app/(app)/pilot/_components/mrt/useButtons.ts +++ b/apps/dispatch/app/(app)/pilot/_components/mrt/useButtons.ts @@ -1,4 +1,4 @@ -import { ConnectedAircraft, Prisma } from "@repo/db"; +import { Prisma } from "@repo/db"; import { usePilotConnectionStore } from "_store/pilot/connectionStore"; import { useMrtStore } from "_store/pilot/MrtStore"; import { pilotSocket } from "(app)/pilot/socket"; @@ -21,7 +21,7 @@ export const useButtons = () => { }) => editConnectedAircraftAPI(aircraftId, data), }); - const { page, setPage } = useMrtStore((state) => state); + const { setPage } = useMrtStore((state) => state); const handleButton = (button: "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "0" | "home") => () => { 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 85e54acb..e39c1f74 100644 --- a/apps/dispatch/app/(app)/pilot/_components/navbar/_components/Connection.tsx +++ b/apps/dispatch/app/(app)/pilot/_components/navbar/_components/Connection.tsx @@ -9,7 +9,6 @@ import { editConnectedAircraftAPI, getConnectedAircraftsAPI } from "_querys/airc import { Prisma } from "@repo/db"; import { getNextDateWithTime } from "@repo/shared-components"; import { Select } from "_components/Select"; -import { components } from "react-select"; import { Radio } from "lucide-react"; export const ConnectionBtn = () => { @@ -54,7 +53,7 @@ export const ConnectionBtn = () => { return () => { connection.disconnect(); }; - }, [connection.disconnect]); + }, [connection, connection.disconnect]); const [logoffHours, logoffMinutes] = form.logoffTime?.split(":").map(Number) || []; @@ -87,7 +86,7 @@ export const ConnectionBtn = () => { return () => { if (logoffDebounce) clearTimeout(logoffDebounce); }; - }, [logoffHours, logoffMinutes, connection.connectedAircraft]); + }, [logoffHours, logoffMinutes, connection.connectedAircraft, aircraftMutation, logoffDebounce]); const session = useSession(); const uid = session.data?.user?.id; @@ -143,7 +142,9 @@ export const ConnectionBtn = () => { }) } value={form.selectedStationId ?? ""} - formatOptionLabel={(option: any) => option.component} + formatOptionLabel={(option: unknown) => + (option as { component: React.ReactNode }).component + } options={ stations?.map((station) => ({ value: station.id.toString(), diff --git a/apps/dispatch/app/(app)/pilot/page.tsx b/apps/dispatch/app/(app)/pilot/page.tsx index 664b0b8e..e72bf3e9 100644 --- a/apps/dispatch/app/(app)/pilot/page.tsx +++ b/apps/dispatch/app/(app)/pilot/page.tsx @@ -8,7 +8,7 @@ import dynamic from "next/dynamic"; import { ConnectedDispatcher } from "tracker/_components/ConnectedDispatcher"; import { useQuery } from "@tanstack/react-query"; import { usePilotConnectionStore } from "_store/pilot/connectionStore"; -import { getAircraftsAPI, getConnectedAircraftsAPI } from "_querys/aircrafts"; +import { getAircraftsAPI } from "_querys/aircrafts"; import { checkSimulatorConnected } from "@repo/shared-components"; import { SimConnectionAlert } from "(app)/pilot/_components/SimConnectionAlert"; diff --git a/apps/dispatch/app/(auth)/layout.tsx b/apps/dispatch/app/(auth)/layout.tsx index 27c67211..a721e44c 100644 --- a/apps/dispatch/app/(auth)/layout.tsx +++ b/apps/dispatch/app/(auth)/layout.tsx @@ -1,5 +1,4 @@ import { NextPage } from "next"; -import { ReactNode } from "react"; const AuthLayout: NextPage< Readonly<{ diff --git a/apps/dispatch/app/(auth)/login/_components/Login.tsx b/apps/dispatch/app/(auth)/login/_components/Login.tsx index 57c23341..515d3a85 100644 --- a/apps/dispatch/app/(auth)/login/_components/Login.tsx +++ b/apps/dispatch/app/(auth)/login/_components/Login.tsx @@ -14,7 +14,7 @@ export const Login = () => { if (status === "authenticated") { navigate.push("/"); } - }, [session, navigate]); + }, [session, navigate, status]); useEffect(() => { const signInWithCode = async () => { diff --git a/apps/dispatch/app/_components/Audio/useSounds.ts b/apps/dispatch/app/_components/Audio/useSounds.ts index 9a7e8acd..c70247da 100644 --- a/apps/dispatch/app/_components/Audio/useSounds.ts +++ b/apps/dispatch/app/_components/Audio/useSounds.ts @@ -1,5 +1,5 @@ "use client"; -import { useDebounce } from "_helpers/useDebounce"; +import { useDebounce } from "@repo/shared-components"; import { useAudioStore } from "_store/audioStore"; import { useEffect, useRef, useState } from "react"; @@ -112,5 +112,6 @@ export const useSounds = ({ callToLong.current!.pause(); }; } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [isTransmitting]); }; diff --git a/apps/dispatch/app/_components/ErrorBoundary.tsx b/apps/dispatch/app/_components/ErrorBoundary.tsx index 3b60d886..11082aa7 100644 --- a/apps/dispatch/app/_components/ErrorBoundary.tsx +++ b/apps/dispatch/app/_components/ErrorBoundary.tsx @@ -11,10 +11,10 @@ export const CustomErrorBoundary = ({ children }: { children?: React.ReactNode } let errorTest; let errorCode = 500; if ("statusCode" in error) { - errorCode = (error as any).statusCode; + errorCode = error.statusCode; } if ("message" in error || error instanceof Error) { - errorTest = (error as any).message; + errorTest = error.message; } else if (typeof error === "string") { errorTest = error; } else { diff --git a/apps/dispatch/app/_components/QueryProvider.tsx b/apps/dispatch/app/_components/QueryProvider.tsx index 2148e219..b973a835 100644 --- a/apps/dispatch/app/_components/QueryProvider.tsx +++ b/apps/dispatch/app/_components/QueryProvider.tsx @@ -2,10 +2,10 @@ "use client"; import { toast } from "react-hot-toast"; -import { QueryClient, QueryClientProvider, useQuery } from "@tanstack/react-query"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { ReactNode, useEffect, useState } from "react"; import { dispatchSocket } from "(app)/dispatch/socket"; -import { Mission, NotificationPayload } from "@repo/db"; +import { NotificationPayload } from "@repo/db"; import { HPGnotificationToast } from "_components/customToasts/HPGnotification"; import { useMapStore } from "_store/mapStore"; import { AdminMessageToast } from "_components/customToasts/AdminMessage"; @@ -30,7 +30,7 @@ export function QueryProvider({ children }: { children: ReactNode }) { }), ); useEffect(() => { - const invalidateMission = (mission: Mission) => { + const invalidateMission = () => { queryClient.invalidateQueries({ queryKey: ["missions"], }); diff --git a/apps/dispatch/app/_components/Select.tsx b/apps/dispatch/app/_components/Select.tsx index 2db672ad..d7605b2d 100644 --- a/apps/dispatch/app/_components/Select.tsx +++ b/apps/dispatch/app/_components/Select.tsx @@ -1,5 +1,5 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ "use client"; -import { FieldValues, Path } from "react-hook-form"; import SelectTemplate, { Props as SelectTemplateProps, StylesConfig } from "react-select"; import { cn } from "@repo/shared-components"; import dynamic from "next/dynamic"; @@ -99,7 +99,7 @@ const SelectCom = ({ ); }; -const SelectWrapper = (props: SelectProps) => ; +const SelectWrapper = (props: SelectProps) => ; export const Select = dynamic(() => Promise.resolve(SelectWrapper), { ssr: false, diff --git a/apps/dispatch/app/_components/customToasts/HPGnotification.tsx b/apps/dispatch/app/_components/customToasts/HPGnotification.tsx index 5437598b..ccf5593d 100644 --- a/apps/dispatch/app/_components/customToasts/HPGnotification.tsx +++ b/apps/dispatch/app/_components/customToasts/HPGnotification.tsx @@ -1,6 +1,6 @@ -import { NotificationPayload, ValidationFailed, ValidationSuccess } from "@repo/db"; +import { ValidationFailed, ValidationSuccess } from "@repo/db"; import { BaseNotification } from "_components/customToasts/BaseNotification"; -import { MapStore, useMapStore } from "_store/mapStore"; +import { MapStore } from "_store/mapStore"; import { Check, Cross } from "lucide-react"; import toast, { Toast } from "react-hot-toast"; diff --git a/apps/dispatch/app/_components/customToasts/StationStatusToast.tsx b/apps/dispatch/app/_components/customToasts/StationStatusToast.tsx index 76737ef1..689cbbde 100644 --- a/apps/dispatch/app/_components/customToasts/StationStatusToast.tsx +++ b/apps/dispatch/app/_components/customToasts/StationStatusToast.tsx @@ -5,7 +5,6 @@ import { FMS_STATUS_COLORS } from "_helpers/fmsStatusColors"; import { editConnectedAircraftAPI, getConnectedAircraftsAPI } from "_querys/aircrafts"; import { getStationsAPI } from "_querys/stations"; import { useMapStore } from "_store/mapStore"; -import { cpSync } from "fs"; import { X } from "lucide-react"; import { useEffect, useRef, useState } from "react"; import { Toast, toast } from "react-hot-toast"; @@ -67,7 +66,7 @@ export const StatusToast = ({ event, t }: { event: StationStatus; t: Toast }) => } else if (event.status == connectedAircraft?.fmsStatus && !aircraftDataAcurate) { setAircraftDataAccurate(true); } - }, [connectedAircraft, station]); + }, [aircraftDataAcurate, connectedAircraft, event.status, t.id]); useEffect(() => { let soundRef: React.RefObject | null = null; diff --git a/apps/dispatch/app/_components/left/Chat.tsx b/apps/dispatch/app/_components/left/Chat.tsx index 79ae6b36..0ef4ed3e 100644 --- a/apps/dispatch/app/_components/left/Chat.tsx +++ b/apps/dispatch/app/_components/left/Chat.tsx @@ -41,7 +41,7 @@ export const Chat = () => { useEffect(() => { if (!session.data?.user.id) return; setOwnId(session.data?.user.id); - }, [session.data?.user.id]); + }, [session.data?.user.id, setOwnId]); const filteredDispatcher = dispatcher?.filter((d) => d.userId !== session.data?.user.id); const filteredAircrafts = aircrafts?.filter((a) => a.userId !== session.data?.user.id); @@ -118,7 +118,7 @@ export const Chat = () => { const dispatcherUser = dispatcher?.find((d) => d.userId === addTabValue); const user = aircraftUser || dispatcherUser; if (!user) return; - let role = "Station" in user ? user.Station.bosCallsignShort : user.zone; + const role = "Station" in user ? user.Station.bosCallsignShort : user.zone; addChat(addTabValue, `${asPublicUser(user.publicUser).fullName} (${role})`); setSelectedChat(addTabValue); }} diff --git a/apps/dispatch/app/_components/left/SituationBoard.tsx b/apps/dispatch/app/_components/left/SituationBoard.tsx index 91014b2f..635f75af 100644 --- a/apps/dispatch/app/_components/left/SituationBoard.tsx +++ b/apps/dispatch/app/_components/left/SituationBoard.tsx @@ -4,7 +4,7 @@ import { cn } from "@repo/shared-components"; import { ListCollapse, Plane } from "lucide-react"; import { useQuery } from "@tanstack/react-query"; import { getMissionsAPI } from "_querys/missions"; -import { Station } from "@repo/db"; +import { Mission, Station } from "@repo/db"; import { getConnectedAircraftsAPI } from "_querys/aircrafts"; import { FMS_STATUS_COLORS, FMS_STATUS_TEXT_COLORS } from "_helpers/fmsStatusColors"; import { useMapStore } from "_store/mapStore"; @@ -20,7 +20,13 @@ export const SituationBoard = () => { const { data: missions } = useQuery({ queryKey: ["missions", "missions-on-stations"], queryFn: () => - getMissionsAPI( + getMissionsAPI< + Mission & { + MissionsOnStations: (Station & { + Station: Station; + })[]; + } + >( { state: { not: "finished", @@ -125,8 +131,8 @@ export const SituationBoard = () => { {mission.missionKeywordAbbreviation} {mission.addressCity} - {(mission as any).MissionsOnStations?.map( - (mos: { Station: Station }) => mos.Station?.bosCallsignShort, + {mission.MissionsOnStations?.map( + (mos) => mos.Station?.bosCallsignShort, ).join(", ")} diff --git a/apps/dispatch/app/_components/map/AircraftMarker.tsx b/apps/dispatch/app/_components/map/AircraftMarker.tsx index 23ac1ef2..28fee344 100644 --- a/apps/dispatch/app/_components/map/AircraftMarker.tsx +++ b/apps/dispatch/app/_components/map/AircraftMarker.tsx @@ -262,7 +262,7 @@ const AircraftMarker = ({ aircraft }: { aircraft: ConnectedAircraft & { Station: return () => { marker?.off("click", handleClick); }; - }, [aircraft.id, openAircraftMarker, setOpenAircraftMarker, markerRef.current]); + }, [aircraft.id, openAircraftMarker, setOpenAircraftMarker]); const [anchor, setAnchor] = useState<"topleft" | "topright" | "bottomleft" | "bottomright">( "topleft", diff --git a/apps/dispatch/app/_components/map/BaseMaps.tsx b/apps/dispatch/app/_components/map/BaseMaps.tsx index f3a8e884..89dfac16 100644 --- a/apps/dispatch/app/_components/map/BaseMaps.tsx +++ b/apps/dispatch/app/_components/map/BaseMaps.tsx @@ -1,7 +1,6 @@ "use client"; -import { usePannelStore } from "_store/pannelStore"; import { Control, Icon, LatLngExpression } from "leaflet"; -import { useEffect, useMemo, useRef, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import { LayerGroup, LayersControl, @@ -15,7 +14,7 @@ import { Marker, Tooltip, } from "react-leaflet"; -// @ts-ignore +// @ts-expect-error geojson hat keine Typen import type { FeatureCollection, Geometry } from "geojson"; import L from "leaflet"; import LEITSTELLENBERECHE from "./_geojson/Leitstellen.json"; @@ -197,7 +196,7 @@ const StationsLayer = ({ attribution }: { attribution: Control.Attribution }) => ); }; -const EsriSatellite = ({ attribution }: { attribution: Control.Attribution }) => { +const EsriSatellite = () => { const accessToken = process.env.NEXT_PUBLIC_ESRI_ACCESS; return ( <> @@ -221,8 +220,7 @@ const StrassentexteEsri = () => { ); }; -const OpenAIP = ({ attribution }: { attribution: Control.Attribution }) => { - const accessToken = process.env.NEXT_PUBLIC_OPENAIP_ACCESS; +const OpenAIP = () => { const ref = useRef(null); return ( @@ -241,7 +239,7 @@ const OpenAIP = ({ attribution }: { attribution: Control.Attribution }) => { ); }; -const NiederschlagOverlay = ({ attribution }: { attribution: Control.Attribution }) => { +const NiederschlagOverlay = () => { const tileLayerRef = useRef(null); return ( @@ -311,7 +309,7 @@ export const BaseMaps = () => { - + @@ -322,7 +320,7 @@ export const BaseMaps = () => { - + @@ -348,7 +346,7 @@ export const BaseMaps = () => { - + diff --git a/apps/dispatch/app/_components/map/ContextMenu.tsx b/apps/dispatch/app/_components/map/ContextMenu.tsx index 79baa740..830a2c33 100644 --- a/apps/dispatch/app/_components/map/ContextMenu.tsx +++ b/apps/dispatch/app/_components/map/ContextMenu.tsx @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { OSMWay, Prisma } from "@repo/db"; +import { OSMWay } from "@repo/db"; import { useDispatchConnectionStore } from "_store/dispatch/connectionStore"; import { useMapStore } from "_store/mapStore"; import { usePannelStore } from "_store/pannelStore"; @@ -8,8 +8,6 @@ import { getOsmAddress } from "_querys/osm"; import { useEffect, useState } from "react"; import toast from "react-hot-toast"; import { Popup, useMap } from "react-leaflet"; -import { useMutation, useQueryClient } from "@tanstack/react-query"; -import { editMissionAPI } from "_querys/missions"; import { findClosestPolygon } from "_helpers/findClosestPolygon"; export const ContextMenu = () => { @@ -22,8 +20,9 @@ export const ContextMenu = () => { setSearchPopup, toggleSearchElementSelection, } = useMapStore(); - const { missionFormValues, setMissionFormValues, setOpen, isOpen, editingMissionId } = - usePannelStore((state) => state); + const { missionFormValues, setMissionFormValues, setOpen, isOpen } = usePannelStore( + (state) => state, + ); const [showRulerOptions, setShowRulerOptions] = useState(false); const [rulerHover, setRulerHover] = useState(false); const [rulerOptionsHover, setRulerOptionsHover] = useState(false); diff --git a/apps/dispatch/app/_components/map/MissionMarkers.tsx b/apps/dispatch/app/_components/map/MissionMarkers.tsx index 1a536087..5b186776 100644 --- a/apps/dispatch/app/_components/map/MissionMarkers.tsx +++ b/apps/dispatch/app/_components/map/MissionMarkers.tsx @@ -72,7 +72,7 @@ const MissionPopupContent = ({ default: return Error; } - }, [currentTab, mission]); + }, [currentTab, hpgNeedsAttention, mission]); const setOpenMissionMarker = useMapStore((state) => state.setOpenMissionMarker); const { anchor } = useSmartPopup(); @@ -350,6 +350,10 @@ const MissionMarker = ({ mission }: { mission: Mission }) => { editingMissionId, mission.addressLat, mission.addressLng, + mission.hpgLocationLat, + mission.hpgLocationLng, + mission.hpgValidationState, + mission.id, missionFormValues?.addressLat, missionFormValues?.addressLng, ]); diff --git a/apps/dispatch/app/_components/map/SearchElements.tsx b/apps/dispatch/app/_components/map/SearchElements.tsx index 24deb97f..05134368 100644 --- a/apps/dispatch/app/_components/map/SearchElements.tsx +++ b/apps/dispatch/app/_components/map/SearchElements.tsx @@ -8,7 +8,7 @@ import { useEffect } from "react"; export const SearchElements = () => { const { searchElements, openMissionMarker, setSearchElements } = useMapStore(); - const { isOpen: pannelOpen, editingMissionId } = usePannelStore((state) => state); + const { isOpen: pannelOpen } = usePannelStore((state) => state); const { data: missions } = useQuery({ queryKey: ["missions"], queryFn: () => @@ -42,7 +42,7 @@ export const SearchElements = () => { ); setSearchElements(elements.filter((e) => !!e)); } - }, [openMissionMarker, pannelOpen, missions]); + }, [openMissionMarker, pannelOpen, missions, setSearchElements]); const SearchElement = ({ element }: { element: OSMWay }) => { const { toggleSearchElementSelection } = useMapStore(); diff --git a/apps/dispatch/app/_components/map/_components/AircraftMarkerTabs.tsx b/apps/dispatch/app/_components/map/_components/AircraftMarkerTabs.tsx index 39c6e55b..3eafedaf 100644 --- a/apps/dispatch/app/_components/map/_components/AircraftMarkerTabs.tsx +++ b/apps/dispatch/app/_components/map/_components/AircraftMarkerTabs.tsx @@ -250,7 +250,7 @@ const StationTab = ({ aircraft }: { aircraft: ConnectedAircraft & { Station: Sta const lstName = useMemo(() => { if (!aircraft.posLng || !aircraft.posLat) return station.bosRadioArea; return findLeitstelleForPosition(aircraft.posLng, aircraft.posLat); - }, [aircraft.posLng, aircraft.posLat]); + }, [aircraft.posLng, aircraft.posLat, station.bosRadioArea]); return (
diff --git a/apps/dispatch/app/_components/map/_components/MissionMarkerTabs.tsx b/apps/dispatch/app/_components/map/_components/MissionMarkerTabs.tsx index c1f68a05..a50a8564 100644 --- a/apps/dispatch/app/_components/map/_components/MissionMarkerTabs.tsx +++ b/apps/dispatch/app/_components/map/_components/MissionMarkerTabs.tsx @@ -18,7 +18,6 @@ import { SmartphoneNfc, CheckCheck, Cross, - Radio, Route, } from "lucide-react"; import { @@ -26,12 +25,9 @@ import { HpgState, HpgValidationState, Mission, - MissionAlertLog, - MissionCompletedLog, MissionLog, MissionMessageLog, Prisma, - Station, } from "@repo/db"; import { usePannelStore } from "_store/pannelStore"; import { useSession } from "next-auth/react"; @@ -143,13 +139,16 @@ const Einsatzdetails = ({ state: "finished", missionLog: { push: { - type: "completed-log", - auto: false, - timeStamp: new Date().toISOString(), - data: { - user: getPublicUser(session.data?.user, { ignorePrivacy: true }), - }, - } as any, + toJSON: () => ({ + type: "message-log", + auto: false, + timeStamp: new Date().toISOString(), + data: { + message: "Einsatz abgeschlossen", + user: getPublicUser(session.data.user, { ignorePrivacy: true }), + }, + }), + }, }, }, }); @@ -408,11 +407,6 @@ const Rettungsmittel = ({ mission }: { mission: Mission }) => { refetchMissionStationIds(); }, [mission.missionStationIds, refetchMissionStationIds]); - const { data: allStations } = useQuery({ - queryKey: ["stations"], - queryFn: () => getStationsAPI(), - }); - const sendAlertMutation = useMutation({ mutationKey: ["missions"], mutationFn: ({ @@ -527,6 +521,7 @@ const Rettungsmittel = ({ mission }: { mission: Mission }) => { menuPlacement="top" className="min-w-[320px] flex-1" isMulti={false} + // eslint-disable-next-line @typescript-eslint/no-explicit-any onChange={(v: any) => { setSelectedStation(v); }} diff --git a/apps/dispatch/app/_components/navbar/AdminPanel.tsx b/apps/dispatch/app/_components/navbar/AdminPanel.tsx index f13649b3..3d1bbb49 100644 --- a/apps/dispatch/app/_components/navbar/AdminPanel.tsx +++ b/apps/dispatch/app/_components/navbar/AdminPanel.tsx @@ -1,13 +1,12 @@ "use client"; import { PublicUser } from "@repo/db"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; -import { cn, PenaltyDropdown } from "@repo/shared-components"; +import { PenaltyDropdown } from "@repo/shared-components"; import { getConnectedAircraftsAPI, kickAircraftAPI } from "_querys/aircrafts"; import { getConnectedDispatcherAPI, kickDispatcherAPI } from "_querys/dispatcher"; import { getLivekitRooms, kickLivekitParticipant } from "_querys/livekit"; import { ParticipantInfo } from "livekit-server-sdk"; import { - Eye, LockKeyhole, Plane, RedoDot, @@ -17,7 +16,7 @@ import { UserCheck, Workflow, } from "lucide-react"; -import { ReactNode, useRef, useState } from "react"; +import { useRef } from "react"; import toast from "react-hot-toast"; export default function AdminPanel() { diff --git a/apps/dispatch/app/_components/navbar/Settings.tsx b/apps/dispatch/app/_components/navbar/Settings.tsx index 1889edb9..0b223602 100644 --- a/apps/dispatch/app/_components/navbar/Settings.tsx +++ b/apps/dispatch/app/_components/navbar/Settings.tsx @@ -5,7 +5,6 @@ import { SettingsIcon, Volume2 } from "lucide-react"; import MicVolumeBar from "_components/MicVolumeIndication"; import { useMutation, useQuery } from "@tanstack/react-query"; import { editUserAPI, getUserAPI } from "_querys/user"; -import { Prisma } from "@repo/db"; import { useSession } from "next-auth/react"; import { useAudioStore } from "_store/audioStore"; import toast from "react-hot-toast"; diff --git a/apps/dispatch/app/_helpers/findClosestPolygon.ts b/apps/dispatch/app/_helpers/findClosestPolygon.ts index fd190696..bfda8688 100644 --- a/apps/dispatch/app/_helpers/findClosestPolygon.ts +++ b/apps/dispatch/app/_helpers/findClosestPolygon.ts @@ -36,6 +36,7 @@ export function findClosestPolygon( const polygon = toPolygonFeature(way.nodes); if (!polygon) continue; + // eslint-disable-next-line @typescript-eslint/no-explicit-any const center = centroid(polygon as any).geometry.coordinates; // [lon, lat] const newDistance = distance([referencePoint.lon, referencePoint.lat], center); diff --git a/apps/dispatch/app/_helpers/findLeitstelleinPoint.ts b/apps/dispatch/app/_helpers/findLeitstelleinPoint.ts index c4bfc5fd..1528d522 100644 --- a/apps/dispatch/app/_helpers/findLeitstelleinPoint.ts +++ b/apps/dispatch/app/_helpers/findLeitstelleinPoint.ts @@ -1,10 +1,10 @@ -import { point, multiPolygon, booleanPointInPolygon, booleanIntersects, polygon } from "@turf/turf"; +import { point, booleanPointInPolygon, polygon } from "@turf/turf"; import leitstellenGeoJSON from "../_components/map/_geojson/Leitstellen.json"; // Pfad anpassen export function findLeitstelleForPosition(lat: number, lng: number) { const heliPoint = point([lat, lng]); - for (const feature of (leitstellenGeoJSON as any).features) { + for (const feature of (leitstellenGeoJSON as GeoJSON.FeatureCollection).features) { const geom = feature.geometry; if (geom.type === "Polygon") { diff --git a/apps/dispatch/app/_helpers/liveKitEventHandler.ts b/apps/dispatch/app/_helpers/liveKitEventHandler.ts index 9a625eb8..3d93f718 100644 --- a/apps/dispatch/app/_helpers/liveKitEventHandler.ts +++ b/apps/dispatch/app/_helpers/liveKitEventHandler.ts @@ -1,8 +1,6 @@ import { useAudioStore } from "_store/audioStore"; import { - LocalParticipant, LocalTrackPublication, - Participant, RemoteParticipant, RemoteTrack, RemoteTrackPublication, @@ -30,19 +28,12 @@ export const handleTrackSubscribed = ( } }; -export const handleTrackUnsubscribed = ( - track: RemoteTrack, - publication: RemoteTrackPublication, - participant: RemoteParticipant, -) => { +export const handleTrackUnsubscribed = (track: RemoteTrack) => { // remove tracks from all attached elements track.detach(); }; -export const handleLocalTrackUnpublished = ( - publication: LocalTrackPublication, - participant: LocalParticipant, -) => { +export const handleLocalTrackUnpublished = (publication: LocalTrackPublication) => { // when local tracks are ended, update UI to remove them from rendering publication.track?.detach(); }; diff --git a/apps/dispatch/app/_querys/aircrafts.ts b/apps/dispatch/app/_querys/aircrafts.ts index b0978f0d..ddc53602 100644 --- a/apps/dispatch/app/_querys/aircrafts.ts +++ b/apps/dispatch/app/_querys/aircrafts.ts @@ -1,4 +1,4 @@ -import { ConnectedAircraft, PositionLog, Prisma, PublicUser, Station } from "@repo/db"; +import { ConnectedAircraft, PositionLog, Prisma, Station } from "@repo/db"; import axios from "axios"; import { serverApi } from "_helpers/axios"; import { checkSimulatorConnected } from "@repo/shared-components"; diff --git a/apps/dispatch/app/_querys/dispatcher.ts b/apps/dispatch/app/_querys/dispatcher.ts index 5865b9ae..fda3ed36 100644 --- a/apps/dispatch/app/_querys/dispatcher.ts +++ b/apps/dispatch/app/_querys/dispatcher.ts @@ -1,4 +1,4 @@ -import { ConnectedAircraft, ConnectedDispatcher, Prisma } from "@repo/db"; +import { ConnectedDispatcher, Prisma } from "@repo/db"; import { serverApi } from "_helpers/axios"; import axios from "axios"; diff --git a/apps/dispatch/app/_querys/missions.ts b/apps/dispatch/app/_querys/missions.ts index 5b106beb..8a212fcd 100644 --- a/apps/dispatch/app/_querys/missions.ts +++ b/apps/dispatch/app/_querys/missions.ts @@ -2,12 +2,12 @@ import { Mission, MissionSdsLog, Prisma } from "@repo/db"; import axios from "axios"; import { serverApi } from "_helpers/axios"; -export const getMissionsAPI = async ( +export const getMissionsAPI = async ( filter?: Prisma.MissionWhereInput, include?: Prisma.MissionInclude, orderBy?: Prisma.MissionOrderByWithRelationInput, -) => { - const res = await axios.get("/api/missions", { +): Promise => { + const res = await axios.get("/api/missions", { params: { filter: JSON.stringify(filter), include: JSON.stringify(include), diff --git a/apps/dispatch/app/_querys/osm.ts b/apps/dispatch/app/_querys/osm.ts index 42175f9f..20addd6f 100644 --- a/apps/dispatch/app/_querys/osm.ts +++ b/apps/dispatch/app/_querys/osm.ts @@ -1,5 +1,3 @@ -import { raw } from "../../../../packages/database/generated/client/runtime/library"; - export const getOsmAddress = async (lat: number, lng: number) => { const address = await fetch( `https://nominatim.openstreetmap.org/reverse?lat=${lat}&lon=${lng}&format=json`, diff --git a/apps/dispatch/app/_store/audioStore.ts b/apps/dispatch/app/_store/audioStore.ts index a6768468..6bf09c61 100644 --- a/apps/dispatch/app/_store/audioStore.ts +++ b/apps/dispatch/app/_store/audioStore.ts @@ -65,7 +65,7 @@ export const useAudioStore = create((set, get) => ({ const newSpeaktingParticipants = get().speakingParticipants.filter( (p) => !(p.identity === participant.identity), ); - set((state) => ({ + set(() => ({ speakingParticipants: newSpeaktingParticipants, })); if (newSpeaktingParticipants.length === 0 && get().transmitBlocked) { @@ -77,8 +77,7 @@ export const useAudioStore = create((set, get) => ({ set({ micDeviceId, micVolume }); }, toggleTalking: () => { - const { room, isTalking, micDeviceId, micVolume, speakingParticipants, transmitBlocked } = - get(); + const { room, isTalking, micDeviceId, speakingParticipants, transmitBlocked } = get(); if (!room) return; if (speakingParticipants.length > 0 && !isTalking && !transmitBlocked) { @@ -187,7 +186,7 @@ interface PTTData { } const handlePTT = (data: PTTData) => { - const { shouldTransmit, source } = data; + const { shouldTransmit } = data; const { room, speakingParticipants } = useAudioStore.getState(); if (!room) return; diff --git a/apps/dispatch/app/api/aircrafts/positionlog/route.ts b/apps/dispatch/app/api/aircrafts/positionlog/route.ts index 5878b4bb..00ea91a4 100644 --- a/apps/dispatch/app/api/aircrafts/positionlog/route.ts +++ b/apps/dispatch/app/api/aircrafts/positionlog/route.ts @@ -1,4 +1,4 @@ -import { prisma, Prisma } from "@repo/db"; +import { prisma } from "@repo/db"; import { NextRequest, NextResponse } from "next/server"; export async function GET(request: NextRequest): Promise { diff --git a/apps/dispatch/app/api/auth/[...nextauth]/auth.ts b/apps/dispatch/app/api/auth/[...nextauth]/auth.ts index 16f406b3..3f1268e9 100644 --- a/apps/dispatch/app/api/auth/[...nextauth]/auth.ts +++ b/apps/dispatch/app/api/auth/[...nextauth]/auth.ts @@ -1,7 +1,8 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { AuthOptions, getServerSession as getNextAuthServerSession } from "next-auth"; import { PrismaAdapter } from "@next-auth/prisma-adapter"; import Credentials from "next-auth/providers/credentials"; -import { prisma, PrismaClient } from "@repo/db"; +import { prisma } from "@repo/db"; export const options: AuthOptions = { providers: [ @@ -9,7 +10,7 @@ export const options: AuthOptions = { credentials: { code: { label: "code", type: "code" }, }, - async authorize(credentials, req) { + async authorize(credentials) { try { if (!credentials) throw new Error("No credentials provided"); const code = await prisma.oAuthToken.findFirstOrThrow({ @@ -60,7 +61,7 @@ export const options: AuthOptions = { adapter: PrismaAdapter(prisma as any), callbacks: { - jwt: async ({ token, user, ...rest }) => { + jwt: async ({ token, user }) => { if (user && "firstname" in user) { return { ...token, @@ -69,7 +70,7 @@ export const options: AuthOptions = { } return token; }, - session: async ({ session, user, token }) => { + session: async ({ session, token }) => { const dbUser = await prisma.user.findUnique({ where: { id: token?.sub, diff --git a/apps/dispatch/app/api/livekit-participant/route.ts b/apps/dispatch/app/api/livekit-participant/route.ts index 5b84765a..e17b57c1 100644 --- a/apps/dispatch/app/api/livekit-participant/route.ts +++ b/apps/dispatch/app/api/livekit-participant/route.ts @@ -3,15 +3,10 @@ import { RoomManager } from "_helpers/LivekitRoomManager"; import { getServerSession } from "api/auth/[...nextauth]/auth"; import { NextRequest } from "next/server"; -export const GET = async (request: NextRequest) => { +export const GET = async () => { const session = await getServerSession(); if (!session) return Response.json({ message: "Unauthorized" }, { status: 401 }); - const user = await prisma.user.findUnique({ - where: { - id: session.user.id, - }, - }); const rooms = await RoomManager.listRooms(); diff --git a/apps/dispatch/app/api/livekit-token/route.ts b/apps/dispatch/app/api/livekit-token/route.ts index 23e5219f..e1e37372 100644 --- a/apps/dispatch/app/api/livekit-token/route.ts +++ b/apps/dispatch/app/api/livekit-token/route.ts @@ -1,5 +1,4 @@ import { getServerSession } from "api/auth/[...nextauth]/auth"; -import { ROOMS } from "_data/livekitRooms"; import { AccessToken } from "livekit-server-sdk"; import { NextRequest } from "next/server"; import { getPublicUser, prisma } from "@repo/db"; diff --git a/apps/dispatch/app/api/position-log/route.ts b/apps/dispatch/app/api/position-log/route.ts index bba54a36..3b50dbcc 100644 --- a/apps/dispatch/app/api/position-log/route.ts +++ b/apps/dispatch/app/api/position-log/route.ts @@ -1,4 +1,4 @@ -import { PositionLog, Prisma, prisma, User } from "@repo/db"; +import { PositionLog, prisma, User } from "@repo/db"; import { getServerSession } from "api/auth/[...nextauth]/auth"; import { verify } from "jsonwebtoken"; diff --git a/apps/dispatch/eslint.config.js b/apps/dispatch/eslint.config.js index e8759ff5..47794e08 100644 --- a/apps/dispatch/eslint.config.js +++ b/apps/dispatch/eslint.config.js @@ -1,4 +1,4 @@ -import { nextJsConfig } from "@repo/eslint-config/next-js"; +import nextJsConfig from "@repo/eslint-config/next-js"; /** @type {import("eslint").Linter.Config} */ export default nextJsConfig; diff --git a/apps/dispatch/package.json b/apps/dispatch/package.json index 075b1b97..d2af73a6 100644 --- a/apps/dispatch/package.json +++ b/apps/dispatch/package.json @@ -12,6 +12,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { + "@eslint/eslintrc": "^3.3.1", "@hookform/resolvers": "^5.1.1", "@livekit/components-react": "^2.9.12", "@livekit/components-styles": "^1.1.6", @@ -34,6 +35,7 @@ "clsx": "^2.1.1", "daisyui": "^5.0.43", "date-fns": "^4.1.0", + "eslint-config-next": "^15.3.4", "geojson": "^0.5.0", "i": "^0.3.7", "jsonwebtoken": "^9.0.2", diff --git a/apps/dispatch/types/next-auth.d.ts b/apps/dispatch/types/next-auth.d.ts index 511b2555..5d6c6cd0 100644 --- a/apps/dispatch/types/next-auth.d.ts +++ b/apps/dispatch/types/next-auth.d.ts @@ -1,4 +1,3 @@ -import NextAuth from "next-auth"; import { User as IUser } from "@repo/db"; declare module "next-auth" { diff --git a/apps/hub/app/(app)/admin/config/action.tsx b/apps/hub/app/(app)/admin/config/action.tsx index 6a1600f2..38be7209 100644 --- a/apps/hub/app/(app)/admin/config/action.tsx +++ b/apps/hub/app/(app)/admin/config/action.tsx @@ -6,8 +6,8 @@ export const addMessage = async (notam: Prisma.ConfigCreateInput) => { await prisma.config.create({ data: notam, }); - } catch (error) { - throw new Error("Failed to add message"); + } catch (e) { + throw new Error(`Failed to add message: ${e instanceof Error ? e.message : "Unknown error"}`); } }; @@ -16,7 +16,7 @@ export const disableMessage = async () => { await prisma.config.create({ data: {}, }); - } catch (error) { - throw new Error("Failed to disable message"); + } catch (e) { + throw new Error(`Failed to add message: ${e instanceof Error ? e.message : "Unknown error"}`); } }; diff --git a/apps/hub/app/(app)/admin/config/page.tsx b/apps/hub/app/(app)/admin/config/page.tsx index e19171e9..b514fb08 100644 --- a/apps/hub/app/(app)/admin/config/page.tsx +++ b/apps/hub/app/(app)/admin/config/page.tsx @@ -1,6 +1,6 @@ "use client"; -import { Check, MessageSquareWarning, Settings } from "lucide-react"; +import { Check, Settings } from "lucide-react"; import { MessageForm } from "./_components/MessageForm"; import { PaginatedTable, PaginatedTableRef } from "_components/PaginatedTable"; import { ColumnDef } from "@tanstack/react-table"; diff --git a/apps/hub/app/(app)/admin/event/_components/AppointmentModal.tsx b/apps/hub/app/(app)/admin/event/_components/AppointmentModal.tsx index 2805750c..4d6ec3d8 100644 --- a/apps/hub/app/(app)/admin/event/_components/AppointmentModal.tsx +++ b/apps/hub/app/(app)/admin/event/_components/AppointmentModal.tsx @@ -1,5 +1,5 @@ import { Event, Participant } from "@repo/db"; -import { EventAppointmentOptionalDefaults } from "@repo/db/zod"; +import { EventAppointmentOptionalDefaults, InputJsonValueType } from "@repo/db/zod"; import { ColumnDef } from "@tanstack/react-table"; import { useSession } from "next-auth/react"; import { RefObject, useRef } from "react"; @@ -45,7 +45,7 @@ export const AppointmentModal = ({ ✕ -

Termin {appointmentForm.watch("id")}

+
{ if (!event) return; @@ -55,13 +55,13 @@ export const AppointmentModal = ({ })} className="flex flex-col" > - +
+

Termin {appointmentForm.watch("id")}

+ appointmentForm.setValue("appointmentDate", date)} + /> +
[] + ] as ColumnDef[] } prismaModel={"participant"} filter={{ diff --git a/apps/hub/app/(app)/admin/event/_components/ParticipantModal.tsx b/apps/hub/app/(app)/admin/event/_components/ParticipantModal.tsx index f242869e..10821ca2 100644 --- a/apps/hub/app/(app)/admin/event/_components/ParticipantModal.tsx +++ b/apps/hub/app/(app)/admin/event/_components/ParticipantModal.tsx @@ -59,9 +59,7 @@ export const ParticipantModal = ({ participantForm, ref }: ParticipantModalProps if (!participantForm.watch("id")) return; const participant = participantForm.getValues(); - await handleParticipantFinished(participant.id.toString()).catch((e) => { - const error = e as AxiosError; - }); + await handleParticipantFinished(participant.id.toString()).catch(() => {}); toast.success("Workflow erfolgreich ausgeführt"); router.refresh(); @@ -119,10 +117,10 @@ export const ParticipantModal = ({ participantForm, ref }: ParticipantModalProps

Verlauf

{(participantForm.watch("statusLog") as unknown as ParticipantLog[])?.map((s) => ( -
+

{s.event}

{s.user}

-

{new Date((s as any).timestamp).toLocaleString()}

+

{new Date(s.timestamp).toLocaleString()}

))}
diff --git a/apps/hub/app/(app)/admin/event/action.ts b/apps/hub/app/(app)/admin/event/action.ts index 93a84183..f972f7b8 100644 --- a/apps/hub/app/(app)/admin/event/action.ts +++ b/apps/hub/app/(app)/admin/event/action.ts @@ -1,11 +1,8 @@ "use server"; -import { prisma, Prisma, Event, Participant, EventAppointment } from "@repo/db"; +import { prisma, Prisma, Event, Participant } from "@repo/db"; -export const upsertEvent = async ( - event: Prisma.EventCreateInput, - id?: Event["id"], -) => { +export const upsertEvent = async (event: Prisma.EventCreateInput, id?: Event["id"]) => { const newEvent = id ? await prisma.event.update({ where: { id: id }, diff --git a/apps/hub/app/(app)/admin/event/new/page.tsx b/apps/hub/app/(app)/admin/event/new/page.tsx index 8a2238ce..d76048c2 100644 --- a/apps/hub/app/(app)/admin/event/new/page.tsx +++ b/apps/hub/app/(app)/admin/event/new/page.tsx @@ -1,4 +1,3 @@ -import { prisma } from "@repo/db"; import { Form } from "../_components/Form"; export default async () => { diff --git a/apps/hub/app/(app)/admin/event/page.tsx b/apps/hub/app/(app)/admin/event/page.tsx index e3f5cccf..286f0f67 100644 --- a/apps/hub/app/(app)/admin/event/page.tsx +++ b/apps/hub/app/(app)/admin/event/page.tsx @@ -1,23 +1,36 @@ import { PartyPopperIcon } from "lucide-react"; import { PaginatedTable } from "../../../_components/PaginatedTable"; import Link from "next/link"; +import { ColumnDef } from "@tanstack/react-table"; +import { Event } from "@repo/db"; export default function Page() { return ( <> ( +
+ + + +
+ ), + }, + ] as ColumnDef[] + } leftOfSearch={ Events diff --git a/apps/hub/app/(app)/admin/keyword/_components/Form.tsx b/apps/hub/app/(app)/admin/keyword/_components/Form.tsx index c6a5fa79..f3687ca0 100644 --- a/apps/hub/app/(app)/admin/keyword/_components/Form.tsx +++ b/apps/hub/app/(app)/admin/keyword/_components/Form.tsx @@ -2,7 +2,6 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { KeywordOptionalDefaultsSchema } from "@repo/db/zod"; import { useForm } from "react-hook-form"; -import { z } from "zod"; import { KEYWORD_CATEGORY, Keyword } from "@repo/db"; import { FileText } from "lucide-react"; import { Input } from "../../../../_components/ui/Input"; @@ -24,7 +23,7 @@ export const KeywordForm = ({ keyword }: { keyword?: Keyword }) => { { setLoading(true); - const createdKeyword = await upsertKeyword(values, keyword?.id); + await upsertKeyword(values, keyword?.id); setLoading(false); if (!keyword) redirect(`/admin/keyword`); })} diff --git a/apps/hub/app/(app)/admin/keyword/page.tsx b/apps/hub/app/(app)/admin/keyword/page.tsx index 4560d293..94f7714d 100644 --- a/apps/hub/app/(app)/admin/keyword/page.tsx +++ b/apps/hub/app/(app)/admin/keyword/page.tsx @@ -9,7 +9,6 @@ export default () => { <> { header: "Name", accessorKey: "name", }, + { + header: "Aktionen", + cell: ({ row }) => ( +
+ + + +
+ ), + }, ] as ColumnDef[] } leftOfSearch={ diff --git a/apps/hub/app/(app)/admin/station/_components/Form.tsx b/apps/hub/app/(app)/admin/station/_components/Form.tsx index fa6ab423..9160d056 100644 --- a/apps/hub/app/(app)/admin/station/_components/Form.tsx +++ b/apps/hub/app/(app)/admin/station/_components/Form.tsx @@ -1,8 +1,7 @@ "use client"; import { zodResolver } from "@hookform/resolvers/zod"; import { StationOptionalDefaultsSchema } from "@repo/db/zod"; -import { set, useForm } from "react-hook-form"; -import { z } from "zod"; +import { useForm } from "react-hook-form"; import { BosUse, Country, Station } from "@repo/db"; import { FileText, LocateIcon, PlaneIcon } from "lucide-react"; import { Input } from "../../../../_components/ui/Input"; diff --git a/apps/hub/app/(app)/admin/station/page.tsx b/apps/hub/app/(app)/admin/station/page.tsx index 0988340a..ba505313 100644 --- a/apps/hub/app/(app)/admin/station/page.tsx +++ b/apps/hub/app/(app)/admin/station/page.tsx @@ -1,32 +1,46 @@ +"use client"; import { DatabaseBackupIcon } from "lucide-react"; import { PaginatedTable } from "../../../_components/PaginatedTable"; import Link from "next/link"; +import { ColumnDef } from "@tanstack/react-table"; +import { Station } from "@repo/db"; const page = () => { return ( <> ( +
+ + + +
+ ), + }, + ] as ColumnDef[] + } leftOfSearch={ Stationen @@ -35,9 +49,7 @@ const page = () => { rightOfSearch={

- +

} diff --git a/apps/hub/app/(app)/admin/user/[id]/_components/forms.tsx b/apps/hub/app/(app)/admin/user/[id]/_components/forms.tsx index 8c4bba70..da3c714c 100644 --- a/apps/hub/app/(app)/admin/user/[id]/_components/forms.tsx +++ b/apps/hub/app/(app)/admin/user/[id]/_components/forms.tsx @@ -39,26 +39,23 @@ import { PaginatedTable, PaginatedTableRef } from "_components/PaginatedTable"; import { cn } from "@repo/shared-components"; import { ChartBarBigIcon, - Check, Eye, LockKeyhole, PlaneIcon, - RedoDot, ShieldUser, Timer, Trash2, Users, - X, } from "lucide-react"; import Link from "next/link"; import { ColumnDef } from "@tanstack/react-table"; import { Error } from "_components/Error"; import { useSession } from "next-auth/react"; -import { setStandardName } from "../../../../../../helper/discord"; +import { setStandardName } from "(app)/../../helper/discord"; import { penaltyColumns } from "(app)/admin/penalty/columns"; import { addPenalty, editPenaltys } from "(app)/admin/penalty/actions"; import { reportColumns } from "(app)/admin/report/columns"; -import { sendMail, sendMailByTemplate } from "../../../../../../helper/mail"; +import { sendMailByTemplate } from "(app)/../../helper/mail"; interface ProfileFormProps { user: User; diff --git a/apps/hub/app/(app)/admin/user/page.tsx b/apps/hub/app/(app)/admin/user/page.tsx index 3576e1b3..d8bead10 100644 --- a/apps/hub/app/(app)/admin/user/page.tsx +++ b/apps/hub/app/(app)/admin/user/page.tsx @@ -1,13 +1,16 @@ +"use client"; import { User2 } from "lucide-react"; import { PaginatedTable } from "../../../_components/PaginatedTable"; -import { getServerSession } from "api/auth/[...nextauth]/auth"; +import Link from "next/link"; +import { ColumnDef } from "@tanstack/react-table"; +import { User } from "@repo/db"; +import { useSession } from "next-auth/react"; -const AdminUserPage = async () => { - const session = await getServerSession(); +const AdminUserPage = () => { + const { data: session } = useSession(); return ( <> { desc: false, }, ]} - columns={[ - { - header: "ID", - accessorKey: "publicId", - }, - { - header: "Vorname", - accessorKey: "firstname", - }, - { - header: "Nachname", - accessorKey: "lastname", - }, - ...(session?.user.permissions.includes("ADMIN_USER_ADVANCED") - ? [ - { - header: "Email", - accessorKey: "email", - }, - ] - : []), - ]} + columns={ + [ + { + header: "ID", + accessorKey: "publicId", + }, + { + header: "Vorname", + accessorKey: "firstname", + }, + { + header: "Nachname", + accessorKey: "lastname", + }, + ...(session?.user.permissions.includes("ADMIN_USER_ADVANCED") + ? [ + { + header: "Email", + accessorKey: "email", + }, + ] + : []), + { + header: "Aktionen", + cell: ({ row }) => ( +
+ + + +
+ ), + }, + ] as ColumnDef[] + } // Define the columns for the user table leftOfSearch={

Benutzer diff --git a/apps/hub/app/(app)/events/_components/EventCard.tsx b/apps/hub/app/(app)/events/_components/EventCard.tsx index de6a56ef..c2097ad3 100644 --- a/apps/hub/app/(app)/events/_components/EventCard.tsx +++ b/apps/hub/app/(app)/events/_components/EventCard.tsx @@ -17,7 +17,9 @@ export const EventCard = ({ Participants: Participant[]; }; selectedAppointments: EventAppointment[]; - appointments: EventAppointment[]; + appointments: (EventAppointment & { + Participants: { userId: string }[]; + })[]; }) => { return (

diff --git a/apps/hub/app/(app)/events/_components/Modal.tsx b/apps/hub/app/(app)/events/_components/Modal.tsx index 79c4145e..5000e35d 100644 --- a/apps/hub/app/(app)/events/_components/Modal.tsx +++ b/apps/hub/app/(app)/events/_components/Modal.tsx @@ -16,7 +16,11 @@ import { TriangleAlert, } from "lucide-react"; import { useForm } from "react-hook-form"; -import { ParticipantOptionalDefaults, ParticipantOptionalDefaultsSchema } from "@repo/db/zod"; +import { + InputJsonValueType, + ParticipantOptionalDefaults, + ParticipantOptionalDefaultsSchema, +} from "@repo/db/zod"; import { zodResolver } from "@hookform/resolvers/zod"; import { Select } from "../../../_components/ui/Select"; import { useRouter } from "next/navigation"; @@ -24,11 +28,14 @@ import { handleParticipantEnrolled } from "../../../../helper/events"; import { eventCompleted } from "@repo/shared-components"; import MDEditor from "@uiw/react-md-editor"; import toast from "react-hot-toast"; +import { formatDate } from "date-fns"; interface ModalBtnProps { title: string; event: Event; - dates: EventAppointment[]; + dates: (EventAppointment & { + Participants: { userId: string }[]; + })[]; selectedAppointments: EventAppointment[]; participant?: Participant; user: User; @@ -88,14 +95,16 @@ const ModalBtn = ({ (date) => date.id === selectAppointmentForm.watch("eventAppointmentId") || selectedAppointment?.id, ); - const ownIndexInParticipantList = (selectedDate as any)?.Participants?.findIndex( - (p: Participant) => p.userId === user.id, + const ownIndexInParticipantList = selectedDate?.Participants?.findIndex( + (p) => p.userId === user.id, ); const ownPlaceInParticipantList = - ownIndexInParticipantList === -1 - ? (selectedDate as any)?.Participants?.length + 1 - : ownIndexInParticipantList + 1; + typeof ownIndexInParticipantList === "number" + ? ownIndexInParticipantList === -1 + ? (selectedDate?.Participants?.length ?? 0) + 1 + : ownIndexInParticipantList + 1 + : undefined; const missingRequirements = event.requiredBadges?.length > 0 && @@ -167,13 +176,7 @@ const ModalBtn = ({ { + const date = e.target.value ? new Date(e.target.value) : null; + if (!date) return; + onChange?.(date); + }} + {...props} /> ); }; diff --git a/apps/hub/app/_components/ui/FormTextInput.tsx b/apps/hub/app/_components/ui/FormTextInput.tsx index 05436bbf..433df844 100644 --- a/apps/hub/app/_components/ui/FormTextInput.tsx +++ b/apps/hub/app/_components/ui/FormTextInput.tsx @@ -1,24 +1,18 @@ -import { DetailedHTMLProps, InputHTMLAttributes, ReactNode } from 'react'; +import { InputHTMLAttributes, ReactNode } from "react"; interface FormTextInputProps extends InputHTMLAttributes { - error: any; - Svg: ReactNode; - children?: ReactNode; + error: ReactNode; + children?: ReactNode; } -export const FormTextInput = ({ - error, - Svg, - children, - ...props -}: FormTextInputProps) => { - return ( - <> - -

{error}

- - ); +export const FormTextInput = ({ error, children, ...props }: FormTextInputProps) => { + return ( + <> + +

{error}

+ + ); }; diff --git a/apps/hub/app/_components/ui/List.tsx b/apps/hub/app/_components/ui/List.tsx index afd62856..6e1b875d 100644 --- a/apps/hub/app/_components/ui/List.tsx +++ b/apps/hub/app/_components/ui/List.tsx @@ -1,5 +1,6 @@ -import DatePicker, { DatePickerProps, registerLocale } from "react-datepicker"; -import { Control, Controller, FieldValues, Path, PathValue } from "react-hook-form"; +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { DatePickerProps, registerLocale } from "react-datepicker"; +import { Control, Controller, FieldValues, Path } from "react-hook-form"; import { de } from "date-fns/locale"; import { useState } from "react"; import { cn } from "@repo/shared-components"; @@ -44,7 +45,7 @@ export const ListInput = ({ setValue(""); }} type="button" - onSubmit={(e) => false} + onSubmit={() => false} > Hinzufügen diff --git a/apps/hub/app/_components/ui/MDEditor.tsx b/apps/hub/app/_components/ui/MDEditor.tsx index 37dd93d7..a8e1dd27 100644 --- a/apps/hub/app/_components/ui/MDEditor.tsx +++ b/apps/hub/app/_components/ui/MDEditor.tsx @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ "use client"; import MDEditor from "@uiw/react-md-editor"; import { FieldValues, Path, RegisterOptions, UseFormReturn } from "react-hook-form"; @@ -5,7 +6,7 @@ import { cn } from "@repo/shared-components"; interface MarkdownEditorProps { name: Path; - form: UseFormReturn; + form: UseFormReturn; formOptions?: RegisterOptions; label?: string; placeholder?: string; diff --git a/apps/hub/app/_components/ui/Select.tsx b/apps/hub/app/_components/ui/Select.tsx index 94fa04e4..edbcbd9d 100644 --- a/apps/hub/app/_components/ui/Select.tsx +++ b/apps/hub/app/_components/ui/Select.tsx @@ -1,19 +1,20 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ "use client"; import { FieldValues, Path, RegisterOptions, UseFormReturn } from "react-hook-form"; import SelectTemplate, { Props as SelectTemplateProps, StylesConfig } from "react-select"; import { cn } from "@repo/shared-components"; import dynamic from "next/dynamic"; -import { CSSProperties } from "react"; interface SelectProps extends Omit { - label?: any; + label?: React.ReactNode; name: Path; - form: UseFormReturn | any; + form: UseFormReturn; formOptions?: RegisterOptions; - // eslint-disable-next-line @typescript-eslint/no-explicit-any } -const customStyles: StylesConfig = { +type OptionType = { label: string; value: string }; + +const customStyles: StylesConfig = { control: (provided) => ({ ...provided, backgroundColor: "var(--color-base-100)", @@ -55,7 +56,6 @@ const SelectCom = ({ label = name, placeholder = label, form, - formOptions, className, ...inputProps }: SelectProps) => { @@ -74,7 +74,6 @@ const SelectCom = ({ }); } form.trigger(name); - form.Dirty; }} value={ (inputProps as any)?.isMulti diff --git a/apps/hub/app/_components/ui/Switch.tsx b/apps/hub/app/_components/ui/Switch.tsx index 094af4bd..4a6d9dc8 100644 --- a/apps/hub/app/_components/ui/Switch.tsx +++ b/apps/hub/app/_components/ui/Switch.tsx @@ -1,10 +1,11 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { FieldValues, Path, RegisterOptions, UseFormReturn } from "react-hook-form"; import { cn } from "@repo/shared-components"; interface InputProps extends Omit, "form"> { name: Path; - form: UseFormReturn; + form: UseFormReturn; formOptions?: RegisterOptions; label?: string; } @@ -13,7 +14,6 @@ export const Switch = ({ name, label = name, form, - formOptions, className, ...inputProps }: InputProps) => { @@ -21,7 +21,12 @@ export const Switch = ({
); diff --git a/apps/hub/app/api/auth/[...nextauth]/auth.ts b/apps/hub/app/api/auth/[...nextauth]/auth.ts index 390faa8f..5344eb86 100644 --- a/apps/hub/app/api/auth/[...nextauth]/auth.ts +++ b/apps/hub/app/api/auth/[...nextauth]/auth.ts @@ -1,7 +1,7 @@ import { AuthOptions, getServerSession as getNextAuthServerSession } from "next-auth"; import { PrismaAdapter } from "@next-auth/prisma-adapter"; import Credentials from "next-auth/providers/credentials"; -import { DiscordAccount, prisma, User } from "@repo/db"; +import { prisma } from "@repo/db"; import bcrypt from "bcryptjs"; import oldUser from "./var.User.json"; import { createNewUserFromOld, OldUser } from "../../../../types/oldUser"; @@ -70,7 +70,7 @@ export const options: AuthOptions = { }, }, }, - adapter: PrismaAdapter(prisma as any), + adapter: PrismaAdapter(prisma), callbacks: { jwt: async ({ token, user }) => { if (user && "firstname" in user) { @@ -88,6 +88,7 @@ export const options: AuthOptions = { }, }); if (!dbUser) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any return null as any; } return { diff --git a/apps/hub/app/api/config/route.ts b/apps/hub/app/api/config/route.ts index 5cd7f85f..0bea3a8b 100644 --- a/apps/hub/app/api/config/route.ts +++ b/apps/hub/app/api/config/route.ts @@ -1,7 +1,7 @@ import { prisma } from "@repo/db"; import { NextResponse } from "next/server"; -export async function GET(request: Request): Promise { +export async function GET(): Promise { try { const config = await prisma.config.findFirst({ orderBy: { diff --git a/apps/hub/app/layout.tsx b/apps/hub/app/layout.tsx index 22b224a3..eb6fb6cb 100644 --- a/apps/hub/app/layout.tsx +++ b/apps/hub/app/layout.tsx @@ -7,7 +7,6 @@ import "./globals.css"; import { QueryProvider } from "_components/QueryClient"; import { prisma } from "@repo/db"; import React from "react"; -import { Error as ErrorComp } from "_components/Error"; import { Maintenance } from "@repo/shared-components"; const geistSans = Geist({ diff --git a/apps/hub/eslint.config.mjs b/apps/hub/eslint.config.mjs index e8759ff5..47794e08 100644 --- a/apps/hub/eslint.config.mjs +++ b/apps/hub/eslint.config.mjs @@ -1,4 +1,4 @@ -import { nextJsConfig } from "@repo/eslint-config/next-js"; +import nextJsConfig from "@repo/eslint-config/next-js"; /** @type {import("eslint").Linter.Config} */ export default nextJsConfig; diff --git a/apps/hub/helper/mail.ts b/apps/hub/helper/mail.ts index 74ac9fad..01c1b66c 100644 --- a/apps/hub/helper/mail.ts +++ b/apps/hub/helper/mail.ts @@ -19,7 +19,7 @@ export const sendMailByTemplate = async ( | "email-verification" | "ban-notice" | "timeban-notice", - data: any, + data: unknown, ) => { try { await fetch(`${process.env.NEXT_PUBLIC_HUB_SERVER_URL}/mail/template/${template}`, { diff --git a/apps/hub/helper/moodle.ts b/apps/hub/helper/moodle.ts index 6ed72609..b2bc9562 100644 --- a/apps/hub/helper/moodle.ts +++ b/apps/hub/helper/moodle.ts @@ -25,7 +25,7 @@ export const enrollUserInCourse = async (courseid: number | string, userid: numb ); return enrollmentResponse; } catch (error) { - return new Error("Failed to enroll user in course"); + return error; } }; diff --git a/apps/hub/next.config.ts b/apps/hub/next.config.ts index 91adb3e6..462b9e72 100644 --- a/apps/hub/next.config.ts +++ b/apps/hub/next.config.ts @@ -1,5 +1,5 @@ /** @type {import('next').NextConfig} */ -const removeImports = require("next-remove-imports")(); +/* const removeImports = require("next-remove-imports")(); */ /* const nextConfig = removeImports({}); */ const nextConfig = {}; diff --git a/apps/hub/package.json b/apps/hub/package.json index 01db4d23..77689001 100644 --- a/apps/hub/package.json +++ b/apps/hub/package.json @@ -31,7 +31,6 @@ "clsx": "^2.1.1", "daisyui": "^5.0.43", "date-fns": "^4.1.0", - "eslint": "^9.30.0", "eslint-config-next": "^15.3.4", "i": "^0.3.7", "jsonwebtoken": "^9.0.2", @@ -52,8 +51,13 @@ "react-select": "^5.10.1", "tailwind-merge": "^3.3.1", "tailwindcss": "^4.1.11", - "typescript": "^5.8.3", "zod": "^3.25.67", "zustand": "^5.0.6" + }, + "devDependencies": { + "@eslint/js": "^9.30.0", + "eslint": "^9.30.0", + "typescript": "^5.8.3", + "typescript-eslint": "^8.33.1" } } diff --git a/apps/hub/types/next-auth.d.ts b/apps/hub/types/next-auth.d.ts index 511b2555..5d6c6cd0 100644 --- a/apps/hub/types/next-auth.d.ts +++ b/apps/hub/types/next-auth.d.ts @@ -1,4 +1,3 @@ -import NextAuth from "next-auth"; import { User as IUser } from "@repo/db"; declare module "next-auth" { diff --git a/apps/hub/types/prisma.d.ts b/apps/hub/types/prisma.d.ts index bc0723f6..f1914bf5 100644 --- a/apps/hub/types/prisma.d.ts +++ b/apps/hub/types/prisma.d.ts @@ -1,14 +1,8 @@ -import { Prisma } from "@prisma/client"; -import { JsonArray, JsonObject } from "@prisma/client/runtime/library"; +/* import { JsonArray, JsonObject } from "@prisma/client/runtime/library"; declare module "@prisma/client" { - export type InputJsonValue = - | string - | number - | boolean - | null - | JsonObject - | JsonArray; + export type InputJsonValue = string | number | boolean | null | JsonObject | JsonArray; export type JsonValue = any; // Erzwingt Flexibilität } + */ diff --git a/package.json b/package.json index 43eff148..3069f01e 100644 --- a/package.json +++ b/package.json @@ -24,5 +24,8 @@ "workspaces": [ "apps/*", "packages/*" - ] + ], + "dependencies": { + "eslint": "^9.30.1" + } } diff --git a/packages/eslint-config/next.js b/packages/eslint-config/next.js index 13f96eee..271aa4b2 100644 --- a/packages/eslint-config/next.js +++ b/packages/eslint-config/next.js @@ -1,49 +1,37 @@ +import { defineConfig } from "eslint/config"; import js from "@eslint/js"; import eslintConfigPrettier from "eslint-config-prettier"; import tseslint from "typescript-eslint"; import pluginReactHooks from "eslint-plugin-react-hooks"; -import pluginReact from "eslint-plugin-react"; import globals from "globals"; import pluginNext from "@next/eslint-plugin-next"; -import { config as baseConfig } from "./base.js"; -/** - * A custom ESLint configuration for libraries that use Next.js. - * - * @type {import("eslint").Linter.Config} - * */ -export const nextJsConfig = [ - ...baseConfig, - js.configs.recommended, - eslintConfigPrettier, - ...tseslint.configs.recommended, +export default defineConfig([ { - ...pluginReact.configs.flat.recommended, - languageOptions: { - ...pluginReact.configs.flat.recommended.languageOptions, - globals: { - ...globals.serviceworker, - }, - }, + ignores: ["node_modules/*", "dist/*", ".next/*", "out/*"], }, { + files: ["**/*.{js,ts,jsx,tsx}"], + languageOptions: { + globals: { + ...globals.browser, + ...globals.node, + }, + }, plugins: { + "react-hooks": pluginReactHooks, "@next/next": pluginNext, }, - rules: { - ...pluginNext.configs.recommended.rules, - ...pluginNext.configs["core-web-vitals"].rules, - }, - }, - { - plugins: { - "react-hooks": pluginReactHooks, - }, - settings: { react: { version: "detect" } }, rules: { ...pluginReactHooks.configs.recommended.rules, - // React scope no longer necessary with new JSX transform. + ...pluginNext.configs.recommended.rules, "react/react-in-jsx-scope": "off", }, }, -]; + ...tseslint.config(js.configs.recommended, tseslint.configs.recommended, eslintConfigPrettier), + { + rules: { + "@typescript-eslint/no-unused-vars": "warn", + }, + }, +]); diff --git a/packages/eslint-config/package.json b/packages/eslint-config/package.json index bef55051..b2d551cd 100644 --- a/packages/eslint-config/package.json +++ b/packages/eslint-config/package.json @@ -9,15 +9,18 @@ }, "devDependencies": { "@eslint/js": "^9.17.0", - "@next/eslint-plugin-next": "^15.1.0", + "@next/eslint-plugin-next": "^15.3.3", "eslint": "^9.15.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-only-warn": "^1.1.0", - "eslint-plugin-react": "^7.37.2", - "eslint-plugin-react-hooks": "^5.0.0", + "eslint-plugin-react": "^7.37.5", + "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-turbo": "^2.3.0", "globals": "^15.12.0", "typescript": "^5.8.3", "typescript-eslint": "^8.15.0" + }, + "dependencies": { + "@typescript-eslint/eslint-plugin": "^8.36.0" } } diff --git a/packages/shared-components/helper/index.ts b/packages/shared-components/helper/index.ts index 6b04f846..072e7e0b 100644 --- a/packages/shared-components/helper/index.ts +++ b/packages/shared-components/helper/index.ts @@ -2,3 +2,5 @@ export * from "./cn"; export * from "./event"; export * from "./dates"; export * from "./simulatorConnected"; +export * from "./useDebounce"; +export * from "./useTimeout"; diff --git a/apps/dispatch/app/_helpers/useDebounce.ts b/packages/shared-components/helper/useDebounce.ts similarity index 95% rename from apps/dispatch/app/_helpers/useDebounce.ts rename to packages/shared-components/helper/useDebounce.ts index f6d35a8b..80e4ef2b 100644 --- a/apps/dispatch/app/_helpers/useDebounce.ts +++ b/packages/shared-components/helper/useDebounce.ts @@ -1,3 +1,4 @@ +"use client"; import { DependencyList, useEffect } from "react"; import useTimeout from "./useTimeout"; diff --git a/apps/dispatch/app/_helpers/useTimeout.ts b/packages/shared-components/helper/useTimeout.ts similarity index 98% rename from apps/dispatch/app/_helpers/useTimeout.ts rename to packages/shared-components/helper/useTimeout.ts index b71734d9..8319fb48 100644 --- a/apps/dispatch/app/_helpers/useTimeout.ts +++ b/packages/shared-components/helper/useTimeout.ts @@ -1,3 +1,4 @@ +"use client"; import { useCallback, useEffect, useRef } from "react"; export default function useTimeout(callback: () => void, delay: number) { diff --git a/packages/typescript-config/base.json b/packages/typescript-config/base.json index edc9c160..a20c637c 100644 --- a/packages/typescript-config/base.json +++ b/packages/typescript-config/base.json @@ -16,5 +16,6 @@ "skipLibCheck": true, "strict": true, "target": "ES2022" - } + }, + "exclude": ["node_modules", "dist", ".next", "out"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c9c1c1e4..1c379cc7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,6 +7,10 @@ settings: importers: .: + dependencies: + eslint: + specifier: ^9.30.1 + version: 9.30.1(jiti@2.4.2) devDependencies: prettier: specifier: ^3.5.3 @@ -81,6 +85,9 @@ importers: apps/dispatch: dependencies: + '@eslint/eslintrc': + specifier: ^3.3.1 + version: 3.3.1 '@hookform/resolvers': specifier: ^5.1.1 version: 5.1.1(react-hook-form@7.59.0(react@19.1.0)) @@ -147,6 +154,9 @@ importers: date-fns: specifier: ^4.1.0 version: 4.1.0 + eslint-config-next: + specifier: ^15.3.4 + version: 15.3.4(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) geojson: specifier: ^0.5.0 version: 0.5.0 @@ -325,9 +335,6 @@ importers: '@catppuccin/vitepress': specifier: ^0.1.2 version: 0.1.2(typescript@5.8.3) - '@repo/typescript-config': - specifier: workspace:* - version: link:../../packages/typescript-config devDependencies: vitepress: specifier: ^1.6.3 @@ -398,9 +405,6 @@ importers: date-fns: specifier: ^4.1.0 version: 4.1.0 - eslint: - specifier: ^9.30.0 - version: 9.30.0(jiti@2.4.2) eslint-config-next: specifier: ^15.3.4 version: 15.3.4(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3) @@ -461,15 +465,25 @@ importers: tailwindcss: specifier: ^4.1.11 version: 4.1.11 - typescript: - specifier: ^5.8.3 - version: 5.8.3 zod: specifier: ^3.25.67 version: 3.25.67 zustand: specifier: ^5.0.6 version: 5.0.6(@types/react@19.1.8)(react@19.1.0) + devDependencies: + '@eslint/js': + specifier: ^9.30.0 + version: 9.30.0 + eslint: + specifier: ^9.30.0 + version: 9.30.0(jiti@2.4.2) + typescript: + specifier: ^5.8.3 + version: 5.8.3 + typescript-eslint: + specifier: ^8.33.1 + version: 8.33.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3) apps/hub-server: dependencies: @@ -555,12 +569,16 @@ importers: version: 6.8.2(typescript@5.8.3) packages/eslint-config: + dependencies: + '@typescript-eslint/eslint-plugin': + specifier: ^8.36.0 + version: 8.36.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) devDependencies: '@eslint/js': specifier: ^9.17.0 version: 9.28.0 '@next/eslint-plugin-next': - specifier: ^15.1.0 + specifier: ^15.3.3 version: 15.3.3 eslint: specifier: ^9.15.0 @@ -572,10 +590,10 @@ importers: specifier: ^1.1.0 version: 1.1.0 eslint-plugin-react: - specifier: ^7.37.2 + specifier: ^7.37.5 version: 7.37.5(eslint@9.28.0(jiti@2.4.2)) eslint-plugin-react-hooks: - specifier: ^5.0.0 + specifier: ^5.2.0 version: 5.2.0(eslint@9.28.0(jiti@2.4.2)) eslint-plugin-turbo: specifier: ^2.3.0 @@ -1226,6 +1244,10 @@ packages: resolution: {integrity: sha512-Wzw3wQwPvc9sHM+NjakWTcPx11mbZyiYHuwWa/QfZ7cIRX7WK54PSk7bdyXDaoaopUcMatv1zaQvOAAO8hCdww==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/js@9.30.1': + resolution: {integrity: sha512-zXhuECFlyep42KZUhWjfvsmXGX39W8K8LFb8AWXM9gSV9dQB+MrJGLKvW6Zw0Ggnbpw0VHTtrhFXYe3Gym18jg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/object-schema@2.1.6': resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2561,11 +2583,11 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/eslint-plugin@8.35.0': - resolution: {integrity: sha512-ijItUYaiWuce0N1SoSMrEd0b6b6lYkYt99pqCPfybd+HKVXtEvYhICfLdwp42MhiI5mp0oq7PKEL+g1cNiz/Eg==} + '@typescript-eslint/eslint-plugin@8.36.0': + resolution: {integrity: sha512-lZNihHUVB6ZZiPBNgOQGSxUASI7UJWhT8nHyUGCnaQ28XFCw98IfrMCG3rUl1uwUWoAvodJQby2KTs79UTcrAg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.35.0 + '@typescript-eslint/parser': ^8.36.0 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' @@ -2595,6 +2617,12 @@ packages: peerDependencies: typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/project-service@8.36.0': + resolution: {integrity: sha512-JAhQFIABkWccQYeLMrHadu/fhpzmSQ1F1KXkpzqiVxA/iYI6UnRt2trqXHt1sYEcw1mxLnB9rKMsOxXPxowN/g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/scope-manager@8.33.1': resolution: {integrity: sha512-dM4UBtgmzHR9bS0Rv09JST0RcHYearoEoo3pG5B6GoTR9XcyeqX87FEhPo+5kTvVfKCvfHaHrcgeJQc6mrDKrA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2603,6 +2631,10 @@ packages: resolution: {integrity: sha512-+AgL5+mcoLxl1vGjwNfiWq5fLDZM1TmTPYs2UkyHfFhgERxBbqHlNjRzhThJqz+ktBqTChRYY6zwbMwy0591AA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/scope-manager@8.36.0': + resolution: {integrity: sha512-wCnapIKnDkN62fYtTGv2+RY8FlnBYA3tNm0fm91kc2BjPhV2vIjwwozJ7LToaLAyb1ca8BxrS7vT+Pvvf7RvqA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/tsconfig-utils@8.33.1': resolution: {integrity: sha512-STAQsGYbHCF0/e+ShUQ4EatXQ7ceh3fBCXkNU7/MZVKulrlq1usH7t2FhxvCpuCi5O5oi1vmVaAjrGeL71OK1g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2615,6 +2647,12 @@ packages: peerDependencies: typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/tsconfig-utils@8.36.0': + resolution: {integrity: sha512-Nhh3TIEgN18mNbdXpd5Q8mSCBnrZQeY9V7Ca3dqYvNDStNIGRmJA6dmrIPMJ0kow3C7gcQbpsG2rPzy1Ks/AnA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/type-utils@8.33.1': resolution: {integrity: sha512-1cG37d9xOkhlykom55WVwG2QRNC7YXlxMaMzqw2uPeJixBFfKWZgaP/hjAObqMN/u3fr5BrTwTnc31/L9jQ2ww==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2622,8 +2660,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/type-utils@8.35.0': - resolution: {integrity: sha512-ceNNttjfmSEoM9PW87bWLDEIaLAyR+E6BoYJQ5PfaDau37UGca9Nyq3lBk8Bw2ad0AKvYabz6wxc7DMTO2jnNA==} + '@typescript-eslint/type-utils@8.36.0': + resolution: {integrity: sha512-5aaGYG8cVDd6cxfk/ynpYzxBRZJk7w/ymto6uiyUFtdCozQIsQWh7M28/6r57Fwkbweng8qAzoMCPwSJfWlmsg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -2637,6 +2675,10 @@ packages: resolution: {integrity: sha512-0mYH3emanku0vHw2aRLNGqe7EXh9WHEhi7kZzscrMDf6IIRUQ5Jk4wp1QrledE/36KtdZrVfKnE32eZCf/vaVQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/types@8.36.0': + resolution: {integrity: sha512-xGms6l5cTJKQPZOKM75Dl9yBfNdGeLRsIyufewnxT4vZTrjC0ImQT4fj8QmtJK84F58uSh5HVBSANwcfiXxABQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/typescript-estree@8.33.1': resolution: {integrity: sha512-+s9LYcT8LWjdYWu7IWs7FvUxpQ/DGkdjZeE/GGulHvv8rvYwQvVaUZ6DE+j5x/prADUgSbbCWZ2nPI3usuVeOA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2649,6 +2691,12 @@ packages: peerDependencies: typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/typescript-estree@8.36.0': + resolution: {integrity: sha512-JaS8bDVrfVJX4av0jLpe4ye0BpAaUW7+tnS4Y4ETa3q7NoZgzYbN9zDQTJ8kPb5fQ4n0hliAt9tA4Pfs2zA2Hg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/utils@8.33.1': resolution: {integrity: sha512-52HaBiEQUaRYqAXpfzWSR2U3gxk92Kw006+xZpElaPMg3C4PgM+A5LqwoQI1f9E5aZ/qlxAZxzm42WX+vn92SQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2656,8 +2704,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/utils@8.35.0': - resolution: {integrity: sha512-nqoMu7WWM7ki5tPgLVsmPM8CkqtoPUG6xXGeefM5t4x3XumOEKMoUZPdi+7F+/EotukN4R9OWdmDxN80fqoZeg==} + '@typescript-eslint/utils@8.36.0': + resolution: {integrity: sha512-VOqmHu42aEMT+P2qYjylw6zP/3E/HvptRwdn/PZxyV27KhZg2IOszXod4NcXisWzPAGSS4trE/g4moNj6XmH2g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -2671,6 +2719,10 @@ packages: resolution: {integrity: sha512-zTh2+1Y8ZpmeQaQVIc/ZZxsx8UzgKJyNg1PTvjzC7WMhPSVS8bfDX34k1SrwOf016qd5RU3az2UxUNue3IfQ5g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/visitor-keys@8.36.0': + resolution: {integrity: sha512-vZrhV2lRPWDuGoxcmrzRZyxAggPL+qp3WzUrlZD+slFueDiYHxeBa34dUXPuC0RmGKzl4lS5kFJYvKCq9cnNDA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@uiw/copy-to-clipboard@1.0.17': resolution: {integrity: sha512-O2GUHV90Iw2VrSLVLK0OmNIMdZ5fgEg4NhvtwINsX+eZ/Wf6DWD0TdsK9xwV7dNRnK/UI2mQtl0a2/kRgm1m1A==} @@ -3694,6 +3746,16 @@ packages: jiti: optional: true + eslint@9.30.1: + resolution: {integrity: sha512-zmxXPNMOXmwm9E0yQLi5uqXHs7uq2UIiqEKo3Gq+3fwo1XrJ+hijAZImyF7hclW3E6oHz43Yk3RP8at6OTKflQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + espree@10.3.0: resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -4394,6 +4456,7 @@ packages: livekit-client@2.14.0: resolution: {integrity: sha512-+ryoX3bFUNVWTjXsPLnPTW8O9wKUo/ZDPxCPLBeE72Ny0JVIK8QRIW0J/CZbcGCK5VRpYf+jMojKmjlztbSuOg==} + deprecated: This release is deprecated, update to @latest peerDependencies: '@types/dom-mediacapture-record': ^1 @@ -6614,6 +6677,11 @@ snapshots: eslint: 9.30.0(jiti@2.4.2) eslint-visitor-keys: 3.4.3 + '@eslint-community/eslint-utils@4.7.0(eslint@9.30.1(jiti@2.4.2))': + dependencies: + eslint: 9.30.1(jiti@2.4.2) + eslint-visitor-keys: 3.4.3 + '@eslint-community/regexpp@4.12.1': {} '@eslint/config-array@0.20.0': @@ -6662,6 +6730,8 @@ snapshots: '@eslint/js@9.30.0': {} + '@eslint/js@9.30.1': {} + '@eslint/object-schema@2.1.6': {} '@eslint/plugin-kit@0.3.1': @@ -8656,14 +8726,48 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/eslint-plugin@8.33.1(@typescript-eslint/parser@8.33.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3)': + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 8.33.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/scope-manager': 8.33.1 + '@typescript-eslint/type-utils': 8.33.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.33.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.33.1 + eslint: 9.30.0(jiti@2.4.2) + graphemer: 1.4.0 + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/eslint-plugin@8.36.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)': + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/scope-manager': 8.36.0 + '@typescript-eslint/type-utils': 8.36.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.36.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.36.0 + eslint: 9.28.0(jiti@2.4.2) + graphemer: 1.4.0 + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/eslint-plugin@8.36.0(@typescript-eslint/parser@8.35.0(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@eslint-community/regexpp': 4.12.1 '@typescript-eslint/parser': 8.35.0(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/scope-manager': 8.35.0 - '@typescript-eslint/type-utils': 8.35.0(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/utils': 8.35.0(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 8.35.0 + '@typescript-eslint/scope-manager': 8.36.0 + '@typescript-eslint/type-utils': 8.36.0(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.36.0(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.36.0 eslint: 9.30.0(jiti@2.4.2) graphemer: 1.4.0 ignore: 7.0.5 @@ -8673,6 +8777,23 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/eslint-plugin@8.36.0(@typescript-eslint/parser@8.35.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)': + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 8.35.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/scope-manager': 8.36.0 + '@typescript-eslint/type-utils': 8.36.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.36.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.36.0 + eslint: 9.30.1(jiti@2.4.2) + graphemer: 1.4.0 + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@typescript-eslint/scope-manager': 8.33.1 @@ -8685,6 +8806,18 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/parser@8.33.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.33.1 + '@typescript-eslint/types': 8.33.1 + '@typescript-eslint/typescript-estree': 8.33.1(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.33.1 + debug: 4.4.1(supports-color@5.5.0) + eslint: 9.30.0(jiti@2.4.2) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/parser@8.35.0(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@typescript-eslint/scope-manager': 8.35.0 @@ -8697,10 +8830,22 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/parser@8.35.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.35.0 + '@typescript-eslint/types': 8.35.0 + '@typescript-eslint/typescript-estree': 8.35.0(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.35.0 + debug: 4.4.1(supports-color@5.5.0) + eslint: 9.30.1(jiti@2.4.2) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/project-service@8.33.1(typescript@5.8.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.33.1(typescript@5.8.3) - '@typescript-eslint/types': 8.33.1 + '@typescript-eslint/tsconfig-utils': 8.36.0(typescript@5.8.3) + '@typescript-eslint/types': 8.36.0 debug: 4.4.1(supports-color@5.5.0) typescript: 5.8.3 transitivePeerDependencies: @@ -8708,8 +8853,17 @@ snapshots: '@typescript-eslint/project-service@8.35.0(typescript@5.8.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.35.0(typescript@5.8.3) - '@typescript-eslint/types': 8.35.0 + '@typescript-eslint/tsconfig-utils': 8.36.0(typescript@5.8.3) + '@typescript-eslint/types': 8.36.0 + debug: 4.4.1(supports-color@5.5.0) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.36.0(typescript@5.8.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.36.0(typescript@5.8.3) + '@typescript-eslint/types': 8.36.0 debug: 4.4.1(supports-color@5.5.0) typescript: 5.8.3 transitivePeerDependencies: @@ -8725,6 +8879,11 @@ snapshots: '@typescript-eslint/types': 8.35.0 '@typescript-eslint/visitor-keys': 8.35.0 + '@typescript-eslint/scope-manager@8.36.0': + dependencies: + '@typescript-eslint/types': 8.36.0 + '@typescript-eslint/visitor-keys': 8.36.0 + '@typescript-eslint/tsconfig-utils@8.33.1(typescript@5.8.3)': dependencies: typescript: 5.8.3 @@ -8733,6 +8892,10 @@ snapshots: dependencies: typescript: 5.8.3 + '@typescript-eslint/tsconfig-utils@8.36.0(typescript@5.8.3)': + dependencies: + typescript: 5.8.3 + '@typescript-eslint/type-utils@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@typescript-eslint/typescript-estree': 8.33.1(typescript@5.8.3) @@ -8744,10 +8907,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.35.0(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/type-utils@8.33.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: - '@typescript-eslint/typescript-estree': 8.35.0(typescript@5.8.3) - '@typescript-eslint/utils': 8.35.0(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/typescript-estree': 8.33.1(typescript@5.8.3) + '@typescript-eslint/utils': 8.33.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3) debug: 4.4.1(supports-color@5.5.0) eslint: 9.30.0(jiti@2.4.2) ts-api-utils: 2.1.0(typescript@5.8.3) @@ -8755,10 +8918,45 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/type-utils@8.36.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)': + dependencies: + '@typescript-eslint/typescript-estree': 8.36.0(typescript@5.8.3) + '@typescript-eslint/utils': 8.36.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) + debug: 4.4.1(supports-color@5.5.0) + eslint: 9.28.0(jiti@2.4.2) + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/type-utils@8.36.0(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3)': + dependencies: + '@typescript-eslint/typescript-estree': 8.36.0(typescript@5.8.3) + '@typescript-eslint/utils': 8.36.0(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3) + debug: 4.4.1(supports-color@5.5.0) + eslint: 9.30.0(jiti@2.4.2) + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/type-utils@8.36.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)': + dependencies: + '@typescript-eslint/typescript-estree': 8.36.0(typescript@5.8.3) + '@typescript-eslint/utils': 8.36.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + debug: 4.4.1(supports-color@5.5.0) + eslint: 9.30.1(jiti@2.4.2) + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/types@8.33.1': {} '@typescript-eslint/types@8.35.0': {} + '@typescript-eslint/types@8.36.0': {} + '@typescript-eslint/typescript-estree@8.33.1(typescript@5.8.3)': dependencies: '@typescript-eslint/project-service': 8.33.1(typescript@5.8.3) @@ -8791,6 +8989,22 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/typescript-estree@8.36.0(typescript@5.8.3)': + dependencies: + '@typescript-eslint/project-service': 8.36.0(typescript@5.8.3) + '@typescript-eslint/tsconfig-utils': 8.36.0(typescript@5.8.3) + '@typescript-eslint/types': 8.36.0 + '@typescript-eslint/visitor-keys': 8.36.0 + debug: 4.4.1(supports-color@5.5.0) + fast-glob: 3.3.3 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.2 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/utils@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@eslint-community/eslint-utils': 4.7.0(eslint@9.28.0(jiti@2.4.2)) @@ -8802,17 +9016,50 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.35.0(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/utils@8.33.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.0(jiti@2.4.2)) - '@typescript-eslint/scope-manager': 8.35.0 - '@typescript-eslint/types': 8.35.0 - '@typescript-eslint/typescript-estree': 8.35.0(typescript@5.8.3) + '@typescript-eslint/scope-manager': 8.33.1 + '@typescript-eslint/types': 8.33.1 + '@typescript-eslint/typescript-estree': 8.33.1(typescript@5.8.3) eslint: 9.30.0(jiti@2.4.2) typescript: 5.8.3 transitivePeerDependencies: - supports-color + '@typescript-eslint/utils@8.36.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)': + dependencies: + '@eslint-community/eslint-utils': 4.7.0(eslint@9.28.0(jiti@2.4.2)) + '@typescript-eslint/scope-manager': 8.36.0 + '@typescript-eslint/types': 8.36.0 + '@typescript-eslint/typescript-estree': 8.36.0(typescript@5.8.3) + eslint: 9.28.0(jiti@2.4.2) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.36.0(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3)': + dependencies: + '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.0(jiti@2.4.2)) + '@typescript-eslint/scope-manager': 8.36.0 + '@typescript-eslint/types': 8.36.0 + '@typescript-eslint/typescript-estree': 8.36.0(typescript@5.8.3) + eslint: 9.30.0(jiti@2.4.2) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.36.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)': + dependencies: + '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.4.2)) + '@typescript-eslint/scope-manager': 8.36.0 + '@typescript-eslint/types': 8.36.0 + '@typescript-eslint/typescript-estree': 8.36.0(typescript@5.8.3) + eslint: 9.30.1(jiti@2.4.2) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/visitor-keys@8.33.1': dependencies: '@typescript-eslint/types': 8.33.1 @@ -8823,6 +9070,11 @@ snapshots: '@typescript-eslint/types': 8.35.0 eslint-visitor-keys: 4.2.1 + '@typescript-eslint/visitor-keys@8.36.0': + dependencies: + '@typescript-eslint/types': 8.36.0 + eslint-visitor-keys: 4.2.1 + '@uiw/copy-to-clipboard@1.0.17': {} '@uiw/react-markdown-preview@5.1.4(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': @@ -9905,7 +10157,7 @@ snapshots: dependencies: '@next/eslint-plugin-next': 15.3.4 '@rushstack/eslint-patch': 1.12.0 - '@typescript-eslint/eslint-plugin': 8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/eslint-plugin': 8.36.0(@typescript-eslint/parser@8.35.0(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3) '@typescript-eslint/parser': 8.35.0(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3) eslint: 9.30.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 @@ -9921,6 +10173,26 @@ snapshots: - eslint-plugin-import-x - supports-color + eslint-config-next@15.3.4(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3): + dependencies: + '@next/eslint-plugin-next': 15.3.4 + '@rushstack/eslint-patch': 1.12.0 + '@typescript-eslint/eslint-plugin': 8.36.0(@typescript-eslint/parser@8.35.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/parser': 8.35.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + eslint: 9.30.1(jiti@2.4.2) + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.35.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-react: 7.37.5(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-react-hooks: 5.2.0(eslint@9.30.1(jiti@2.4.2)) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - eslint-import-resolver-webpack + - eslint-plugin-import-x + - supports-color + eslint-config-prettier@9.1.0(eslint@9.28.0(jiti@2.4.2)): dependencies: eslint: 9.28.0(jiti@2.4.2) @@ -9948,6 +10220,21 @@ snapshots: transitivePeerDependencies: - supports-color + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.30.1(jiti@2.4.2)): + dependencies: + '@nolyfill/is-core-module': 1.0.39 + debug: 4.4.1(supports-color@5.5.0) + eslint: 9.30.1(jiti@2.4.2) + get-tsconfig: 4.10.1 + is-bun-module: 2.0.0 + stable-hash: 0.0.5 + tinyglobby: 0.2.14 + unrs-resolver: 1.9.2 + optionalDependencies: + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.35.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.1(jiti@2.4.2)) + transitivePeerDependencies: + - supports-color + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.35.0(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.0(jiti@2.4.2)): dependencies: debug: 3.2.7 @@ -9959,6 +10246,17 @@ snapshots: transitivePeerDependencies: - supports-color + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.35.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.1(jiti@2.4.2)): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 8.35.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + eslint: 9.30.1(jiti@2.4.2) + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.30.1(jiti@2.4.2)) + transitivePeerDependencies: + - supports-color + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.35.0(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.0(jiti@2.4.2)): dependencies: '@rtsao/scc': 1.1.0 @@ -9988,6 +10286,35 @@ snapshots: - eslint-import-resolver-webpack - supports-color + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.35.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.1(jiti@2.4.2)): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.9 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 9.30.1(jiti@2.4.2) + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.35.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.1(jiti@2.4.2)) + hasown: 2.0.2 + is-core-module: 2.16.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 8.35.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + eslint-plugin-jsx-a11y@6.10.2(eslint@9.30.0(jiti@2.4.2)): dependencies: aria-query: 5.3.2 @@ -10007,6 +10334,25 @@ snapshots: safe-regex-test: 1.1.0 string.prototype.includes: 2.0.1 + eslint-plugin-jsx-a11y@6.10.2(eslint@9.30.1(jiti@2.4.2)): + dependencies: + aria-query: 5.3.2 + array-includes: 3.1.9 + array.prototype.flatmap: 1.3.3 + ast-types-flow: 0.0.8 + axe-core: 4.10.3 + axobject-query: 4.1.0 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + eslint: 9.30.1(jiti@2.4.2) + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + language-tags: 1.0.9 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + safe-regex-test: 1.1.0 + string.prototype.includes: 2.0.1 + eslint-plugin-only-warn@1.1.0: {} eslint-plugin-react-hooks@5.2.0(eslint@9.28.0(jiti@2.4.2)): @@ -10017,6 +10363,10 @@ snapshots: dependencies: eslint: 9.30.0(jiti@2.4.2) + eslint-plugin-react-hooks@5.2.0(eslint@9.30.1(jiti@2.4.2)): + dependencies: + eslint: 9.30.1(jiti@2.4.2) + eslint-plugin-react@7.37.5(eslint@9.28.0(jiti@2.4.2)): dependencies: array-includes: 3.1.9 @@ -10061,6 +10411,28 @@ snapshots: string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 + eslint-plugin-react@7.37.5(eslint@9.30.1(jiti@2.4.2)): + dependencies: + array-includes: 3.1.9 + array.prototype.findlast: 1.2.5 + array.prototype.flatmap: 1.3.3 + array.prototype.tosorted: 1.1.4 + doctrine: 2.1.0 + es-iterator-helpers: 1.2.1 + eslint: 9.30.1(jiti@2.4.2) + estraverse: 5.3.0 + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.2 + object.entries: 1.1.9 + object.fromentries: 2.0.8 + object.values: 1.2.1 + prop-types: 15.8.1 + resolve: 2.0.0-next.5 + semver: 6.3.1 + string.prototype.matchall: 4.0.12 + string.prototype.repeat: 1.0.0 + eslint-plugin-turbo@2.5.4(eslint@9.28.0(jiti@2.4.2))(turbo@2.5.4): dependencies: dotenv: 16.0.3 @@ -10172,6 +10544,48 @@ snapshots: transitivePeerDependencies: - supports-color + eslint@9.30.1(jiti@2.4.2): + dependencies: + '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.4.2)) + '@eslint-community/regexpp': 4.12.1 + '@eslint/config-array': 0.21.0 + '@eslint/config-helpers': 0.3.0 + '@eslint/core': 0.14.0 + '@eslint/eslintrc': 3.3.1 + '@eslint/js': 9.30.1 + '@eslint/plugin-kit': 0.3.3 + '@humanfs/node': 0.16.6 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.8 + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.1(supports-color@5.5.0) + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + optionalDependencies: + jiti: 2.4.2 + transitivePeerDependencies: + - supports-color + espree@10.3.0: dependencies: acorn: 8.14.1 @@ -12710,6 +13124,16 @@ snapshots: transitivePeerDependencies: - supports-color + typescript-eslint@8.33.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.33.1(@typescript-eslint/parser@8.33.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/parser': 8.33.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.33.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3) + eslint: 9.30.0(jiti@2.4.2) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + typescript@5.8.3: {} uid2@1.0.0: {}