Stage 1: Course/Module/Lesson CRUD admin UI with TipTap editor

This commit is contained in:
2026-04-07 11:36:27 +05:00
parent 9d82b73e58
commit d356dddc96
30 changed files with 2090 additions and 41 deletions
+70
View File
@@ -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>
);
}