diff --git a/app/courrier/page.tsx b/app/courrier/page.tsx index 5cd64c11..c2b0c806 100644 --- a/app/courrier/page.tsx +++ b/app/courrier/page.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useEffect, useState, useMemo, useCallback } from 'react'; +import { useEffect, useState, useMemo, useCallback, useRef } from 'react'; import { useRouter } from 'next/navigation'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Input } from '@/components/ui/input'; @@ -39,6 +39,7 @@ import { extractHeader } from '@/lib/infomaniak-mime-decoder'; import DOMPurify from 'isomorphic-dompurify'; +import ComposeEmail from '@/components/ComposeEmail'; interface Account { id: number; @@ -490,6 +491,7 @@ export default function CourrierPage() { const [isMarkingRead, setIsMarkingRead] = useState(false); const [isMarkingUnread, setIsMarkingUnread] = useState(false); const [isRefreshing, setIsRefreshing] = useState(false); + const composeBodyRef = useRef(null); // Debug logging for email distribution useEffect(() => { @@ -1394,6 +1396,12 @@ export default function CourrierPage() { setComposeCc(replyEmail.cc); setComposeSubject(replyEmail.subject); setComposeBody(replyEmail.body); + + // Set the content directly on the div + if (composeBodyRef.current) { + composeBodyRef.current.innerHTML = replyEmail.body; + } + setComposeBcc(''); // Show the compose form and CC field for Reply All @@ -1594,167 +1602,27 @@ export default function CourrierPage() { {/* Compose Email Modal */} - {showCompose && ( -
-
- {/* Modal Header */} -
-

- {composeSubject.startsWith('Re:') ? 'Reply' : - composeSubject.startsWith('Fwd:') ? 'Forward' : 'New Message'} -

- -
- - {/* Modal Body */} -
-
- {/* To Field */} -
- - setComposeTo(e.target.value)} - placeholder="recipient@example.com" - className="w-full mt-1 bg-white border-gray-300 text-gray-900" - /> -
- - {/* CC/BCC Toggle Buttons */} -
- - -
- - {/* CC Field */} - {showCc && ( -
- - setComposeCc(e.target.value)} - placeholder="cc@example.com" - className="w-full mt-1 bg-white border-gray-300 text-gray-900" - /> -
- )} - - {/* BCC Field */} - {showBcc && ( -
- - setComposeBcc(e.target.value)} - placeholder="bcc@example.com" - className="w-full mt-1 bg-white border-gray-300 text-gray-900" - /> -
- )} - - {/* Subject Field */} -
- - setComposeSubject(e.target.value)} - placeholder="Enter subject" - className="w-full mt-1 bg-white border-gray-300 text-gray-900" - /> -
- - {/* Message Body */} -
-
) => { - setComposeBody((e.target as HTMLDivElement).innerHTML); - }} - > - {composeBody} -
-
-
-
- - {/* Modal Footer */} -
-
- {/* File Input for Attachments */} - - -
-
- - -
-
-
-
- )} + {renderDeleteConfirmDialog()} ); diff --git a/components/ComposeEmail.tsx b/components/ComposeEmail.tsx new file mode 100644 index 00000000..eb65cb52 --- /dev/null +++ b/components/ComposeEmail.tsx @@ -0,0 +1,260 @@ +'use client'; + +import { useRef } from 'react'; +import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import { Label } from '@/components/ui/label'; +import { Paperclip, X } from 'lucide-react'; + +interface ComposeEmailProps { + showCompose: boolean; + setShowCompose: (show: boolean) => void; + composeTo: string; + setComposeTo: (to: string) => void; + composeCc: string; + setComposeCc: (cc: string) => void; + composeBcc: string; + setComposeBcc: (bcc: string) => void; + composeSubject: string; + setComposeSubject: (subject: string) => void; + composeBody: string; + setComposeBody: (body: string) => void; + showCc: boolean; + setShowCc: (show: boolean) => void; + showBcc: boolean; + setShowBcc: (show: boolean) => void; + attachments: any[]; + setAttachments: (attachments: any[]) => void; + handleSend: () => Promise; +} + +export default function ComposeEmail({ + showCompose, + setShowCompose, + composeTo, + setComposeTo, + composeCc, + setComposeCc, + composeBcc, + setComposeBcc, + composeSubject, + setComposeSubject, + composeBody, + setComposeBody, + showCc, + setShowCc, + showBcc, + setShowBcc, + attachments, + setAttachments, + handleSend +}: ComposeEmailProps) { + const composeBodyRef = useRef(null); + + const handleFileAttachment = async (e: React.ChangeEvent) => { + if (!e.target.files) return; + + const newAttachments: any[] = []; + const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB in bytes + const oversizedFiles: string[] = []; + + for (const file of e.target.files) { + if (file.size > MAX_FILE_SIZE) { + oversizedFiles.push(file.name); + continue; + } + + try { + // Read file as base64 + const base64Content = await new Promise((resolve) => { + const reader = new FileReader(); + reader.onloadend = () => { + const base64 = reader.result as string; + resolve(base64.split(',')[1]); // Remove data URL prefix + }; + reader.readAsDataURL(file); + }); + + newAttachments.push({ + name: file.name, + type: file.type, + content: base64Content, + encoding: 'base64' + }); + } catch (error) { + console.error('Error processing attachment:', error); + } + } + + if (oversizedFiles.length > 0) { + alert(`The following files exceed the 10MB size limit and were not attached:\n${oversizedFiles.join('\n')}`); + } + + if (newAttachments.length > 0) { + setAttachments([...attachments, ...newAttachments]); + } + }; + + if (!showCompose) return null; + + return ( +
+
+ {/* Modal Header */} +
+

+ {composeSubject.startsWith('Re:') ? 'Reply' : + composeSubject.startsWith('Fwd:') ? 'Forward' : 'New Message'} +

+ +
+ + {/* Modal Body */} +
+
+ {/* To Field */} +
+ + setComposeTo(e.target.value)} + placeholder="recipient@example.com" + className="w-full mt-1 bg-white border-gray-300 text-gray-900" + /> +
+ + {/* CC/BCC Toggle Buttons */} +
+ + +
+ + {/* CC Field */} + {showCc && ( +
+ + setComposeCc(e.target.value)} + placeholder="cc@example.com" + className="w-full mt-1 bg-white border-gray-300 text-gray-900" + /> +
+ )} + + {/* BCC Field */} + {showBcc && ( +
+ + setComposeBcc(e.target.value)} + placeholder="bcc@example.com" + className="w-full mt-1 bg-white border-gray-300 text-gray-900" + /> +
+ )} + + {/* Subject Field */} +
+ + setComposeSubject(e.target.value)} + placeholder="Enter subject" + className="w-full mt-1 bg-white border-gray-300 text-gray-900" + /> +
+ + {/* Message Body */} +
+
) => { + setComposeBody((e.target as HTMLDivElement).innerHTML); + }} + /> +
+
+
+ + {/* Modal Footer */} +
+
+ {/* File Input for Attachments */} + + +
+
+ + +
+
+
+
+ ); +} \ No newline at end of file