import Link from "next/link"; import { StatusCard } from "@/components/admin/dashboard"; import { prisma } from "@/lib/prisma"; import { DoorOpen } from "lucide-react"; export const dynamic = "force-dynamic"; const PER_PAGE = 25; type RoomRow = { id: number; name: string; ownerName: string; users: number; usersMax: number; state: string; category: number; }; export default async function AdminRooms({ searchParams, }: { searchParams: Promise<{ q?: string; page?: string }>; }) { const sp = await searchParams; const q = (sp.q ?? "").trim(); const page = Math.max(1, Number(sp.page ?? "1") || 1); // Search matches room name OR owner username (ownerName is denormalised on the // emulator rooms table, so no join is needed). const where = q ? { OR: [{ name: { contains: q } }, { ownerName: { contains: q } }] } : {}; let rooms: RoomRow[] = []; let total = 0; try { [rooms, total] = await Promise.all([ prisma.rooms.findMany({ where, select: { id: true, name: true, ownerName: true, users: true, usersMax: true, state: true, category: true, }, orderBy: { id: "desc" }, skip: (page - 1) * PER_PAGE, take: PER_PAGE, }), prisma.rooms.count({ where }), ]); } catch { rooms = []; total = 0; } const pages = Math.max(1, Math.ceil(total / PER_PAGE)); const qs = (p: number) => `/admin/rooms?q=${encodeURIComponent(q)}&page=${p}`; // Page-local tallies (the full counts aren't fetched to keep the query cheap). const openOnPage = rooms.filter((r) => r.state === "open").length; const usersOnPage = rooms.reduce((sum, r) => sum + r.users, 0); return (

Rooms

{q ? `Matching "${q}" ยท ` : ""}{total} room{total === 1 ? "" : "s"} total.

{rooms.map((r) => ( ))}
ID Name Owner Users State Cat
{r.id} {r.name || "(unnamed)"} {r.ownerName || "โ€”"} {r.users} / {r.usersMax} {r.state} {r.category}
{rooms.length === 0 ? (

No rooms found.

) : null}

Page {page} / {pages} ยท {total} rooms {page > 1 ? ( <> {" ยท "} โ† Prev ) : null} {page < pages ? ( <> {" ยท "} Next โ†’ ) : null}

); }