72 lines
3.0 KiB
TypeScript
72 lines
3.0 KiB
TypeScript
import { prisma } from "@/lib/prisma";
|
||
import { Badge } from "@/components/ui/badge";
|
||
import Link from "next/link";
|
||
|
||
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 last:border-0" style={{ borderColor: "var(--border)" }}>
|
||
<td className="px-5 py-3">
|
||
<Link href={`/admin/users/${user.id}`} className="font-medium hover:underline" style={{ color: "var(--foreground)" }}>{user.name}</Link>
|
||
<p className="text-xs" style={{ color: "var(--muted-foreground)" }}>{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>
|
||
);
|
||
}
|