Files
var-monorepo/apps/hub/app/(app)/admin/user/page.tsx
2026-01-06 03:07:09 +01:00

141 lines
3.8 KiB
TypeScript

"use client";
import { User2 } from "lucide-react";
import { PaginatedTable } from "../../../_components/PaginatedTable";
import Link from "next/link";
import { ColumnDef } from "@tanstack/react-table";
import { DiscordAccount, Penalty, Prisma, User } from "@repo/db";
import { useSession } from "next-auth/react";
const AdminUserPage = () => {
const { data: session } = useSession();
return (
<>
<PaginatedTable
stickyHeaders
prismaModel="user"
showSearch
getFilter={(searchTerm) => {
return {
OR: [
{ firstname: { contains: searchTerm, mode: "insensitive" } },
{ lastname: { contains: searchTerm, mode: "insensitive" } },
{ email: { contains: searchTerm, mode: "insensitive" } },
{ publicId: { contains: searchTerm, mode: "insensitive" } },
{ DiscordAccount: { username: { contains: searchTerm, mode: "insensitive" } } },
],
} as Prisma.UserWhereInput;
}}
include={{
DiscordAccount: true,
ReceivedReports: true,
Penaltys: true,
}}
initialOrderBy={[
{
id: "publicId",
desc: false,
},
]}
columns={
[
{
header: "ID",
accessorKey: "publicId",
},
{
header: "Vorname",
accessorKey: "firstname",
},
{
header: "Nachname",
accessorKey: "lastname",
},
{
header: "Berechtigungen",
cell(props) {
const activePenaltys = props.row.original.Penaltys.filter(
(penalty) =>
!penalty.suspended &&
(penalty.type === "BAN" ||
(penalty.type === "TIME_BAN" && penalty!.until! > new Date())),
);
if (activePenaltys.length > 0) {
return <span className="font-bold text-red-600">AKTIVE STRAFE</span>;
}
if (props.row.original.permissions.length === 0) {
return <span className="text-gray-700">Keine</span>;
} else if (props.row.original.permissions.includes("ADMIN_USER_ADVANCED")) {
return <span className="text-primary">Admin</span>;
}
return (
<span className="text-secondary">
{props.row.original.permissions
.filter((p) => p === "PILOT" || p === "DISPO")
.join(", ")}
</span>
);
},
},
{
header: "Strafen / Reports",
cell(props) {
const penaltyCount = props.row.original.Penaltys.length;
const reportCount = props.row.original.ReceivedReports.length;
return (
<span className="w-full text-center">
{penaltyCount} / {reportCount}
</span>
);
},
},
{
header: "Discord",
cell(props) {
const discord = props.row.original.DiscordAccount;
if (!discord) {
return <span className="text-gray-700">Nicht verbunden</span>;
}
return <span>{discord.username}</span>;
},
},
...(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/user/${row.original.id}`}>
<button className="btn btn-sm">Anzeigen</button>
</Link>
</div>
),
},
] as ColumnDef<
User & {
DiscordAccount: DiscordAccount;
ReceivedReports: Report[];
Penaltys: Penalty[];
}
>[]
} // Define the columns for the user table
leftOfSearch={
<p className="flex items-center gap-2 text-left text-2xl font-semibold">
<User2 className="h-5 w-5" /> Benutzer
</p>
}
/>
</>
);
};
AdminUserPage.displayName = "AdminUserPage";
export default AdminUserPage;