209 lines
5.9 KiB
TypeScript
209 lines
5.9 KiB
TypeScript
'use client';
|
|
|
|
/**
|
|
* Client-side utilities for formatting email content
|
|
* This file contains functions for formatting email content in the browser
|
|
* without any server dependencies.
|
|
*/
|
|
|
|
interface EmailAddress {
|
|
name?: string;
|
|
address: string;
|
|
}
|
|
|
|
interface FormattedEmail {
|
|
to: string;
|
|
cc?: string;
|
|
subject: string;
|
|
body: string;
|
|
}
|
|
|
|
/**
|
|
* Format an email for replying or forwarding
|
|
* Client-side friendly version that doesn't depend on server modules
|
|
*/
|
|
export function formatEmailForReply(
|
|
email: any,
|
|
type: 'reply' | 'reply-all' = 'reply'
|
|
): FormattedEmail {
|
|
// Format the subject with Re: prefix
|
|
const subject = formatSubject(email.subject || '(No subject)', type);
|
|
|
|
// Format recipients
|
|
let to = '';
|
|
let cc = '';
|
|
|
|
// Process 'to' field for reply
|
|
if (typeof email.from === 'string') {
|
|
to = email.from;
|
|
} else if (Array.isArray(email.from)) {
|
|
to = email.from.map((addr: EmailAddress) =>
|
|
addr.name && addr.name !== addr.address
|
|
? `${addr.name} <${addr.address}>`
|
|
: addr.address
|
|
).join(', ');
|
|
} else if (email.fromName || email.from) {
|
|
// Handle cases where from is an object with name and address
|
|
if (email.fromName && email.from && email.fromName !== email.from) {
|
|
to = `${email.fromName} <${email.from}>`;
|
|
} else {
|
|
to = email.from;
|
|
}
|
|
}
|
|
|
|
// For reply-all, include other recipients in cc
|
|
if (type === 'reply-all' && email.to) {
|
|
if (typeof email.to === 'string') {
|
|
cc = email.to;
|
|
} else if (Array.isArray(email.to)) {
|
|
cc = email.to.map((addr: EmailAddress) =>
|
|
addr.name && addr.name !== addr.address
|
|
? `${addr.name} <${addr.address}>`
|
|
: addr.address
|
|
).join(', ');
|
|
}
|
|
|
|
// Include cc recipients from original email too if available
|
|
if (email.cc) {
|
|
const ccList = typeof email.cc === 'string'
|
|
? email.cc
|
|
: Array.isArray(email.cc)
|
|
? email.cc.map((addr: EmailAddress) => addr.address).join(', ')
|
|
: '';
|
|
|
|
if (ccList) {
|
|
cc = cc ? `${cc}, ${ccList}` : ccList;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Create quote header
|
|
const quoteHeader = createQuoteHeader(email);
|
|
|
|
// Format body with quote
|
|
let body = `<br/><br/>${quoteHeader}<blockquote style="margin: 0 0 0 0.8ex; border-left: 1px solid #ccc; padding-left: 1ex;">`;
|
|
|
|
// Add quoted content
|
|
if (email.content) {
|
|
body += email.content;
|
|
} else if (email.html) {
|
|
body += email.html;
|
|
} else if (email.text) {
|
|
body += `<pre>${email.text}</pre>`;
|
|
} else if (email.body) {
|
|
body += email.body;
|
|
} else {
|
|
body += '<div style="color: #666; font-style: italic;">No content available</div>';
|
|
}
|
|
|
|
body += '</blockquote>';
|
|
|
|
return {
|
|
to,
|
|
cc,
|
|
subject,
|
|
body
|
|
};
|
|
}
|
|
|
|
function formatSubject(subject: string, type: 'reply' | 'reply-all' | 'forward'): string {
|
|
// Clean up existing prefixes first
|
|
let cleanSubject = subject.replace(/^(Re|Fwd|FW|Forward):\s*/gi, '');
|
|
cleanSubject = cleanSubject.trim() || '(No subject)';
|
|
|
|
// Add appropriate prefix
|
|
if (type === 'forward') {
|
|
return `Fwd: ${cleanSubject}`;
|
|
} else {
|
|
// For reply and reply-all
|
|
return `Re: ${cleanSubject}`;
|
|
}
|
|
}
|
|
|
|
function createQuoteHeader(email: any): string {
|
|
let from = 'Unknown Sender';
|
|
let date = email.date ? new Date(email.date).toLocaleString() : 'Unknown Date';
|
|
let subject = email.subject || '(No subject)';
|
|
let to = '';
|
|
|
|
// Extract from
|
|
if (typeof email.from === 'string') {
|
|
from = email.from;
|
|
} else if (Array.isArray(email.from)) {
|
|
from = email.from.map((addr: EmailAddress) =>
|
|
addr.name ? `${addr.name} <${addr.address}>` : addr.address
|
|
).join(', ');
|
|
} else if (email.fromName || email.from) {
|
|
from = email.fromName && email.fromName !== email.from
|
|
? `${email.fromName} <${email.from}>`
|
|
: email.from;
|
|
}
|
|
|
|
// Extract to
|
|
if (typeof email.to === 'string') {
|
|
to = email.to;
|
|
} else if (Array.isArray(email.to)) {
|
|
to = email.to.map((addr: EmailAddress) =>
|
|
addr.name ? `${addr.name} <${addr.address}>` : addr.address
|
|
).join(', ');
|
|
}
|
|
|
|
return `
|
|
<div style="color: #666; margin-bottom: 10px; font-family: Arial, sans-serif;">
|
|
<div>On ${date}, ${from} wrote:</div>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
/**
|
|
* Format an email for forwarding
|
|
*/
|
|
export function formatEmailForForward(email: any): {
|
|
subject: string;
|
|
headerHtml: string;
|
|
} {
|
|
// Format subject with Fwd: prefix
|
|
const subject = formatSubject(email.subject || '(No subject)', 'forward');
|
|
|
|
// Get sender information
|
|
let fromString = 'Unknown Sender';
|
|
if (typeof email.from === 'string') {
|
|
fromString = email.from;
|
|
} else if (Array.isArray(email.from)) {
|
|
fromString = email.from.map((addr: EmailAddress) =>
|
|
addr.name ? `${addr.name} <${addr.address}>` : addr.address
|
|
).join(', ');
|
|
} else if (email.fromName && email.from) {
|
|
fromString = email.fromName !== email.from
|
|
? `${email.fromName} <${email.from}>`
|
|
: email.from;
|
|
}
|
|
|
|
// Get recipient information
|
|
let toString = '';
|
|
if (typeof email.to === 'string') {
|
|
toString = email.to;
|
|
} else if (Array.isArray(email.to)) {
|
|
toString = email.to.map((addr: EmailAddress) =>
|
|
addr.name ? `${addr.name} <${addr.address}>` : addr.address
|
|
).join(', ');
|
|
}
|
|
|
|
// Create header for forwarded email
|
|
const headerHtml = `
|
|
<div style="border-top: 1px solid #e1e1e1; margin-top: 20px; padding-top: 15px; font-family: Arial, sans-serif;">
|
|
<div style="margin-bottom: 15px;">
|
|
<div style="font-weight: normal; margin-bottom: 10px;">---------- Forwarded message ---------</div>
|
|
<div><b>From:</b> ${fromString}</div>
|
|
<div><b>Date:</b> ${email.date ? new Date(email.date).toLocaleString() : 'Unknown Date'}</div>
|
|
<div><b>Subject:</b> ${email.subject || '(No subject)'}</div>
|
|
<div><b>To:</b> ${toString || 'Unknown Recipient'}</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
return {
|
|
subject,
|
|
headerHtml
|
|
};
|
|
}
|