courrier preview

This commit is contained in:
alma 2025-05-01 11:03:43 +02:00
parent 6c9f2d86a6
commit c4958d7e4c
2 changed files with 53 additions and 21 deletions

View File

@ -15,7 +15,7 @@ import {
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import RichTextEditor from '@/components/ui/rich-text-editor';
import RichEmailEditor from '@/components/email/RichEmailEditor';
import { processContentWithDirection } from '@/lib/utils/text-direction';
// Import from the centralized utils
@ -137,14 +137,6 @@ export default function ComposeEmail(props: ComposeEmailProps) {
// Focus the editor
editorRef.current.focus();
// Put cursor at the beginning
const selection = window.getSelection();
const range = document.createRange();
range.setStart(editorRef.current, 0);
range.collapse(true);
selection?.removeAllRanges();
selection?.addRange(range);
// Also make sure editor container is scrolled to top
editorRef.current.scrollTop = 0;
@ -216,6 +208,9 @@ export default function ComposeEmail(props: ComposeEmailProps) {
}
};
// Get initial direction for the content
const { direction } = processContentWithDirection(emailContent);
return (
<div className="flex flex-col h-full max-h-[80vh] bg-white border rounded-md shadow-md">
{/* Header */}
@ -348,17 +343,13 @@ export default function ComposeEmail(props: ComposeEmailProps) {
</div>
{/* Message Body */}
<RichTextEditor
ref={editorRef}
<RichEmailEditor
initialContent={emailContent}
initialDirection={processContentWithDirection(emailContent).direction}
onChange={(html) => {
// Store the content
setEmailContent(html);
// Direction will be handled automatically by the RichTextEditor based on content
}}
className="min-h-[320px] border rounded-md bg-white text-gray-800 flex-1"
placeholder="Write your message here..."
minHeight="320px"
/>
{/* Attachments */}

View File

@ -3,6 +3,7 @@
import React, { useEffect, useRef, useState } from 'react';
import 'quill/dist/quill.snow.css';
import { sanitizeHtml } from '@/lib/utils/email-utils';
import { processContentWithDirection } from '@/lib/utils/text-direction';
interface RichEmailEditorProps {
initialContent: string;
@ -58,6 +59,7 @@ const RichEmailEditor: React.FC<RichEmailEditorProps> = ({
[{ 'list': 'ordered'}, { 'list': 'bullet' }],
[{ 'indent': '-1'}, { 'indent': '+1' }],
[{ 'align': [] }],
[{ 'direction': 'rtl' }], // Add direction to toolbar
['link'],
['clean'],
];
@ -79,19 +81,20 @@ const RichEmailEditor: React.FC<RichEmailEditorProps> = ({
theme: 'snow',
});
// Process initial content to detect direction
const { direction, html: processedContent } = processContentWithDirection(initialContent);
// Set initial content properly
if (initialContent) {
try {
console.log('Setting initial content in editor', {
length: initialContent.length,
startsWithHtml: initialContent.trim().startsWith('<')
startsWithHtml: initialContent.trim().startsWith('<'),
direction
});
// Make sure content is properly sanitized before injecting it
const cleanContent = initialContent
.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '') // Remove scripts
.replace(/on\w+="[^"]*"/g, '') // Remove event handlers
.replace(/(javascript|jscript|vbscript|mocha):/gi, 'removed:'); // Remove protocol handlers
const cleanContent = sanitizeHtml(processedContent || initialContent);
// First, directly set the content
if (editorRef.current) {
@ -112,6 +115,12 @@ const RichEmailEditor: React.FC<RichEmailEditorProps> = ({
// Insert clean content
quillRef.current.clipboard.dangerouslyPasteHTML(0, content);
// Set the direction for the content
quillRef.current.format('direction', direction);
if (direction === 'rtl') {
quillRef.current.format('align', 'right');
}
// Set cursor at the beginning (before the quoted content)
quillRef.current.setSelection(0, 0);
@ -188,11 +197,20 @@ const RichEmailEditor: React.FC<RichEmailEditorProps> = ({
// Preserve cursor position if possible
const selection = quillRef.current.getSelection();
// Process content to ensure correct direction
const { direction, html: processedContent } = processContentWithDirection(initialContent);
// First clear the content
quillRef.current.root.innerHTML = '';
// Then insert the new content at position 0
quillRef.current.clipboard.dangerouslyPasteHTML(0, sanitizeHtml(initialContent));
quillRef.current.clipboard.dangerouslyPasteHTML(0, sanitizeHtml(processedContent || initialContent));
// Set the direction for the content
quillRef.current.format('direction', direction);
if (direction === 'rtl') {
quillRef.current.format('align', 'right');
}
// Force update
quillRef.current.update();
@ -235,6 +253,9 @@ const RichEmailEditor: React.FC<RichEmailEditorProps> = ({
<span className="ql-formats">
<select className="ql-align"></select>
</span>
<span className="ql-formats">
<button className="ql-direction" value="rtl"></button>
</span>
<span className="ql-formats">
<button className="ql-link"></button>
</span>
@ -268,6 +289,7 @@ const RichEmailEditor: React.FC<RichEmailEditorProps> = ({
overflow: hidden;
border-radius: 6px;
flex: 1;
border: 1px solid #e2e8f0;
}
.rich-email-editor-container {
@ -296,6 +318,17 @@ const RichEmailEditor: React.FC<RichEmailEditorProps> = ({
display: none !important;
}
/* Add RTL support styles */
:global([dir="rtl"] .ql-editor) {
text-align: right;
direction: rtl;
}
:global(.ql-editor[dir="rtl"]) {
text-align: right;
direction: rtl;
}
:global(.ql-container) {
border: none !important;
height: auto !important;
@ -339,6 +372,14 @@ const RichEmailEditor: React.FC<RichEmailEditorProps> = ({
font-size: 13px !important;
}
/* RTL blockquote styling */
:global(.ql-editor[dir="rtl"] blockquote),
:global([dir="rtl"] .ql-editor blockquote) {
border-left: none !important;
border-right: 2px solid #ddd !important;
padding: 10px 15px 10px 0 !important;
}
/* Fix table rendering */
:global(.ql-editor table) {
width: 100% !important;