/** * Email Template Helper Functions * * Reusable functions for generating dynamic email sections */ import { ApprovalChainItem } from './types'; /** * Get rich text styles for email-safe HTML rendering * Styles common HTML elements from rich text editors */ export function getRichTextStyles(): string { return ` `; } /** * Wrap rich text content with proper styling * Use this for descriptions and comments from rich text editors */ export function wrapRichText(htmlContent: string): string { return `
${htmlContent}
`; } /** * Get inline styles for email container table * This ensures width is preserved when emails are forwarded * Email clients often strip CSS classes, so inline styles are critical */ export function getEmailContainerStyles(): string { return 'width: 95%; max-width: 1200px; min-width: 600px; margin: 0 auto; background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);'; } /** * Generate all email styles (responsive + rich text) * Desktop-first design (optimized for browser) with mobile responsive breakpoints */ export function getResponsiveStyles(): string { return ` ${getRichTextStyles()} `; } /** * Email header configuration types */ export interface EmailHeaderConfig { title: string; subtitle?: string; gradientFrom: string; gradientTo: string; logoUrl?: string; logoAlt?: string; logoWidth?: number; logoHeight?: number; productName?: string; // e.g., "RE Flow" } /** * Generate professional email header with Royal Enfield branding * Black background with logo, product name, and gold accent line * Fully responsive for mobile devices */ export function getEmailHeader(config: EmailHeaderConfig): string { const logoWidth = config.logoWidth || 220; const logoHeight = config.logoHeight || 65; const logoSection = config.logoUrl ? `
${config.logoAlt || 'Company Logo'}
` : ''; const productNameSection = config.productName ? `

${config.productName}

` : ''; const dividerLine = `
`; const subtitleSection = config.subtitle ? `

${config.subtitle}

` : ''; return ` ${logoSection} ${productNameSection} ${dividerLine}

${config.title}

${subtitleSection} `; } /** * Royal Enfield Brand Colors (Official) */ export const BrandColors = { red: '#DB281B', // Royal Enfield Red (Official) black: '#1a1a1a', // Royal Enfield Black gold: '#DEB219', // Royal Enfield Gold darkRed: '#A51F16', // Darker red for accents darkGold: '#C89F16', // Darker gold for accents white: '#ffffff' // White for text }; /** * Predefined header styles using Royal Enfield brand colors */ export const HeaderStyles = { // Primary - Red & Black (Main brand colors) primary: { gradientFrom: BrandColors.red, gradientTo: BrandColors.darkRed }, // Information/Neutral - Black & Gold accent info: { gradientFrom: BrandColors.black, gradientTo: '#2d2d2d' }, // Success - Black with gold accent success: { gradientFrom: BrandColors.black, gradientTo: '#2d2d2d' }, // Error/Critical - Red (Brand red) error: { gradientFrom: BrandColors.red, gradientTo: BrandColors.darkRed }, // Warning - Gold warning: { gradientFrom: BrandColors.gold, gradientTo: BrandColors.darkGold }, // Neutral - Black neutral: { gradientFrom: BrandColors.black, gradientTo: '#2d2d2d' }, // Info Secondary - Dark grey infoSecondary: { gradientFrom: '#424242', gradientTo: '#1a1a1a' }, // Complete - Black with gold complete: { gradientFrom: BrandColors.black, gradientTo: '#2d2d2d' } }; /** * Generate priority alert section */ export function getPrioritySection(priority: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL'): string { if (priority === 'HIGH' || priority === 'CRITICAL') { return `

High Priority

This request has been marked as ${priority} priority and requires prompt attention.

`; } return ''; } /** * Generate approval chain visualization */ export function getApprovalChain(approvers: ApprovalChainItem[]): string { return approvers.map(approver => { let icon = ''; let textColor = '#333333'; let status = ''; switch (approver.status) { case 'approved': icon = ``; status = approver.date ? `Approved on ${approver.date}` : 'Approved'; break; case 'current': icon = `${approver.levelNumber}`; textColor = '#667eea'; status = 'Pending (Your Turn)'; break; case 'pending': icon = `${approver.levelNumber}`; status = 'Pending'; break; case 'awaiting': icon = `${approver.levelNumber}`; textColor = '#999999'; status = 'Awaiting'; break; } return `
${icon} ${approver.name} - ${status}
`; }).join(''); } /** * Generate next steps section for approval confirmation */ export function getNextStepsSection(isFinalApproval: boolean, nextApproverName?: string): string { if (isFinalApproval) { return `

Next Steps

All approvals are complete! Please review the request and add any conclusion remarks before closing it.

`; } else if (nextApproverName) { return `

Next Steps

The request has been forwarded to ${nextApproverName} for the next level of approval. You'll be notified when the request progresses.

`; } return ''; } /** * Generate permissions section for participant added */ export function getPermissionsContent(role: 'Approver' | 'Spectator'): string { if (role === 'Approver') { return ` `; } else { return ` `; } } /** * Generate conclusion section for closed requests (supports rich text) */ export function getConclusionSection(conclusionRemark?: string): string { if (conclusionRemark) { return `

Conclusion Remarks:

${wrapRichText(conclusionRemark)}
`; } return ''; } /** * Generate role description for participant added */ export function getRoleDescription(role: 'Approver' | 'Spectator'): string { if (role === 'Approver') { return 'You can now review and take action on this request.'; } else { return 'You can now view this request and participate in discussions.'; } } /** * Generate action required section for workflow resumed */ export function getActionRequiredSection(isApprover: boolean): string { if (isApprover) { return `

Action Required

This request requires your immediate attention. Please review and take action to keep the workflow moving forward.

`; } return ''; } /** * Common email footer with optional branding */ export interface EmailFooterConfig { companyName: string; companyWebsite?: string; supportEmail?: string; additionalLinks?: Array<{ text: string; url: string }>; } export function getEmailFooter(config: EmailFooterConfig | string): string { // Backward compatibility - if string is passed, use it as companyName const footerConfig: EmailFooterConfig = typeof config === 'string' ? { companyName: config } : config; const supportSection = footerConfig.supportEmail ? `

Need help? Contact us at ${footerConfig.supportEmail}

` : ''; const linksSection = footerConfig.additionalLinks && footerConfig.additionalLinks.length > 0 ? `

${footerConfig.additionalLinks.map(link => `${link.text}` ).join(' | ')}

` : ''; const companyLink = footerConfig.companyWebsite ? `${footerConfig.companyName}` : footerConfig.companyName; return `

This is an automated notification. Please do not reply to this email.

${supportSection} ${linksSection}

© 2025 ${companyLink}. All rights reserved.

`; }