Stage 1: Course/Module/Lesson CRUD admin UI with TipTap editor
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
|
||||
const roleLabel: Record<string, string> = {
|
||||
admin: "Администратор",
|
||||
curator: "Куратор",
|
||||
student: "Ученик",
|
||||
};
|
||||
|
||||
const roleVariant: Record<string, "default" | "secondary" | "outline"> = {
|
||||
admin: "default",
|
||||
curator: "secondary",
|
||||
student: "outline",
|
||||
};
|
||||
|
||||
export default async function UsersPage() {
|
||||
const users = await prisma.user.findMany({
|
||||
orderBy: { createdAt: "desc" },
|
||||
include: { _count: { select: { enrollments: true } } },
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="p-8">
|
||||
<div className="mb-6">
|
||||
<h1 className="text-2xl font-semibold text-slate-800">Пользователи</h1>
|
||||
<p className="text-slate-500 text-sm mt-0.5">{users.length} пользователей</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-white border border-slate-200 rounded-2xl overflow-hidden">
|
||||
<table className="w-full">
|
||||
<thead>
|
||||
<tr className="border-b border-slate-100 bg-slate-50">
|
||||
<th className="text-left px-5 py-3 text-xs font-medium text-slate-500 uppercase">Пользователь</th>
|
||||
<th className="text-left px-5 py-3 text-xs font-medium text-slate-500 uppercase">Роль</th>
|
||||
<th className="text-left px-5 py-3 text-xs font-medium text-slate-500 uppercase">Курсов</th>
|
||||
<th className="text-left px-5 py-3 text-xs font-medium text-slate-500 uppercase">Email подтверждён</th>
|
||||
<th className="text-left px-5 py-3 text-xs font-medium text-slate-500 uppercase">Зарегистрирован</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{users.map((user) => (
|
||||
<tr key={user.id} className="border-b border-slate-50 last:border-0 hover:bg-slate-50">
|
||||
<td className="px-5 py-3">
|
||||
<p className="font-medium text-slate-800">{user.name}</p>
|
||||
<p className="text-xs text-slate-400">{user.email}</p>
|
||||
</td>
|
||||
<td className="px-5 py-3">
|
||||
<Badge variant={roleVariant[user.role] ?? "outline"}>
|
||||
{roleLabel[user.role] ?? user.role}
|
||||
</Badge>
|
||||
</td>
|
||||
<td className="px-5 py-3 text-sm text-slate-600">
|
||||
{user._count.enrollments}
|
||||
</td>
|
||||
<td className="px-5 py-3">
|
||||
<span className={`text-xs font-medium ${user.emailVerified ? "text-green-600" : "text-slate-400"}`}>
|
||||
{user.emailVerified ? "Да" : "Нет"}
|
||||
</span>
|
||||
</td>
|
||||
<td className="px-5 py-3 text-sm text-slate-400">
|
||||
{new Date(user.createdAt).toLocaleDateString("ru-RU")}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user