From 98ed0cb5ca895850ad33eaa3c6f15bf49381249d Mon Sep 17 00:00:00 2001 From: PxlLoewe <72106766+PxlLoewe@users.noreply.github.com> Date: Wed, 9 Jul 2025 01:06:54 -0700 Subject: [PATCH 01/51] implemented initial eslintFixes --- .vscode/settings.json | 1 + apps/hub/app/_components/ui/DateInput.tsx | 2 +- apps/hub/app/_components/ui/FormTextInput.tsx | 32 +-- apps/hub/app/_components/ui/List.tsx | 7 +- apps/hub/app/_components/ui/MDEditor.tsx | 3 +- apps/hub/app/_components/ui/Select.tsx | 13 +- apps/hub/app/_components/ui/Switch.tsx | 11 +- apps/hub/app/api/auth/[...nextauth]/auth.ts | 5 +- apps/hub/app/api/config/route.ts | 2 +- apps/hub/app/layout.tsx | 1 - apps/hub/eslint.config.mjs | 2 +- apps/hub/helper/mail.ts | 2 +- apps/hub/helper/moodle.ts | 2 +- apps/hub/next.config.ts | 2 +- apps/hub/package.json | 8 +- apps/hub/types/next-auth.d.ts | 1 - apps/hub/types/prisma.d.ts | 12 +- packages/eslint-config/next.js | 45 +-- packages/eslint-config/package.json | 9 +- pnpm-lock.yaml | 260 ++++++++++++++++-- 20 files changed, 309 insertions(+), 111 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 07bb728a..d40ae7d2 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": [{ "pattern": "./apps/*/" }, { "pattern": "./packages/*/" }], "editor.codeActionsOnSave": ["source.formatDocument", "source.fixAll.eslint"], "typescript.validate.enable": true, "typescript.tsserver.experimental.enableProjectDiagnostics": true, diff --git a/apps/hub/app/_components/ui/DateInput.tsx b/apps/hub/app/_components/ui/DateInput.tsx index 6558d627..870f8b9e 100644 --- a/apps/hub/app/_components/ui/DateInput.tsx +++ b/apps/hub/app/_components/ui/DateInput.tsx @@ -24,7 +24,7 @@ export const DateInput = ({ locale={"de"} onChange={(date) => field.onChange(date)} selected={field.value} - {...(props as any)} + {...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/packages/eslint-config/next.js b/packages/eslint-config/next.js index 13f96eee..a79ba5ea 100644 --- a/packages/eslint-config/next.js +++ b/packages/eslint-config/next.js @@ -1,49 +1,32 @@ +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), +]); 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/pnpm-lock.yaml b/pnpm-lock.yaml index c9c1c1e4..980656a9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -95,7 +95,7 @@ importers: version: 0.5.7(@types/dom-mediacapture-transform@0.1.11)(livekit-client@2.14.0(@types/dom-mediacapture-record@1.0.22)) '@next-auth/prisma-adapter': specifier: ^1.0.7 - version: 1.0.7(@prisma/client@6.8.2(prisma@6.8.2(typescript@5.8.3))(typescript@5.8.3))(next-auth@4.24.11(next@15.3.4(@babel/core@7.27.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)) + version: 1.0.7(@prisma/client@6.8.2(prisma@6.8.2(typescript@5.8.3))(typescript@5.8.3))(next-auth@4.24.11(next@15.3.4(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)) '@radix-ui/react-icons': specifier: ^1.3.2 version: 1.3.2(react@19.1.0) @@ -176,7 +176,7 @@ importers: version: 15.3.4(@babel/core@7.27.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) next-auth: specifier: ^4.24.11 - version: 4.24.11(next@15.3.4(@babel/core@7.27.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 4.24.11(next@15.3.4(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) npm: specifier: ^11.4.2 version: 11.4.2 @@ -325,9 +325,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 @@ -343,7 +340,7 @@ importers: version: 5.1.1(react-hook-form@7.59.0(react@19.1.0)) '@next-auth/prisma-adapter': specifier: ^1.0.7 - version: 1.0.7(@prisma/client@6.8.2(prisma@6.8.2(typescript@5.8.3))(typescript@5.8.3))(next-auth@4.24.11(next@15.3.4(@babel/core@7.27.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)) + version: 1.0.7(@prisma/client@6.8.2(prisma@6.8.2(typescript@5.8.3))(typescript@5.8.3))(next-auth@4.24.11(next@15.3.4(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)) '@radix-ui/react-icons': specifier: ^1.3.2 version: 1.3.2(react@19.1.0) @@ -398,9 +395,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) @@ -421,7 +415,7 @@ importers: version: 15.3.4(@babel/core@7.27.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) next-auth: specifier: ^4.24.11 - version: 4.24.11(next@15.3.4(@babel/core@7.27.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 4.24.11(next@15.3.4(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) next-remove-imports: specifier: ^1.0.12 version: 1.0.12(webpack@5.99.9) @@ -461,15 +455,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 +559,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.35.0(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 +580,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 @@ -2569,6 +2577,14 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' + '@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.36.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/parser@8.33.1': resolution: {integrity: sha512-qwxv6dq682yVvgKKp2qWwLgRbscDAYktPptK4JPojCwwi3R9cwrvIxS4lvBpzmcqzR4bdn54Z0IG1uHFskW4dA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2595,6 +2611,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 +2625,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 +2641,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} @@ -2629,6 +2661,13 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' + '@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 + typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/types@8.33.1': resolution: {integrity: sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2637,6 +2676,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 +2692,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} @@ -2663,6 +2712,13 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' + '@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 + typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/visitor-keys@8.33.1': resolution: {integrity: sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2671,6 +2727,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==} @@ -4394,6 +4454,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 @@ -6884,10 +6945,10 @@ snapshots: '@tybys/wasm-util': 0.9.0 optional: true - '@next-auth/prisma-adapter@1.0.7(@prisma/client@6.8.2(prisma@6.8.2(typescript@5.8.3))(typescript@5.8.3))(next-auth@4.24.11(next@15.3.4(@babel/core@7.27.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0))': + '@next-auth/prisma-adapter@1.0.7(@prisma/client@6.8.2(prisma@6.8.2(typescript@5.8.3))(typescript@5.8.3))(next-auth@4.24.11(next@15.3.4(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0))': dependencies: '@prisma/client': 6.8.2(prisma@6.8.2(typescript@5.8.3))(typescript@5.8.3) - next-auth: 4.24.11(next@15.3.4(@babel/core@7.27.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + next-auth: 4.24.11(next@15.3.4(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@next/env@15.3.4': {} @@ -8656,6 +8717,23 @@ snapshots: transitivePeerDependencies: - supports-color + '@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.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)': dependencies: '@eslint-community/regexpp': 4.12.1 @@ -8673,6 +8751,23 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/eslint-plugin@8.36.0(@typescript-eslint/parser@8.35.0(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.35.0(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/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 +8780,30 @@ 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.28.0(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.28.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 @@ -8699,8 +8818,8 @@ snapshots: '@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 +8827,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 +8853,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 +8866,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,6 +8881,17 @@ snapshots: transitivePeerDependencies: - supports-color + '@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.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) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/type-utils@8.35.0(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@typescript-eslint/typescript-estree': 8.35.0(typescript@5.8.3) @@ -8755,10 +8903,23 @@ 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/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 +8952,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,6 +8979,17 @@ snapshots: transitivePeerDependencies: - supports-color + '@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.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.35.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)) @@ -8813,6 +9001,17 @@ snapshots: 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/visitor-keys@8.33.1': dependencies: '@typescript-eslint/types': 8.33.1 @@ -8823,6 +9022,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)': @@ -11472,7 +11676,7 @@ snapshots: neo-async@2.6.2: {} - next-auth@4.24.11(next@15.3.4(@babel/core@7.27.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + next-auth@4.24.11(next@15.3.4(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: '@babel/runtime': 7.27.6 '@panva/hkdf': 1.2.1 @@ -12710,6 +12914,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: {} From e3b475240dd1fb3a87766f7488b88928116faca1 Mon Sep 17 00:00:00 2001 From: PxlLoewe <72106766+PxlLoewe@users.noreply.github.com> Date: Wed, 9 Jul 2025 16:06:47 -0700 Subject: [PATCH 02/51] Fix nachname in user formularen --- .../app/(app)/settings/_components/forms.tsx | 28 +++++++++++++++---- .../(auth)/register/_components/Register.tsx | 2 +- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/apps/hub/app/(app)/settings/_components/forms.tsx b/apps/hub/app/(app)/settings/_components/forms.tsx index 06eb93fa..7b22104c 100644 --- a/apps/hub/app/(app)/settings/_components/forms.tsx +++ b/apps/hub/app/(app)/settings/_components/forms.tsx @@ -38,13 +38,9 @@ export const ProfileForm = ({ const canEdit = penaltys.length === 0 && !user.isBanned; const schema = z.object({ - firstname: z.string().min(2).max(30), - lastname: z.string().min(2).max(30), email: z .string() - .email({ - message: "Bitte gebe eine gültige E-Mail Adresse ein", - }) + .email({ message: "Gebe eine gültige E-Mail-Adresse ein" }) .refine( (value) => { // Regex to check for email aliases like + or % @@ -55,6 +51,28 @@ export const ProfileForm = ({ message: "Email-Aliase (wie + oder %) sind nicht erlaubt", }, ), + firstname: z + .string() + .min(2, { + message: "Der Vorname muss mindestens 2 Zeichen lang sein", + }) + .max(30, { + message: "Der Vorname darf maximal 30 Zeichen lang sein", + }) + .refine((val) => val.length === 0 || (/^[A-ZÄÖÜ]/.test(val) && val.split(" ").length > 1), { + message: "Der Vorname muss mit einem Großbuchstaben beginnen", + }), + lastname: z + .string() + .min(2, { + message: "Der Nachname muss mindestens 2 Zeichen lang sein", + }) + .max(30, { + message: "Der Nachname darf maximal 30 Zeichen lang sein", + }) + .refine((val) => val.length === 0 || val.includes(" ") || /^[A-ZÄÖÜ]/.test(val), { + message: "Der Nachname muss mit einem Großbuchstaben beginnen", + }), settingsHideLastname: z.boolean(), emailVerified: z.boolean().optional(), }); diff --git a/apps/hub/app/(auth)/register/_components/Register.tsx b/apps/hub/app/(auth)/register/_components/Register.tsx index 30d31961..29d9d854 100644 --- a/apps/hub/app/(auth)/register/_components/Register.tsx +++ b/apps/hub/app/(auth)/register/_components/Register.tsx @@ -45,7 +45,7 @@ export const Register = () => { .max(30, { message: "Der Nachname darf maximal 30 Zeichen lang sein", }) - .refine((val) => val.length === 0 || /^[A-ZÄÖÜ]/.test(val), { + .refine((val) => val.length === 0 || val.includes(" ") || /^[A-ZÄÖÜ]/.test(val), { message: "Der Nachname muss mit einem Großbuchstaben beginnen", }), password: z.string().min(12, { From eec72a51b8c630c90496c74076dabcec5efa822f Mon Sep 17 00:00:00 2001 From: PxlLoewe <72106766+PxlLoewe@users.noreply.github.com> Date: Wed, 9 Jul 2025 23:26:09 -0700 Subject: [PATCH 03/51] Finished Hub ESLINT rule enforcement --- apps/hub/app/(app)/admin/config/action.tsx | 8 +-- apps/hub/app/(app)/admin/config/page.tsx | 2 +- .../event/_components/AppointmentModal.tsx | 22 +++--- .../event/_components/ParticipantModal.tsx | 8 +-- apps/hub/app/(app)/admin/event/action.ts | 7 +- apps/hub/app/(app)/admin/event/new/page.tsx | 1 - apps/hub/app/(app)/admin/event/page.tsx | 35 +++++++--- .../(app)/admin/keyword/_components/Form.tsx | 3 +- apps/hub/app/(app)/admin/keyword/page.tsx | 11 ++- .../(app)/admin/station/_components/Form.tsx | 3 +- apps/hub/app/(app)/admin/station/page.tsx | 56 ++++++++++------ .../admin/user/[id]/_components/forms.tsx | 7 +- apps/hub/app/(app)/admin/user/page.tsx | 67 ++++++++++++------- .../(app)/events/_components/EventCard.tsx | 4 +- .../app/(app)/events/_components/Modal.tsx | 33 ++++----- .../app/(app)/resources/_components/Card.tsx | 1 - .../(auth)/oauth/_components/Authorize.tsx | 1 - apps/hub/app/_components/ErrorBoundary.tsx | 4 +- apps/hub/app/_components/PaginatedTable.tsx | 48 +++++-------- apps/hub/app/_components/QueryClient.tsx | 2 +- apps/hub/app/_components/Table.tsx | 19 +----- apps/hub/app/_components/ui/Button.tsx | 4 +- apps/hub/app/_components/ui/DateInput.tsx | 44 +++++------- packages/shared-components/helper/index.ts | 2 + .../shared-components/helper}/useDebounce.ts | 1 + .../shared-components/helper}/useTimeout.ts | 1 + 26 files changed, 199 insertions(+), 195 deletions(-) rename {apps/dispatch/app/_helpers => packages/shared-components/helper}/useDebounce.ts (95%) rename {apps/dispatch/app/_helpers => packages/shared-components/helper}/useTimeout.ts (98%) 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/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) { From a9a4f1617a620dfe1b7d5a9ece7f9575d0dd75e2 Mon Sep 17 00:00:00 2001 From: PxlLoewe <72106766+PxlLoewe@users.noreply.github.com> Date: Thu, 10 Jul 2025 00:35:34 -0700 Subject: [PATCH 04/51] fixed dispatch eslint errors --- .vscode/settings.json | 2 +- .../dispatch/_components/StationSelect.tsx | 3 +- .../navbar/_components/Connection.tsx | 4 +- .../_components/pannel/MissionForm.tsx | 3 +- .../dispatch/_components/pannel/Pannel.tsx | 9 +- .../(app)/pilot/_components/mrt/useButtons.ts | 4 +- .../navbar/_components/Connection.tsx | 9 +- apps/dispatch/app/(app)/pilot/page.tsx | 2 +- apps/dispatch/app/(auth)/layout.tsx | 1 - .../app/(auth)/login/_components/Login.tsx | 2 +- .../app/_components/Audio/useSounds.ts | 3 +- .../app/_components/ErrorBoundary.tsx | 4 +- .../app/_components/QueryProvider.tsx | 6 +- apps/dispatch/app/_components/Select.tsx | 4 +- .../customToasts/HPGnotification.tsx | 4 +- .../customToasts/StationStatusToast.tsx | 3 +- apps/dispatch/app/_components/left/Chat.tsx | 4 +- .../app/_components/left/SituationBoard.tsx | 14 +- .../app/_components/map/AircraftMarker.tsx | 2 +- .../dispatch/app/_components/map/BaseMaps.tsx | 18 +- .../app/_components/map/ContextMenu.tsx | 9 +- .../app/_components/map/MissionMarkers.tsx | 6 +- .../app/_components/map/SearchElements.tsx | 4 +- .../map/_components/AircraftMarkerTabs.tsx | 2 +- .../map/_components/MissionMarkerTabs.tsx | 27 +- .../app/_components/navbar/AdminPanel.tsx | 5 +- .../app/_components/navbar/Settings.tsx | 1 - .../app/_helpers/findClosestPolygon.ts | 1 + .../app/_helpers/findLeitstelleinPoint.ts | 4 +- .../app/_helpers/liveKitEventHandler.ts | 13 +- apps/dispatch/app/_querys/aircrafts.ts | 2 +- apps/dispatch/app/_querys/dispatcher.ts | 2 +- apps/dispatch/app/_querys/missions.ts | 6 +- apps/dispatch/app/_querys/osm.ts | 2 - apps/dispatch/app/_store/audioStore.ts | 7 +- .../app/api/aircrafts/positionlog/route.ts | 2 +- .../app/api/auth/[...nextauth]/auth.ts | 9 +- .../app/api/livekit-participant/route.ts | 7 +- apps/dispatch/app/api/livekit-token/route.ts | 1 - apps/dispatch/app/api/position-log/route.ts | 2 +- apps/dispatch/eslint.config.js | 2 +- apps/dispatch/package.json | 2 + apps/dispatch/types/next-auth.d.ts | 1 - package.json | 5 +- packages/eslint-config/next.js | 5 + packages/typescript-config/base.json | 3 +- pnpm-lock.yaml | 350 ++++++++++++++---- 47 files changed, 396 insertions(+), 185 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index d40ae7d2..7265ca71 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,7 +2,7 @@ "editor.formatOnSave": true, "files.autoSave": "off", "editor.defaultFormatter": "esbenp.prettier-vscode", - "eslint.workingDirectories": [{ "pattern": "./apps/*/" }, { "pattern": "./packages/*/" }], + "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/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 a79ba5ea..271aa4b2 100644 --- a/packages/eslint-config/next.js +++ b/packages/eslint-config/next.js @@ -29,4 +29,9 @@ export default defineConfig([ }, }, ...tseslint.config(js.configs.recommended, tseslint.configs.recommended, eslintConfigPrettier), + { + rules: { + "@typescript-eslint/no-unused-vars": "warn", + }, + }, ]); 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 980656a9..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)) @@ -95,7 +102,7 @@ importers: version: 0.5.7(@types/dom-mediacapture-transform@0.1.11)(livekit-client@2.14.0(@types/dom-mediacapture-record@1.0.22)) '@next-auth/prisma-adapter': specifier: ^1.0.7 - version: 1.0.7(@prisma/client@6.8.2(prisma@6.8.2(typescript@5.8.3))(typescript@5.8.3))(next-auth@4.24.11(next@15.3.4(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)) + version: 1.0.7(@prisma/client@6.8.2(prisma@6.8.2(typescript@5.8.3))(typescript@5.8.3))(next-auth@4.24.11(next@15.3.4(@babel/core@7.27.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)) '@radix-ui/react-icons': specifier: ^1.3.2 version: 1.3.2(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 @@ -176,7 +186,7 @@ importers: version: 15.3.4(@babel/core@7.27.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) next-auth: specifier: ^4.24.11 - version: 4.24.11(next@15.3.4(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 4.24.11(next@15.3.4(@babel/core@7.27.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) npm: specifier: ^11.4.2 version: 11.4.2 @@ -340,7 +350,7 @@ importers: version: 5.1.1(react-hook-form@7.59.0(react@19.1.0)) '@next-auth/prisma-adapter': specifier: ^1.0.7 - version: 1.0.7(@prisma/client@6.8.2(prisma@6.8.2(typescript@5.8.3))(typescript@5.8.3))(next-auth@4.24.11(next@15.3.4(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)) + version: 1.0.7(@prisma/client@6.8.2(prisma@6.8.2(typescript@5.8.3))(typescript@5.8.3))(next-auth@4.24.11(next@15.3.4(@babel/core@7.27.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)) '@radix-ui/react-icons': specifier: ^1.3.2 version: 1.3.2(react@19.1.0) @@ -415,7 +425,7 @@ importers: version: 15.3.4(@babel/core@7.27.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) next-auth: specifier: ^4.24.11 - version: 4.24.11(next@15.3.4(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 4.24.11(next@15.3.4(@babel/core@7.27.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) next-remove-imports: specifier: ^1.0.12 version: 1.0.12(webpack@5.99.9) @@ -562,7 +572,7 @@ importers: dependencies: '@typescript-eslint/eslint-plugin': specifier: ^8.36.0 - version: 8.36.0(@typescript-eslint/parser@8.35.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) + 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 @@ -1234,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} @@ -2569,14 +2583,6 @@ 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==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@typescript-eslint/parser': ^8.35.0 - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/eslint-plugin@8.36.0': resolution: {integrity: sha512-lZNihHUVB6ZZiPBNgOQGSxUASI7UJWhT8nHyUGCnaQ28XFCw98IfrMCG3rUl1uwUWoAvodJQby2KTs79UTcrAg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2654,13 +2660,6 @@ 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==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - '@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} @@ -2705,13 +2704,6 @@ 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==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - '@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} @@ -3754,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} @@ -6675,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': @@ -6723,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': @@ -6945,10 +6954,10 @@ snapshots: '@tybys/wasm-util': 0.9.0 optional: true - '@next-auth/prisma-adapter@1.0.7(@prisma/client@6.8.2(prisma@6.8.2(typescript@5.8.3))(typescript@5.8.3))(next-auth@4.24.11(next@15.3.4(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0))': + '@next-auth/prisma-adapter@1.0.7(@prisma/client@6.8.2(prisma@6.8.2(typescript@5.8.3))(typescript@5.8.3))(next-auth@4.24.11(next@15.3.4(@babel/core@7.27.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0))': dependencies: '@prisma/client': 6.8.2(prisma@6.8.2(typescript@5.8.3))(typescript@5.8.3) - next-auth: 4.24.11(next@15.3.4(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + next-auth: 4.24.11(next@15.3.4(@babel/core@7.27.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@next/env@15.3.4': {} @@ -8734,14 +8743,31 @@ 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.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 @@ -8751,15 +8777,15 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.36.0(@typescript-eslint/parser@8.35.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.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.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.28.0(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) '@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/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.28.0(jiti@2.4.2) + eslint: 9.30.1(jiti@2.4.2) graphemer: 1.4.0 ignore: 7.0.5 natural-compare: 1.4.0 @@ -8792,18 +8818,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.35.0(eslint@9.28.0(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.28.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 @@ -8816,6 +8830,18 @@ 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.36.0(typescript@5.8.3) @@ -8892,10 +8918,21 @@ 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.36.0(eslint@9.28.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.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) @@ -8903,12 +8940,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.36.0(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)': + '@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.28.0(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) debug: 4.4.1(supports-color@5.5.0) - eslint: 9.28.0(jiti@2.4.2) + eslint: 9.30.1(jiti@2.4.2) ts-api-utils: 2.1.0(typescript@5.8.3) typescript: 5.8.3 transitivePeerDependencies: @@ -8990,17 +9027,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.35.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.35.0 - '@typescript-eslint/types': 8.35.0 - '@typescript-eslint/typescript-estree': 8.35.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.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)) @@ -9012,6 +9038,28 @@ snapshots: 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 @@ -10109,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 @@ -10125,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) @@ -10152,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 @@ -10163,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 @@ -10192,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 @@ -10211,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)): @@ -10221,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 @@ -10265,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 @@ -10376,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 @@ -11676,7 +11886,7 @@ snapshots: neo-async@2.6.2: {} - next-auth@4.24.11(next@15.3.4(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + next-auth@4.24.11(next@15.3.4(@babel/core@7.27.7)(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: '@babel/runtime': 7.27.6 '@panva/hkdf': 1.2.1 From 3b1ceb8f8c88fd8f003da043d55be788c389d829 Mon Sep 17 00:00:00 2001 From: PxlLoewe <72106766+PxlLoewe@users.noreply.github.com> Date: Thu, 10 Jul 2025 00:50:52 -0700 Subject: [PATCH 05/51] Aktualisieren von deploy-staging.yml --- .github/workflows/deploy-staging.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/deploy-staging.yml b/.github/workflows/deploy-staging.yml index e3fb7c2d..20440e60 100644 --- a/.github/workflows/deploy-staging.yml +++ b/.github/workflows/deploy-staging.yml @@ -40,6 +40,7 @@ jobs: username: ${{ secrets.SSH_USERNAME }} password: ${{ secrets.SSH_PASSWORD }} port: 22 + command_timeout: 30m script: | export NVM_DIR="$HOME/.nvm" source "$NVM_DIR/nvm.sh" From b9eef5252e901ed033b1e8339678d6780728f2bf Mon Sep 17 00:00:00 2001 From: PxlLoewe <72106766+PxlLoewe@users.noreply.github.com> Date: Thu, 10 Jul 2025 10:19:36 -0700 Subject: [PATCH 06/51] Fix Pilot-conenction --- .../navbar/_components/Connection.tsx | 70 +++++------ .../navbar/_components/Connection.tsx | 111 +++++++++--------- .../shared-components/components/Button.tsx | 43 +++++++ .../shared-components/components/index.ts | 1 + packages/shared-components/package.json | 2 +- pnpm-lock.yaml | 10 +- 6 files changed, 135 insertions(+), 102 deletions(-) create mode 100644 packages/shared-components/components/Button.tsx 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 3ec4a56a..5189ab0f 100644 --- a/apps/dispatch/app/(app)/dispatch/_components/navbar/_components/Connection.tsx +++ b/apps/dispatch/app/(app)/dispatch/_components/navbar/_components/Connection.tsx @@ -3,11 +3,10 @@ import { useSession } from "next-auth/react"; import { useDispatchConnectionStore } from "../../../../../_store/dispatch/connectionStore"; import { useEffect, useRef, useState } from "react"; -import { toast } from "react-hot-toast"; import { useMutation } from "@tanstack/react-query"; import { Prisma } from "@repo/db"; import { changeDispatcherAPI } from "_querys/dispatcher"; -import { getNextDateWithTime } from "@repo/shared-components"; +import { Button, getNextDateWithTime } from "@repo/shared-components"; export const ConnectionBtn = () => { const modalRef = useRef(null); @@ -20,44 +19,19 @@ export const ConnectionBtn = () => { mutationFn: ({ id, data }: { id: number; data: Prisma.ConnectedDispatcherUpdateInput }) => changeDispatcherAPI(id, data), }); - const [logoffDebounce, setLogoffDebounce] = useState(null); const session = useSession(); const uid = session.data?.user?.id; // useEffect für die Logoff-Zeit const [logoffHours, logoffMinutes] = form.logoffTime?.split(":").map(Number) || []; - useEffect(() => { - if (!logoffHours || !logoffMinutes) return; - if (logoffDebounce) clearTimeout(logoffDebounce); - - const timeout = setTimeout(async () => { - if (!logoffHours || !logoffMinutes || !connection.connectedDispatcher) return; - await changeDispatcherMutation.mutateAsync({ - id: connection.connectedDispatcher?.id, - data: { - esimatedLogoutTime: - logoffHours && logoffMinutes ? getNextDateWithTime(logoffHours, logoffMinutes) : null, - }, - }); - toast.success("Änderung gespeichert!"); - modalRef.current?.close(); - }, 2000); - - setLogoffDebounce(timeout); - - // Cleanup function - return () => { - if (logoffDebounce) clearTimeout(logoffDebounce); - }; - }, [form.logoffTime, connection.connectedDispatcher]); - useEffect(() => { // Disconnect the socket when the component unmounts return () => { connection.disconnect(); }; }, [connection.disconnect]); + if (!uid) return null; return (
@@ -122,16 +96,36 @@ export const ConnectionBtn = () => { {connection.status == "connected" ? ( - + <> + + + ) : ( {connection.status == "connected" ? ( - + <> + + + ) : ( - + )}
diff --git a/packages/shared-components/components/Button.tsx b/packages/shared-components/components/Button.tsx new file mode 100644 index 00000000..99d9ee42 --- /dev/null +++ b/packages/shared-components/components/Button.tsx @@ -0,0 +1,43 @@ +"use client"; +import React, { + ButtonHTMLAttributes, + DetailedHTMLProps, + useEffect, + useState, + forwardRef, +} from "react"; +import { cn } from "@repo/shared-components"; + +export const Button = forwardRef< + HTMLButtonElement, + DetailedHTMLProps, HTMLButtonElement> & { + isLoading?: boolean; + } +>(({ isLoading, ...props }, ref) => { + const [isLoadingState, setIsLoadingState] = useState(isLoading); + + useEffect(() => { + setIsLoadingState(isLoading); + }, [isLoading]); + + return ( + + ); +}); + +Button.displayName = "Button"; diff --git a/packages/shared-components/components/index.ts b/packages/shared-components/components/index.ts index 8f59c043..77206c39 100644 --- a/packages/shared-components/components/index.ts +++ b/packages/shared-components/components/index.ts @@ -1,3 +1,4 @@ export * from "./Badge"; export * from "./PenaltyDropdown"; export * from "./Maintenance"; +export * from "./Button"; diff --git a/packages/shared-components/package.json b/packages/shared-components/package.json index 574e5fab..193155fd 100644 --- a/packages/shared-components/package.json +++ b/packages/shared-components/package.json @@ -15,7 +15,7 @@ "tailwind-merge": "^3.3.0" }, "devDependencies": { - "@types/react": "^19.1.6", + "@types/react": "^19.1.8", "@types/react-dom": "^19.1.5", "react": "^19.1.0", "react-dom": "^19.1.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1c379cc7..e911870d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -630,11 +630,11 @@ importers: version: 3.3.0 devDependencies: '@types/react': - specifier: ^19.1.6 - version: 19.1.6 + specifier: ^19.1.8 + version: 19.1.8 '@types/react-dom': specifier: ^19.1.5 - version: 19.1.5(@types/react@19.1.6) + version: 19.1.5(@types/react@19.1.8) react: specifier: ^19.1.0 version: 19.1.0 @@ -8668,9 +8668,9 @@ snapshots: '@types/range-parser@1.2.7': {} - '@types/react-dom@19.1.5(@types/react@19.1.6)': + '@types/react-dom@19.1.5(@types/react@19.1.8)': dependencies: - '@types/react': 19.1.6 + '@types/react': 19.1.8 '@types/react-dom@19.1.6(@types/react@19.1.8)': dependencies: From 8e71571da940b65500fb2bf85c9b0f7253caf3e7 Mon Sep 17 00:00:00 2001 From: PxlLoewe <72106766+PxlLoewe@users.noreply.github.com> Date: Thu, 10 Jul 2025 10:40:19 -0700 Subject: [PATCH 07/51] =?UTF-8?q?Fix=20Admin=20Links,=20Piloten=20k=C3=B6n?= =?UTF-8?q?nen=20nur=20mit=20Dispos=20schreiben?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/dispatch/app/_components/left/Chat.tsx | 7 ++++++- apps/hub/app/(app)/admin/station/page.tsx | 2 +- .../app/(app)/admin/user/[id]/_components/forms.tsx | 4 ++-- apps/hub/app/(app)/admin/user/page.tsx | 2 +- apps/hub/app/(app)/settings/_components/forms.tsx | 10 ++++------ .../migration.sql | 2 ++ packages/database/prisma/schema/user.prisma | 10 +++++----- 7 files changed, 21 insertions(+), 16 deletions(-) create mode 100644 packages/database/prisma/schema/migrations/20250710172949_change_vatsim_id_to_string/migration.sql diff --git a/apps/dispatch/app/_components/left/Chat.tsx b/apps/dispatch/app/_components/left/Chat.tsx index 0ef4ed3e..635c518e 100644 --- a/apps/dispatch/app/_components/left/Chat.tsx +++ b/apps/dispatch/app/_components/left/Chat.tsx @@ -8,6 +8,7 @@ import { asPublicUser } from "@repo/db"; import { useQuery } from "@tanstack/react-query"; import { getConnectedDispatcherAPI } from "_querys/dispatcher"; import { getConnectedAircraftsAPI } from "_querys/aircrafts"; +import { useDispatchConnectionStore } from "_store/dispatch/connectionStore"; export const Chat = () => { const { @@ -26,6 +27,7 @@ export const Chat = () => { const session = useSession(); const [addTabValue, setAddTabValue] = useState("default"); const [message, setMessage] = useState(""); + const dispatcherConnected = useDispatchConnectionStore((state) => state.status === "connected"); const { data: dispatcher } = useQuery({ queryKey: ["dispatcher"], @@ -36,6 +38,7 @@ export const Chat = () => { queryKey: ["aircrafts"], queryFn: () => getConnectedAircraftsAPI(), refetchInterval: 10000, + enabled: dispatcherConnected, }); useEffect(() => { @@ -44,7 +47,9 @@ export const Chat = () => { }, [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); + const filteredAircrafts = aircrafts?.filter( + (a) => a.userId !== session.data?.user.id && dispatcherConnected, + ); return (
diff --git a/apps/hub/app/(app)/admin/station/page.tsx b/apps/hub/app/(app)/admin/station/page.tsx index ba505313..12397a9a 100644 --- a/apps/hub/app/(app)/admin/station/page.tsx +++ b/apps/hub/app/(app)/admin/station/page.tsx @@ -33,7 +33,7 @@ const page = () => { header: "Aktionen", cell: ({ row }) => (
- +
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 da3c714c..0a90c5c2 100644 --- a/apps/hub/app/(app)/admin/user/[id]/_components/forms.tsx +++ b/apps/hub/app/(app)/admin/user/[id]/_components/forms.tsx @@ -51,11 +51,11 @@ 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 "(app)/../../helper/discord"; +import { setStandardName } from "../../../../../../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 { sendMailByTemplate } from "(app)/../../helper/mail"; +import { sendMailByTemplate } from "../../../../../../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 d8bead10..550544cd 100644 --- a/apps/hub/app/(app)/admin/user/page.tsx +++ b/apps/hub/app/(app)/admin/user/page.tsx @@ -45,7 +45,7 @@ const AdminUserPage = () => { header: "Aktionen", cell: ({ row }) => (
- +
diff --git a/apps/hub/app/(app)/settings/_components/forms.tsx b/apps/hub/app/(app)/settings/_components/forms.tsx index 7b22104c..79df594b 100644 --- a/apps/hub/app/(app)/settings/_components/forms.tsx +++ b/apps/hub/app/(app)/settings/_components/forms.tsx @@ -223,7 +223,7 @@ export const SocialForm = ({ const router = useRouter(); const schema = z.object({ - vatsimCid: z.number().min(1000).max(9999999), + vatsimCid: z.string(), }); type IFormInput = z.infer; @@ -293,12 +293,10 @@ export const SocialForm = ({ VATSIM-CID

Date: Thu, 10 Jul 2025 11:57:13 -0700 Subject: [PATCH 08/51] event page --- apps/hub/app/(app)/admin/event/page.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/hub/app/(app)/admin/event/page.tsx b/apps/hub/app/(app)/admin/event/page.tsx index 286f0f67..cf3a0448 100644 --- a/apps/hub/app/(app)/admin/event/page.tsx +++ b/apps/hub/app/(app)/admin/event/page.tsx @@ -1,3 +1,4 @@ +"use client"; import { PartyPopperIcon } from "lucide-react"; import { PaginatedTable } from "../../../_components/PaginatedTable"; import Link from "next/link"; From 446391679ce278f3e1e4d3957d6dc1b710fe57be Mon Sep 17 00:00:00 2001 From: PxlLoewe <72106766+PxlLoewe@users.noreply.github.com> Date: Thu, 10 Jul 2025 23:41:39 -0700 Subject: [PATCH 09/51] Fix lougout-Zeit --- apps/dispatch-server/socket-events/connect-dispatch.ts | 4 +++- apps/dispatch-server/socket-events/connect-pilot.ts | 4 +++- .../_components/navbar/_components/Connection.tsx | 7 +++---- .../pilot/_components/navbar/_components/Connection.tsx | 9 ++++++--- apps/hub/app/(app)/admin/keyword/page.tsx | 1 + apps/hub/app/(app)/admin/station/page.tsx | 2 +- 6 files changed, 17 insertions(+), 10 deletions(-) diff --git a/apps/dispatch-server/socket-events/connect-dispatch.ts b/apps/dispatch-server/socket-events/connect-dispatch.ts index ba41eee5..ddd6528c 100644 --- a/apps/dispatch-server/socket-events/connect-dispatch.ts +++ b/apps/dispatch-server/socket-events/connect-dispatch.ts @@ -51,7 +51,9 @@ export const handleConnectDispatch = data: { publicUser: getPublicUser(user) as any, esimatedLogoutTime: - logoffHours && logoffMinutes ? getNextDateWithTime(logoffHours, logoffMinutes) : null, + logoffHours !== undefined && logoffMinutes !== undefined + ? getNextDateWithTime(logoffHours, logoffMinutes) + : null, lastHeartbeat: new Date().toISOString(), userId: user.id, zone: selectedZone, diff --git a/apps/dispatch-server/socket-events/connect-pilot.ts b/apps/dispatch-server/socket-events/connect-pilot.ts index efe7582b..0f9b4118 100644 --- a/apps/dispatch-server/socket-events/connect-pilot.ts +++ b/apps/dispatch-server/socket-events/connect-pilot.ts @@ -79,7 +79,9 @@ export const handleConnectPilot = data: { publicUser: getPublicUser(user) as any, esimatedLogoutTime: - logoffHours && logoffMinutes ? getNextDateWithTime(logoffHours, logoffMinutes) : null, + logoffHours !== undefined && logoffMinutes !== undefined + ? getNextDateWithTime(logoffHours, logoffMinutes) + : null, userId: userId, stationId: parseInt(stationId), lastHeartbeat: debug ? nowPlus2h.toISOString() : undefined, 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 5189ab0f..2bb6bbab 100644 --- a/apps/dispatch/app/(app)/dispatch/_components/navbar/_components/Connection.tsx +++ b/apps/dispatch/app/(app)/dispatch/_components/navbar/_components/Connection.tsx @@ -22,9 +22,6 @@ export const ConnectionBtn = () => { const session = useSession(); const uid = session.data?.user?.id; - // useEffect für die Logoff-Zeit - const [logoffHours, logoffMinutes] = form.logoffTime?.split(":").map(Number) || []; - useEffect(() => { // Disconnect the socket when the component unmounts return () => { @@ -101,11 +98,13 @@ export const ConnectionBtn = () => { className="btn" onClick={async () => { if (!connection.connectedDispatcher?.id) return; + const [logoffHours, logoffMinutes] = + form.logoffTime?.split(":").map(Number) || []; await changeDispatcherMutation.mutateAsync({ id: connection.connectedDispatcher?.id, data: { esimatedLogoutTime: - logoffHours && logoffMinutes + logoffHours !== undefined && logoffMinutes !== undefined ? getNextDateWithTime(logoffHours, logoffMinutes) : null, }, 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 83c0a5ce..09258ea9 100644 --- a/apps/dispatch/app/(app)/pilot/_components/navbar/_components/Connection.tsx +++ b/apps/dispatch/app/(app)/pilot/_components/navbar/_components/Connection.tsx @@ -54,8 +54,6 @@ export const ConnectionBtn = () => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [connection.disconnect]); - const [logoffHours, logoffMinutes] = form.logoffTime?.split(":").map(Number) || []; - const { data: connectedAircrafts } = useQuery({ queryKey: ["aircrafts"], queryFn: () => getConnectedAircraftsAPI(), @@ -182,11 +180,15 @@ export const ConnectionBtn = () => { className="btn" onClick={async () => { if (!connection.connectedAircraft) return; + const [logoffHours, logoffMinutes] = + form.logoffTime?.split(":").map(Number) || []; + + console.log(logoffHours, logoffMinutes, form.logoffTime); await aircraftMutation.mutateAsync({ sessionId: connection.connectedAircraft.id, change: { esimatedLogoutTime: - logoffHours && logoffMinutes + logoffHours !== undefined && logoffMinutes !== undefined ? getNextDateWithTime(logoffHours, logoffMinutes) : null, }, @@ -202,6 +204,7 @@ export const ConnectionBtn = () => { onSubmit={() => false} onClick={() => { connection.disconnect(); + modalRef.current?.close(); }} > Verbindung Trennen diff --git a/apps/hub/app/(app)/admin/keyword/page.tsx b/apps/hub/app/(app)/admin/keyword/page.tsx index 94f7714d..25a57b1a 100644 --- a/apps/hub/app/(app)/admin/keyword/page.tsx +++ b/apps/hub/app/(app)/admin/keyword/page.tsx @@ -1,3 +1,4 @@ +"use client"; import { DatabaseBackupIcon } from "lucide-react"; import { PaginatedTable } from "../../../_components/PaginatedTable"; import Link from "next/link"; diff --git a/apps/hub/app/(app)/admin/station/page.tsx b/apps/hub/app/(app)/admin/station/page.tsx index 12397a9a..07b5611f 100644 --- a/apps/hub/app/(app)/admin/station/page.tsx +++ b/apps/hub/app/(app)/admin/station/page.tsx @@ -10,7 +10,7 @@ const page = () => { <> Date: Fri, 11 Jul 2025 21:10:26 -0700 Subject: [PATCH 10/51] =?UTF-8?q?Filter=20Verlegung=20aus=20Prim=C3=A4rein?= =?UTF-8?q?s=C3=A4tzen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dispatch/_components/pannel/MissionForm.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/apps/dispatch/app/(app)/dispatch/_components/pannel/MissionForm.tsx b/apps/dispatch/app/(app)/dispatch/_components/pannel/MissionForm.tsx index df0baa41..02c33695 100644 --- a/apps/dispatch/app/(app)/dispatch/_components/pannel/MissionForm.tsx +++ b/apps/dispatch/app/(app)/dispatch/_components/pannel/MissionForm.tsx @@ -307,11 +307,13 @@ export const MissionForm = () => { - {Object.keys(KEYWORD_CATEGORY).map((use) => ( - - ))} + {Object.keys(KEYWORD_CATEGORY) + .filter((k) => !k.startsWith("V_")) + .map((use) => ( + + ))} {form.formState.errors.missionKeywordCategory && (

Bitte wähle eine Kategorie aus.

From d2b287abdc44323463e6c8162a9ab568eb51bf4c Mon Sep 17 00:00:00 2001 From: PxlLoewe <72106766+PxlLoewe@users.noreply.github.com> Date: Fri, 11 Jul 2025 23:23:30 -0700 Subject: [PATCH 11/51] =?UTF-8?q?Lade-anzeige=20f=C3=BCr=20Tabellen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/hub/app/_components/PaginatedTable.tsx | 61 +++++++++++++++------ apps/hub/app/_components/Table.tsx | 22 ++++++++ 2 files changed, 67 insertions(+), 16 deletions(-) diff --git a/apps/hub/app/_components/PaginatedTable.tsx b/apps/hub/app/_components/PaginatedTable.tsx index f9f6edb3..2b82f1ba 100644 --- a/apps/hub/app/_components/PaginatedTable.tsx +++ b/apps/hub/app/_components/PaginatedTable.tsx @@ -1,6 +1,6 @@ "use client"; -import { useState, Ref, useImperativeHandle } from "react"; -import SortableTable, { Pagination, SortableTableProps } from "./Table"; +import { useState, Ref, useImperativeHandle, useEffect, useCallback } from "react"; +import SortableTable, { Pagination, RowsPerPage, SortableTableProps } from "./Table"; import { PrismaClient } from "@repo/db"; import { getData } from "./pagiantedTableActions"; import { useDebounce } from "@repo/shared-components"; @@ -12,7 +12,7 @@ export interface PaginatedTableRef { interface PaginatedTableProps extends Omit, "data"> { prismaModel: keyof PrismaClient; filter?: Record; - rowsPerPage?: number; + initialRowsPerPage?: number; searchFields?: string[]; include?: Record; strictQuery?: boolean; @@ -25,7 +25,7 @@ interface PaginatedTableProps extends Omit, "da export function PaginatedTable({ prismaModel, - rowsPerPage = 10, + initialRowsPerPage = 30, searchFields = [], filter, include, @@ -38,6 +38,7 @@ export function PaginatedTable({ ...restProps }: PaginatedTableProps) { const [data, setData] = useState([]); + const [rowsPerPage, setRowsPerPage] = useState(initialRowsPerPage); const [page, setPage] = useState(0); const [total, setTotal] = useState(0); const [searchTerm, setSearchTerm] = useState(""); @@ -52,8 +53,10 @@ export function PaginatedTable({ ) : {}, ); + const [loading, setLoading] = useState(false); - const RefreshTableData = async () => { + const refreshTableData = useCallback(async () => { + setLoading(true); getData( prismaModel, rowsPerPage, @@ -75,23 +78,43 @@ export function PaginatedTable({ return acc; }, {}) : undefined, - ).then((result) => { - if (result) { - setData(result.data); - setTotal(result.total); - } - }); - }; + ) + .then((result) => { + if (result) { + setData(result.data); + setTotal(result.total); + } + }) + .finally(() => { + setLoading(false); + }); + }, [ + prismaModel, + rowsPerPage, + page, + searchTerm, + searchFields, + filter, + include, + orderBy, + strictQuery, + restProps.columns, + ]); useImperativeHandle(ref, () => ({ refresh: () => { - RefreshTableData(); + refreshTableData(); }, })); + // useEffect to show loading spinner + useEffect(() => { + setLoading(true); + }, [searchTerm, page, rowsPerPage, orderBy, filter, setLoading, refreshTableData]); + useDebounce( () => { - RefreshTableData(); + refreshTableData(); }, 500, [searchTerm, page, rowsPerPage, orderBy, filter], @@ -100,7 +123,10 @@ export function PaginatedTable({ return (
-
{leftOfSearch}
+
+
{leftOfSearch}
+
{loading && }
+
{searchFields.length > 0 && ( ({
{leftOfPagination} {!hide && ( - + <> + + + )}
diff --git a/apps/hub/app/_components/Table.tsx b/apps/hub/app/_components/Table.tsx index 3a0e6d5f..115dfce4 100644 --- a/apps/hub/app/_components/Table.tsx +++ b/apps/hub/app/_components/Table.tsx @@ -86,6 +86,28 @@ export default function SortableTable({ ); } +export const RowsPerPage = ({ + rowsPerPage, + setRowsPerPage, +}: { + rowsPerPage: number; + setRowsPerPage: (rowsPerPage: number) => void; +}) => { + return ( + + ); +}; + export const Pagination = ({ page, totalPages, From 280393b307a7230ef261c4baca75f742c7e5ecb8 Mon Sep 17 00:00:00 2001 From: PxlLoewe <72106766+PxlLoewe@users.noreply.github.com> Date: Fri, 11 Jul 2025 23:26:01 -0700 Subject: [PATCH 12/51] Moodle Chron wrapped in tryCatch --- apps/hub-server/modules/chron.ts | 80 +++++++++++++++++--------------- 1 file changed, 42 insertions(+), 38 deletions(-) diff --git a/apps/hub-server/modules/chron.ts b/apps/hub-server/modules/chron.ts index a833d265..3b8e4f2b 100644 --- a/apps/hub-server/modules/chron.ts +++ b/apps/hub-server/modules/chron.ts @@ -32,51 +32,55 @@ const syncMoodleIds = async () => { }; const updateParticipantMoodleResults = async () => { - const participantsMoodlePending = await prisma.participant.findMany({ - where: { - finisherMoodleCurseCompleted: false, - Event: { - finisherMoodleCourseId: { - not: null, + try { + const participantsMoodlePending = await prisma.participant.findMany({ + where: { + finisherMoodleCurseCompleted: false, + Event: { + finisherMoodleCourseId: { + not: null, + }, }, }, - }, - include: { - Event: true, - User: true, - }, - }); - await Promise.all( - participantsMoodlePending.map(async (p) => { - if (!p.User) return; - if (!p.User.moodleId) return; + include: { + Event: true, + User: true, + }, + }); + await Promise.all( + participantsMoodlePending.map(async (p) => { + if (!p.User) return; + if (!p.User.moodleId) return; - const quizzResult = await getMoodleCourseCompletionStatus( - p.User.moodleId.toString(), - p.Event.finisherMoodleCourseId!, - ); + const quizzResult = await getMoodleCourseCompletionStatus( + p.User.moodleId.toString(), + p.Event.finisherMoodleCourseId!, + ); - if (quizzResult?.completionstatus?.completed === true) { - await handleParticipantFinished(p.Event, p, p.User); + if (quizzResult?.completionstatus?.completed === true) { + await handleParticipantFinished(p.Event, p, p.User); - return prisma.participant.update({ - where: { - id: p.id, - }, - data: { - finisherMoodleCurseCompleted: true, - statusLog: { - push: { - event: "Moodle-Kurs abgeschlossen", - timestamp: new Date(), - user: "system", + return prisma.participant.update({ + where: { + id: p.id, + }, + data: { + finisherMoodleCurseCompleted: true, + statusLog: { + push: { + event: "Moodle-Kurs abgeschlossen", + timestamp: new Date(), + user: "system", + }, }, }, - }, - }); - } - }), - ); + }); + } + }), + ); + } catch (error) { + console.error("Error updating participant Moodle results:", error); + } }; CronJob.from({ cronTime: "0 * * * *", onTick: syncMoodleIds, start: true }); From a11c8683c40d5bd484841999935f62cb5e474d75 Mon Sep 17 00:00:00 2001 From: PxlLoewe <72106766+PxlLoewe@users.noreply.github.com> Date: Fri, 11 Jul 2025 23:31:47 -0700 Subject: [PATCH 13/51] =?UTF-8?q?Chat=20tabs=20k=C3=B6nnen=20durch=20erneu?= =?UTF-8?q?tes=20ausw=C3=A4hlen=20geschlossen=20werden?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/dispatch/app/_components/left/Chat.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/dispatch/app/_components/left/Chat.tsx b/apps/dispatch/app/_components/left/Chat.tsx index 635c518e..8f75105c 100644 --- a/apps/dispatch/app/_components/left/Chat.tsx +++ b/apps/dispatch/app/_components/left/Chat.tsx @@ -139,7 +139,13 @@ export const Chat = () => { setSelectedChat(userId)} + onClick={() => { + if (selectedChat === userId) { + setSelectedChat(null); + return; + } + setSelectedChat(userId); + }} > {chat.name} {chat.notification && } From 01bef65218f902b52a248b55558e297e0ed52832 Mon Sep 17 00:00:00 2001 From: PxlLoewe <72106766+PxlLoewe@users.noreply.github.com> Date: Fri, 11 Jul 2025 23:56:24 -0700 Subject: [PATCH 14/51] =?UTF-8?q?Skigebiete=20layer=20in=20Karte=20hinzuge?= =?UTF-8?q?f=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dispatch/app/_components/map/BaseMaps.tsx | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/apps/dispatch/app/_components/map/BaseMaps.tsx b/apps/dispatch/app/_components/map/BaseMaps.tsx index 89dfac16..e33d0d91 100644 --- a/apps/dispatch/app/_components/map/BaseMaps.tsx +++ b/apps/dispatch/app/_components/map/BaseMaps.tsx @@ -260,6 +260,25 @@ const NiederschlagOverlay = () => { ); }; +const SlopesOverlay = () => { + const tileLayerRef = useRef(null); + + return ( + { + tileLayerRef.current?.bringToFront(); + }, + }} + attribution="Opensnowmap.org (CC-BY-SA)" + url="http://tiles.opensnowmap.org/pistes/{z}/{x}/{y}.png?" + transparent + zIndex={1000} + /> + ); +}; + const WindfarmOutlineLayer = () => { const map = useMap(); const [isVisible, setIsVisible] = useState(false); @@ -304,7 +323,7 @@ const WindfarmOutlineLayer = () => { export const BaseMaps = () => { const map = useMap(); return ( - + @@ -322,6 +341,9 @@ export const BaseMaps = () => { + + + Date: Sat, 12 Jul 2025 00:48:48 -0700 Subject: [PATCH 15/51] Chat animation, Audio-Berechtigungsabfrage, Berechtigung Fehlermeldung --- apps/dispatch/app/(app)/dispatch/layout.tsx | 8 +++++++- apps/dispatch/app/(app)/pilot/layout.tsx | 8 +++++++- apps/dispatch/app/_components/left/Chat.tsx | 2 +- .../app/_components/navbar/Settings.tsx | 19 ++++++++++++++----- 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/apps/dispatch/app/(app)/dispatch/layout.tsx b/apps/dispatch/app/(app)/dispatch/layout.tsx index 9ef4a9bc..bade8d8d 100644 --- a/apps/dispatch/app/(app)/dispatch/layout.tsx +++ b/apps/dispatch/app/(app)/dispatch/layout.tsx @@ -16,7 +16,13 @@ export default async function RootLayout({ const session = await getServerSession(); if (!session?.user.permissions.includes("DISPO")) - return ; + return ( + + ); return ( <> diff --git a/apps/dispatch/app/(app)/pilot/layout.tsx b/apps/dispatch/app/(app)/pilot/layout.tsx index c734eb8e..ab71548f 100644 --- a/apps/dispatch/app/(app)/pilot/layout.tsx +++ b/apps/dispatch/app/(app)/pilot/layout.tsx @@ -16,7 +16,13 @@ export default async function RootLayout({ const session = await getServerSession(); if (!session?.user.permissions.includes("PILOT")) - return ; + return ( + + ); return ( <> diff --git a/apps/dispatch/app/_components/left/Chat.tsx b/apps/dispatch/app/_components/left/Chat.tsx index 8f75105c..b62e4842 100644 --- a/apps/dispatch/app/_components/left/Chat.tsx +++ b/apps/dispatch/app/_components/left/Chat.tsx @@ -55,7 +55,7 @@ export const Chat = () => {
{Object.values(chats).some((c) => c.notification) && ( - + )}