feat(housekeeping): deliver people account workflows

This commit is contained in:
Simo committed 2026-08-29 11:45:50 +02:00
1 parent 7920d4f46c
commit e1b31ff773
45 files changed
+4290 -1243

No files matched your search

@@ -0,0 +1,102 @@
import {
createCorrelationId,
fail,
type HousekeepingCapabilityContext,
type HousekeepingResult,
} from "../../../foundation/contracts";
import type { HousekeepingPageInput } from "../../../route-handlers";
import { type PeopleUsersQueryData, peopleUsersQuery } from "../queries/users";
import { PeoplePageFrame } from "./page-state";
interface PeopleUserEditPageProps {
readonly context: HousekeepingCapabilityContext;
readonly result?: HousekeepingResult<PeopleUsersQueryData>;
readonly partialDependencies?: readonly string[];
}
export function PeopleUserEditPage({
context: _context,
result,
partialDependencies,
}: PeopleUserEditPageProps) {
return (
<PeoplePageFrame
title="Edit user"
description="Update bounded account fields through an audited command."
result={result}
partialDependencies={partialDependencies}
isEmpty={() => false}
>
{(data) =>
data.kind === "user" ? (
<form
data-housekeeping-command="people.user.update"
className="space-y-4 rounded-lg border border-[var(--admin-border)] bg-[var(--admin-surface)] p-4"
>
<input type="hidden" name="userId" value={data.user.id} />
<label className="block text-sm">
Username
<input
name="username"
defaultValue={data.user.username}
maxLength={20}
className="mt-1 block w-full"
/>
</label>
{data.user.mail !== null ? (
<label className="block text-sm">
Email
<input
name="mail"
type="email"
defaultValue={data.user.mail}
className="mt-1 block w-full"
/>
</label>
) : null}
<label className="block text-sm">
Motto
<input
name="motto"
defaultValue={data.user.motto}
maxLength={127}
className="mt-1 block w-full"
/>
</label>
<label className="block text-sm">
Rank
<select
name="rank"
defaultValue={data.user.rank}
className="mt-1 block w-full"
>
{data.user.permission.ranks.map((rank) => (
<option key={rank.id} value={rank.id}>
{rank.name}
</option>
))}
</select>
</label>
<button type="submit">Save user</button>
</form>
) : null
}
</PeoplePageFrame>
);
}
export async function renderPeopleUserEditPage(input: HousekeepingPageInput) {
const id = Number(input.match.params.id);
const result =
Number.isSafeInteger(id) && id > 0
? await peopleUsersQuery.run(input.context, {
routeId: "people.users.edit",
id,
})
: fail(
"VALIDATION",
"errors.housekeeping.validation",
createCorrelationId(),
);
return <PeopleUserEditPage context={input.context} result={result} />;
}