courrier clean 2$

This commit is contained in:
alma 2025-04-26 21:12:18 +02:00
parent 1685946c07
commit fb0ab72675

View File

@ -6,33 +6,21 @@ import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Textarea } from '@/components/ui/textarea';
import { Label } from '@/components/ui/label';
import DOMPurify from 'isomorphic-dompurify';
import { sanitizeHtml } from '@/lib/utils/email-formatter';
// Add a CSS style block to handle the direction properly
const forceLTRStyles = `
.force-ltr {
direction: ltr !important;
text-align: left !important;
unicode-bidi: isolate !important;
writing-mode: horizontal-tb !important;
}
.force-ltr * {
direction: ltr !important;
text-align: left !important;
unicode-bidi: isolate !important;
}
[dir="rtl"] .force-ltr,
[dir="rtl"] .force-ltr * {
direction: ltr !important;
text-align: left !important;
}
// Simple CSS for email styling - leverages our centralized sanitization for text direction
const emailStyles = `
.email-content {
direction: ltr !important;
text-align: left !important;
font-family: Arial, sans-serif;
}
.email-content * {
direction: ltr !important;
text-align: left !important;
.quoted-content {
margin-top: 20px;
border-top: 1px solid #e2e2e2;
padding-top: 10px;
color: #555;
}
.user-message {
margin-bottom: 20px;
}
`;
@ -164,17 +152,19 @@ export default function ComposeEmail({
// Handle contentEditable input changes
const handleUserMessageChange = () => {
if (contentEditableRef.current) {
const content = contentEditableRef.current.innerHTML;
let content = contentEditableRef.current.innerHTML;
// Check if this is the initial state or if the user has actually typed something
if (content && content !== '<p>Write your message here...</p>') {
setHasStartedTyping(true);
}
// Sanitize the user's message using our centralized sanitizer
content = sanitizeHtml(content);
setUserMessage(content);
// Combine user message with quoted content for the full email body
const combined = `${content}${quotedContent ? `<div class="original-content">${quotedContent}</div>` : ''}`;
const combined = `${content}${quotedContent ? `<div class="quoted-content">${quotedContent}</div>` : ''}`;
setComposeBody(combined);
}
};
@ -188,10 +178,12 @@ export default function ComposeEmail({
// For rich editor, combine user message with quoted content
if (useRichEditor) {
// Wrap the content with proper direction styles
const userContent = userMessage ? `<div class="force-ltr user-message">${userMessage}</div>` : '';
const quotedWithStyles = quotedContent ? `<div class="force-ltr quoted-content" style="margin-top: 20px; border-top: 1px solid #e2e2e2; padding-top: 10px;">${quotedContent}</div>` : '';
const combinedContent = `${userContent}${quotedWithStyles}`;
// Wrap the content with appropriate styling
const userContent = userMessage ? `<div class="user-message">${userMessage}</div>` : '';
const quotedWithStyles = quotedContent ? `<div class="quoted-content">${quotedContent}</div>` : '';
// Use our centralized sanitizer to ensure proper direction
const combinedContent = sanitizeHtml(`${userContent}${quotedWithStyles}`);
setComposeBody(combinedContent);
@ -235,7 +227,7 @@ export default function ComposeEmail({
{showCompose && (
<div className="fixed inset-0 bg-gray-600/30 backdrop-blur-sm z-50 flex items-center justify-center">
{/* Add global styles for email direction */}
<style dangerouslySetInnerHTML={{ __html: forceLTRStyles }} />
<style dangerouslySetInnerHTML={{ __html: emailStyles }} />
<div className="w-full max-w-2xl h-[80vh] bg-white rounded-xl shadow-xl flex flex-col mx-4">
{/* Modal Header */}
@ -341,58 +333,39 @@ export default function ComposeEmail({
<Label htmlFor="message" className="block text-sm font-medium text-gray-700">Message</Label>
{useRichEditor ? (
<div className="mt-1 border border-gray-300 rounded-md overflow-hidden flex flex-col">
{/* User input area - clearly separated from quoted content */}
<div
ref={contentEditableRef}
contentEditable="true"
className="w-full p-3 bg-white min-h-[150px] text-gray-900 email-editor"
onInput={handleUserMessageChange}
onFocus={() => {
// Clear placeholder text when user focuses if they haven't started typing
if (!hasStartedTyping && contentEditableRef.current) {
contentEditableRef.current.innerHTML = '';
}
}}
onBlur={() => {
// Restore placeholder if user hasn't typed anything
if (!hasStartedTyping && contentEditableRef.current && !contentEditableRef.current.innerHTML.trim()) {
contentEditableRef.current.innerHTML = '<p>Write your message here...</p>';
}
}}
dangerouslySetInnerHTML={hasStartedTyping ? { __html: userMessage } : { __html: '<p>Write your message here...</p>' }}
style={{ direction: 'ltr', textAlign: 'left' }}
/>
{/* Original email content with clear visual separation */}
{quotedContent && (
<>
<div className="px-3 py-2 bg-gray-100 border-t border-gray-300 text-xs text-gray-500 font-medium">
{composeSubject.startsWith('Re:') ? 'Original message' : 'Forwarded message'}
</div>
<>
<div className="border rounded-md mb-4 overflow-hidden">
<div className="flex flex-col h-full">
<div
className="w-full bg-gray-50 border-t border-gray-200 email-content-wrapper"
style={{ direction: 'ltr' }}
>
<div
className="p-3 text-sm email-content force-ltr"
dangerouslySetInnerHTML={{ __html: quotedContent }}
contentEditable="false"
style={{
direction: 'ltr',
textAlign: 'left',
unicodeBidi: 'isolate',
writingMode: 'horizontal-tb',
color: '#555',
borderLeft: '3px solid #ccc',
paddingLeft: '10px',
margin: '0 10px',
}}
/>
</div>
</>
className="p-3 prose max-w-none flex-grow min-h-[200px]"
ref={contentEditableRef}
contentEditable="true"
onInput={handleUserMessageChange}
onFocus={() => {
// Clear 'Write your message here...' when user focuses on the editor
if (!hasStartedTyping && contentEditableRef.current) {
contentEditableRef.current.innerHTML = '';
}
}}
onBlur={() => {
// Restore 'Write your message here...' placeholder if empty
if (!hasStartedTyping && contentEditableRef.current && !contentEditableRef.current.innerHTML.trim()) {
contentEditableRef.current.innerHTML = '<p>Write your message here...</p>';
}
}}
dangerouslySetInnerHTML={hasStartedTyping ? { __html: userMessage } : { __html: '<p>Write your message here...</p>' }}
/>
</div>
</div>
{/* Original email content (quoted part) */}
{quotedContent && (
<div
className="p-3 text-sm email-content quoted-content"
dangerouslySetInnerHTML={{ __html: quotedContent }}
contentEditable="false"
/>
)}
</div>
</>
) : (
<Textarea
id="message"
@ -400,7 +373,6 @@ export default function ComposeEmail({
onChange={(e) => setComposeBody(e.target.value)}
placeholder="Write your message..."
className="w-full mt-1 min-h-[200px] bg-white border-gray-300 text-gray-900 resize-none email-editor"
style={{ direction: 'ltr', textAlign: 'left' }}
/>
)}
</div>