courrier preview
This commit is contained in:
parent
6c9f2d86a6
commit
c4958d7e4c
@ -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 */}
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user