Merge pull request #48 from VAR-Virtual-Air-Rescue/eslint

Fix NextJS app ESlint errors
This commit was merged in pull request #48.
This commit is contained in:
PxlLoewe
2025-07-10 00:37:12 -07:00
committed by GitHub
89 changed files with 845 additions and 432 deletions

View File

@@ -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"}`);
}
};

View File

@@ -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";

View File

@@ -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 = ({
</button>
</form>
<h3 className="font-bold text-lg">Termin {appointmentForm.watch("id")}</h3>
<form
onSubmit={appointmentForm.handleSubmit(async (values) => {
if (!event) return;
@@ -55,13 +55,13 @@ export const AppointmentModal = ({
})}
className="flex flex-col"
>
<DateInput
control={appointmentForm.control}
name="appointmentDate"
showTimeInput
timeCaption="Uhrzeit"
showTimeCaption
/>
<div className="flex justify-between mr-7">
<h3 className="font-bold text-lg">Termin {appointmentForm.watch("id")}</h3>
<DateInput
value={new Date(appointmentForm.watch("appointmentDate") || Date.now())}
onChange={(date) => appointmentForm.setValue("appointmentDate", date)}
/>
</div>
<div>
<PaginatedTable
hide={appointmentForm.watch("id") === undefined}
@@ -150,7 +150,7 @@ export const AppointmentModal = ({
attended: false,
appointmentCancelled: true,
statusLog: [
...(row.original.statusLog as any),
...(row.original.statusLog as InputJsonValueType[]),
{
event: "Gefehlt an Event",
timestamp: new Date().toISOString(),
@@ -169,7 +169,7 @@ export const AppointmentModal = ({
);
},
},
] as ColumnDef<Participant, any>[]
] as ColumnDef<Participant>[]
}
prismaModel={"participant"}
filter={{

View File

@@ -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
<div className="flex flex-col">
<h3 className="text-xl">Verlauf</h3>
{(participantForm.watch("statusLog") as unknown as ParticipantLog[])?.map((s) => (
<div className="flex justify-between" key={(s as any).timestamp}>
<div className="flex justify-between" key={s.timestamp.toString()}>
<p>{s.event}</p>
<p>{s.user}</p>
<p>{new Date((s as any).timestamp).toLocaleString()}</p>
<p>{new Date(s.timestamp).toLocaleString()}</p>
</div>
))}
</div>

View File

@@ -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 },

View File

@@ -1,4 +1,3 @@
import { prisma } from "@repo/db";
import { Form } from "../_components/Form";
export default async () => {

View File

@@ -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 (
<>
<PaginatedTable
showEditButton
prismaModel="event"
columns={[
{
header: "Name",
accessorKey: "name",
},
{
header: "Versteckt",
accessorKey: "hidden",
},
]}
columns={
[
{
header: "Name",
accessorKey: "name",
},
{
header: "Versteckt",
accessorKey: "hidden",
},
{
header: "Aktionen",
cell: ({ row }) => (
<div className="flex items-center gap-1">
<Link href={`/admin/event/${row.original.id}`}>
<button className="btn btn-sm">Edit</button>
</Link>
</div>
),
},
] as ColumnDef<Event>[]
}
leftOfSearch={
<span className="flex items-center gap-2">
<PartyPopperIcon className="w-5 h-5" /> Events

View File

@@ -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 }) => {
<form
onSubmit={form.handleSubmit(async (values) => {
setLoading(true);
const createdKeyword = await upsertKeyword(values, keyword?.id);
await upsertKeyword(values, keyword?.id);
setLoading(false);
if (!keyword) redirect(`/admin/keyword`);
})}

View File

@@ -9,7 +9,6 @@ export default () => {
<>
<PaginatedTable
initialOrderBy={[{ id: "category", desc: true }]}
showEditButton
prismaModel="keyword"
searchFields={["name", "abreviation", "description"]}
columns={
@@ -26,6 +25,16 @@ export default () => {
header: "Name",
accessorKey: "name",
},
{
header: "Aktionen",
cell: ({ row }) => (
<div className="flex items-center gap-1">
<Link href={`/admin/keyword/${row.original.id}`}>
<button className="btn btn-sm">bearbeiten</button>
</Link>
</div>
),
},
] as ColumnDef<Keyword>[]
}
leftOfSearch={

View File

@@ -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";

View File

@@ -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 (
<>
<PaginatedTable
showEditButton
prismaModel="station"
searchFields={["bosCallsign", "bosUse", "country", "operator"]}
columns={[
{
header: "BOS Name",
accessorKey: "bosCallsign",
},
{
header: "Bos Use",
accessorKey: "bosUse",
},
{
header: "Country",
accessorKey: "country",
},
{
header: "operator",
accessorKey: "operator",
},
]}
columns={
[
{
header: "BOS Name",
accessorKey: "bosCallsign",
},
{
header: "Bos Use",
accessorKey: "bosUse",
},
{
header: "Country",
accessorKey: "country",
},
{
header: "operator",
accessorKey: "operator",
},
{
header: "Aktionen",
cell: ({ row }) => (
<div className="flex items-center gap-1">
<Link href={`/admin/event/${row.original.id}`}>
<button className="btn btn-sm">Edit</button>
</Link>
</div>
),
},
] as ColumnDef<Station>[]
}
leftOfSearch={
<span className="flex items-center gap-2">
<DatabaseBackupIcon className="w-5 h-5" /> Stationen
@@ -35,9 +49,7 @@ const page = () => {
rightOfSearch={
<p className="text-2xl font-semibold text-left flex items-center gap-2 justify-between">
<Link href={"/admin/station/new"}>
<button className="btn btn-sm btn-outline btn-primary">
Erstellen
</button>
<button className="btn btn-sm btn-outline btn-primary">Erstellen</button>
</Link>
</p>
}

View File

@@ -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;

View File

@@ -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 (
<>
<PaginatedTable
showEditButton
prismaModel="user"
searchFields={["publicId", "firstname", "lastname", "email"]}
initialOrderBy={[
@@ -16,28 +19,40 @@ const AdminUserPage = async () => {
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 }) => (
<div className="flex items-center gap-1">
<Link href={`/admin/event/${row.original.id}`}>
<button className="btn btn-sm">Anzeigen</button>
</Link>
</div>
),
},
] as ColumnDef<User>[]
} // Define the columns for the user table
leftOfSearch={
<p className="text-2xl font-semibold text-left flex items-center gap-2">
<User2 className="w-5 h-5" /> Benutzer

View File

@@ -17,7 +17,9 @@ export const EventCard = ({
Participants: Participant[];
};
selectedAppointments: EventAppointment[];
appointments: EventAppointment[];
appointments: (EventAppointment & {
Participants: { userId: string }[];
})[];
}) => {
return (
<div className="col-span-full">

View File

@@ -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 = ({
<Select
form={selectAppointmentForm}
options={dates.map((date) => ({
label: `${new Date(date.appointmentDate).toLocaleString("de-DE", {
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
})} - (${(date as any).Participants.length}/${event.maxParticipants})`,
label: `${formatDate(date.appointmentDate, "dd.MM.yyyy HH:mm")} - (${date.Participants.length}/${event.maxParticipants})`,
value: date.id,
}))}
name="eventAppointmentId"
@@ -296,7 +299,7 @@ const ModalBtn = ({
userId: participant!.userId,
appointmentCancelled: true,
statusLog: [
...(participant?.statusLog as any),
...(participant?.statusLog as unknown as InputJsonValueType[]),
{
data: {
appointmentId: selectedAppointment.id,

View File

@@ -1,4 +1,3 @@
import { Download } from "lucide-react";
import Image, { StaticImageData } from "next/image";
import { ReactNode } from "react";