Penalty Nachricht im Admin form, abgelaufen für Timebans in tabelle werden Farblich dargestellt

This commit is contained in:
PxlLoewe
2025-07-29 15:54:09 -07:00
parent 99c3024d85
commit 266ff87fd8
7 changed files with 32 additions and 19 deletions

View File

@@ -1,9 +1,8 @@
import { getPublicUser, prisma, User } from "@repo/db"; import { getPublicUser, prisma, User } from "@repo/db";
import { addRolesToMember, removeRolesFromMember, renameMember } from "modules/discord"; import { addRolesToMember, removeRolesFromMember, renameMember } from "modules/discord";
import { getNextDateWithTime } from "@repo/shared-components"; import { getNextDateWithTime, getUserPenaltys } from "@repo/shared-components";
import { DISCORD_ROLES } from "@repo/db"; import { DISCORD_ROLES } from "@repo/db";
import { Server, Socket } from "socket.io"; import { Server, Socket } from "socket.io";
import { getUserPenaltys } from "helper";
export const handleConnectDispatch = export const handleConnectDispatch =
(socket: Socket, io: Server) => (socket: Socket, io: Server) =>

View File

@@ -1,9 +1,8 @@
import { getPublicUser, prisma, User } from "@repo/db"; import { getPublicUser, prisma, User } from "@repo/db";
import { addRolesToMember, removeRolesFromMember, renameMember } from "modules/discord"; import { addRolesToMember, removeRolesFromMember, renameMember } from "modules/discord";
import { getNextDateWithTime } from "@repo/shared-components";
import { DISCORD_ROLES } from "@repo/db"; import { DISCORD_ROLES } from "@repo/db";
import { Server, Socket } from "socket.io"; import { Server, Socket } from "socket.io";
import { getUserPenaltys } from "helper"; import { getUserPenaltys } from "@repo/shared-components";
export const handleConnectPilot = export const handleConnectPilot =
(socket: Socket, io: Server) => (socket: Socket, io: Server) =>

View File

@@ -30,12 +30,17 @@ export const penaltyColumns: ColumnDef<Penalty & { Report: Report; CreatedUser:
new Date(row.original.until || Date.now()), new Date(row.original.until || Date.now()),
{ locale: de }, { locale: de },
); );
const isExpired = new Date(row.original.until || Date.now()) < new Date();
return ( return (
<div <div
className={cn("text-warning flex gap-3", row.original.suspended && "text-gray-400")} className={cn(
"text-warning flex gap-3",
(row.original.suspended || isExpired) && "text-gray-400",
)}
> >
<Timer /> <Timer />
Zeit Sperre ({length}) {row.original.suspended && "(ausgesetzt)"} Zeit Sperre ({length}) {row.original.suspended && "(ausgesetzt)"}{" "}
{isExpired && !row.original.suspended && "(abgelaufen)"}
</div> </div>
); );
} }
@@ -78,14 +83,14 @@ export const penaltyColumns: ColumnDef<Penalty & { Report: Report; CreatedUser:
<div className="flex gap-2"> <div className="flex gap-2">
<Link href={`/admin/penalty/${row.original.id}`}> <Link href={`/admin/penalty/${row.original.id}`}>
<button className="btn btn-sm btn-outline btn-info flex items-center gap-2"> <button className="btn btn-sm btn-outline btn-info flex items-center gap-2">
<Shield className="w-4 h-4" /> <Shield className="h-4 w-4" />
Anzeigen Anzeigen
</button> </button>
</Link> </Link>
{report && ( {report && (
<Link href={`/admin/report/${report.id}`}> <Link href={`/admin/report/${report.id}`}>
<button className="btn btn-sm btn-outliney flex items-center gap-2"> <button className="btn btn-sm btn-outliney flex items-center gap-2">
<TriangleAlert className="w-4 h-4" /> <TriangleAlert className="h-4 w-4" />
Report Anzeigen Report Anzeigen
</button> </button>
</Link> </Link>

View File

@@ -10,6 +10,12 @@ export default function ReportPage() {
CreatedUser: true, CreatedUser: true,
Report: true, Report: true,
}} }}
initialOrderBy={[
{
id: "timestamp",
desc: true,
},
]}
columns={penaltyColumns} columns={penaltyColumns}
/> />
); );

View File

@@ -8,10 +8,10 @@ import {
UserReports, UserReports,
} from "./_components/forms"; } from "./_components/forms";
import { Error } from "../../../../_components/Error"; import { Error } from "../../../../_components/Error";
import { getUserPenaltys } from "@repo/shared-components";
export default async function Page({ params }: { params: Promise<{ id: string }> }) { export default async function Page({ params }: { params: Promise<{ id: string }> }) {
const { id } = await params; const { id } = await params;
const user = await prisma.user.findUnique({ const user = await prisma.user.findUnique({
where: { where: {
id: id, id: id,
@@ -20,6 +20,7 @@ export default async function Page({ params }: { params: Promise<{ id: string }>
discordAccounts: true, discordAccounts: true,
}, },
}); });
if (!user) return <Error statusCode={404} title="User not found" />;
const dispoSessions = await prisma.connectedDispatcher.findMany({ const dispoSessions = await prisma.connectedDispatcher.findMany({
where: { where: {
@@ -97,41 +98,43 @@ export default async function Page({ params }: { params: Promise<{ id: string }>
open: totalReportsOpen, open: totalReportsOpen,
total60Days: totalReports60Days, total60Days: totalReports60Days,
}; };
if (!user) return <Error statusCode={404} title="User not found" />; const { openBans, openTimeban } = await getUserPenaltys(user?.id);
return ( return (
<div className="grid grid-cols-6 gap-4"> <div className="grid grid-cols-6 gap-4">
<div className="col-span-full flex justify-between items-center"> <div className="col-span-full flex items-center justify-between">
<p className="text-2xl font-semibold text-left flex items-center gap-2"> <p className="flex items-center gap-2 text-left text-2xl font-semibold">
<PersonIcon className="w-5 h-5" /> <PersonIcon className="h-5 w-5" />
{user?.firstname} {user?.lastname} #{user?.publicId} {user?.firstname} {user?.lastname} #{user?.publicId}
</p> </p>
<p <p
className="text-sm text-gray-400 font-thin tooltip tooltip-left" className="tooltip tooltip-left text-sm font-thin text-gray-400"
data-tip="Account erstellt am" data-tip="Account erstellt am"
> >
{new Date(user.createdAt).toLocaleString("de-DE")} {new Date(user.createdAt).toLocaleString("de-DE")}
</p> </p>
</div> </div>
<div className="card bg-base-200 shadow-xl mb-4 col-span-6 xl:col-span-3"> <div className="card bg-base-200 col-span-6 mb-4 shadow-xl xl:col-span-3">
<ProfileForm user={user} /> <ProfileForm user={user} />
</div> </div>
<div className="card bg-base-200 shadow-xl mb-4 col-span-6 xl:col-span-3"> <div className="card bg-base-200 col-span-6 mb-4 shadow-xl xl:col-span-3">
<AdminForm <AdminForm
user={user} user={user}
dispoTime={dispoTime} dispoTime={dispoTime}
pilotTime={pilotTime} pilotTime={pilotTime}
reports={reports} reports={reports}
discordAccount={user.discordAccounts[0]} discordAccount={user.discordAccounts[0]}
openBans={openBans}
openTimebans={openTimeban}
/> />
</div> </div>
<div className="card bg-base-200 shadow-xl mb-4 col-span-6 xl:col-span-6"> <div className="card bg-base-200 col-span-6 mb-4 shadow-xl xl:col-span-6">
<UserReports user={user} /> <UserReports user={user} />
</div> </div>
<div className="card bg-base-200 shadow-xl mb-4 col-span-6 xl:col-span-6"> <div className="card bg-base-200 col-span-6 mb-4 shadow-xl xl:col-span-6">
<UserPenalties user={user} /> <UserPenalties user={user} />
</div> </div>
<div className="card bg-base-200 shadow-xl mb-4 col-span-6 xl:col-span-6"> <div className="card bg-base-200 col-span-6 mb-4 shadow-xl xl:col-span-6">
<ConnectionHistory user={user} /> <ConnectionHistory user={user} />
</div> </div>
</div> </div>

View File

@@ -4,3 +4,4 @@ export * from "./dates";
export * from "./simulatorConnected"; export * from "./simulatorConnected";
export * from "./useDebounce"; export * from "./useDebounce";
export * from "./useTimeout"; export * from "./useTimeout";
export * from "./penaltys";