import { count, desc, eq, inArray, like, or } from "drizzle-orm"; import { Shield } from "lucide-react"; import { redirect } from "next/navigation"; import { getTranslations } from "next-intl/server"; import { AdminPageShell } from "@/components/admin/admin-page-shell"; import { AdminSimplePager } from "@/components/admin/admin-simple-pager"; import { StatusCard } from "@/components/admin/dashboard"; import Link from "@/components/link"; import { Button } from "@/components/ui/button"; import { calcPagination, parseListParams } from "@/lib/admin-helpers"; import { db, Guilds, GuildsMembers, User } from "@/lib/db"; import { formatDate } from "@/lib/format-date"; import { canAccess, getAdminContext, PERMS } from "@/lib/permissions"; import { getCachedAdminCount } from "@/lib/services/admin-stats"; export default async function AdminGuildsPage({ searchParams, }: { searchParams: Promise>; }) { const { session, permissions } = await getAdminContext(); if (!canAccess(permissions, PERMS.USERS_VIEW, session.user.rank)) { redirect("/admin"); } const t = await getTranslations("pages.admin.guilds"); const raw = await searchParams; const parsed = parseListParams(new URLSearchParams(raw)); const q = parsed.search.trim(); let total = 0; let rows: Array<{ id: number; name: string; description: string; userId: number; badge: string; dateCreated: number; roomId: number; }> = []; let loadError = false; try { const where = q ? or( like(Guilds.name, `%${q}%`), like(Guilds.description, `%${q}%`), ...(Number.isFinite(Number(q)) && Number(q) > 0 ? [eq(Guilds.id, Number(q))] : []), ) : undefined; total = await getCachedAdminCount(Guilds, "guilds", where); const pagination = calcPagination(total, parsed.page, parsed.perPage); rows = await db .select({ id: Guilds.id, name: Guilds.name, description: Guilds.description, userId: Guilds.userId, badge: Guilds.badge, dateCreated: Guilds.dateCreated, roomId: Guilds.roomId, }) .from(Guilds) .where(where) .orderBy(desc(Guilds.id)) .limit(pagination.perPage) .offset(pagination.offset); } catch { loadError = true; } const pagination = calcPagination(total, parsed.page, parsed.perPage); const ownerIds = [ ...new Set(rows.map((r) => r.userId).filter((id) => id > 0)), ]; const guildIds = rows.map((r) => r.id); const [owners, memberGroups] = await Promise.all([ ownerIds.length ? db .select({ id: User.id, username: User.username }) .from(User) .where(inArray(User.id, ownerIds)) .catch(() => []) : Promise.resolve([]), guildIds.length ? db .select({ guildId: GuildsMembers.guildId, total: count(), }) .from(GuildsMembers) .where(inArray(GuildsMembers.guildId, guildIds)) .groupBy(GuildsMembers.guildId) .catch(() => []) : Promise.resolve([]), ]); const ownerById = new Map(owners.map((u) => [u.id, u.username])); const membersByGuild = new Map( memberGroups.map((g) => [g.guildId, Number(g.total)]), ); return (
{loadError ? (
{t("loadError")}
) : null}

{t("listHeading", { count: total })}

{rows.length === 0 ? (
{t("empty")}
) : (
{rows.map((g) => ( ))}
{t("colId")} {t("colBadge")} {t("colName")} {t("colOwner")} {t("colMembers")} {t("colCreated")}
{g.id} {g.badge ? ( ) : ( — )} {g.name || `#${g.id}`} {g.description ? (
{g.description}
) : null}
{ownerById.get(g.userId) ?? `#${g.userId}`} {membersByGuild.get(g.id) ?? 0} {formatDate(new Date(g.dateCreated * 1000), "date")}
)}
); }