69 lines
2.0 KiB
TypeScript
69 lines
2.0 KiB
TypeScript
import type {
|
|
HousekeepingCapabilityContext,
|
|
HousekeepingResult,
|
|
} from "../../../foundation/contracts";
|
|
import type { HousekeepingPageInput } from "../../../route-handlers";
|
|
import { type PeopleUsersQueryData, peopleUsersQuery } from "../queries/users";
|
|
import { PeoplePageFrame } from "./page-state";
|
|
|
|
interface PeopleMultiAccountsPageProps {
|
|
readonly context: HousekeepingCapabilityContext;
|
|
readonly result?: HousekeepingResult<PeopleUsersQueryData>;
|
|
readonly partialDependencies?: readonly string[];
|
|
}
|
|
|
|
export function PeopleMultiAccountsPage({
|
|
context: _context,
|
|
result,
|
|
partialDependencies,
|
|
}: PeopleMultiAccountsPageProps) {
|
|
return (
|
|
<PeoplePageFrame
|
|
title="Multi-account clusters"
|
|
description="Review bounded account clusters grouped by current IP."
|
|
result={result}
|
|
partialDependencies={partialDependencies}
|
|
isEmpty={(data) =>
|
|
data.kind === "multi-accounts" && data.page.items.length === 0
|
|
}
|
|
>
|
|
{(data) =>
|
|
data.kind === "multi-accounts" ? (
|
|
<ul className="space-y-3">
|
|
{data.page.items.map((cluster) => (
|
|
<li
|
|
key={cluster.key}
|
|
className="rounded-lg border border-[var(--admin-border)] bg-[var(--admin-surface)] p-4"
|
|
>
|
|
<h2 className="font-medium text-[var(--admin-text)]">
|
|
{cluster.key}
|
|
</h2>
|
|
<p className="text-sm text-[var(--admin-text-muted)]">
|
|
{cluster.accountCount} accounts
|
|
</p>
|
|
<ul className="mt-2 flex flex-wrap gap-3 text-sm">
|
|
{cluster.accounts.map((account) => (
|
|
<li key={account.id}>
|
|
<a href={account.href}>{account.username}</a>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
) : null
|
|
}
|
|
</PeoplePageFrame>
|
|
);
|
|
}
|
|
|
|
export async function renderPeopleMultiAccountsPage(
|
|
input: HousekeepingPageInput,
|
|
) {
|
|
const result = await peopleUsersQuery.run(input.context, {
|
|
routeId: "people.users.multi-accounts",
|
|
list: {},
|
|
});
|
|
return <PeopleMultiAccountsPage context={input.context} result={result} />;
|
|
}
|