Files

204 lines
4.3 KiB
TypeScript

import { notFound, redirect } from "next/navigation";
import type { StatusBriefing, TipoPessoa } from "@prisma/client";
import { auth } from "@/auth";
import { db } from "@/lib/db";
import { decryptCpf } from "@/lib/crypto";
export async function requireAdmin() {
const session = await auth();
if (!session?.user?.id) {
redirect("/login");
}
if (session.user.papel !== "ADMIN") {
redirect("/briefings");
}
return session.user;
}
export function maskCpf(cpf: string) {
const digits = cpf.replace(/\D/g, "");
if (digits.length !== 11) {
return "***.***.***-**";
}
return `***.${digits.slice(3, 6)}.${digits.slice(6, 9)}-**`;
}
export function whatsappLink(value: string) {
const digits = value.replace(/\D/g, "");
return `https://wa.me/${digits}`;
}
export async function getAdminDashboard() {
await requireAdmin();
const since = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
const [porStatus, novosUltimos7Dias, ultimosEnvios] = await Promise.all([
db.briefing.groupBy({
by: ["status"],
_count: { _all: true }
}),
db.briefing.count({
where: {
criadoEm: {
gte: since
}
}
}),
db.briefing.findMany({
where: {
enviadoEm: {
not: null
}
},
orderBy: { enviadoEm: "desc" },
take: 8,
include: {
cliente: {
include: { user: true }
}
}
})
]);
return { porStatus, novosUltimos7Dias, ultimosEnvios };
}
export async function listarClientesAdmin(filters: {
busca?: string;
tipo?: TipoPessoa;
}) {
await requireAdmin();
const busca = filters.busca?.trim();
return db.cliente.findMany({
where: {
tipo: filters.tipo,
OR: busca
? [
{ nomeCompleto: { contains: busca, mode: "insensitive" } },
{ razaoSocial: { contains: busca, mode: "insensitive" } },
{ cnpj: { contains: busca.replace(/\D/g, "") } },
{ whatsapp: { contains: busca.replace(/\D/g, "") || busca } },
{ user: { email: { contains: busca, mode: "insensitive" } } }
]
: undefined
},
orderBy: { criadoEm: "desc" },
include: {
user: true,
briefings: {
orderBy: { atualizadoEm: "desc" }
}
}
});
}
export async function getClienteAdmin(clienteId: string) {
await requireAdmin();
const cliente = await db.cliente.findUnique({
where: { id: clienteId },
include: {
user: true,
briefings: {
orderBy: { atualizadoEm: "desc" }
}
}
});
if (!cliente) {
notFound();
}
return cliente;
}
export async function revelarCpfCliente(clienteId: string) {
const admin = await requireAdmin();
const cliente = await db.cliente.findUnique({
where: { id: clienteId }
});
if (!cliente) {
notFound();
}
await db.auditoriaAcesso.create({
data: {
adminId: admin.id,
clienteId,
acao: "REVELOU_CPF"
}
});
return decryptCpf(cliente.cpfCifrado);
}
export async function getBriefingAdmin(briefingId: string) {
await requireAdmin();
const briefing = await db.briefing.findUnique({
where: { id: briefingId },
include: {
cliente: {
include: { user: true }
},
notasInternas: {
orderBy: { criadoEm: "desc" },
include: { admin: true }
},
anexos: true
}
});
if (!briefing) {
notFound();
}
const secoes = await db.secao.findMany({
where: { ativo: true },
orderBy: { ordem: "asc" },
include: {
perguntas: {
orderBy: { ordem: "asc" },
include: {
respostas: {
where: { briefingId }
},
anexos: {
where: { briefingId },
orderBy: { criadoEm: "desc" }
}
}
}
}
});
return { briefing, secoes };
}
export async function listarPerguntasAdmin() {
await requireAdmin();
return db.secao.findMany({
orderBy: { ordem: "asc" },
include: {
perguntas: {
orderBy: { ordem: "asc" },
include: { ajuda: true }
}
}
});
}
export async function atualizarStatusBriefing(briefingId: string, status: StatusBriefing) {
await requireAdmin();
return db.briefing.update({
where: { id: briefingId },
data: { status }
});
}