Files
dingxing/src/components/user-actions.tsx
T

109 lines
2.8 KiB
TypeScript

"use client";
import { useRouter } from "next/navigation";
import { useState } from "react";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Button } from "@/components/ui/button";
import { authClient } from "@/lib/auth-client";
import { MoreHorizontal, ShieldCheck, User, Ban, CircleCheck, Loader2 } from "lucide-react";
type UserRow = {
id: string;
name: string;
email: string;
role: string;
banned: boolean;
};
export function UserActions({ user }: { user: UserRow }) {
const router = useRouter();
const [loading, setLoading] = useState(false);
async function setRole(role: "admin" | "user") {
setLoading(true);
const { error } = await authClient.admin.setRole({
userId: user.id,
role,
});
setLoading(false);
if (error) {
console.error("设置角色失败:", error.message);
return;
}
router.refresh();
}
async function toggleBan() {
setLoading(true);
if (user.banned) {
const { error } = await authClient.admin.unbanUser({ userId: user.id });
setLoading(false);
if (error) {
console.error("解封失败:", error.message);
return;
}
} else {
const { error } = await authClient.admin.banUser({
userId: user.id,
banReason: "管理员手动封禁",
});
setLoading(false);
if (error) {
console.error("封禁失败:", error.message);
return;
}
}
router.refresh();
}
return (
<DropdownMenu>
<DropdownMenuTrigger
render={
<Button variant="ghost" size="icon-sm" disabled={loading} />
}
>
{loading ? (
<Loader2 className="size-4 animate-spin" />
) : (
<MoreHorizontal className="size-4" />
)}
<span className="sr-only">操作菜单</span>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-40">
<DropdownMenuLabel>设置角色</DropdownMenuLabel>
<DropdownMenuItem onClick={() => setRole("admin")}>
<ShieldCheck className="size-4" />
管理员
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setRole("user")}>
<User className="size-4" />
普通用户
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem onClick={toggleBan}>
{user.banned ? (
<>
<CircleCheck className="size-4" />
解除封禁
</>
) : (
<>
<Ban className="size-4" />
封禁用户
</>
)}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}