style: format code biome
Local Build and Deploy / deploy (push) Failing after 46s

This commit is contained in:
openhands committed 2026-07-13 21:57:41 +02:00
1 parent 8efd032cc6
commit df38dccbf1
735 files changed
+128321 -120870

No files matched your search

+109 -95
View File
@@ -1,110 +1,124 @@
import Link from "next/link";
import { redirect } from "next/navigation";
import { detectMultiAccounts, type MultiAccountCluster } from "@/actions/multi-account-detect";
import {
detectMultiAccounts,
type MultiAccountCluster,
} from "@/actions/multi-account-detect";
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,
}: {
searchParams: Promise<Record<string, string>>;
searchParams: Promise<Record<string, string>>;
}) {
const { session, permissions } = await getAdminContext();
if (!canAccess(permissions, PERMS.USERS_VIEW, session.user.rank)) redirect("/admin");
const { session, permissions } = await getAdminContext();
if (!canAccess(permissions, PERMS.USERS_VIEW, session.user.rank))
redirect("/admin");
const params = await searchParams;
const minAccounts = Math.max(2, Number(params.min) || 2);
const limit = Math.min(200, Number(params.limit) || 50);
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 ?? [])
: [];
const result = await detectMultiAccounts({ minAccounts, limit });
const clusters: MultiAccountCluster[] = result.ok
? ((result.data as { clusters: MultiAccountCluster[] }).clusters ?? [])
: [];
return (
<div className="space-y-6">
<div>
<h1 className="text-3xl font-bold tracking-tight">Multi-account detector</h1>
<p className="text-muted-foreground">
Clusters of users sharing a registration IP, current IP, or machine ID. Detection is passive — no
AI, just a GROUP BY with index support.
</p>
</div>
return (
<div className="space-y-6">
<div>
<h1 className="text-3xl font-bold tracking-tight">
Multi-account detector
</h1>
<p className="text-muted-foreground">
Clusters of users sharing a registration IP, current IP, or machine
ID. Detection is passive — no AI, just a GROUP BY with index support.
</p>
</div>
<form className="flex flex-wrap items-end gap-3" action="">
<label className="text-sm">
<span className="block text-muted-foreground">Min accounts per cluster</span>
<input
type="number"
name="min"
defaultValue={minAccounts}
min={2}
max={50}
className="mt-1 h-9 w-24 rounded-md border bg-background px-2"
/>
</label>
<label className="text-sm">
<span className="block text-muted-foreground">Result limit</span>
<input
type="number"
name="limit"
defaultValue={limit}
min={1}
max={200}
className="mt-1 h-9 w-24 rounded-md border bg-background px-2"
/>
</label>
<button type="submit" className="h-9 rounded-md bg-primary px-4 text-sm text-primary-foreground">
Refresh
</button>
</form>
<form className="flex flex-wrap items-end gap-3" action="">
<label className="text-sm">
<span className="block text-muted-foreground">
Min accounts per cluster
</span>
<input
type="number"
name="min"
defaultValue={minAccounts}
min={2}
max={50}
className="mt-1 h-9 w-24 rounded-md border bg-background px-2"
/>
</label>
<label className="text-sm">
<span className="block text-muted-foreground">Result limit</span>
<input
type="number"
name="limit"
defaultValue={limit}
min={1}
max={200}
className="mt-1 h-9 w-24 rounded-md border bg-background px-2"
/>
</label>
<button
type="submit"
className="h-9 rounded-md bg-primary px-4 text-sm text-primary-foreground"
>
Refresh
</button>
</form>
{clusters.length === 0 ? (
<Card>
<CardContent className="py-10 text-center text-muted-foreground">
No clusters found at the current thresholds.
</CardContent>
</Card>
) : (
<div className="grid gap-4">
{clusters.map((cluster) => (
<Card key={cluster.key}>
<CardHeader className="flex flex-row items-center justify-between space-y-0">
<CardTitle className="text-base">
<Badge variant="secondary" className="mr-2">
{cluster.label}
</Badge>
{cluster.accountCount} accounts share this identifier
</CardTitle>
</CardHeader>
<CardContent>
<div className="flex flex-wrap gap-2">
{cluster.accounts.map((acc) => (
<Link
key={acc.id}
href={`/admin/users/show/${acc.id}`}
className="inline-flex items-center gap-1.5 rounded-md border bg-background px-2 py-1 text-sm hover:bg-accent"
>
<span className="font-medium">{acc.username}</span>
<span className="text-xs text-muted-foreground">#{acc.id}</span>
{acc.rank >= 5 && <Badge variant="outline">staff</Badge>}
{acc.online === "1" && (
<span className="h-1.5 w-1.5 rounded-full bg-[var(--admin-success-subtle)]" />
)}
</Link>
))}
{cluster.accountCount > cluster.accounts.length && (
<span className="text-xs text-muted-foreground">
… and {cluster.accountCount - cluster.accounts.length} more
</span>
)}
</div>
</CardContent>
</Card>
))}
</div>
)}
</div>
);
{clusters.length === 0 ? (
<Card>
<CardContent className="py-10 text-center text-muted-foreground">
No clusters found at the current thresholds.
</CardContent>
</Card>
) : (
<div className="grid gap-4">
{clusters.map((cluster) => (
<Card key={cluster.key}>
<CardHeader className="flex flex-row items-center justify-between space-y-0">
<CardTitle className="text-base">
<Badge variant="secondary" className="mr-2">
{cluster.label}
</Badge>
{cluster.accountCount} accounts share this identifier
</CardTitle>
</CardHeader>
<CardContent>
<div className="flex flex-wrap gap-2">
{cluster.accounts.map((acc) => (
<Link
key={acc.id}
href={`/admin/users/show/${acc.id}`}
className="inline-flex items-center gap-1.5 rounded-md border bg-background px-2 py-1 text-sm hover:bg-accent"
>
<span className="font-medium">{acc.username}</span>
<span className="text-xs text-muted-foreground">
#{acc.id}
</span>
{acc.rank >= 5 && <Badge variant="outline">staff</Badge>}
{acc.online === "1" && (
<span className="h-1.5 w-1.5 rounded-full bg-[var(--admin-success-subtle)]" />
)}
</Link>
))}
{cluster.accountCount > cluster.accounts.length && (
<span className="text-xs text-muted-foreground">
… and {cluster.accountCount - cluster.accounts.length}{" "}
more
</span>
)}
</div>
</CardContent>
</Card>
))}
</div>
)}
</div>
);
}