167 lines
4.2 KiB
TypeScript
167 lines
4.2 KiB
TypeScript
import { PersonIcon } from "@radix-ui/react-icons";
|
|
import { prisma } from "@repo/db";
|
|
import {
|
|
AdminForm,
|
|
ConnectionHistory,
|
|
ProfileForm,
|
|
UserPenalties,
|
|
UserReports,
|
|
} from "./_components/forms";
|
|
import { Error } from "../../../../_components/Error";
|
|
import { getUserPenaltys } from "@repo/shared-components";
|
|
|
|
export default async function Page({ params }: { params: Promise<{ id: string }> }) {
|
|
const { id } = await params;
|
|
let user = await prisma.user.findUnique({
|
|
where: {
|
|
id: id,
|
|
},
|
|
include: {
|
|
DiscordAccount: true,
|
|
CanonicalUser: true,
|
|
Duplicates: true,
|
|
},
|
|
});
|
|
if (!user) {
|
|
user = await prisma.user.findFirst({
|
|
where: {
|
|
publicId: id,
|
|
},
|
|
include: {
|
|
DiscordAccount: true,
|
|
CanonicalUser: true,
|
|
Duplicates: true,
|
|
},
|
|
});
|
|
}
|
|
|
|
const formerDiscordAccounts = await prisma.formerDiscordAccount.findMany({
|
|
where: {
|
|
userId: user?.id,
|
|
},
|
|
include: {
|
|
DiscordAccount: true,
|
|
},
|
|
});
|
|
if (!user) return <Error statusCode={404} title="User not found" />;
|
|
|
|
const dispoSessions = await prisma.connectedDispatcher.findMany({
|
|
where: {
|
|
userId: user?.id,
|
|
logoutTime: {
|
|
not: null,
|
|
},
|
|
},
|
|
select: {
|
|
loginTime: true,
|
|
logoutTime: true,
|
|
},
|
|
});
|
|
const totalDispoTime = dispoSessions.reduce((acc, session) => {
|
|
const logoffTime = new Date(session.logoutTime!).getTime();
|
|
const logonTime = new Date(session.loginTime).getTime();
|
|
return acc + (logoffTime - logonTime);
|
|
}, 0);
|
|
|
|
const dispoTime = {
|
|
hours: Math.floor(totalDispoTime / (1000 * 60 * 60)),
|
|
minutes: Math.floor((totalDispoTime % (1000 * 60 * 60)) / (1000 * 60)),
|
|
lastLogin: dispoSessions[dispoSessions.length - 1]?.loginTime,
|
|
};
|
|
|
|
const pilotSessions = await prisma.connectedAircraft.findMany({
|
|
where: {
|
|
userId: user?.id,
|
|
logoutTime: {
|
|
not: null,
|
|
},
|
|
},
|
|
select: {
|
|
loginTime: true,
|
|
logoutTime: true,
|
|
Station: true,
|
|
},
|
|
});
|
|
|
|
const totalPilotTime = pilotSessions.reduce((acc, session) => {
|
|
const logoffTime = new Date(session.logoutTime!).getTime();
|
|
const logonTime = new Date(session.loginTime).getTime();
|
|
return acc + (logoffTime - logonTime);
|
|
}, 0);
|
|
|
|
const pilotTime = {
|
|
hours: Math.floor(totalPilotTime / (1000 * 60 * 60)),
|
|
minutes: Math.floor((totalPilotTime % (1000 * 60 * 60)) / (1000 * 60)),
|
|
lastLogin: pilotSessions[pilotSessions.length - 1]?.loginTime,
|
|
};
|
|
|
|
const totalReportsReports = await prisma.report.count({
|
|
where: {
|
|
reportedUserId: user?.id,
|
|
},
|
|
});
|
|
const totalReports60Days = await prisma.report.count({
|
|
where: {
|
|
reportedUserId: user?.id,
|
|
timestamp: {
|
|
gte: new Date(Date.now() - 60 * 24 * 60 * 60 * 1000),
|
|
},
|
|
},
|
|
});
|
|
|
|
const totalReportsOpen = await prisma.report.count({
|
|
where: {
|
|
reportedUserId: user?.id,
|
|
reviewed: false,
|
|
},
|
|
});
|
|
|
|
const reports = {
|
|
total: totalReportsReports,
|
|
open: totalReportsOpen,
|
|
total60Days: totalReports60Days,
|
|
};
|
|
const { openBans, openTimeban } = await getUserPenaltys(user?.id);
|
|
|
|
return (
|
|
<div className="grid grid-cols-6 gap-4">
|
|
<div className="col-span-full flex items-center justify-between">
|
|
<p className="flex items-center gap-2 text-left text-2xl font-semibold">
|
|
<PersonIcon className="h-5 w-5" />
|
|
{user?.firstname} {user?.lastname} #{user?.publicId}
|
|
</p>
|
|
<p
|
|
className="tooltip tooltip-left text-sm font-thin text-gray-400"
|
|
data-tip="Account erstellt am"
|
|
>
|
|
{new Date(user.createdAt).toLocaleString("de-DE")}
|
|
</p>
|
|
</div>
|
|
<div className="card bg-base-200 col-span-6 mb-4 shadow-xl xl:col-span-3">
|
|
<ProfileForm user={user} />
|
|
</div>
|
|
<div className="card bg-base-200 col-span-6 mb-4 shadow-xl xl:col-span-3">
|
|
<AdminForm
|
|
formerDiscordAccounts={formerDiscordAccounts}
|
|
user={user}
|
|
dispoTime={dispoTime}
|
|
pilotTime={pilotTime}
|
|
reports={reports}
|
|
discordAccount={user.DiscordAccount ?? undefined}
|
|
openBans={openBans}
|
|
openTimebans={openTimeban}
|
|
/>
|
|
</div>
|
|
<div className="card bg-base-200 col-span-6 mb-4 shadow-xl xl:col-span-6">
|
|
<UserReports user={user} />
|
|
</div>
|
|
<div className="card bg-base-200 col-span-6 mb-4 shadow-xl xl:col-span-6">
|
|
<UserPenalties user={user} />
|
|
</div>
|
|
<div className="card bg-base-200 col-span-6 mb-4 shadow-xl xl:col-span-6">
|
|
<ConnectionHistory user={user} />
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|