forked from administration/panel
129 lines
3.6 KiB
TypeScript
129 lines
3.6 KiB
TypeScript
import { JsonCard } from "@/components/cards/JsonCard";
|
|
import { UserCard } from "@/components/cards/UserCard";
|
|
import { NavigationToolbar } from "@/components/common/NavigationToolbar";
|
|
import { RecentMessages } from "@/components/inspector/RecentMessages";
|
|
import { RelevantModerationNotices } from "@/components/inspector/RelevantModerationNotices";
|
|
import { RelevantObjects } from "@/components/inspector/RelevantObjects";
|
|
import { RelevantReports } from "@/components/inspector/RelevantReports";
|
|
import { UserActions } from "@/components/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 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>
|
|
);
|
|
}
|