/**
* 用户 CRUD 演示岛:tRPC + React Query。
* Provider 包在组件内部,便于 Astro 以 client:visible 挂载而不污染全局。
*/
import type { RouterOutputs } from "@app/trpc";
import {
Badge,
Button,
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
Input,
Label,
Separator,
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
toast,
} from "@app/ui";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { useState } from "react";
import { createTRPCReactClient, trpc } from "../lib/trpc";
const queryClient = new QueryClient();
const trpcClient = createTRPCReactClient();
type User = RouterOutputs["user"]["list"]["users"][number];
export default function UserList() {
return (
);
}
function UserListInner() {
const users = trpc.user.list.useQuery({ limit: 20, offset: 0 });
const createUser = trpc.user.create.useMutation({
onSuccess: () => {
users.refetch();
toast.success("用户创建成功");
},
onError: (err) => {
toast.error(`创建失败: ${err.message}`);
},
});
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!name || !email || !password) return;
await createUser.mutateAsync({ name, email, password });
setName("");
setEmail("");
setPassword("");
};
return (
用户列表
当前共 {users.data?.total ?? "—"} 位用户
{users.isPending ? (
加载中…
) : users.isError ? (
加载失败: {users.error.message}
) : (
ID
名称
邮箱
状态
{users.data?.users.length === 0 ? (
暂无数据
) : (
users.data?.users.map((u: User) => (
{u.id.slice(0, 8)}…
{u.name}
{u.email}
活跃
))
)}
)}
新建用户
);
}