diff --git a/app/globals.css b/app/globals.css index 45ac427b..e5c3dec4 100644 --- a/app/globals.css +++ b/app/globals.css @@ -97,15 +97,56 @@ /* Tables */ .email-content-display table { - width: 100%; + width: 100% !important; border-collapse: collapse; margin: 16px 0; + table-layout: fixed; + max-width: 100%; + overflow-x: auto; + display: block; } .email-content-display td, .email-content-display th { padding: 8px; border: 1px solid #e5e7eb; + word-break: break-word; + overflow-wrap: break-word; + max-width: 100%; + font-size: 13px; +} + +/* Make sure quoted content tables are properly displayed */ +.email-content-display .quoted-content table, +.email-content-display blockquote table { + font-size: 12px; + margin: 8px 0; +} + +.email-content-display .quoted-content td, +.email-content-display .quoted-content th, +.email-content-display blockquote td, +.email-content-display blockquote th { + padding: 4px; + font-size: 12px; +} + +/* Fix for tables in Quill editor */ +.ql-editor table { + width: 100% !important; + border-collapse: collapse; + table-layout: fixed; + margin: 10px 0; +} + +.ql-editor td, +.ql-editor th { + border: 1px solid #ccc; + padding: 4px 8px; + overflow-wrap: break-word; + word-break: break-word; + min-width: 30px; + font-size: 13px; } /* Buttons */ diff --git a/components/email/ComposeEmail.tsx b/components/email/ComposeEmail.tsx index 3d4757b2..5ffd684e 100644 --- a/components/email/ComposeEmail.tsx +++ b/components/email/ComposeEmail.tsx @@ -331,14 +331,14 @@ export default function ComposeEmail(props: ComposeEmailAllProps) { {/* Message Body */} -
+
@@ -617,14 +617,14 @@ function LegacyAdapter({
{/* Message Body */} -
+
diff --git a/components/email/RichEmailEditor.tsx b/components/email/RichEmailEditor.tsx index 04f8c464..0834136a 100644 --- a/components/email/RichEmailEditor.tsx +++ b/components/email/RichEmailEditor.tsx @@ -20,6 +20,7 @@ const RichEmailEditor: React.FC = ({ maxHeight = 'calc(100vh - 400px)', }) => { const editorRef = useRef(null); + const toolbarRef = useRef(null); const quillRef = useRef(null); const [isReady, setIsReady] = useState(false); @@ -27,11 +28,11 @@ const RichEmailEditor: React.FC = ({ useEffect(() => { // Import Quill dynamically (client-side only) const initializeQuill = async () => { - if (!editorRef.current) return; + if (!editorRef.current || !toolbarRef.current) return; const Quill = (await import('quill')).default; - // Define custom formats/modules as needed for email + // Define custom formats/modules with table support const emailToolbarOptions = [ ['bold', 'italic', 'underline', 'strike'], [{ 'color': [] }, { 'background': [] }], @@ -42,11 +43,16 @@ const RichEmailEditor: React.FC = ({ ['clean'], ]; - // Create new Quill instance with the DOM element + // Create new Quill instance with the DOM element and custom toolbar const editorElement = editorRef.current; quillRef.current = new Quill(editorElement, { modules: { - toolbar: emailToolbarOptions + toolbar: { + container: toolbarRef.current, + handlers: { + // Add any custom toolbar handlers here + } + }, }, placeholder: placeholder, theme: 'snow', @@ -54,7 +60,10 @@ const RichEmailEditor: React.FC = ({ // Set initial content (sanitized) if (initialContent) { - quillRef.current.clipboard.dangerouslyPasteHTML(sanitizeHtml(initialContent)); + // Properly handle table content in the sanitized HTML + const cleanContent = sanitizeHtml(initialContent); + // Use clipboard API to ensure tables and complex HTML are rendered correctly + quillRef.current.clipboard.dangerouslyPasteHTML(cleanContent); } // Add change listener @@ -63,10 +72,18 @@ const RichEmailEditor: React.FC = ({ onChange(html); }); + // Improve editor layout + const editorContainer = editorElement.closest('.ql-container'); + if (editorContainer) { + editorContainer.classList.add('email-editor-container'); + } + setIsReady(true); }; - initializeQuill(); + initializeQuill().catch(err => { + console.error('Failed to initialize Quill editor:', err); + }); // Clean up on unmount return () => { @@ -81,49 +98,130 @@ const RichEmailEditor: React.FC = ({ useEffect(() => { if (quillRef.current && isReady) { const currentContent = quillRef.current.root.innerHTML; + // Only update if content changed to avoid editor position reset if (initialContent !== currentContent) { + // Preserve cursor position if possible + const selection = quillRef.current.getSelection(); quillRef.current.clipboard.dangerouslyPasteHTML(sanitizeHtml(initialContent)); + if (selection) { + quillRef.current.setSelection(selection); + } } } }, [initialContent, isReady]); return ( -
- {/* Quill container */} -
+
+ {/* Custom toolbar container */} +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
- {/* Loading indicator */} - {!isReady && ( -
-
-
- )} + {/* Editor container with improved scrolling */} +
+
+ + {/* Loading indicator */} + {!isReady && ( +
+
+
+ )} +
{/* Custom styles for email context */}
);