frontend: remove admin user management page and nav link
- Delete admin user management page - Remove 管理后台 link from main layout header
This commit is contained in:
@@ -1,186 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import { useEffect, useState } from "react";
|
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { Input } from "@/components/ui/input";
|
|
||||||
import { Label } from "@/components/ui/label";
|
|
||||||
import {
|
|
||||||
Dialog,
|
|
||||||
DialogContent,
|
|
||||||
DialogHeader,
|
|
||||||
DialogTitle,
|
|
||||||
DialogTrigger,
|
|
||||||
} from "@/components/ui/dialog";
|
|
||||||
import {
|
|
||||||
Table,
|
|
||||||
TableBody,
|
|
||||||
TableCell,
|
|
||||||
TableHead,
|
|
||||||
TableHeader,
|
|
||||||
TableRow,
|
|
||||||
} from "@/components/ui/table";
|
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
||||||
|
|
||||||
interface User {
|
|
||||||
id: number;
|
|
||||||
username: string;
|
|
||||||
email: string;
|
|
||||||
role: string;
|
|
||||||
createdAt: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function AdminPage() {
|
|
||||||
const [users, setUsers] = useState<User[]>([]);
|
|
||||||
const [loading, setLoading] = useState(true);
|
|
||||||
const [open, setOpen] = useState(false);
|
|
||||||
const [form, setForm] = useState({
|
|
||||||
username: "",
|
|
||||||
email: "",
|
|
||||||
password: "",
|
|
||||||
role: "user",
|
|
||||||
});
|
|
||||||
|
|
||||||
async function fetchUsers() {
|
|
||||||
const res = await fetch("/api/proxy/admin/users");
|
|
||||||
if (res.ok) {
|
|
||||||
const data = await res.json();
|
|
||||||
setUsers(data.users || []);
|
|
||||||
}
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
fetchUsers();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
async function handleCreate(e: React.FormEvent) {
|
|
||||||
e.preventDefault();
|
|
||||||
const res = await fetch("/api/proxy/admin/users", {
|
|
||||||
method: "POST",
|
|
||||||
headers: { "Content-Type": "application/json" },
|
|
||||||
body: JSON.stringify(form),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (res.ok) {
|
|
||||||
setOpen(false);
|
|
||||||
setForm({ username: "", email: "", password: "", role: "user" });
|
|
||||||
fetchUsers();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleDelete(id: number) {
|
|
||||||
if (!confirm("确定删除该用户?")) return;
|
|
||||||
const res = await fetch(`/api/proxy/admin/users/${id}`, {
|
|
||||||
method: "DELETE",
|
|
||||||
});
|
|
||||||
if (res.ok) {
|
|
||||||
fetchUsers();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="space-y-4">
|
|
||||||
<div className="flex items-center justify-between">
|
|
||||||
<h1 className="text-2xl font-bold">用户管理</h1>
|
|
||||||
<Dialog open={open} onOpenChange={setOpen}>
|
|
||||||
<DialogTrigger render={<Button>创建用户</Button>} />
|
|
||||||
<DialogContent>
|
|
||||||
<DialogHeader>
|
|
||||||
<DialogTitle>新建用户</DialogTitle>
|
|
||||||
</DialogHeader>
|
|
||||||
<form onSubmit={handleCreate} className="space-y-4">
|
|
||||||
<div>
|
|
||||||
<Label>用户名</Label>
|
|
||||||
<Input
|
|
||||||
value={form.username}
|
|
||||||
onChange={(e) =>
|
|
||||||
setForm({ ...form, username: e.target.value })
|
|
||||||
}
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<Label>邮箱</Label>
|
|
||||||
<Input
|
|
||||||
type="email"
|
|
||||||
value={form.email}
|
|
||||||
onChange={(e) =>
|
|
||||||
setForm({ ...form, email: e.target.value })
|
|
||||||
}
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<Label>密码</Label>
|
|
||||||
<Input
|
|
||||||
type="password"
|
|
||||||
value={form.password}
|
|
||||||
onChange={(e) =>
|
|
||||||
setForm({ ...form, password: e.target.value })
|
|
||||||
}
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<Label>角色</Label>
|
|
||||||
<select
|
|
||||||
className="w-full rounded-md border px-3 py-2 text-sm"
|
|
||||||
value={form.role}
|
|
||||||
onChange={(e) => setForm({ ...form, role: e.target.value })}
|
|
||||||
>
|
|
||||||
<option value="user">user</option>
|
|
||||||
<option value="admin">admin</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<Button type="submit" className="w-full">
|
|
||||||
创建
|
|
||||||
</Button>
|
|
||||||
</form>
|
|
||||||
</DialogContent>
|
|
||||||
</Dialog>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Card>
|
|
||||||
<CardHeader>
|
|
||||||
<CardTitle>用户列表</CardTitle>
|
|
||||||
</CardHeader>
|
|
||||||
<CardContent>
|
|
||||||
{loading ? (
|
|
||||||
<p>加载中...</p>
|
|
||||||
) : (
|
|
||||||
<Table>
|
|
||||||
<TableHeader>
|
|
||||||
<TableRow>
|
|
||||||
<TableHead>ID</TableHead>
|
|
||||||
<TableHead>用户名</TableHead>
|
|
||||||
<TableHead>邮箱</TableHead>
|
|
||||||
<TableHead>角色</TableHead>
|
|
||||||
<TableHead>操作</TableHead>
|
|
||||||
</TableRow>
|
|
||||||
</TableHeader>
|
|
||||||
<TableBody>
|
|
||||||
{users.map((user) => (
|
|
||||||
<TableRow key={user.id}>
|
|
||||||
<TableCell>{user.id}</TableCell>
|
|
||||||
<TableCell>{user.username}</TableCell>
|
|
||||||
<TableCell>{user.email}</TableCell>
|
|
||||||
<TableCell>{user.role}</TableCell>
|
|
||||||
<TableCell>
|
|
||||||
<Button
|
|
||||||
variant="destructive"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => handleDelete(user.id)}
|
|
||||||
>
|
|
||||||
删除
|
|
||||||
</Button>
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
))}
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
|
||||||
)}
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -22,11 +22,6 @@ export default async function MainLayout({
|
|||||||
<Link href="/dashboard" className="text-sm hover:underline">
|
<Link href="/dashboard" className="text-sm hover:underline">
|
||||||
仪表盘
|
仪表盘
|
||||||
</Link>
|
</Link>
|
||||||
{user?.role === "admin" && (
|
|
||||||
<Link href="/admin" className="text-sm hover:underline">
|
|
||||||
管理后台
|
|
||||||
</Link>
|
|
||||||
)}
|
|
||||||
<form
|
<form
|
||||||
action={async () => {
|
action={async () => {
|
||||||
"use server";
|
"use server";
|
||||||
|
|||||||
Reference in New Issue
Block a user