138 lines
5.7 KiB
TypeScript
138 lines
5.7 KiB
TypeScript
export interface EmailLayoutOptions {
|
|
previewText: string;
|
|
title: string;
|
|
bodyContent: string;
|
|
ctaText?: string;
|
|
ctaUrl?: string;
|
|
footerNote?: string;
|
|
}
|
|
|
|
const BRAND_COLORS = {
|
|
bgPrimary: '#0a0f1e',
|
|
bgCard: '#1a2332',
|
|
textPrimary: '#f1f5f9',
|
|
textSecondary: '#94a3b8',
|
|
textMuted: '#64748b',
|
|
accentPrimary: '#3b82f6',
|
|
accentSecondary: '#06b6d4',
|
|
borderColor: '#1e293b',
|
|
};
|
|
|
|
export function buildEmailHtml(opts: EmailLayoutOptions): string {
|
|
const ctaBlock = opts.ctaText && opts.ctaUrl
|
|
? `<tr>
|
|
<td align="center" style="padding: 32px 0 0;">
|
|
<table role="presentation" cellspacing="0" cellpadding="0" border="0">
|
|
<tr>
|
|
<td style="border-radius: 8px; background: linear-gradient(135deg, ${BRAND_COLORS.accentPrimary}, ${BRAND_COLORS.accentSecondary}); padding: 14px 36px;">
|
|
<a href="${opts.ctaUrl}" style="color: #ffffff; font-size: 16px; font-weight: 600; font-family: 'Inter', Arial, Helvetica, sans-serif; text-decoration: none; display: inline-block;">${opts.ctaText}</a>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
</tr>`
|
|
: '';
|
|
|
|
const noteBlock = opts.footerNote
|
|
? `<tr><td style="padding: 24px 0 0; color: ${BRAND_COLORS.textMuted}; font-size: 14px; line-height: 1.6;">${opts.footerNote}</td></tr>`
|
|
: '';
|
|
|
|
return `<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta name="color-scheme" content="dark">
|
|
<meta name="supported-color-schemes" content="dark">
|
|
<title>${opts.title}</title>
|
|
<style>
|
|
@media only screen and (max-width: 600px) {
|
|
.email-container { width: 100% !important; }
|
|
.email-padding { padding: 0 16px !important; }
|
|
.card-padding { padding: 32px 24px !important; }
|
|
.cta-button { padding: 14px 28px !important; font-size: 15px !important; }
|
|
}
|
|
</style>
|
|
</head>
|
|
<body style="margin: 0; padding: 0; background-color: ${BRAND_COLORS.bgPrimary}; font-family: 'Inter', Arial, Helvetica, sans-serif; -webkit-font-smoothing: antialiased;">
|
|
<div style="display: none; max-height: 0; overflow: hidden; color: ${BRAND_COLORS.bgPrimary}; font-size: 1px; line-height: 1px;">${opts.previewText}</div>
|
|
|
|
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="background-color: ${BRAND_COLORS.bgPrimary};">
|
|
<tr>
|
|
<td align="center" style="padding: 40px 0;">
|
|
<table class="email-container" role="presentation" cellspacing="0" cellpadding="0" border="0" width="600" style="max-width: 600px; width: 100%;">
|
|
|
|
<!-- Header -->
|
|
<tr>
|
|
<td class="email-padding" align="center" style="padding: 0 24px 32px;">
|
|
<table role="presentation" cellspacing="0" cellpadding="0" border="0">
|
|
<tr>
|
|
<td style="font-size: 28px; font-weight: 800; background: linear-gradient(135deg, ${BRAND_COLORS.accentPrimary}, ${BRAND_COLORS.accentSecondary}); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; letter-spacing: -0.02em;">
|
|
ShieldAI
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
|
|
<!-- Main Card -->
|
|
<tr>
|
|
<td class="email-padding" style="padding: 0 24px;">
|
|
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="background-color: ${BRAND_COLORS.bgCard}; border-radius: 12px; border: 1px solid ${BRAND_COLORS.borderColor};">
|
|
<tr>
|
|
<td class="card-padding" style="padding: 48px 40px;">
|
|
|
|
<!-- Title -->
|
|
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
|
<tr>
|
|
<td style="color: ${BRAND_COLORS.textPrimary}; font-size: 24px; font-weight: 700; line-height: 1.3; padding-bottom: 16px;">
|
|
${opts.title}
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<!-- Body -->
|
|
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
|
<tr>
|
|
<td style="color: ${BRAND_COLORS.textSecondary}; font-size: 16px; line-height: 1.7;">
|
|
${opts.bodyContent}
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
${ctaBlock}
|
|
${noteBlock}
|
|
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
|
|
<!-- Footer -->
|
|
<tr>
|
|
<td align="center" style="padding: 32px 24px 0;">
|
|
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
|
<tr>
|
|
<td style="color: ${BRAND_COLORS.textMuted}; font-size: 13px; line-height: 1.5; text-align: center;">
|
|
<p style="margin: 0 0 8px;">ShieldAI — Protecting what matters most</p>
|
|
<p style="margin: 0 0 8px;">
|
|
<a href="{{unsubscribe_url}}" style="color: ${BRAND_COLORS.textMuted}; text-decoration: underline;">Unsubscribe</a>
|
|
·
|
|
<a href="https://shieldai.com" style="color: ${BRAND_COLORS.textMuted}; text-decoration: underline;">Visit Website</a>
|
|
</p>
|
|
<p style="margin: 0;">© 2026 ShieldAI. All rights reserved.</p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</body>
|
|
</html>`;
|
|
}
|