Neah/components/email/EmailContentDisplay.tsx
2025-04-30 22:00:20 +02:00

189 lines
5.6 KiB
TypeScript

'use client';
import React, { useMemo, CSSProperties } from 'react';
import { renderEmailContent } from '@/lib/utils/email-utils';
import { EmailContent } from '@/types/email';
interface EmailContentDisplayProps {
content: EmailContent | any;
className?: string;
showQuotedText?: boolean;
type?: 'html' | 'text' | 'auto';
debug?: boolean;
}
/**
* Unified component for displaying email content in a consistent way
* This handles both HTML and plain text content with proper styling
*/
const EmailContentDisplay: React.FC<EmailContentDisplayProps> = ({
content,
className = '',
showQuotedText = true,
type = 'auto',
debug = false
}) => {
// Normalize the content to our standard format if needed
const normalizedContent = useMemo(() => {
try {
// Handle different input types
if (!content) {
return {
html: undefined,
text: 'No content available',
isHtml: false,
direction: 'ltr'
} as EmailContent;
}
// If content is already in our EmailContent format
if (content &&
typeof content === 'object' &&
'text' in content &&
'isHtml' in content) {
return content as EmailContent;
}
// Special case for email message with content property
if (content && typeof content === 'object' && content.content &&
typeof content.content === 'object' &&
'text' in content.content &&
'isHtml' in content.content) {
return content.content as EmailContent;
}
// Special case for simple string content
if (typeof content === 'string') {
return {
text: content,
isHtml: content.trim().startsWith('<'),
direction: 'ltr'
} as EmailContent;
}
// For HTML/text properties
if (content && typeof content === 'object') {
if (content.html || content.text) {
return {
html: content.html,
text: content.text || '',
isHtml: !!content.html,
direction: 'ltr'
} as EmailContent;
}
}
// Fallback
console.warn('EmailContentDisplay: Unable to properly normalize content format');
return {
text: 'Content format not supported',
isHtml: false,
direction: 'ltr'
} as EmailContent;
} catch (error) {
console.error('Error normalizing content in EmailContentDisplay:', error);
return {
html: undefined,
text: `Error processing email content: ${error instanceof Error ? error.message : 'Unknown error'}`,
isHtml: false,
direction: 'ltr'
} as EmailContent;
}
}, [content]);
// Render the normalized content
const htmlContent = useMemo(() => {
if (!normalizedContent) return '';
try {
// Override content type if specified
let contentToRender: EmailContent = { ...normalizedContent };
if (type === 'html' && !contentToRender.isHtml) {
// Force HTML rendering for text content
contentToRender = {
...contentToRender,
isHtml: true,
html: `<p>${contentToRender.text.replace(/\n/g, '<br>')}</p>`
};
} else if (type === 'text' && contentToRender.isHtml) {
// Force text rendering
contentToRender = {
...contentToRender,
isHtml: false
};
}
return renderEmailContent(contentToRender);
} catch (error) {
console.error('Error rendering content in EmailContentDisplay:', error);
return `<div class="error-message p-4 text-red-500">Error rendering email content: ${error instanceof Error ? error.message : 'Unknown error'}</div>`;
}
}, [normalizedContent, type]);
// Apply quoted text styling if needed
const containerStyle: CSSProperties = showQuotedText
? {}
: { maxHeight: '400px', overflowY: 'auto' };
return (
<div
className={`email-content-display ${className} ${showQuotedText ? 'quoted-text' : ''}`}
style={containerStyle}
>
<div
className="email-content-inner"
dangerouslySetInnerHTML={{ __html: htmlContent }}
/>
{/* Debug output if enabled */}
{debug && (
<div className="content-debug mt-4 p-2 text-xs bg-gray-100 border rounded">
<p><strong>Content Type:</strong> {typeof content}</p>
{typeof content === 'object' && (
<p><strong>Keys:</strong> {Object.keys(content).join(', ')}</p>
)}
<p><strong>Normalized:</strong> {normalizedContent?.isHtml ? 'HTML' : 'Text'}</p>
<p><strong>Direction:</strong> {normalizedContent?.direction}</p>
<p><strong>Has HTML:</strong> {!!normalizedContent?.html}</p>
<p><strong>Text Length:</strong> {normalizedContent?.text?.length || 0}</p>
</div>
)}
<style jsx>{`
.email-content-display {
width: 100%;
}
.email-content-display.quoted-text {
opacity: 0.85;
font-size: 0.95em;
}
.email-content-inner :global(img) {
max-width: 100%;
height: auto;
}
.email-content-inner :global(table) {
max-width: 100%;
border-collapse: collapse;
margin-bottom: 1rem;
}
.email-content-inner :global(td),
.email-content-inner :global(th) {
padding: 0.5rem;
border: 1px solid #ddd;
}
.content-debug {
font-family: monospace;
color: #666;
}
`}</style>
</div>
);
};
export default EmailContentDisplay;