'use client'; import { useState, useEffect, useMemo, useCallback } from 'react'; import EmailPreview from './EmailPreview'; import ComposeEmail from './ComposeEmail'; import { Loader2 } from 'lucide-react'; import { formatReplyEmail, EmailMessage as FormatterEmailMessage } from '@/lib/utils/email-formatter'; import { useEmailFetch } from '@/hooks/use-email-fetch'; import { debounce } from '@/lib/utils/debounce'; import { formatEmailContent } from '@/lib/utils/email-content'; // Add local EmailMessage interface interface EmailAddress { name: string; address: string; } interface EmailMessage { id: string; messageId?: string; subject: string; from: EmailAddress[]; to: EmailAddress[]; cc?: EmailAddress[]; bcc?: EmailAddress[]; date: Date | string; flags?: { seen: boolean; flagged: boolean; answered: boolean; deleted: boolean; draft: boolean; }; preview?: string; content?: string; html?: string; text?: string; hasAttachments?: boolean; attachments?: any[]; folder?: string; size?: number; contentFetched?: boolean; } interface EmailPanelProps { selectedEmail: { emailId: string; accountId: string; folder: string; } | null; onSendEmail: (email: any) => void; } export default function EmailPanel({ selectedEmail, onSendEmail }: EmailPanelProps) { // Use the new email fetch hook const { email, loading, error, fetchEmail } = useEmailFetch({ onEmailLoaded: (email) => { // Handle any post-load actions console.log('Email loaded:', email.id); }, onError: (error) => { console.error('Error loading email:', error); } }); // Compose mode state const [isComposing, setIsComposing] = useState(false); const [composeType, setComposeType] = useState<'new' | 'reply' | 'reply-all' | 'forward'>('new'); // Format the email content const formattedEmail = useMemo(() => { if (!email) { console.log('EmailPanel: No email provided'); return null; } console.log('EmailPanel: Raw email:', email); // If content is already an object with html/text, use it directly if (email.content && typeof email.content === 'object') { console.log('EmailPanel: Using existing content object'); return { ...email, content: { text: email.content.text || '', html: email.content.html || '' } }; } // If content is a string, convert it to object format if (typeof email.content === 'string') { console.log('EmailPanel: Converting string content to object'); return { ...email, content: { text: email.text || email.content, html: email.html || email.content } }; } // Fallback to html/text properties console.log('EmailPanel: Using html/text properties'); return { ...email, content: { text: email.text || '', html: email.html || '' } }; }, [email]); // Debounced email fetch const debouncedFetchEmail = useCallback( debounce((emailId: string, accountId: string, folder: string) => { fetchEmail(emailId, accountId, folder); }, 300), [fetchEmail] ); // Load email content when selectedEmail changes useEffect(() => { if (selectedEmail) { // CRITICAL FIX: Store the current account ID to check for changes // This helps prevent race conditions during account switching const currentAccountId = selectedEmail.accountId; console.log(`EmailPanel: Loading email ${selectedEmail.emailId} from account ${currentAccountId}`); debouncedFetchEmail(selectedEmail.emailId, selectedEmail.accountId, selectedEmail.folder); setIsComposing(false); // Return a cleanup function that can detect and handle account changes return () => { console.log(`EmailPanel: Cleaning up email fetch for account ${currentAccountId}`); }; } }, [selectedEmail, debouncedFetchEmail]); // Handle reply/forward actions const handleReply = (type: 'reply' | 'reply-all' | 'forward') => { setComposeType(type); setIsComposing(true); }; // Handle compose mode close const handleComposeClose = () => { setIsComposing(false); setComposeType('new'); }; // If no email is selected and not composing if (!selectedEmail && !isComposing) { return (

Select an email to view or

); } // Show loading state if (loading) { return (

Loading email...

); } // Show error state if (error) { return (

{error}

); } // Show compose mode or email preview return (
{isComposing ? ( ) : (
)}
); }