diff --git a/components/email/EmailPanel.tsx b/components/email/EmailPanel.tsx index cf099f6a..cc8dce6b 100644 --- a/components/email/EmailPanel.tsx +++ b/components/email/EmailPanel.tsx @@ -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: { diff --git a/components/email/EmailPreview.tsx b/components/email/EmailPreview.tsx index 27ee1eac..20d6b778 100644 --- a/components/email/EmailPreview.tsx +++ b/components/email/EmailPreview.tsx @@ -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 ) + const senderInfo = standardizedEmail.from.match(/^(?:"?([^"]*)"?\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
- {getSenderInitials(sender?.name || '')} + {getSenderInitials(senderName)}
-
{sender?.name || sender?.address}
+
{senderName}
{formatEmailDate(standardizedEmail.date)}
- To: {formatEmailAddresses(standardizedEmail.to)} + To: {standardizedEmail.to}
- {standardizedEmail.cc && standardizedEmail.cc.length > 0 && ( + {standardizedEmail.cc && (
- Cc: {formatEmailAddresses(standardizedEmail.cc)} + Cc: {standardizedEmail.cc}
)}
diff --git a/components/email/RichEmailEditor.tsx b/components/email/RichEmailEditor.tsx index f6a528fe..e661a1e2 100644 --- a/components/email/RichEmailEditor.tsx +++ b/components/email/RichEmailEditor.tsx @@ -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; diff --git a/hooks/use-courrier.ts b/hooks/use-courrier.ts index b9cdc8d8..5fd3f41d 100644 --- a/hooks/use-courrier.ts +++ b/hooks/use-courrier.ts @@ -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'; diff --git a/hooks/use-email-state.ts b/hooks/use-email-state.ts index be4e415d..fa08e11c 100644 --- a/hooks/use-email-state.ts +++ b/hooks/use-email-state.ts @@ -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 diff --git a/lib/actions/email-actions.ts b/lib/actions/email-actions.ts index 2a8fb922..5c9d1037 100644 --- a/lib/actions/email-actions.ts +++ b/lib/actions/email-actions.ts @@ -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 diff --git a/lib/utils/email-adapters.ts b/lib/utils/email-adapters.ts index 3987c7ee..1a177a78 100644 --- a/lib/utils/email-adapters.ts +++ b/lib/utils/email-adapters.ts @@ -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