'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; } // 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; attachments?: Array<{ name: string; content: string; type: string; }>; }) => Promise; } 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'); // Convert the email to the standardized format const standardizedEmail = useMemo(() => { if (!email) { console.log('EmailPanel: No email provided'); return null; } console.log('EmailPanel: Raw email:', email); try { // Use the adapter utility to convert to the standardized format return adaptLegacyEmail(email); } catch (error) { console.error('EmailPanel: Error adapting email:', error); return null; } }, [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 ? ( ) : (
)}
); }