From 5138649fcd0f748b07fe2babacfb8c62f50f3f6a Mon Sep 17 00:00:00 2001 From: alma Date: Wed, 30 Apr 2025 14:18:02 +0200 Subject: [PATCH] courrier multi account restore compose --- app/courrier/page.tsx | 98 +++++++++++++++++++++++++++++++++------- hooks/use-email-state.ts | 22 +++++++++ 2 files changed, 103 insertions(+), 17 deletions(-) diff --git a/app/courrier/page.tsx b/app/courrier/page.tsx index c259092e..a8f06f67 100644 --- a/app/courrier/page.tsx +++ b/app/courrier/page.tsx @@ -307,6 +307,8 @@ export default function CourrierPage() { folders: validFolders }); }); + + console.log('[DEBUG] Constructed accounts:', updatedAccounts); } else { // Fallback to single account if allAccounts is not available const folderList = (data.mailboxes && data.mailboxes.length > 0) ? @@ -319,11 +321,20 @@ export default function CourrierPage() { color: colorPalette[0], folders: folderList }); + + console.log('[DEBUG] Constructed single fallback account:', updatedAccounts[0]); } // Update accounts state using our reducer actions // First, set the accounts - setEmails([]); // Clear any existing emails first + setEmails([]); // Clear any existing emails first + + // Log current state for debugging + console.log('[DEBUG] Current state before setting accounts:', { + accounts: accounts?.length || 0, + selectedAccount: selectedAccount?.id || 'none', + currentFolder: currentFolder || 'none' + }); // Use our reducer actions instead of setState setAccounts(updatedAccounts); @@ -331,10 +342,14 @@ export default function CourrierPage() { // Auto-select the first account if available if (updatedAccounts.length > 0) { const firstAccount = updatedAccounts[0]; - console.log('Auto-selecting first account:', firstAccount); + console.log('[DEBUG] Auto-selecting first account:', firstAccount); // Use our new selectAccount function which handles state atomically - selectAccount(firstAccount); + // Add a slight delay to ensure the accounts are set first + setTimeout(() => { + console.log('[DEBUG] Now calling selectAccount'); + selectAccount(firstAccount); + }, 100); } } else { // User is authenticated but doesn't have email credentials @@ -398,10 +413,37 @@ export default function CourrierPage() { // Handle account selection - replace with reducer-based function const handleAccountSelect = (account: Account) => { + // Add extensive debugging to track the process + console.log('[DEBUG] handleAccountSelect called with account:', { + id: account.id, + email: account.email, + folders: account.folders?.length + }); + + // Skip if no valid account provided + if (!account || !account.id) { + console.error('Invalid account passed to handleAccountSelect'); + return; + } + + // Skip if this is already the selected account + if (selectedAccount?.id === account.id) { + console.log('[DEBUG] Account already selected, skipping'); + return; + } + // Simply call our new selectAccount function which handles everything atomically setLoading(true); + + // Clear all existing selections first + console.log('[DEBUG] Now selecting account through reducer action'); selectAccount(account); - setTimeout(() => setLoading(false), 300); // Give UI time to update + + // Log what happened + console.log('[DEBUG] Account selection completed'); + + // Give some time for the UI to update + setTimeout(() => setLoading(false), 300); }; // Email actions @@ -489,17 +531,37 @@ export default function CourrierPage() { // Update the accounts from state - fix type issues const setAccounts = (newAccounts: Account[]) => { - // Dispatch action directly through our hook's returned state values - const action = { type: 'SET_ACCOUNTS', payload: newAccounts }; - // We don't have direct access to dispatch, so we need a workaround - // This is a temporary solution until we fully migrate to the reducer pattern - try { - // @ts-ignore - We're accessing internal functionality for transition purposes - // This will be cleaned up in a future refactor when we fully migrate - window.dispatchEmailAction?.(action); - } catch (err) { - console.error('Failed to update accounts through reducer:', err); - // Fallback approach if needed + console.log('[DEBUG] Setting accounts:', newAccounts); + + // In the previous implementation, we'd dispatch an action + // But since we don't have direct access to the reducer's dispatch function, + // we need to use the exported actions from our hook + + // This dispatch function should be made available by our hook + const windowWithDispatch = window as any; + if (typeof windowWithDispatch.dispatchEmailAction === 'function') { + // Use the global dispatch function if available + windowWithDispatch.dispatchEmailAction({ + type: 'SET_ACCOUNTS', + payload: newAccounts + }); + } else { + console.error('Cannot dispatch SET_ACCOUNTS action - no dispatch function available'); + + // Fallback: Try to directly modify the accounts array if we have access + // This isn't ideal but ensures backward compatibility during transition + console.log('[DEBUG] Using fallback method to update accounts'); + + // Our reducer should expose this action + const useEmailStateDispatch = windowWithDispatch.__emailStateDispatch; + if (typeof useEmailStateDispatch === 'function') { + useEmailStateDispatch({ + type: 'SET_ACCOUNTS', + payload: newAccounts + }); + } else { + console.error('No fallback dispatch method available either'); + } } }; @@ -517,7 +579,7 @@ export default function CourrierPage() { selectedAccount={selectedAccount} selectedFolders={selectedFolders} currentFolder={currentFolder} - loading={loading} + loading={loading || isLoading} unreadCount={unreadCountMap} showAddAccountForm={showAddAccountForm} onFolderChange={handleMailboxChange} @@ -527,11 +589,13 @@ export default function CourrierPage() { loadEmails().finally(() => setLoading(false)); }} onComposeNew={handleComposeNew} - onAccountSelect={handleAccountSelect as any} + onAccountSelect={handleAccountSelect} onShowAddAccountForm={setShowAddAccountForm} onAddAccount={async (formData) => { setLoading(true); + console.log('[DEBUG] Add account form submission:', formData); + // Pull values from form with proper type handling const formValues = { email: formData.get('email')?.toString() || '', diff --git a/hooks/use-email-state.ts b/hooks/use-email-state.ts index 7a8ae259..8c8d7f46 100644 --- a/hooks/use-email-state.ts +++ b/hooks/use-email-state.ts @@ -16,11 +16,33 @@ import { import { Email, EmailData } from './use-courrier'; import { formatEmailForReplyOrForward } from '@/lib/utils/email-formatter'; +// Add a global dispatcher for compatibility with older code +// This is a temporary solution until we fully migrate to the reducer pattern +declare global { + interface Window { + dispatchEmailAction?: (action: EmailAction) => void; + __emailStateDispatch?: (action: EmailAction) => void; + } +} + export const useEmailState = () => { const [state, dispatch] = useReducer(emailReducer, initialState); const { data: session } = useSession(); const { toast } = useToast(); + // Expose dispatch function to window for external components + useEffect(() => { + // Make dispatch available globally for older code + window.dispatchEmailAction = dispatch; + window.__emailStateDispatch = dispatch; + + // Clean up on unmount + return () => { + window.dispatchEmailAction = undefined; + window.__emailStateDispatch = undefined; + }; + }, [dispatch]); + // Helper function to log operations const logEmailOp = useCallback((operation: string, details: string, data?: any) => { const timestamp = new Date().toISOString().split('T')[1].substring(0, 12);