sistema-de-chamados/src/app/admin/users/page.tsx
2025-11-13 21:43:36 -03:00

119 lines
3.7 KiB
TypeScript

import { AppShell } from "@/components/app-shell"
import { SiteHeader } from "@/components/site-header"
import { prisma } from "@/lib/prisma"
import { DEFAULT_TENANT_ID } from "@/lib/constants"
import { requireStaffSession } from "@/lib/auth-server"
import { AdminUsersWorkspace, type AdminAccount } from "@/components/admin/users/admin-users-workspace"
import { fetchCompaniesByTenant, normalizeCompany } from "@/server/company-service"
export const runtime = "nodejs"
export const dynamic = "force-dynamic"
export default async function AdminUsersPage({
searchParams,
}: { searchParams: Promise<Record<string, string | string[] | undefined>> }) {
const session = await requireStaffSession()
const tenantId = session.user.tenantId ?? DEFAULT_TENANT_ID
const params = await searchParams
const autoOpenCreateUser = params.quick === "new-user"
const users = await prisma.user.findMany({
where: {
tenantId,
role: { in: ["MANAGER", "COLLABORATOR"] },
},
include: {
company: {
select: {
id: true,
name: true,
},
},
manager: {
select: {
id: true,
name: true,
email: true,
},
},
},
orderBy: { createdAt: "desc" },
})
const emails = users.map((user: (typeof users)[number]) => user.email)
const authUsers = await prisma.authUser.findMany({
where: { email: { in: emails } },
select: { id: true, email: true, updatedAt: true, createdAt: true },
})
const sessions = await prisma.authSession.findMany({
where: {
userId: {
in: authUsers.map((auth: (typeof authUsers)[number]) => auth.id),
},
},
orderBy: { updatedAt: "desc" },
select: { userId: true, updatedAt: true },
})
const sessionByUserId = new Map<string, Date>()
for (const sessionRow of sessions) {
if (!sessionByUserId.has(sessionRow.userId)) {
sessionByUserId.set(sessionRow.userId, sessionRow.updatedAt)
}
}
const authByEmail = new Map<string, { id: string; updatedAt: Date; createdAt: Date }>()
for (const authUser of authUsers) {
authByEmail.set(authUser.email.toLowerCase(), {
id: authUser.id,
updatedAt: authUser.updatedAt,
createdAt: authUser.createdAt,
})
}
const accounts: AdminAccount[] = users.map((user: (typeof users)[number]) => {
const auth = authByEmail.get(user.email.toLowerCase())
const lastSeenAt = auth ? sessionByUserId.get(auth.id) ?? auth.updatedAt : null
return {
id: user.id,
email: user.email,
name: user.name ?? user.email,
role: user.role === "MANAGER" ? "MANAGER" : "COLLABORATOR",
companyId: user.companyId ?? null,
companyName: user.company?.name ?? null,
jobTitle: user.jobTitle ?? null,
managerId: user.managerId ?? null,
managerName: user.manager?.name ?? null,
managerEmail: user.manager?.email ?? null,
tenantId: user.tenantId,
createdAt: user.createdAt.toISOString(),
updatedAt: user.updatedAt.toISOString(),
authUserId: auth?.id ?? null,
lastSeenAt: lastSeenAt ? lastSeenAt.toISOString() : null,
}
})
const companiesRaw = await fetchCompaniesByTenant(tenantId)
const companies = companiesRaw.map(normalizeCompany)
return (
<AppShell
header={
<SiteHeader
title="Usuários"
lead="Gerencie acessos de gestores/colaboradores e mantenha contatos, unidades e contratos atualizados."
/>
}
>
<div className="mx-auto w-full max-w-7xl px-4 pb-12 lg:px-8">
<AdminUsersWorkspace
initialAccounts={accounts}
companies={companies}
tenantId={tenantId}
autoOpenCreate={autoOpenCreateUser}
/>
</div>
</AppShell>
)
}