const COLORS = { primary: "#00e8ff", primaryDark: "#00c4d6", primaryForeground: "#020617", background: "#f8fafc", card: "#ffffff", border: "#e2e8f0", textPrimary: "#0f172a", textSecondary: "#334155", textMuted: "#64748b", statusPending: "#64748b", statusPendingBg: "#f1f5f9", statusProgress: "#0ea5e9", statusProgressBg: "#e0f2fe", statusPaused: "#f59e0b", statusPausedBg: "#fef3c7", statusResolved: "#10b981", statusResolvedBg: "#d1fae5", priorityLow: "#64748b", priorityLowBg: "#f1f5f9", priorityMedium: "#0a4760", priorityMediumBg: "#dff1fb", priorityHigh: "#7d3b05", priorityHighBg: "#fde8d1", priorityUrgent: "#8b0f1c", priorityUrgentBg: "#fbd9dd", } export type EmailTicketSummary = { reference: number subject: string status?: string | null priority?: string | null companyName?: string | null requesterName?: string | null assigneeName?: string | null } function escapeHtml(value: unknown): string { if (value === null || value === undefined) return "" const s = String(value) return s .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'") } function textToHtmlParagraphs(text: string): string { const trimmed = text.replace(/\r\n/g, "\n").trim() if (!trimmed) return "" const paragraphs = trimmed.split(/\n{2,}/g) return paragraphs .map((p) => `

${escapeHtml(p).replace(/\n/g, "
")}

`) .join("") } function badge(label: string, bg: string, color: string) { return `${escapeHtml(label)}` } function statusBadge(statusRaw: string) { const status = statusRaw.trim().toUpperCase() const map: Record = { PENDING: { label: "Pendente", bg: COLORS.statusPendingBg, color: COLORS.statusPending }, AWAITING_ATTENDANCE: { label: "Em andamento", bg: COLORS.statusProgressBg, color: COLORS.statusProgress }, PAUSED: { label: "Pausado", bg: COLORS.statusPausedBg, color: COLORS.statusPaused }, RESOLVED: { label: "Resolvido", bg: COLORS.statusResolvedBg, color: COLORS.statusResolved }, } const entry = map[status] ?? { label: statusRaw, bg: COLORS.statusPendingBg, color: COLORS.statusPending } return badge(entry.label, entry.bg, entry.color) } function priorityBadge(priorityRaw: string) { const priority = priorityRaw.trim().toUpperCase() const map: Record = { LOW: { label: "Baixa", bg: COLORS.priorityLowBg, color: COLORS.priorityLow }, MEDIUM: { label: "Média", bg: COLORS.priorityMediumBg, color: COLORS.priorityMedium }, HIGH: { label: "Alta", bg: COLORS.priorityHighBg, color: COLORS.priorityHigh }, URGENT: { label: "Urgente", bg: COLORS.priorityUrgentBg, color: COLORS.priorityUrgent }, } const entry = map[priority] ?? { label: priorityRaw, bg: COLORS.priorityMediumBg, color: COLORS.priorityMedium } return badge(entry.label, entry.bg, entry.color) } export function buildBaseUrl() { return process.env.NEXT_PUBLIC_APP_URL || process.env.APP_BASE_URL || "http://localhost:3000" } function ticketInfoCard(ticket: EmailTicketSummary) { const rows: string[] = [] rows.push(` Chamado #${escapeHtml(ticket.reference)} `) rows.push(` Assunto ${escapeHtml(ticket.subject)} `) if (ticket.companyName) { rows.push(` Empresa ${escapeHtml(ticket.companyName)} `) } if (ticket.status) { rows.push(` Status ${statusBadge(ticket.status)} `) } if (ticket.priority) { rows.push(` Prioridade ${priorityBadge(ticket.priority)} `) } if (ticket.requesterName) { rows.push(` Solicitante ${escapeHtml(ticket.requesterName)} `) } if (ticket.assigneeName) { rows.push(` Responsável ${escapeHtml(ticket.assigneeName)} `) } return `
${rows.join("")}
` } function button(label: string, url: string) { return `${escapeHtml(label)}` } export function renderAutomationEmail(params: { title: string message: string ticket: EmailTicketSummary ctaLabel: string ctaUrl: string }) { const baseUrl = buildBaseUrl() const content = `
Raven Raven

${escapeHtml(params.title)}

${textToHtmlParagraphs(params.message)} ${ticketInfoCard(params.ticket)}
${button(params.ctaLabel, params.ctaUrl)}

Se o botão não funcionar, copie e cole esta URL no navegador:
${escapeHtml(params.ctaUrl)}

` return `
${content}

© ${new Date().getFullYear()} Raven — Rever Tecnologia

` } export function renderSimpleNotificationEmail(params: { title: string message: string ctaLabel: string ctaUrl: string }) { const baseUrl = buildBaseUrl() const content = `
Raven Raven

${escapeHtml(params.title)}

${textToHtmlParagraphs(params.message)}
${button(params.ctaLabel, params.ctaUrl)}

Se o botão não funcionar, copie e cole esta URL no navegador:
${escapeHtml(params.ctaUrl)}

` return `
${content}

© ${new Date().getFullYear()} Raven — Rever Tecnologia

` }