diff --git a/app/courrier/page.tsx b/app/courrier/page.tsx index ec1188b6..7305eb9b 100644 --- a/app/courrier/page.tsx +++ b/app/courrier/page.tsx @@ -2309,8 +2309,7 @@ export default function CourrierPage() { - {/* Compose Email Modal - Commented out due to type mismatch */} - {/* The component expected different props than what we're providing */} + {/* Compose Email Modal */} Promise; onCancel: () => void; - onBodyChange?: (body: string) => void; - initialTo?: string; - initialSubject?: string; - initialBody?: string; - initialCc?: string; - initialBcc?: string; replyTo?: Email | null; forwardFrom?: Email | null; } @@ -64,159 +60,195 @@ export default function ComposeEmail({ setAttachments, handleSend, originalEmail, - onSend, - onCancel, - onBodyChange, - initialTo, - initialSubject, - initialBody, - initialCc, - initialBcc, replyTo, - forwardFrom + forwardFrom, + onSend, + onCancel }: ComposeEmailProps) { const [sending, setSending] = useState(false); const editorRef = useRef(null); const fileInputRef = useRef(null); - if (!showCompose) return null; - - const handleInput = (e: React.FormEvent) => { - const content = e.currentTarget.innerHTML; - setComposeBody(content); - if (onBodyChange) { - onBodyChange(content); + useEffect(() => { + if (editorRef.current) { + editorRef.current.focus(); } + }, [showCompose]); + + // Initialize content when replying or forwarding + useEffect(() => { + // Handle reply or forward initialization + if (replyTo) { + // For reply/reply-all + const formattedEmail = formatEmailForReplyOrForward(replyTo as any, 'reply'); + setComposeTo(formattedEmail.to); + setComposeSubject(formattedEmail.subject); + setComposeBody(formattedEmail.body); + + // Show CC if needed for reply-all + if (formattedEmail.cc) { + setComposeCc(formattedEmail.cc); + setShowCc(true); + } + } else if (forwardFrom) { + // For forward + initializeForwardedEmail(forwardFrom); + } + }, [replyTo, forwardFrom]); + + // Initialize forwarded email content + const initializeForwardedEmail = async (email: any) => { + if (!email) return; + + // Format subject with Fwd: prefix if needed + const subjectBase = email.subject || '(No subject)'; + const subjectRegex = /^(Fwd|FW|Forward):\s*/i; + const subject = subjectRegex.test(subjectBase) + ? subjectBase + : `Fwd: ${subjectBase}`; + + setComposeSubject(subject); + + // Create header for forwarded email + const headerHtml = ` +
+
+
---------- Forwarded message ---------
+
From: ${email.fromName || email.from}
+
Date: ${new Date(email.date).toLocaleString()}
+
Subject: ${email.subject || '(No subject)'}
+
To: ${email.to}
+
+
+ `; + + // Prepare content + let contentHtml = '
No content available
'; + + if (email.content) { + // Sanitize the content + contentHtml = DOMPurify.sanitize(email.content, { + ADD_TAGS: ['style'], + FORBID_TAGS: ['script', 'iframe'] + }); + } + + // Set body with header and content + setComposeBody(` + ${headerHtml} +
+ ${contentHtml} +
+ `); }; - const handleSendEmail = async () => { - if (!composeTo.trim()) { - alert('Please enter a recipient'); - return; - } + if (!showCompose) return null; - setSending(true); - try { - // Prepare email data for sending - const emailData = { - to: composeTo, - cc: composeCc, - bcc: composeBcc, - subject: composeSubject, - body: composeBody, - attachments: attachments - }; - - // Call the provided onSend function - await onSend(emailData); - - // Reset the form - onCancel(); - } catch (error) { - console.error('Error sending email:', error); - alert('Failed to send email. Please try again.'); - } finally { - setSending(false); + const handleFileSelection = (e: React.ChangeEvent) => { + if (e.target.files && e.target.files.length > 0) { + const newAttachments = Array.from(e.target.files).map(file => ({ + name: file.name, + type: file.type, + size: file.size, + file + })); + setAttachments([...attachments, ...newAttachments]); } }; return ( -
- - - +
+ + + {replyTo ? 'Reply' : forwardFrom ? 'Forward' : 'New Message'} -
-
- To: - + To: + setComposeTo(e.target.value)} - placeholder="recipient@example.com" className="border-0 focus-visible:ring-0" + placeholder="recipient@example.com" />
{showCc && ( -
- Cc: - + Cc: + setComposeCc(e.target.value)} - placeholder="cc@example.com" className="border-0 focus-visible:ring-0" + placeholder="cc@example.com" />
)} {showBcc && ( -
- Bcc: - + Bcc: + setComposeBcc(e.target.value)} - placeholder="bcc@example.com" className="border-0 focus-visible:ring-0" + placeholder="bcc@example.com" />
)} -
- Subject: - + Subject: + setComposeSubject(e.target.value)} - placeholder="Subject" className="border-0 focus-visible:ring-0" + placeholder="Subject" />
-
+
{!showCc && ( - )} {!showBcc && ( - )}
-
setComposeBody(e.currentTarget.innerHTML)} /> {attachments.length > 0 && ( -
-

Attachments

+
+

Attachments

{attachments.map((attachment, index) => (
- {attachment.name} -
)} - -
+ +
{ - if (e.target.files?.length) { - const newAttachments = Array.from(e.target.files).map(file => ({ - name: file.name, - type: file.type, - content: URL.createObjectURL(file), - file - })); - setAttachments([...attachments, ...newAttachments]); - } - }} + className="hidden" + onChange={handleFileSelection} multiple /> -
-