feat(email): adiciona templates React Email e melhora UI admin
Some checks failed
Some checks failed
- Cria 10 novos templates React Email (invite, password-reset, new-login, sla-warning, sla-breached, ticket-created, ticket-resolved, ticket-assigned, ticket-status, ticket-comment) - Adiciona envio de email ao criar convite de usuario - Adiciona security_invite em COLLABORATOR_VISIBLE_TYPES - Melhora tabela de equipe com badges de papel e colunas fixas - Atualiza TicketCard com nova interface de props - Remove botao de limpeza de dados antigos do admin 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
8546a1feb1
commit
498b9789b5
17 changed files with 1422 additions and 190 deletions
|
|
@ -10,7 +10,8 @@ import { DEFAULT_TENANT_ID } from "@/lib/constants"
|
|||
import { ROLE_OPTIONS, type RoleOption, isAdmin } from "@/lib/authz"
|
||||
import { env } from "@/lib/env"
|
||||
import { prisma } from "@/lib/prisma"
|
||||
import { computeInviteStatus, normalizeInvite, type InviteWithEvents, type NormalizedInvite } from "@/server/invite-utils"
|
||||
import { buildInviteUrl, computeInviteStatus, normalizeInvite, type InviteWithEvents, type NormalizedInvite } from "@/server/invite-utils"
|
||||
import { notifyUserInvite } from "@/server/notification/notification-service"
|
||||
|
||||
const DEFAULT_EXPIRATION_DAYS = 7
|
||||
const JSON_NULL = Prisma.JsonNull as Prisma.NullableJsonNullValueInput
|
||||
|
|
@ -27,6 +28,17 @@ function normalizeRole(input: string | null | undefined): RoleOption {
|
|||
return (ROLE_OPTIONS as readonly string[]).includes(role) ? role : "agent"
|
||||
}
|
||||
|
||||
const ROLE_LABELS: Record<string, string> = {
|
||||
admin: "Administrador",
|
||||
manager: "Gestor",
|
||||
agent: "Agente",
|
||||
collaborator: "Colaborador",
|
||||
}
|
||||
|
||||
function formatRoleName(role: string): string {
|
||||
return ROLE_LABELS[role.toLowerCase()] ?? role
|
||||
}
|
||||
|
||||
function generateToken() {
|
||||
return randomBytes(32).toString("hex")
|
||||
}
|
||||
|
|
@ -213,5 +225,24 @@ export async function POST(request: Request) {
|
|||
const normalized = buildInvitePayload(inviteWithEvents, now)
|
||||
await syncInviteWithConvex(normalized)
|
||||
|
||||
// Envia email de convite
|
||||
const inviteUrl = buildInviteUrl(token)
|
||||
const inviterName = session.user.name ?? session.user.email
|
||||
const roleName = formatRoleName(role)
|
||||
|
||||
try {
|
||||
await notifyUserInvite(
|
||||
email,
|
||||
name ?? null,
|
||||
inviterName,
|
||||
roleName,
|
||||
null, // companyName - não temos essa informação no convite
|
||||
inviteUrl
|
||||
)
|
||||
} catch (error) {
|
||||
// Log do erro mas não falha a criação do convite
|
||||
console.error("[invites] Falha ao enviar email de convite:", error)
|
||||
}
|
||||
|
||||
return NextResponse.json({ invite: normalized })
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue