courrier preview

This commit is contained in:
alma 2025-04-30 21:52:21 +02:00
parent b5411945b3
commit c355585355
7 changed files with 71 additions and 46 deletions

View File

@ -7,7 +7,7 @@ import { Loader2 } from 'lucide-react';
import { useEmailFetch } from '@/hooks/use-email-fetch';
import { debounce } from '@/lib/utils/debounce';
import { EmailMessage } from '@/types/email';
import { adaptLegacyEmail } from '@/lib/utils/email-adapter';
import { adaptLegacyEmail } from '@/lib/utils/email-adapters';
interface EmailPanelProps {
selectedEmail: {

View File

@ -8,7 +8,7 @@ import { Avatar, AvatarFallback } from '@/components/ui/avatar';
import { Card } from '@/components/ui/card';
import { EmailMessage, EmailAddress } from '@/types/email';
import { formatEmailAddresses, formatEmailDate } from '@/lib/utils/email-utils';
import { adaptLegacyEmail } from '@/lib/utils/email-adapter';
import { adaptLegacyEmail } from '@/lib/utils/email-adapters';
import EmailContentDisplay from './EmailContentDisplay';
interface EmailPreviewProps {
@ -26,6 +26,19 @@ export default function EmailPreview({ email, loading = false, onReply }: EmailP
if (!email) return null;
try {
// Log input email details for debugging
console.log('EmailPreview: Input email type:', typeof email);
console.log('EmailPreview: Input email properties:', Object.keys(email));
if (email.content) {
console.log('EmailPreview: Content type:', typeof email.content);
if (typeof email.content === 'object') {
console.log('EmailPreview: Content properties:', Object.keys(email.content));
} else {
console.log('EmailPreview: Content first 100 chars:', email.content.substring(0, 100));
}
}
// Check if the email is already in the standardized format
if (
email.content &&
@ -39,10 +52,38 @@ export default function EmailPreview({ email, loading = false, onReply }: EmailP
// Otherwise, adapt it
console.log('EmailPreview: Adapting legacy email format');
return adaptLegacyEmail(email);
const adapted = adaptLegacyEmail(email);
// Log the adapted email structure for debugging
console.log('EmailPreview: Adapted email:', {
id: adapted.id,
subject: adapted.subject,
from: adapted.from,
content: adapted.content ? {
isHtml: adapted.content.isHtml,
direction: adapted.content.direction,
textLength: adapted.content.text?.length,
htmlExists: !!adapted.content.html
} : 'No content'
});
return adapted;
} catch (error) {
console.error('Error adapting email:', error);
return null;
// Instead of returning null, try to create a minimal valid email to display the error
return {
id: email?.id || 'error',
subject: email?.subject || 'Error processing email',
from: email?.from || '',
to: email?.to || '',
date: email?.date || new Date().toISOString(),
flags: [],
content: {
text: `Error processing email: ${error instanceof Error ? error.message : 'Unknown error'}`,
isHtml: false,
direction: 'ltr'
}
} as EmailMessage;
}
}, [email]);
@ -83,7 +124,10 @@ export default function EmailPreview({ email, loading = false, onReply }: EmailP
// Debug output for content structure
console.log('EmailPreview: Standardized Email Content:', standardizedEmail.content);
const sender = standardizedEmail.from && standardizedEmail.from.length > 0 ? standardizedEmail.from[0] : undefined;
// Extract sender from string (name <email@example.com>)
const senderInfo = standardizedEmail.from.match(/^(?:"?([^"]*)"?\s)?<?([^\s>]+@[^\s>]+)>?$/);
const senderName = senderInfo ? senderInfo[1] || senderInfo[2] : standardizedEmail.from;
const senderEmail = senderInfo ? senderInfo[2] : standardizedEmail.from;
// Check for attachments
const hasAttachments = standardizedEmail.attachments && standardizedEmail.attachments.length > 0;
@ -97,22 +141,22 @@ export default function EmailPreview({ email, loading = false, onReply }: EmailP
<div className="flex items-start gap-3 mb-4">
<Avatar className="h-10 w-10">
<AvatarFallback>{getSenderInitials(sender?.name || '')}</AvatarFallback>
<AvatarFallback>{getSenderInitials(senderName)}</AvatarFallback>
</Avatar>
<div className="flex-1 min-w-0">
<div className="flex items-center justify-between">
<div className="font-medium">{sender?.name || sender?.address}</div>
<div className="font-medium">{senderName}</div>
<span className="text-sm text-muted-foreground">{formatEmailDate(standardizedEmail.date)}</span>
</div>
<div className="text-sm text-muted-foreground truncate mt-1">
To: {formatEmailAddresses(standardizedEmail.to)}
To: {standardizedEmail.to}
</div>
{standardizedEmail.cc && standardizedEmail.cc.length > 0 && (
{standardizedEmail.cc && (
<div className="text-sm text-muted-foreground truncate mt-1">
Cc: {formatEmailAddresses(standardizedEmail.cc)}
Cc: {standardizedEmail.cc}
</div>
)}
</div>

View File

@ -2,7 +2,7 @@
import React, { useEffect, useRef, useState } from 'react';
import 'quill/dist/quill.snow.css';
import { sanitizeHtml } from '@/lib/utils/email-formatter';
import { sanitizeHtml } from '@/lib/utils/email-utils';
interface RichEmailEditorProps {
initialContent: string;

View File

@ -1,7 +1,7 @@
import { useState, useCallback, useEffect } from 'react';
import { useSession } from 'next-auth/react';
import { useToast } from './use-toast';
import { formatEmailForReplyOrForward } from '@/lib/utils/email-formatter';
import { formatEmailForReplyOrForward } from '@/lib/utils/email-utils';
import { getCachedEmailsWithTimeout, refreshEmailsInBackground } from '@/lib/services/prefetch-service';
import { EmailAddress, EmailAttachment } from '@/lib/types';

View File

@ -14,7 +14,7 @@ import {
refreshEmailsInBackground
} from '@/lib/services/prefetch-service';
import { Email, EmailData } from './use-courrier';
import { formatEmailForReplyOrForward } from '@/lib/utils/email-formatter';
import { formatEmailForReplyOrForward } from '@/lib/utils/email-utils';
// Add a global dispatcher for compatibility with older code
// This is a temporary solution until we fully migrate to the reducer pattern

View File

@ -1,7 +1,8 @@
'use server';
import { getEmails, EmailMessage, EmailAddress } from '@/lib/services/email-service';
import { formatEmailForReplyOrForward } from '@/lib/utils/email-formatter';
import { getEmails } from '@/lib/services/email-service';
import { EmailMessage, EmailContent } from '@/types/email';
import { formatEmailForReplyOrForward } from '@/lib/utils/email-utils';
/**
* Server action to fetch emails
@ -41,36 +42,16 @@ export async function formatEmailServerSide(
const serverEmail: EmailMessage = {
id: email.id,
subject: email.subject,
from: [
{
name: email.fromName || email.from.split('@')[0],
address: email.from
}
],
to: [
{
name: '',
address: email.to
}
],
cc: email.cc ? [
{
name: '',
address: email.cc
}
] : undefined,
date: new Date(email.date),
flags: {
seen: true,
flagged: false,
answered: false,
deleted: false,
draft: false
},
content: email.content,
hasAttachments: false,
folder: 'INBOX',
contentFetched: true
from: email.from,
to: email.to,
cc: email.cc,
date: email.date,
flags: [],
content: {
text: email.content,
isHtml: email.content.includes('<'),
direction: 'ltr'
}
};
// Use the centralized formatter

View File

@ -1,5 +1,5 @@
import { EmailMessage, EmailContent, EmailAddress, LegacyEmailMessage } from '@/types/email';
import { sanitizeHtml } from './email-formatter';
import { sanitizeHtml } from './email-utils';
/**
* Adapts a legacy email format to the standardized EmailMessage format