import { prisma } from "@/lib/prisma"; import Link from "next/link"; import { UserPlus } from "lucide-react"; import { UsersTable } from "@/components/admin/users-table"; import { Suspense } from "react"; import { UsersSearch } from "@/components/admin/users-search"; const PAGE_SIZE = 20; interface Props { searchParams: Promise<{ search?: string; role?: string; page?: string; balance?: string }>; } export default async function UsersPage({ searchParams }: Props) { const { search = "", role = "", page = "1", balance = "" } = await searchParams; const currentPage = Math.max(1, parseInt(page) || 1); const skip = (currentPage - 1) * PAGE_SIZE; // Collect userIds with non-zero balance if filter is active let balanceUserIds: string[] | null = null; if (balance === "nonzero") { const groups = await prisma.balanceTransaction.groupBy({ by: ["userId"], _sum: { amount: true }, having: { amount: { _sum: { not: { equals: 0 } } } }, }); balanceUserIds = groups.map((g) => g.userId); } const where = { ...(search ? { OR: [ { name: { contains: search, mode: "insensitive" as const } }, { email: { contains: search, mode: "insensitive" as const } }, ], } : {}), ...(role ? { role } : {}), ...(balanceUserIds !== null ? { id: { in: balanceUserIds } } : {}), }; const [users, total] = await Promise.all([ prisma.user.findMany({ where, orderBy: { createdAt: "desc" }, skip, take: PAGE_SIZE, include: { _count: { select: { enrollments: true } }, enrollments: { include: { course: { select: { title: true } } }, orderBy: { enrolledAt: "desc" }, }, }, }), prisma.user.count({ where }), ]); const totalPages = Math.ceil(total / PAGE_SIZE); const tableUsers = users.map((u) => ({ id: u.id, name: u.name, email: u.email, role: u.role, emailVerified: u.emailVerified, createdAt: u.createdAt, enrollmentCount: u._count.enrollments, enrollments: u.enrollments.map((e) => ({ courseId: e.courseId, courseTitle: e.course.title, expiresAt: e.expiresAt, })), })); function pageUrl(p: number) { const params = new URLSearchParams(); if (search) params.set("search", search); if (role) params.set("role", role); if (balance) params.set("balance", balance); params.set("page", String(p)); return `/admin/users?${params.toString()}`; } return (

Пользователи

{total} пользователей

Добавить пользователя
{/* Filters */} {/* Pagination */} {totalPages > 1 && (
{currentPage > 1 && ( ← )} {Array.from({ length: totalPages }, (_, i) => i + 1) .filter((p) => p === 1 || p === totalPages || Math.abs(p - currentPage) <= 2) .reduce<(number | "…")[]>((acc, p, i, arr) => { if (i > 0 && (p as number) - (arr[i - 1] as number) > 1) acc.push("…"); acc.push(p); return acc; }, []) .map((p, i) => p === "…" ? ( ) : ( {p} ) )} {currentPage < totalPages && ( → )} стр. {currentPage} из {totalPages}
)}
); }