From 80d631eee090d163508fcaa28c362e96a3a36d85 Mon Sep 17 00:00:00 2001 From: alma Date: Sun, 27 Apr 2025 11:47:05 +0200 Subject: [PATCH] courrier refactor rebuild 2 --- components/email/ComposeEmail.tsx | 178 +++++++----------------- components/email/QuotedEmailContent.tsx | 20 ++- 2 files changed, 67 insertions(+), 131 deletions(-) diff --git a/components/email/ComposeEmail.tsx b/components/email/ComposeEmail.tsx index 1c77745c..176b8593 100644 --- a/components/email/ComposeEmail.tsx +++ b/components/email/ComposeEmail.tsx @@ -146,7 +146,7 @@ export default function ComposeEmail(props: ComposeEmailAllProps) { const [cc, setCc] = useState(''); const [bcc, setBcc] = useState(''); const [subject, setSubject] = useState(''); - const [emailContent, setEmailContent] = useState(''); + const [emailContent, setEmailContent] = useState('
'); const [showCc, setShowCc] = useState(false); const [showBcc, setShowBcc] = useState(false); const [sending, setSending] = useState(false); @@ -158,129 +158,36 @@ export default function ComposeEmail(props: ComposeEmailAllProps) { // Initialize the form when replying to or forwarding an email useEffect(() => { - if (initialEmail && type !== 'new') { + if (initialEmail && (type === 'reply' || type === 'reply-all' || type === 'forward')) { try { - // Set recipients based on type + // Handle reply and reply all if (type === 'reply' || type === 'reply-all') { - // Reply goes to the original sender - setTo(formatEmailAddresses(initialEmail.from || [])); + const result = formatReplyEmail(initialEmail, type === 'reply-all' ? 'reply-all' : 'reply'); - // For reply-all, include all original recipients in CC - if (type === 'reply-all') { - const allRecipients = [ - ...(initialEmail.to || []), - ...(initialEmail.cc || []) - ]; - // Filter out the current user if they were a recipient - // This would need some user context to properly implement - setCc(formatEmailAddresses(allRecipients)); + setTo(result.to || ''); + if (type === 'reply-all' && result.cc) { + setCc(result.cc); + setShowCc(Boolean(result.cc)); } + setSubject(result.subject || `Re: ${initialEmail.subject || ''}`); + setEmailContent('
'); + } + + // Handle forward + if (type === 'forward') { + const result = formatForwardedEmail(initialEmail); - // 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 with the quoted message included directly - const content = initialEmail.content || initialEmail.html || initialEmail.text || ''; - const sender = initialEmail.from && initialEmail.from.length > 0 - ? initialEmail.from[0].name || initialEmail.from[0].address - : 'Unknown sender'; - const date = initialEmail.date ? - (typeof initialEmail.date === 'string' ? new Date(initialEmail.date) : initialEmail.date) : - new Date(); - - // Format date for display - const formattedDate = date.toLocaleString('en-US', { - weekday: 'short', - year: 'numeric', - month: 'short', - day: 'numeric', - hour: '2-digit', - minute: '2-digit' - }); - - // Create reply content with quote - const replyContent = ` -

-

-

-

-
On ${formattedDate}, ${sender} wrote:
-
-
- ${content} -
-
- `; - - setEmailContent(replyContent); - - // Show CC field if there are CC recipients - if (initialEmail.cc && initialEmail.cc.length > 0) { - setShowCc(true); - } - } - else if (type === 'forward') { - // Set subject with Fwd: prefix - const subjectBase = initialEmail.subject || '(No subject)'; - const subject = subjectBase.match(/^(Fwd|FW|Forward):/i) ? subjectBase : `Fwd: ${subjectBase}`; - setSubject(subject); - - // Format the forward content with the original email included directly - const content = initialEmail.content || initialEmail.html || initialEmail.text || ''; - const fromString = formatEmailAddresses(initialEmail.from || []); - const toString = formatEmailAddresses(initialEmail.to || []); - const date = initialEmail.date ? - (typeof initialEmail.date === 'string' ? new Date(initialEmail.date) : initialEmail.date) : - new Date(); - - // Format date for display - const formattedDate = date.toLocaleString('en-US', { - weekday: 'short', - year: 'numeric', - month: 'short', - day: 'numeric', - hour: '2-digit', - minute: '2-digit' - }); - - // Create forwarded content - const forwardContent = ` -

-

-

-

-
-
-
-
---------- Forwarded message ---------
-
From: ${fromString}
-
Date: ${formattedDate}
-
Subject: ${initialEmail.subject || ''}
-
To: ${toString}
-
- -
-
- `; - - setEmailContent(forwardContent); - - // If the original email has attachments, we should include them - if (initialEmail.attachments && initialEmail.attachments.length > 0) { - const formattedAttachments = initialEmail.attachments.map(att => ({ - name: att.filename || 'attachment', - type: att.contentType || 'application/octet-stream', - content: att.content || '' - })); - setAttachments(formattedAttachments); - } + setSubject(result.subject || `Fwd: ${initialEmail.subject || ''}`); + setEmailContent('
'); } } catch (error) { console.error('Error initializing compose form:', error); + // Set default subject if we couldn't format it + if (initialEmail.subject) { + setSubject(type === 'forward' + ? `Fwd: ${initialEmail.subject}` + : `Re: ${initialEmail.subject}`); + } } } }, [initialEmail, type]); @@ -462,6 +369,25 @@ export default function ComposeEmail(props: ComposeEmailAllProps) { preserveFormatting={true} /> + + {/* Use QuotedEmailContent component */} + {initialEmail && (type === 'reply' || type === 'reply-all' || type === 'forward') && ( + 0 ? initialEmail.from[0].name : undefined, + email: initialEmail.from && initialEmail.from.length > 0 ? initialEmail.from[0].address : 'unknown@example.com' + }} + date={initialEmail.date || new Date()} + type={type === 'forward' ? 'forward' : 'reply'} + subject={initialEmail.subject} + recipients={initialEmail.to?.map(to => ({ + name: to.name, + email: to.address + }))} + className="mt-4" + /> + )} {/* Attachments */} @@ -813,18 +739,14 @@ function LegacyAdapter({ /> - {/* Message Body */} -
- -
- -
+ {/* Message content */} +
+
setComposeBody(e.currentTarget.innerHTML)} + />
{/* Attachments */} diff --git a/components/email/QuotedEmailContent.tsx b/components/email/QuotedEmailContent.tsx index 87f49820..9d76b42f 100644 --- a/components/email/QuotedEmailContent.tsx +++ b/components/email/QuotedEmailContent.tsx @@ -12,6 +12,8 @@ interface QuotedEmailContentProps { date: Date | string; type: 'reply' | 'forward'; className?: string; + subject?: string; + recipients?: Array<{name?: string; email: string}>; } /** @@ -22,7 +24,9 @@ const QuotedEmailContent: React.FC = ({ sender, date, type, - className = '' + className = '', + subject, + recipients }) => { // Format the date const formatDate = (date: Date | string) => { @@ -48,6 +52,16 @@ const QuotedEmailContent: React.FC = ({ const senderName = sender.name || sender.email; const formattedDate = formatDate(date); + // Format recipients for display + const formatRecipientList = (recipients?: Array<{name?: string; email: string}>) => { + if (!recipients || recipients.length === 0) return ''; + + return recipients.map(r => { + const displayName = r.name || r.email; + return `${displayName} <${r.email}>`; + }).join(', '); + }; + // Create header based on type const renderQuoteHeader = () => { if (type === 'reply') { @@ -62,8 +76,8 @@ const QuotedEmailContent: React.FC = ({
---------- Forwarded message ---------
From: {senderName} <{sender.email}>
Date: {formattedDate}
-
Subject: {/* Subject would be passed as a prop if needed */}
-
To: {/* Recipients would be passed as a prop if needed */}
+
Subject: {subject || 'No Subject'}
+
To: {formatRecipientList(recipients) || 'No Recipients'}
); }