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