'use client'; import { useState, useEffect, useMemo, useCallback } from 'react'; import EmailPreview from './EmailPreview'; import ComposeEmailAdapter from './ComposeEmailAdapter'; 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-adapters'; interface EmailPanelProps { selectedEmail: { emailId: string; accountId: string; folder: string; } | null; onSendEmail: (email: any) => Promise; accounts?: Array<{ id: string; email: string; display_name?: string; }>; } // Type for the legacy ComposeEmail component props interface ComposeEmailProps { initialEmail?: any; type?: 'new' | 'reply' | 'reply-all' | 'forward'; onClose: () => void; onSend: (emailData: { to: string; cc?: string; bcc?: string; subject: string; body: string; fromAccount?: string; attachments?: Array<{ name: string; content: string; type: string; }>; }) => Promise; } export default function EmailPanel({ selectedEmail, onSendEmail, accounts = [] }: 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'); // Convert the email to the standardized format const standardizedEmail = useMemo(() => { if (!email) { return null; } // The useEmailFetch hook now provides fully formatted email return email; }, [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'); }; // Wrap the onSendEmail function to ensure it returns a Promise const handleSendEmail = async (emailData: any) => { try { return await onSendEmail(emailData); } catch (error) { console.error('Error sending email:', error); throw error; // Re-throw to let ComposeEmail handle it } }; // 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 ? ( ) : (
)}
); } // Helper function to normalize address to string format function normalizeAddress(address: any): string { if (!address) return ''; // If already a string, return as is if (typeof address === 'string') { return address; } // If array of EmailAddress objects if (Array.isArray(address)) { return address.map(addr => { if (typeof addr === 'object' && addr !== null) { // Handle EmailAddress object if ('name' in addr && 'address' in addr) { return addr.name && addr.name !== addr.address ? `${addr.name} <${addr.address}>` : addr.address; } } return String(addr || ''); }).join(', '); } // Handle single EmailAddress object if (typeof address === 'object' && address !== null) { if ('name' in address && 'address' in address) { return address.name && address.name !== address.address ? `${address.name} <${address.address}>` : address.address; } } // Fallback return String(address); }