139 lines
3.3 KiB
TypeScript
139 lines
3.3 KiB
TypeScript
/**
|
||
* 用户管理 Hooks
|
||
*
|
||
* contract §2.4:adminUsers / adminUser / createUser / updateUser / toggleUserStatus
|
||
*/
|
||
import { useCallback, useState } from "react";
|
||
import { useGraphMutation, useGraphQuery } from "./use-graphql";
|
||
import {
|
||
ADMIN_USERS_QUERY,
|
||
ADMIN_USER_QUERY,
|
||
CREATE_USER_MUTATION,
|
||
UPDATE_USER_MUTATION,
|
||
TOGGLE_USER_STATUS_MUTATION,
|
||
} from "@/lib/graphql-client";
|
||
import type {
|
||
UserViewModel,
|
||
PaginatedResult,
|
||
ListFilter,
|
||
} from "@/types/view-models";
|
||
|
||
interface AdminUsersResponse {
|
||
adminUsers: PaginatedResult<UserViewModel>;
|
||
}
|
||
|
||
interface AdminUserResponse {
|
||
adminUser: UserViewModel | null;
|
||
}
|
||
|
||
interface UserMutationResponse {
|
||
createUser?: { id: string; email: string; name: string; status: string };
|
||
updateUser?: { id: string; email: string; name: string; status: string };
|
||
toggleUserStatus?: { id: string; status: string };
|
||
}
|
||
|
||
interface CreateUserInput {
|
||
email: string;
|
||
name: string;
|
||
password: string;
|
||
roleIds?: string[];
|
||
dataScope?: string;
|
||
organizationId?: string;
|
||
}
|
||
|
||
interface UpdateUserInput {
|
||
name?: string;
|
||
email?: string;
|
||
roleIds?: string[];
|
||
dataScope?: string;
|
||
organizationId?: string;
|
||
}
|
||
|
||
export function useUsers(filter: Partial<ListFilter>) {
|
||
const result = useGraphQuery<AdminUsersResponse>(ADMIN_USERS_QUERY, {
|
||
filter,
|
||
});
|
||
return {
|
||
...result,
|
||
data: result.data?.adminUsers ?? null,
|
||
};
|
||
}
|
||
|
||
export function useUser(id: string | null) {
|
||
const result = useGraphQuery<AdminUserResponse>(
|
||
ADMIN_USER_QUERY,
|
||
id ? { id } : undefined,
|
||
);
|
||
return {
|
||
...result,
|
||
data: result.data?.adminUser ?? null,
|
||
};
|
||
}
|
||
|
||
export function useCreateUser() {
|
||
const [run, state] = useGraphMutation<
|
||
UserMutationResponse,
|
||
{ input: CreateUserInput }
|
||
>(CREATE_USER_MUTATION);
|
||
const create = useCallback(
|
||
async (input: CreateUserInput) => {
|
||
const res = await run({ input });
|
||
return res.data?.createUser ?? null;
|
||
},
|
||
[run],
|
||
);
|
||
return [create, state] as const;
|
||
}
|
||
|
||
export function useUpdateUser() {
|
||
const [run, state] = useGraphMutation<
|
||
UserMutationResponse,
|
||
{ id: string; input: UpdateUserInput }
|
||
>(UPDATE_USER_MUTATION);
|
||
const update = useCallback(
|
||
async (id: string, input: UpdateUserInput) => {
|
||
const res = await run({ id, input });
|
||
return res.data?.updateUser ?? null;
|
||
},
|
||
[run],
|
||
);
|
||
return [update, state] as const;
|
||
}
|
||
|
||
export function useToggleUserStatus() {
|
||
const [run, state] = useGraphMutation<
|
||
UserMutationResponse,
|
||
{ id: string; status: string }
|
||
>(TOGGLE_USER_STATUS_MUTATION);
|
||
const toggle = useCallback(
|
||
async (id: string, status: string) => {
|
||
const res = await run({ id, status });
|
||
return res.data?.toggleUserStatus ?? null;
|
||
},
|
||
[run],
|
||
);
|
||
return [toggle, state] as const;
|
||
}
|
||
|
||
/** 本地筛选状态管理 */
|
||
export function useUserFilter(initial?: Partial<ListFilter>) {
|
||
const [filter, setFilter] = useState<Partial<ListFilter>>({
|
||
page: 1,
|
||
pageSize: 20,
|
||
...initial,
|
||
});
|
||
const setPage = useCallback(
|
||
(page: number) => setFilter((f) => ({ ...f, page })),
|
||
[],
|
||
);
|
||
const setSearch = useCallback(
|
||
(search: string) => setFilter((f) => ({ ...f, search, page: 1 })),
|
||
[],
|
||
);
|
||
const setStatus = useCallback(
|
||
(status: string) => setFilter((f) => ({ ...f, status, page: 1 })),
|
||
[],
|
||
);
|
||
return { filter, setFilter, setPage, setSearch, setStatus };
|
||
}
|