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
150
emails/new-login-email.tsx
Normal file
150
emails/new-login-email.tsx
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
import * as React from "react"
|
||||
import { Heading, Hr, Section, Text } from "@react-email/components"
|
||||
|
||||
import { RavenEmailLayout } from "./_components/layout"
|
||||
import { EMAIL_COLORS } from "./_components/tokens"
|
||||
|
||||
export type NewLoginEmailProps = {
|
||||
loginAt: string
|
||||
ipAddress: string
|
||||
userAgent: string
|
||||
location?: string | null
|
||||
}
|
||||
|
||||
function formatDate(dateStr: string): string {
|
||||
try {
|
||||
const date = new Date(dateStr)
|
||||
return new Intl.DateTimeFormat("pt-BR", {
|
||||
dateStyle: "long",
|
||||
timeStyle: "short",
|
||||
}).format(date)
|
||||
} catch {
|
||||
return dateStr
|
||||
}
|
||||
}
|
||||
|
||||
export default function NewLoginEmail(props: NewLoginEmailProps) {
|
||||
const { loginAt, ipAddress, userAgent, location } = props
|
||||
|
||||
return (
|
||||
<RavenEmailLayout title="Novo acesso detectado" preview="Detectamos um novo acesso a sua conta">
|
||||
<Section style={{ textAlign: "center", margin: "24px 0" }}>
|
||||
<div
|
||||
style={{
|
||||
display: "inline-block",
|
||||
width: "64px",
|
||||
height: "64px",
|
||||
backgroundColor: "#fef3c7",
|
||||
borderRadius: "50%",
|
||||
lineHeight: "64px",
|
||||
fontSize: "28px",
|
||||
border: "1px solid #f59e0b",
|
||||
}}
|
||||
>
|
||||
🔒
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
<Heading style={{ margin: "0 0 12px 0", fontSize: "26px", fontWeight: 700, color: EMAIL_COLORS.textPrimary, textAlign: "center" }}>
|
||||
Novo acesso detectado
|
||||
</Heading>
|
||||
|
||||
<Text style={{ margin: "0 0 24px 0", fontSize: "15px", lineHeight: "1.7", color: EMAIL_COLORS.textSecondary, textAlign: "center" }}>
|
||||
Detectamos um novo acesso a sua conta. Se foi voce, pode ignorar este e-mail.
|
||||
</Text>
|
||||
|
||||
<Section
|
||||
style={{
|
||||
backgroundColor: "#f8fafc",
|
||||
borderRadius: "12px",
|
||||
border: `1px solid ${EMAIL_COLORS.border}`,
|
||||
margin: "24px 0",
|
||||
}}
|
||||
>
|
||||
<table cellPadding="0" cellSpacing="0" role="presentation" style={{ width: "100%" }}>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style={{ padding: "16px 20px", borderBottom: `1px solid #f1f5f9` }}>
|
||||
<table cellPadding="0" cellSpacing="0" role="presentation" style={{ width: "100%" }}>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style={{ color: EMAIL_COLORS.textMuted, fontSize: "13px", fontWeight: 500, width: "120px" }}>
|
||||
Data/Hora
|
||||
</td>
|
||||
<td style={{ color: EMAIL_COLORS.textPrimary, fontSize: "14px" }}>
|
||||
{formatDate(loginAt)}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style={{ padding: "16px 20px", borderBottom: `1px solid #f1f5f9` }}>
|
||||
<table cellPadding="0" cellSpacing="0" role="presentation" style={{ width: "100%" }}>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style={{ color: EMAIL_COLORS.textMuted, fontSize: "13px", fontWeight: 500, width: "120px" }}>
|
||||
Endereco IP
|
||||
</td>
|
||||
<td style={{ color: EMAIL_COLORS.textPrimary, fontSize: "14px", fontFamily: "monospace" }}>
|
||||
{ipAddress}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
{location ? (
|
||||
<tr>
|
||||
<td style={{ padding: "16px 20px", borderBottom: `1px solid #f1f5f9` }}>
|
||||
<table cellPadding="0" cellSpacing="0" role="presentation" style={{ width: "100%" }}>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style={{ color: EMAIL_COLORS.textMuted, fontSize: "13px", fontWeight: 500, width: "120px" }}>
|
||||
Localizacao
|
||||
</td>
|
||||
<td style={{ color: EMAIL_COLORS.textPrimary, fontSize: "14px" }}>
|
||||
{location}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
) : null}
|
||||
<tr>
|
||||
<td style={{ padding: "16px 20px" }}>
|
||||
<table cellPadding="0" cellSpacing="0" role="presentation" style={{ width: "100%" }}>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style={{ color: EMAIL_COLORS.textMuted, fontSize: "13px", fontWeight: 500, width: "120px" }}>
|
||||
Dispositivo
|
||||
</td>
|
||||
<td style={{ color: EMAIL_COLORS.textPrimary, fontSize: "13px" }}>
|
||||
{userAgent}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</Section>
|
||||
|
||||
<Hr style={{ borderColor: EMAIL_COLORS.border, margin: "24px 0" }} />
|
||||
|
||||
<Text style={{ margin: "0", fontSize: "13px", color: EMAIL_COLORS.textMuted, textAlign: "center", lineHeight: "1.6" }}>
|
||||
Se voce nao reconhece este acesso, recomendamos que altere sua senha imediatamente.
|
||||
</Text>
|
||||
</RavenEmailLayout>
|
||||
)
|
||||
}
|
||||
|
||||
NewLoginEmail.PreviewProps = {
|
||||
loginAt: new Date().toISOString(),
|
||||
ipAddress: "192.168.1.100",
|
||||
userAgent: "Chrome 120.0 / Windows 11",
|
||||
location: "Sao Paulo, SP, Brasil",
|
||||
} satisfies NewLoginEmailProps
|
||||
Loading…
Add table
Add a link
Reference in a new issue