"use client"; import { FormEvent, useMemo, useState } from "react"; import { Check, Plus, X } from "lucide-react"; import { useRouter } from "next/navigation"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import type { ApiResult } from "@/modules/core/server/api"; import type { JoinRequest, Organization, RoleDefinition } from "@/modules/core/types"; type UserManagementClientProps = { organizations: Organization[]; roles: RoleDefinition[]; joinRequests: JoinRequest[]; }; function getOrganizationRoles(roles: RoleDefinition[], organizationId: string): RoleDefinition[] { return roles.filter((role) => role.scope === "organization" && role.organizationId === organizationId && role.isEnabled); } function getDefaultOrganizationId(organizations: Organization[]): string { return organizations[0]?.id ?? ""; } export function UserManagementClient({ organizations, roles, joinRequests, }: UserManagementClientProps): React.ReactElement { const router = useRouter(); const [selectedOrganizationId, setSelectedOrganizationId] = useState(() => getDefaultOrganizationId(organizations)); const [message, setMessage] = useState(""); const [isPending, setIsPending] = useState(false); const organizationRoles = useMemo( () => getOrganizationRoles(roles, selectedOrganizationId), [roles, selectedOrganizationId], ); const pendingJoinRequests = joinRequests.filter((request) => request.status === "pending"); async function handleCreateAccount(event: FormEvent): Promise { event.preventDefault(); setMessage(""); setIsPending(true); const formData = new FormData(event.currentTarget); const response = await fetch("/api/settings/accounts", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ organizationId: String(formData.get("organizationId") ?? ""), roleId: String(formData.get("roleId") ?? ""), name: String(formData.get("name") ?? ""), email: String(formData.get("email") ?? ""), password: String(formData.get("password") ?? ""), }), }); const result = (await response.json()) as ApiResult<{ account: unknown }>; setIsPending(false); if (!result.success) { setMessage(result.reason); return; } setMessage(result.reason); event.currentTarget.reset(); router.refresh(); } async function reviewJoinRequest(requestId: string, decision: "approved" | "rejected", roleId: string): Promise { setMessage(""); setIsPending(true); const response = await fetch(`/api/settings/join-requests/${requestId}`, { method: "PATCH", headers: { "content-type": "application/json" }, body: JSON.stringify({ decision, roleId }), }); const result = (await response.json()) as ApiResult<{ joinRequest: unknown }>; setIsPending(false); if (!result.success) { setMessage(result.reason); return; } setMessage(result.reason); router.refresh(); } return (
创建机构用户 管理员创建账号后立即分配到机构和角色。
{message ? (

{message}

) : null}
加入申请审批 公开注册选择机构后进入这里审批。 {pendingJoinRequests.map((request) => { const requestRoles = getOrganizationRoles(roles, request.organizationId); const defaultRoleId = requestRoles.find((role) => role.key === "caregiver")?.id ?? requestRoles[0]?.id ?? ""; return (

{request.accountName}

{request.accountEmail}

{request.organizationName}

待审批
); })} {pendingJoinRequests.length === 0 ?

暂无待审批申请

: null}
); }