import { groups, minecraftAccounts, userGroupMemberships, users } from "@minecraft-account-manager/database"; import { and, asc, desc, eq, ilike, isNull, or, sql } from "drizzle-orm"; import Link from "next/link"; import { UserGroupSelect } from "@/components/user-group-select"; import { db } from "@/lib/database"; import { assignUserGroupFromRegistry } from "./actions"; export const dynamic = "force-dynamic"; export default async function AdminUsersPage({ searchParams, }: { searchParams: Promise<{ q?: string; error?: string; saved?: string }>; }) { const query = await searchParams; const search = query.q?.trim().slice(0, 100) ?? ""; const pattern = `%${search}%`; const where = search ? or( ilike(users.firstName, pattern), ilike(users.discordUsername, pattern), ilike(users.discordGlobalName, pattern), eq(users.discordUserId, search), sql`exists ( select 1 from ${minecraftAccounts} where ${minecraftAccounts.userId} = ${users.id} and ${minecraftAccounts.deletedAt} is null and ( ${minecraftAccounts.username} ilike ${pattern} or ${minecraftAccounts.minecraftUuid} = ${search.toLowerCase()} ) )`, ) : undefined; const [results, allGroups, memberships] = await Promise.all([ db .select({ id: users.id, firstName: users.firstName, discordUsername: users.discordUsername, discordGlobalName: users.discordGlobalName, discordUserId: users.discordUserId, onboardingCompletedAt: users.onboardingCompletedAt, primaryUsername: minecraftAccounts.username, accountCount: sql`( select count(*)::int from ${minecraftAccounts} account_count where account_count.user_id = ${users.id} and account_count.deleted_at is null )`, }) .from(users) .leftJoin( minecraftAccounts, and( eq(minecraftAccounts.userId, users.id), eq(minecraftAccounts.isPrimary, true), isNull(minecraftAccounts.deletedAt), ), ) .where(where) .orderBy(users.firstName, users.discordUsername) .limit(100), db.select({ id: groups.id, name: groups.name, isDefault: groups.isDefault }) .from(groups).orderBy(desc(groups.isDefault), asc(groups.name)), db.select({ userId: userGroupMemberships.userId, groupId: userGroupMemberships.groupId }) .from(userGroupMemberships), ]); const defaultGroup = allGroups.find((group) => group.isDefault); const groupByUser = new Map(memberships.map((membership) => [membership.userId, membership.groupId])); return (

Identity registry

Users

{query.error &&

{query.error === "invalid-group-assignment" ? "The user or group no longer exists. No group change was applied." : "The requested user could not be found."}

} {query.saved === "group" &&

User group updated.

}
{results.map((user) => ( ))} {!results.length && }
Registered portal users
UserDiscordPrimaryAccountsGroupStatus
{user.firstName ?? "Name needed"}
{user.discordGlobalName ?? user.discordUsername}
@{user.discordUsername}
{user.discordUserId}
{user.primaryUsername ?? "—"} {user.accountCount} {defaultGroup ? : Default group missing} {user.onboardingCompletedAt ? "Ready" : "Onboarding"}
No users match that search.

Showing up to 100 users

); }