87 lines
2.6 KiB
TypeScript
87 lines
2.6 KiB
TypeScript
import { PERMS } from "@/lib/permission-slugs";
|
|
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 PeopleUsersPageProps {
|
|
readonly context: HousekeepingCapabilityContext;
|
|
readonly result?: HousekeepingResult<PeopleUsersQueryData>;
|
|
readonly partialDependencies?: readonly string[];
|
|
}
|
|
|
|
export function PeopleUsersPage({
|
|
context,
|
|
result,
|
|
partialDependencies,
|
|
}: PeopleUsersPageProps) {
|
|
return (
|
|
<PeoplePageFrame
|
|
title="Users"
|
|
description="Search accounts and open the canonical People workflow."
|
|
result={result}
|
|
partialDependencies={partialDependencies}
|
|
isEmpty={(data) => data.kind === "users" && data.page.items.length === 0}
|
|
>
|
|
{(data) =>
|
|
data.kind === "users" ? (
|
|
<section className="rounded-lg border border-[var(--admin-border)] bg-[var(--admin-surface)] p-4">
|
|
<p className="text-sm text-[var(--admin-text-muted)]">
|
|
{data.page.total} matching users
|
|
</p>
|
|
<ul className="mt-3 divide-y divide-[var(--admin-border)]">
|
|
{data.page.items.map((user) => (
|
|
<li
|
|
key={user.id}
|
|
className="flex flex-wrap items-center gap-3 py-3 text-sm"
|
|
>
|
|
<a
|
|
className="font-medium text-[var(--admin-text)]"
|
|
href={user.href}
|
|
>
|
|
{user.username}
|
|
</a>
|
|
<span className="text-[var(--admin-text-muted)]">
|
|
Rank {user.rank}
|
|
</span>
|
|
<span className="text-[var(--admin-text-muted)]">
|
|
{user.online ? "Online" : "Offline"}
|
|
</span>
|
|
{user.mail !== null ? <span>{user.mail}</span> : null}
|
|
{user.ipCurrent !== null ? (
|
|
<span>{user.ipCurrent}</span>
|
|
) : null}
|
|
{context.has(PERMS.USERS_EDIT) ? (
|
|
<a
|
|
href={`${user.href}/edit`}
|
|
data-housekeeping-command="people.user.update"
|
|
>
|
|
Edit
|
|
</a>
|
|
) : null}
|
|
{context.has(PERMS.USERS_BAN) ? (
|
|
<span data-housekeeping-command="people.user.ban">
|
|
Ban controls available
|
|
</span>
|
|
) : null}
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</section>
|
|
) : null
|
|
}
|
|
</PeoplePageFrame>
|
|
);
|
|
}
|
|
|
|
export async function renderPeopleUsersPage(input: HousekeepingPageInput) {
|
|
const result = await peopleUsersQuery.run(input.context, {
|
|
routeId: "people.users.list",
|
|
list: {},
|
|
});
|
|
return <PeopleUsersPage context={input.context} result={result} />;
|
|
}
|