141 lines
3.8 KiB
TypeScript
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;
|