courrier preview

This commit is contained in:
alma 2025-04-30 22:00:20 +02:00
parent c355585355
commit 41480e6666
3 changed files with 63 additions and 45 deletions

View File

@ -17,14 +17,13 @@ import ComposeEmailFooter from './ComposeEmailFooter';
import RichEmailEditor from './RichEmailEditor'; import RichEmailEditor from './RichEmailEditor';
import QuotedEmailContent from './QuotedEmailContent'; import QuotedEmailContent from './QuotedEmailContent';
// Import ONLY from the centralized formatter // Import from the centralized utils
import { import {
formatReplyEmail, formatReplyEmail,
formatForwardedEmail, formatForwardedEmail,
formatEmailAddresses, formatEmailAddresses
type EmailMessage, } from '@/lib/utils/email-utils';
type EmailAddress import { EmailMessage, EmailAddress } from '@/types/email';
} from '@/lib/utils/email-formatter';
/** /**
* CENTRAL EMAIL COMPOSER COMPONENT * CENTRAL EMAIL COMPOSER COMPONENT
@ -88,41 +87,31 @@ export default function ComposeEmail(props: ComposeEmailProps) {
try { try {
// Set recipients based on type // Set recipients based on type
if (type === 'reply' || type === 'reply-all') { if (type === 'reply' || type === 'reply-all') {
// Reply goes to the original sender // Get formatted data for reply
setTo(formatEmailAddresses(initialEmail.from || [])); const formatted = formatReplyEmail(initialEmail, type);
// For reply-all, include all original recipients in CC // Set the recipients
if (type === 'reply-all') { setTo(formatted.to);
const allRecipients = [ if (formatted.cc) {
...(initialEmail.to || []), setCc(formatted.cc);
...(initialEmail.cc || [])
];
setCc(formatEmailAddresses(allRecipients));
}
// Set subject with Re: prefix
const subjectBase = initialEmail.subject || '(No subject)';
const subject = subjectBase.match(/^Re:/i) ? subjectBase : `Re: ${subjectBase}`;
setSubject(subject);
// Format the reply content
const { content } = formatReplyEmail(initialEmail, type);
setEmailContent(content);
// Show CC field if there are CC recipients
if (initialEmail.cc && initialEmail.cc.length > 0) {
setShowCc(true); setShowCc(true);
} }
// Set subject
setSubject(formatted.subject);
// Set the email content (use HTML if available)
setEmailContent(formatted.content.html || formatted.content.text);
} }
else if (type === 'forward') { else if (type === 'forward') {
// Set subject with Fwd: prefix // Get formatted data for forward
const subjectBase = initialEmail.subject || '(No subject)'; const formatted = formatForwardedEmail(initialEmail);
const subject = subjectBase.match(/^(Fwd|FW|Forward):/i) ? subjectBase : `Fwd: ${subjectBase}`;
setSubject(subject);
// Format the forward content // Set subject
const { content } = formatForwardedEmail(initialEmail); setSubject(formatted.subject);
setEmailContent(content);
// Set the email content (use HTML if available)
setEmailContent(formatted.content.html || formatted.content.text);
// If the original email has attachments, we should include them // If the original email has attachments, we should include them
if (initialEmail.attachments && initialEmail.attachments.length > 0) { if (initialEmail.attachments && initialEmail.attachments.length > 0) {

View File

@ -1,7 +1,7 @@
'use client'; 'use client';
import React, { useMemo, CSSProperties } from 'react'; import React, { useMemo, CSSProperties } from 'react';
import { renderEmailContent, normalizeEmailContent } from '@/lib/utils/email-utils'; import { renderEmailContent } from '@/lib/utils/email-utils';
import { EmailContent } from '@/types/email'; import { EmailContent } from '@/types/email';
interface EmailContentDisplayProps { interface EmailContentDisplayProps {
@ -44,13 +44,42 @@ const EmailContentDisplay: React.FC<EmailContentDisplayProps> = ({
return content as EmailContent; return content as EmailContent;
} }
// Special case for simple string content // Special case for email message with content property
if (typeof content === 'string') { if (content && typeof content === 'object' && content.content &&
return normalizeEmailContent({ content }); typeof content.content === 'object' &&
'text' in content.content &&
'isHtml' in content.content) {
return content.content as EmailContent;
} }
// Otherwise normalize it // Special case for simple string content
return normalizeEmailContent(content); if (typeof content === 'string') {
return {
text: content,
isHtml: content.trim().startsWith('<'),
direction: 'ltr'
} as EmailContent;
}
// For HTML/text properties
if (content && typeof content === 'object') {
if (content.html || content.text) {
return {
html: content.html,
text: content.text || '',
isHtml: !!content.html,
direction: 'ltr'
} as EmailContent;
}
}
// Fallback
console.warn('EmailContentDisplay: Unable to properly normalize content format');
return {
text: 'Content format not supported',
isHtml: false,
direction: 'ltr'
} as EmailContent;
} catch (error) { } catch (error) {
console.error('Error normalizing content in EmailContentDisplay:', error); console.error('Error normalizing content in EmailContentDisplay:', error);
return { return {
@ -114,10 +143,10 @@ const EmailContentDisplay: React.FC<EmailContentDisplayProps> = ({
{typeof content === 'object' && ( {typeof content === 'object' && (
<p><strong>Keys:</strong> {Object.keys(content).join(', ')}</p> <p><strong>Keys:</strong> {Object.keys(content).join(', ')}</p>
)} )}
<p><strong>Normalized:</strong> {normalizedContent.isHtml ? 'HTML' : 'Text'}</p> <p><strong>Normalized:</strong> {normalizedContent?.isHtml ? 'HTML' : 'Text'}</p>
<p><strong>Direction:</strong> {normalizedContent.direction}</p> <p><strong>Direction:</strong> {normalizedContent?.direction}</p>
<p><strong>Has HTML:</strong> {!!normalizedContent.html}</p> <p><strong>Has HTML:</strong> {!!normalizedContent?.html}</p>
<p><strong>Text Length:</strong> {normalizedContent.text?.length || 0}</p> <p><strong>Text Length:</strong> {normalizedContent?.text?.length || 0}</p>
</div> </div>
)} )}

View File

@ -191,7 +191,7 @@ export default function EmailPreview({ email, loading = false, onReply }: EmailP
</div> </div>
{/* Attachments list */} {/* Attachments list */}
{hasAttachments && ( {hasAttachments && standardizedEmail.attachments && (
<div className="px-6 py-3 border-b bg-muted/20"> <div className="px-6 py-3 border-b bg-muted/20">
<h3 className="text-sm font-medium mb-2">Attachments ({standardizedEmail.attachments.length})</h3> <h3 className="text-sm font-medium mb-2">Attachments ({standardizedEmail.attachments.length})</h3>
<div className="flex flex-wrap gap-2"> <div className="flex flex-wrap gap-2">