1
0
Fork 0
panel/app/panel/inspect/user/[id]/page.tsx

133 lines
3.7 KiB
TypeScript

import { JsonCard } from "@/components/cards/JsonCard";
import { UserCard } from "@/components/cards/UserCard";
import { NavigationToolbar } from "@/components/common/NavigationToolbar";
import { RecentMessages } from "@/components/pages/inspector/RecentMessages";
import { RelevantModerationNotices } from "@/components/pages/inspector/RelevantModerationNotices";
import { RelevantObjects } from "@/components/pages/inspector/RelevantObjects";
import { RelevantReports } from "@/components/pages/inspector/RelevantReports";
import { UserActions } from "@/components/pages/inspector/UserActions";
import { Card, CardHeader } from "@/components/ui/card";
import { Separator } from "@/components/ui/separator";
import { PLATFORM_MOD_ID } from "@/lib/constants";
import {
fetchBotById,
fetchBotsByUser,
fetchMembershipsByUser,
fetchMessages,
fetchReports,
fetchServers,
fetchSnapshots,
fetchStrikesByUser,
fetchUserById,
fetchUsersById,
findDM,
} from "@/lib/db";
import Link from "next/link";
import { notFound } from "next/navigation";
import { Bot } from "revolt-api";
export default async function User({
params,
}: {
params: { id: string; type: string };
}) {
const user = await fetchUserById(params.id);
if (!user) return notFound();
const bot = user.bot ? await fetchBotById(user._id) : undefined;
const botOwner = user.bot ? await fetchUserById(user.bot.owner) : undefined;
// Fetch strikes
const strikes = await fetchStrikesByUser(user._id);
// Fetch moderation alerts
const dm = await findDM(PLATFORM_MOD_ID, user._id);
const notices = dm ? await fetchMessages({ channel: dm._id }) : [];
// Fetch friends and bots
const botIds = await fetchBotsByUser(user._id).then((bots) =>
bots.map((bot) => bot._id)
);
const relevantUsers = await fetchUsersById([
...botIds,
...(
user.relations?.filter((relation) => relation.status === "Friend") ?? []
).map((relation) => relation._id),
]);
relevantUsers.sort((a) => (a.bot ? -1 : 0));
// Fetch server memberships
const serverMemberships = await fetchMembershipsByUser(user._id);
const servers = await fetchServers({
_id: {
$in: serverMemberships.map((member) => member._id.server),
},
});
// Fetch reports
const reportsByUser = await fetchReports({
author_id: user._id,
});
const reportIdsInvolvingUser = await fetchSnapshots({
// TODO: slow query
$or: [{ "content._id": user._id }, { "content.author": user._id }],
}).then((snapshots) => [
...new Set(snapshots.map((snapshot) => snapshot.report_id)),
]);
const reportsAgainstUser = await fetchReports({
_id: {
$in: reportIdsInvolvingUser,
},
});
return (
<div className="flex flex-col gap-2">
<NavigationToolbar>Inspecting User</NavigationToolbar>
<UserCard user={user} subtitle={user.status?.text ?? "No status set"} />
<UserActions user={user} bot={bot as Bot} />
{user.profile?.content && (
<Card>
<CardHeader>
<p>{user.profile?.content}</p>
</CardHeader>
</Card>
)}
{botOwner && (
<Link href={`/panel/inspect/user/${botOwner!._id}`}>
<UserCard user={botOwner} subtitle="Bot Owner" />
</Link>
)}
<Separator />
<RelevantModerationNotices
userId={user._id}
strikes={strikes}
notices={notices}
/>
<Separator />
<RelevantObjects
users={relevantUsers}
servers={servers}
userId={user._id}
/>
<Separator />
<RelevantReports byUser={reportsByUser} forUser={reportsAgainstUser} />
<Separator />
<RecentMessages query={{ author: user._id }} />
<Separator />
<JsonCard obj={user} />
</div>
);
}