From dabcad2525df07953064e5b5cb2a514fa3f208cb Mon Sep 17 00:00:00 2001
From: PxlLoewe <72106766+PxlLoewe@users.noreply.github.com>
Date: Mon, 23 Jun 2025 19:33:00 -0700
Subject: [PATCH] dev
---
.../app/_components/navbar/AdminPanel.tsx | 6 +-
apps/hub/app/(app)/_components/Penalty.tsx | 21 ++-
.../hub/app/(app)/admin/penalty/[id]/page.tsx | 53 +++++-
.../(app)/admin/penalty/_components/form.tsx | 83 ++++++++++
apps/hub/app/(app)/admin/penalty/actions.ts | 9 ++
apps/hub/app/(app)/admin/penalty/page.tsx | 152 ++++++++++--------
.../(app)/admin/report/_components/form.tsx | 89 +---------
.../admin/user/[id]/_components/forms.tsx | 97 ++---------
apps/hub/app/(app)/admin/user/action.ts | 6 -
apps/hub/app/(app)/layout.tsx | 3 -
apps/hub/app/_components/ui/Switch.tsx | 49 +++---
.../database/prisma/schema/penalty.prisma | 9 +-
packages/database/prisma/schema/report.prisma | 9 +-
13 files changed, 294 insertions(+), 292 deletions(-)
diff --git a/apps/dispatch/app/_components/navbar/AdminPanel.tsx b/apps/dispatch/app/_components/navbar/AdminPanel.tsx
index fbc7dd95..acf566b7 100644
--- a/apps/dispatch/app/_components/navbar/AdminPanel.tsx
+++ b/apps/dispatch/app/_components/navbar/AdminPanel.tsx
@@ -267,7 +267,7 @@ export default function AdminPanel() {
/>
}
onClick={({ reason, until }) =>
@@ -320,7 +320,7 @@ export default function AdminPanel() {
/>
}
onClick={({ reason, until }) =>
@@ -374,7 +374,7 @@ export default function AdminPanel() {
diff --git a/apps/hub/app/(app)/_components/Penalty.tsx b/apps/hub/app/(app)/_components/Penalty.tsx
index d66119b7..2e64e1b7 100644
--- a/apps/hub/app/(app)/_components/Penalty.tsx
+++ b/apps/hub/app/(app)/_components/Penalty.tsx
@@ -1,4 +1,4 @@
-import { prisma } from "@repo/db";
+import { getPublicUser, prisma } from "@repo/db";
import { TriangleAlert } from "lucide-react";
import { getServerSession } from "next-auth";
import { PenaltyCountdown } from "./PenaltyCountdown";
@@ -11,8 +11,13 @@ export const Penalty = async () => {
until: {
gte: new Date(),
},
+ suspended: false,
+
type: { in: ["TIME_BAN", "BAN"] },
},
+ include: {
+ CreatedUser: true,
+ },
});
if (!openPenaltys[0]) {
return null;
@@ -30,10 +35,16 @@ export const Penalty = async () => {
Du hast eine aktive Strafe und kannst dich deshalb nicht mit dem Netzwerk verbinden.
- Grund: {openPenaltys[0].reason}
+
+ Grund: {openPenaltys[0].reason}
+
+
+ Admin:{" "}
+ {getPublicUser(openPenaltys[0].CreatedUser).fullName}
+
)}
- {openPenaltys[0].type === "BAN" && (
+ {session?.user.isBanned && (
@@ -44,6 +55,10 @@ export const Penalty = async () => {
ausgeschlossen wurdest. Du kannst dich nicht mehr mit dem Netzwerk verbinden.
Grund: {openPenaltys[0].reason}
+
+ Admin:{" "}
+ {getPublicUser(openPenaltys[0].CreatedUser).fullName}
+
)}
diff --git a/apps/hub/app/(app)/admin/penalty/[id]/page.tsx b/apps/hub/app/(app)/admin/penalty/[id]/page.tsx
index 5335ff2c..b7f31691 100644
--- a/apps/hub/app/(app)/admin/penalty/[id]/page.tsx
+++ b/apps/hub/app/(app)/admin/penalty/[id]/page.tsx
@@ -1,6 +1,7 @@
-import { ExclamationTriangleIcon } from "@radix-ui/react-icons";
+import { ReasonForm } from "(app)/admin/penalty/_components/form";
import { prisma } from "@repo/db";
import { Error } from "_components/Error";
+import { Shield } from "lucide-react";
export default async function Page({ params }: { params: Promise<{ id: string }> }) {
const { id } = await params;
@@ -15,16 +16,62 @@ export default async function Page({ params }: { params: Promise<{ id: string }>
},
});
- if (!penalty) return ;
+ const userReports = await prisma.report.findMany({
+ where: {
+ reportedUserId: penalty?.User.id,
+ },
+ include: {
+ Reported: true,
+ },
+ });
+
+ if (!penalty) return ;
return (
+
+
+
Details
+
+
+ Benutzer: {penalty.User.firstname}{" "}
+ {penalty.User.lastname} ({penalty.User.publicId})
+
+
+ Erstellt von: {penalty.CreatedUser.firstname}{" "}
+ {penalty.CreatedUser.lastname} ({penalty.CreatedUser.publicId})
+
+
+ Typ: {penalty.type}
+
+
+
+ Erstellt am:{" "}
+ {new Date(penalty.timestamp).toLocaleString("de-DE", {
+ dateStyle: "medium",
+ timeStyle: "short",
+ })}
+
+ {penalty.until && (
+
+ Gültig bis:{" "}
+ {new Date(penalty.until).toLocaleString("de-DE", {
+ dateStyle: "medium",
+ timeStyle: "short",
+ })}
+
+ )}
+
+
+
+
+
);
}
diff --git a/apps/hub/app/(app)/admin/penalty/_components/form.tsx b/apps/hub/app/(app)/admin/penalty/_components/form.tsx
index e69de29b..40870519 100644
--- a/apps/hub/app/(app)/admin/penalty/_components/form.tsx
+++ b/apps/hub/app/(app)/admin/penalty/_components/form.tsx
@@ -0,0 +1,83 @@
+"use client";
+import { editPenalty } from "(app)/admin/penalty/actions";
+import { zodResolver } from "@hookform/resolvers/zod";
+import { Penalty, Report, User } from "@repo/db";
+import { PenaltyOptionalDefaults, PenaltyOptionalDefaultsSchema } from "@repo/db/zod";
+import { Button } from "_components/ui/Button";
+import { Switch } from "_components/ui/Switch";
+import { useForm } from "react-hook-form";
+
+export const ReasonForm = ({
+ penalty,
+ userReports: suerReportsOfDay,
+}: {
+ penalty: Penalty;
+ userReports: (Report & { Reported: User })[];
+}) => {
+ const form = useForm({
+ defaultValues: penalty,
+ resolver: zodResolver(PenaltyOptionalDefaultsSchema),
+ });
+ const isLoading = form.formState.isSubmitting;
+
+ return (
+ <>
+
+ >
+ );
+};
diff --git a/apps/hub/app/(app)/admin/penalty/actions.ts b/apps/hub/app/(app)/admin/penalty/actions.ts
index df7f9e98..98c85d82 100644
--- a/apps/hub/app/(app)/admin/penalty/actions.ts
+++ b/apps/hub/app/(app)/admin/penalty/actions.ts
@@ -6,3 +6,12 @@ export const addPenalty = async (data: Prisma.PenaltyCreateInput) => {
data,
});
};
+
+export const editPenalty = async (id: number, data: Prisma.PenaltyUpdateInput) => {
+ return await prisma.penalty.update({
+ where: {
+ id: id,
+ },
+ data,
+ });
+};
diff --git a/apps/hub/app/(app)/admin/penalty/page.tsx b/apps/hub/app/(app)/admin/penalty/page.tsx
index 162acc91..c67b5edb 100644
--- a/apps/hub/app/(app)/admin/penalty/page.tsx
+++ b/apps/hub/app/(app)/admin/penalty/page.tsx
@@ -1,11 +1,92 @@
"use client";
-import { Eye, LockKeyhole, RedoDot, Timer } from "lucide-react";
+import { LockKeyhole, RedoDot, Shield, Timer, TriangleAlert } from "lucide-react";
import Link from "next/link";
import { PaginatedTable } from "_components/PaginatedTable";
import { Penalty, PenaltyType, Report, User } from "@repo/db";
import { ColumnDef } from "@tanstack/react-table";
import { formatDistance } from "date-fns";
import { de } from "date-fns/locale";
+import { cn } from "../../../../helper/cn";
+
+export const penaltyColumns: ColumnDef[] = [
+ {
+ accessorKey: "type",
+ header: "Typ",
+
+ cell: ({ row }) => {
+ switch (row.getValue("type") as PenaltyType) {
+ case "KICK":
+ return (
+
+
+ Kick {row.original.suspended && "(ausgesetzt)"}
+
+ );
+ case "TIME_BAN": {
+ const length = formatDistance(
+ new Date(row.original.timestamp),
+ new Date(row.original.until || Date.now()),
+ { locale: de },
+ );
+ return (
+
+
+ Zeit Sperre ({length}) {row.original.suspended && "(ausgesetzt)"}
+
+ );
+ }
+ case "BAN":
+ return (
+
+ Bann {row.original.suspended && "(ausgesetzt)"}
+
+ );
+ }
+ },
+ },
+ {
+ accessorKey: "CreatedUser",
+ header: "Bestraft durch",
+ cell: ({ row }) => {
+ const user = row.getValue("CreatedUser") as User;
+ return `${user.firstname} ${user.lastname} (${user.publicId})`;
+ },
+ },
+ {
+ accessorKey: "timestamp",
+ header: "Time",
+ cell: ({ row }) => new Date(row.getValue("timestamp")).toLocaleString(),
+ },
+ {
+ accessorKey: "actions",
+ header: "Actions",
+ cell: ({ row }) => {
+ const report = row.original.Report;
+ return (
+
+
+
+
+ {report && (
+
+
+
+ )}
+
+ );
+ },
+ },
+];
export default function ReportPage() {
return (
@@ -15,74 +96,7 @@ export default function ReportPage() {
CreatedUser: true,
Report: true,
}}
- columns={
- [
- {
- accessorKey: "type",
- header: "Typ",
-
- cell: ({ row }) => {
- switch (row.getValue("type") as PenaltyType) {
- case "KICK":
- return (
-
-
- Kick
-
- );
- case "TIME_BAN": {
- const length = formatDistance(
- new Date(row.original.timestamp),
- new Date(row.original.until || Date.now()),
- { locale: de },
- );
- return (
-
-
- Zeit Sperre ({length})
-
- );
- }
- case "BAN":
- return (
-
- Bann
-
- );
- }
- },
- },
- {
- accessorKey: "CreatedUser",
- header: "Bestraft durch",
- cell: ({ row }) => {
- const user = row.getValue("CreatedUser") as User;
- return `${user.firstname} ${user.lastname} (${user.publicId})`;
- },
- },
- {
- accessorKey: "timestamp",
- header: "Time",
- cell: ({ row }) => new Date(row.getValue("timestamp")).toLocaleString(),
- },
- {
- accessorKey: "actions",
- header: "Actions",
- cell: ({ row }) => {
- const report = row.original.Report;
- if (!report[0]) return null;
- return (
-
-
-
- );
- },
- },
- ] as ColumnDef[]
- }
+ columns={penaltyColumns}
/>
);
}
diff --git a/apps/hub/app/(app)/admin/report/_components/form.tsx b/apps/hub/app/(app)/admin/report/_components/form.tsx
index 04806719..705a6a45 100644
--- a/apps/hub/app/(app)/admin/report/_components/form.tsx
+++ b/apps/hub/app/(app)/admin/report/_components/form.tsx
@@ -1,15 +1,13 @@
"use client";
+import { penaltyColumns as penaltyColumns } from "(app)/admin/penalty/page";
import { editReport } from "(app)/admin/report/actions";
import { zodResolver } from "@hookform/resolvers/zod";
-import { Report as IReport, Penalty, PenaltyType, Report, User } from "@repo/db";
+import { Report as IReport, User } from "@repo/db";
import { ReportSchema, Report as IReportZod } from "@repo/db/zod";
-import { ColumnDef } from "@tanstack/react-table";
import { PaginatedTable } from "_components/PaginatedTable";
import { Button } from "_components/ui/Button";
import { Switch } from "_components/ui/Switch";
-import { formatDistance } from "date-fns";
-import { de } from "date-fns/locale";
-import { Eye, LockKeyhole, RedoDot, Shield, Timer, Trash } from "lucide-react";
+import { Shield, Trash } from "lucide-react";
import { useSession } from "next-auth/react";
import Link from "next/link";
import { useRouter } from "next/navigation";
@@ -142,16 +140,6 @@ export const ReportPenalties = ({
Reviewer?: User | null;
};
}) => {
- if (!report.penaltyId)
- return (
-
-
- Strafen zu diesem Report
-
-
Es wurden keine Strafen zu diesem Report erfasst.
-
- );
-
return (
@@ -164,76 +152,9 @@ export const ReportPenalties = ({
Report: true,
}}
filter={{
- id: report.penaltyId,
+ reportId: report.id,
}}
- columns={
- [
- {
- accessorKey: "type",
- header: "Typ",
-
- cell: ({ row }) => {
- switch (row.getValue("type") as PenaltyType) {
- case "KICK":
- return (
-
-
- Kick
-
- );
- case "TIME_BAN": {
- const length = formatDistance(
- new Date(row.original.timestamp),
- new Date(row.original.until || Date.now()),
- { locale: de },
- );
- return (
-
-
- Zeit Sperre ({length})
-
- );
- }
- case "BAN":
- return (
-
- Bann
-
- );
- }
- },
- },
- {
- accessorKey: "CreatedUser",
- header: "Bestraft durch",
- cell: ({ row }) => {
- const user = row.getValue("CreatedUser") as User;
- return `${user.firstname} ${user.lastname} (${user.publicId})`;
- },
- },
- {
- accessorKey: "timestamp",
- header: "Time",
- cell: ({ row }) => new Date(row.getValue("timestamp")).toLocaleString(),
- },
- {
- accessorKey: "actions",
- header: "Actions",
- cell: ({ row }) => {
- const report = row.original.Report;
- if (!report[0]) return null;
- return (
-
-
-
- );
- },
- },
- ] as ColumnDef[]
- }
+ columns={penaltyColumns}
/>
);
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 7918dba2..73541aab 100644
--- a/apps/hub/app/(app)/admin/user/[id]/_components/forms.tsx
+++ b/apps/hub/app/(app)/admin/user/[id]/_components/forms.tsx
@@ -33,23 +33,13 @@ import { UserOptionalDefaults, UserOptionalDefaultsSchema } from "@repo/db/zod";
import { useRouter } from "next/navigation";
import { PaginatedTable, PaginatedTableRef } from "_components/PaginatedTable";
import { cn } from "../../../../../../helper/cn";
-import {
- ChartBarBigIcon,
- Check,
- Eye,
- LockKeyhole,
- PlaneIcon,
- RedoDot,
- Timer,
- X,
-} from "lucide-react";
+import { ChartBarBigIcon, Check, Eye, PlaneIcon, Timer, 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 { de } from "date-fns/locale";
-import { formatDistance } from "date-fns";
+import { penaltyColumns } from "(app)/admin/penalty/page";
interface ProfileFormProps {
user: User;
@@ -328,74 +318,7 @@ export const UserPenalties = ({ user }: { user: User }) => {
filter={{
userId: user.id,
}}
- columns={
- [
- {
- accessorKey: "type",
- header: "Typ",
-
- cell: ({ row }) => {
- switch (row.getValue("type") as PenaltyType) {
- case "KICK":
- return (
-
-
- Kick
-
- );
- case "TIME_BAN": {
- const length = formatDistance(
- new Date(row.original.timestamp),
- new Date(row.original.until || Date.now()),
- { locale: de },
- );
- return (
-
-
- Zeit Sperre ({length})
-
- );
- }
- case "BAN":
- return (
-
- Bann
-
- );
- }
- },
- },
- {
- accessorKey: "CreatedUser",
- header: "Bestraft durch",
- cell: ({ row }) => {
- const user = row.getValue("CreatedUser") as User;
- return `${user.firstname} ${user.lastname} (${user.publicId})`;
- },
- },
- {
- accessorKey: "timestamp",
- header: "Time",
- cell: ({ row }) => new Date(row.getValue("timestamp")).toLocaleString(),
- },
- {
- accessorKey: "actions",
- header: "Actions",
- cell: ({ row }) => {
- const report = row.original.Report;
- if (!report[0]) return null;
- return (
-
-
-
- );
- },
- },
- ] as ColumnDef[]
- }
+ columns={penaltyColumns}
/>
);
@@ -500,7 +423,7 @@ export const AdminForm = ({
Administration
-
+
@@ -532,7 +456,7 @@ export const AdminForm = ({
router.refresh();
}}
role="submit"
- className="btn-sm btn-wide btn-outline btn-error"
+ className="btn-sm flex-1 min-w-[250px] btn-outline btn-error"
>
HUB zugang sperren
@@ -550,13 +474,16 @@ export const AdminForm = ({
router.refresh();
}}
role="submit"
- className="btn-sm btn-wide btn-outline btn-warning"
+ className="btn-sm flex-1 min-w-[250px] btn-outline btn-warning"
>
HUB zugang entsperren
)}
{discordAccount && (
-
+