'use client'; import DOMPurify from 'dompurify'; /** * Client-side utilities for formatting email content * This file contains functions for formatting email content in the browser * without any server dependencies. */ export interface EmailAddress { address: string; name?: string; } export interface FormattedEmail { subject: string; to?: EmailAddress[]; cc?: EmailAddress[]; bcc?: EmailAddress[]; body: string; } export interface EmailMessageForFormatting { subject?: string; from?: EmailAddress | EmailAddress[]; to?: EmailAddress | EmailAddress[]; date?: Date | string; html?: string; text?: string; cc?: EmailAddress | EmailAddress[]; bcc?: EmailAddress | EmailAddress[]; } /** * Format an email for replying or forwarding * Client-side friendly version that doesn't depend on server modules */ export function formatEmailForReply( originalEmail: EmailMessageForFormatting, type: 'reply' | 'replyAll' | 'forward' = 'reply' ): FormattedEmail { // Format the subject with Re: or Fwd: prefix const subject = formatSubject(originalEmail.subject || '', type); // Initialize recipients based on reply type let to: EmailAddress[] = []; let cc: EmailAddress[] = []; if (type === 'reply' && originalEmail.from) { to = Array.isArray(originalEmail.from) ? originalEmail.from : [originalEmail.from]; } else if (type === 'replyAll') { // To: original sender if (originalEmail.from) { to = Array.isArray(originalEmail.from) ? originalEmail.from : [originalEmail.from]; } // CC: all other recipients if (originalEmail.to) { cc = Array.isArray(originalEmail.to) ? originalEmail.to : [originalEmail.to]; } if (originalEmail.cc) { const existingCc = Array.isArray(originalEmail.cc) ? originalEmail.cc : [originalEmail.cc]; cc = [...cc, ...existingCc]; } // Remove duplicates and self from CC (would need user's email here) // This is simplified - in a real app you'd filter out the current user cc = cc.filter((value, index, self) => index === self.findIndex((t) => t.address === value.address) ); } // Create the quoted content with header const quoteHeader = createQuoteHeader(originalEmail); // Get the original content, preferring HTML over plain text let originalContent = ''; if (originalEmail.html) { // Sanitize any potentially unsafe HTML originalContent = DOMPurify.sanitize(originalEmail.html); } else if (originalEmail.text) { // Convert text to HTML by replacing newlines with br tags originalContent = originalEmail.text.replace(/\n/g, '
'); } // Combine the header with the original content const body = `

${quoteHeader}
${originalContent || 'No content available'}
`; return { subject, to, cc, body }; } /** * Format email subject with appropriate prefix */ export function formatSubject( originalSubject: string, type: 'reply' | 'replyAll' | 'forward' ): string { // Trim whitespace let subject = originalSubject.trim(); // Remove existing prefixes to avoid duplication subject = subject.replace(/^(Re|Fwd):\s*/gi, ''); // Add appropriate prefix based on action type if (type === 'forward') { return `Fwd: ${subject}`; } else { return `Re: ${subject}`; } } /** * Create a formatted quote header with sender and date information */ export function createQuoteHeader(email: EmailMessageForFormatting): string { let fromName = 'Unknown Sender'; let fromEmail = ''; // Extract sender information if (email.from) { if (Array.isArray(email.from)) { fromName = email.from[0].name || email.from[0].address; fromEmail = email.from[0].address; } else { fromName = email.from.name || email.from.address; fromEmail = email.from.address; } } // Format the date let dateFormatted = ''; if (email.date) { const date = typeof email.date === 'string' ? new Date(email.date) : email.date; // Check if the date is valid if (!isNaN(date.getTime())) { dateFormatted = date.toLocaleString('en-US', { weekday: 'short', year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }); } } // Generate recipients string let recipients = ''; if (email.to) { if (Array.isArray(email.to)) { recipients = email.to.map(r => r.name || r.address).join(', '); } else { recipients = email.to.name || email.to.address; } } // Create the header HTML return `
From: ${fromName} <${fromEmail}>
${dateFormatted ? `
Date: ${dateFormatted}
` : ''}
Subject: ${email.subject || 'No Subject'}
To: ${recipients || 'No Recipients'}
${email.cc ? `
Cc: ${Array.isArray(email.cc) ? email.cc.map(r => r.name || r.address).join(', ') : (email.cc.name || email.cc.address)}
` : ''}

`; } /** * Format an email for forwarding */ export function formatEmailForForward(email: EmailMessageForFormatting): FormattedEmail { // Format the subject with Fwd: prefix const subject = formatSubject(email.subject || '', 'forward'); // Create the forward header const forwardHeader = createQuoteHeader(email); // Get the original content, preferring HTML over plain text let originalContent = ''; if (email.html) { // Sanitize any potentially unsafe HTML originalContent = DOMPurify.sanitize(email.html); } else if (email.text) { // Convert text to HTML by replacing newlines with br tags originalContent = email.text.replace(/\n/g, '
'); } // Combine the header with the original content const body = `

---------- Forwarded message ---------
${forwardHeader}
${originalContent || '
No content available
'}
`; return { subject, body }; }