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] 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) {