import { redirect } from "next/navigation"; import { getTranslations } from "next-intl/server"; import { detectMultiAccounts, type MultiAccountCluster, } from "@/actions/multi-account-detect"; import Link from "@/components/link"; import { Badge } from "@/components/ui/badge"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { canAccess, getAdminContext, PERMS } from "@/lib/permissions"; export default async function MultiAccountsPage({ searchParams, }: { searchParams: Promise>; }) { const { session, permissions } = await getAdminContext(); if (!canAccess(permissions, PERMS.USERS_VIEW, session.user.rank)) redirect("/admin"); const t = await getTranslations("pages.admin.multiAccounts"); const params = await searchParams; const minAccounts = Math.max(2, Number(params.min) || 2); const limit = Math.min(200, Number(params.limit) || 50); const result = await detectMultiAccounts({ minAccounts, limit }); const clusters: MultiAccountCluster[] = result.ok ? ((result.data as { clusters: MultiAccountCluster[] }).clusters ?? []) : []; return (
{clusters.length === 0 ? (
{t("noClusters")}
) : (
{clusters.map((cluster) => ( {cluster.label} {cluster.accountCount} accounts share this identifier
{cluster.accounts.map((acc) => ( {acc.username} #{acc.id} {acc.rank >= 5 && staff} {acc.online === "1" && ( )} ))} {cluster.accountCount > cluster.accounts.length && ( … and {cluster.accountCount - cluster.accounts.length}{" "} more )}
))}
)}
); }