659 lines
23 KiB
TypeScript
659 lines
23 KiB
TypeScript
'use client';
|
|
|
|
import React, { useState, useEffect } from 'react';
|
|
import { useRouter } from 'next/navigation';
|
|
import {
|
|
Mail, Loader2, AlertCircle,
|
|
MoreVertical, Settings, Plus as PlusIcon, Trash2, Edit,
|
|
Inbox, Send, Star, Trash, Plus, ChevronLeft, ChevronRight,
|
|
Search, ChevronDown, Folder, ChevronUp, Reply, Forward, ReplyAll,
|
|
MoreHorizontal, FolderOpen, X, Paperclip, MessageSquare, Copy, EyeOff,
|
|
AlertOctagon, Archive, RefreshCw
|
|
} from 'lucide-react';
|
|
import { Dialog, DialogContent } from '@/components/ui/dialog';
|
|
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
|
|
import {
|
|
AlertDialog,
|
|
AlertDialogAction,
|
|
AlertDialogCancel,
|
|
AlertDialogContent,
|
|
AlertDialogDescription,
|
|
AlertDialogFooter,
|
|
AlertDialogHeader,
|
|
AlertDialogTitle,
|
|
} from "@/components/ui/alert-dialog";
|
|
import { ScrollArea } from '@/components/ui/scroll-area';
|
|
import { Avatar, AvatarFallback } from '@/components/ui/avatar';
|
|
import { Button } from '@/components/ui/button';
|
|
|
|
// Import components
|
|
import EmailSidebar from '@/components/email/EmailSidebar';
|
|
import EmailList from '@/components/email/EmailList';
|
|
import EmailContent from '@/components/email/EmailContent';
|
|
import EmailHeader from '@/components/email/EmailHeader';
|
|
import ComposeEmail from '@/components/email/ComposeEmail';
|
|
|
|
// Import the custom hook
|
|
import { useCourrier, EmailData } from '@/hooks/use-courrier';
|
|
|
|
// Simplified version for this component
|
|
function SimplifiedLoadingFix() {
|
|
// In production, don't render anything
|
|
if (process.env.NODE_ENV === 'production') {
|
|
return null;
|
|
}
|
|
|
|
// Simple debugging component
|
|
return (
|
|
<div className="fixed bottom-4 right-4 z-50 p-2 bg-white/80 shadow rounded-lg text-xs">
|
|
Debug: Email app loaded
|
|
</div>
|
|
);
|
|
}
|
|
|
|
interface Account {
|
|
id: number;
|
|
name: string;
|
|
email: string;
|
|
color: string;
|
|
folders?: string[];
|
|
}
|
|
|
|
export default function CourrierPage() {
|
|
const router = useRouter();
|
|
|
|
// Get all the email functionality from the hook
|
|
const {
|
|
emails,
|
|
selectedEmail,
|
|
selectedEmailIds,
|
|
currentFolder,
|
|
mailboxes,
|
|
isLoading,
|
|
isSending,
|
|
error,
|
|
searchQuery,
|
|
page,
|
|
totalPages,
|
|
loadEmails,
|
|
handleEmailSelect,
|
|
markEmailAsRead,
|
|
toggleStarred,
|
|
sendEmail,
|
|
deleteEmails,
|
|
toggleEmailSelection,
|
|
toggleSelectAll,
|
|
changeFolder,
|
|
searchEmails,
|
|
formatEmailForAction,
|
|
setPage,
|
|
} = useCourrier();
|
|
|
|
// Local state
|
|
const [showComposeModal, setShowComposeModal] = useState(false);
|
|
const [composeData, setComposeData] = useState<EmailData | null>(null);
|
|
const [composeType, setComposeType] = useState<'new' | 'reply' | 'reply-all' | 'forward'>('new');
|
|
const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
|
|
const [showLoginNeeded, setShowLoginNeeded] = useState(false);
|
|
|
|
// States to match the provided implementation
|
|
const [sidebarOpen, setSidebarOpen] = useState(true);
|
|
const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false);
|
|
const [isReplying, setIsReplying] = useState(false);
|
|
const [isForwarding, setIsForwarding] = useState(false);
|
|
const [accountsDropdownOpen, setAccountsDropdownOpen] = useState(false);
|
|
const [showCompose, setShowCompose] = useState(false);
|
|
const [composeTo, setComposeTo] = useState('');
|
|
const [composeCc, setComposeCc] = useState('');
|
|
const [composeBcc, setComposeBcc] = useState('');
|
|
const [composeSubject, setComposeSubject] = useState('');
|
|
const [composeBody, setComposeBody] = useState('');
|
|
const [showCc, setShowCc] = useState(false);
|
|
const [showBcc, setShowBcc] = useState(false);
|
|
const [attachments, setAttachments] = useState<any[]>([]);
|
|
|
|
// Mock accounts
|
|
const [accounts, setAccounts] = useState<Account[]>([
|
|
{ id: 0, name: 'All', email: '', color: 'bg-gray-500' },
|
|
{ id: 1, name: 'Mail', email: 'user@example.com', color: 'bg-blue-500' }
|
|
]);
|
|
const [selectedAccount, setSelectedAccount] = useState<Account | null>(null);
|
|
|
|
// Check for more emails
|
|
const hasMoreEmails = page < totalPages;
|
|
|
|
// Handle loading more emails on scroll
|
|
const handleLoadMore = () => {
|
|
if (hasMoreEmails && !isLoading) {
|
|
setPage(page + 1);
|
|
}
|
|
};
|
|
|
|
// Handle bulk actions
|
|
const handleBulkAction = async (action: 'delete' | 'mark-read' | 'mark-unread' | 'archive') => {
|
|
if (selectedEmailIds.length === 0) return;
|
|
|
|
switch (action) {
|
|
case 'delete':
|
|
setShowDeleteConfirm(true);
|
|
break;
|
|
|
|
case 'mark-read':
|
|
// Mark all selected emails as read
|
|
for (const emailId of selectedEmailIds) {
|
|
await markEmailAsRead(emailId, true);
|
|
}
|
|
break;
|
|
|
|
case 'mark-unread':
|
|
// Mark all selected emails as unread
|
|
for (const emailId of selectedEmailIds) {
|
|
await markEmailAsRead(emailId, false);
|
|
}
|
|
break;
|
|
|
|
case 'archive':
|
|
// Archive functionality would be implemented here
|
|
break;
|
|
}
|
|
};
|
|
|
|
// Handle email reply or forward
|
|
const handleReplyOrForward = (type: 'reply' | 'reply-all' | 'forward') => {
|
|
if (!selectedEmail) return;
|
|
|
|
const formattedEmail = formatEmailForAction(selectedEmail, type);
|
|
if (!formattedEmail) return;
|
|
|
|
setComposeTo(formattedEmail.to || '');
|
|
setComposeCc(formattedEmail.cc || '');
|
|
setComposeSubject(formattedEmail.subject || '');
|
|
setComposeBody(formattedEmail.body || '');
|
|
|
|
if (type === 'forward') {
|
|
setIsForwarding(true);
|
|
} else {
|
|
setIsReplying(true);
|
|
}
|
|
|
|
setShowCompose(true);
|
|
setShowCc(type === 'reply-all');
|
|
};
|
|
|
|
// Handle compose new email
|
|
const handleComposeNew = () => {
|
|
setComposeTo('');
|
|
setComposeCc('');
|
|
setComposeBcc('');
|
|
setComposeSubject('');
|
|
setComposeBody('');
|
|
setShowCc(false);
|
|
setShowBcc(false);
|
|
setIsReplying(false);
|
|
setIsForwarding(false);
|
|
setShowCompose(true);
|
|
};
|
|
|
|
// Handle sending email
|
|
const handleSend = async () => {
|
|
if (!composeTo) {
|
|
alert('Please specify at least one recipient');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
await sendEmail({
|
|
to: composeTo,
|
|
cc: composeCc,
|
|
bcc: composeBcc,
|
|
subject: composeSubject,
|
|
body: composeBody,
|
|
});
|
|
|
|
// Clear compose form and close modal
|
|
setComposeTo('');
|
|
setComposeCc('');
|
|
setComposeBcc('');
|
|
setComposeSubject('');
|
|
setComposeBody('');
|
|
setAttachments([]);
|
|
setShowCompose(false);
|
|
setIsReplying(false);
|
|
setIsForwarding(false);
|
|
|
|
// Refresh the Sent folder if we're currently viewing it
|
|
if (currentFolder.toLowerCase() === 'sent') {
|
|
loadEmails();
|
|
}
|
|
} catch (error) {
|
|
console.error('Error sending email:', error);
|
|
alert('Failed to send email. Please try again.');
|
|
}
|
|
};
|
|
|
|
// Handle delete confirmation
|
|
const handleDeleteConfirm = async () => {
|
|
await deleteEmails(selectedEmailIds);
|
|
setShowDeleteConfirm(false);
|
|
};
|
|
|
|
// Check login on mount
|
|
useEffect(() => {
|
|
// Check if the user is logged in after a short delay
|
|
const timer = setTimeout(() => {
|
|
if (error?.includes('Not authenticated') || error?.includes('No email credentials found')) {
|
|
setShowLoginNeeded(true);
|
|
}
|
|
}, 2000);
|
|
|
|
return () => clearTimeout(timer);
|
|
}, [error]);
|
|
|
|
// Go to login page
|
|
const handleGoToLogin = () => {
|
|
router.push('/courrier/login');
|
|
};
|
|
|
|
// Handle mailbox change
|
|
const handleMailboxChange = (newMailbox: string) => {
|
|
changeFolder(newMailbox);
|
|
};
|
|
|
|
// Format date for display
|
|
const formatDate = (dateString: string) => {
|
|
const date = new Date(dateString);
|
|
const now = new Date();
|
|
|
|
if (date.toDateString() === now.toDateString()) {
|
|
return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
|
} else {
|
|
return date.toLocaleDateString([], { month: 'short', day: 'numeric' });
|
|
}
|
|
};
|
|
|
|
// Render sidebar navigation
|
|
const renderSidebarNav = () => (
|
|
<nav className="p-3">
|
|
<ul className="space-y-0.5 px-2">
|
|
{mailboxes.map((folder) => (
|
|
<li key={folder}>
|
|
<Button
|
|
variant={currentFolder === folder ? 'secondary' : 'ghost'}
|
|
className={`w-full justify-start py-2 ${
|
|
currentFolder === folder ? 'bg-gray-100 text-gray-900' : 'text-gray-600 hover:text-gray-900'
|
|
}`}
|
|
onClick={() => handleMailboxChange(folder)}
|
|
>
|
|
<div className="flex items-center">
|
|
{getFolderIcon(folder)}
|
|
<span className="ml-2">{formatFolderName(folder)}</span>
|
|
</div>
|
|
</Button>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</nav>
|
|
);
|
|
|
|
// Helper to format folder names
|
|
const formatFolderName = (folder: string) => {
|
|
return folder.charAt(0).toUpperCase() + folder.slice(1).toLowerCase();
|
|
};
|
|
|
|
// Get account color
|
|
const getAccountColor = (accountId: number) => {
|
|
const account = accounts.find(acc => acc.id === accountId);
|
|
return account ? account.color : 'bg-gray-500';
|
|
};
|
|
|
|
// Helper to get folder icons
|
|
const getFolderIcon = (folder: string) => {
|
|
const folderLower = folder.toLowerCase();
|
|
|
|
if (folderLower.includes('inbox')) {
|
|
return <Inbox className="h-4 w-4" />;
|
|
} else if (folderLower.includes('sent')) {
|
|
return <Send className="h-4 w-4" />;
|
|
} else if (folderLower.includes('trash')) {
|
|
return <Trash className="h-4 w-4" />;
|
|
} else if (folderLower.includes('archive')) {
|
|
return <Archive className="h-4 w-4" />;
|
|
} else if (folderLower.includes('draft')) {
|
|
return <Edit className="h-4 w-4" />;
|
|
} else if (folderLower.includes('spam') || folderLower.includes('junk')) {
|
|
return <AlertOctagon className="h-4 w-4" />;
|
|
} else {
|
|
return <Folder className="h-4 w-4" />;
|
|
}
|
|
};
|
|
|
|
// Render email list component
|
|
const renderEmailList = () => (
|
|
<EmailList
|
|
emails={emails}
|
|
selectedEmailIds={selectedEmailIds}
|
|
selectedEmail={selectedEmail}
|
|
currentFolder={currentFolder}
|
|
isLoading={isLoading}
|
|
totalEmails={emails.length}
|
|
hasMoreEmails={hasMoreEmails}
|
|
onSelectEmail={handleEmailSelect}
|
|
onToggleSelect={toggleEmailSelection}
|
|
onToggleSelectAll={toggleSelectAll}
|
|
onBulkAction={handleBulkAction}
|
|
onToggleStarred={toggleStarred}
|
|
onLoadMore={handleLoadMore}
|
|
onSearch={searchEmails}
|
|
/>
|
|
);
|
|
|
|
// Render email content based on the email body
|
|
const renderEmailContent = (email: any) => {
|
|
try {
|
|
// For simple rendering in this example, we'll just display the content directly
|
|
return <div dangerouslySetInnerHTML={{ __html: email.content || email.html || email.body || '' }} />;
|
|
} catch (e) {
|
|
console.error('Error rendering email:', e);
|
|
return <div className="text-gray-500">Failed to render email content</div>;
|
|
}
|
|
};
|
|
|
|
// Email list wrapper with preview panel
|
|
const renderEmailListWrapper = () => (
|
|
<div className="flex-1 flex overflow-hidden">
|
|
{/* Email list panel */}
|
|
{renderEmailList()}
|
|
|
|
{/* Preview panel - will automatically take remaining space */}
|
|
<div className="flex-1 bg-white/95 backdrop-blur-sm flex flex-col">
|
|
{selectedEmail ? (
|
|
<>
|
|
{/* Email actions header */}
|
|
<div className="flex-none px-4 py-3 border-b border-gray-100">
|
|
<div className="flex items-center gap-4">
|
|
<div className="flex items-center gap-2 min-w-0 flex-1">
|
|
<Button
|
|
variant="ghost"
|
|
size="icon"
|
|
onClick={() => handleEmailSelect('')}
|
|
className="md:hidden flex-shrink-0"
|
|
>
|
|
<ChevronLeft className="h-5 w-5" />
|
|
</Button>
|
|
<div className="min-w-0 max-w-[500px]">
|
|
<h2 className="text-lg font-semibold text-gray-900 truncate">
|
|
{selectedEmail.subject}
|
|
</h2>
|
|
</div>
|
|
</div>
|
|
<div className="flex items-center gap-1 flex-shrink-0 ml-auto">
|
|
<div className="flex items-center border-l border-gray-200 pl-4">
|
|
<Button
|
|
variant="ghost"
|
|
size="icon"
|
|
className="text-gray-400 hover:text-gray-900 h-9 w-9"
|
|
onClick={() => handleReplyOrForward('reply')}
|
|
>
|
|
<Reply className="h-4 w-4" />
|
|
</Button>
|
|
<Button
|
|
variant="ghost"
|
|
size="icon"
|
|
className="text-gray-400 hover:text-gray-900 h-9 w-9"
|
|
onClick={() => handleReplyOrForward('reply-all')}
|
|
>
|
|
<ReplyAll className="h-4 w-4" />
|
|
</Button>
|
|
<Button
|
|
variant="ghost"
|
|
size="icon"
|
|
className="text-gray-400 hover:text-gray-900 h-9 w-9"
|
|
onClick={() => handleReplyOrForward('forward')}
|
|
>
|
|
<Forward className="h-4 w-4" />
|
|
</Button>
|
|
<Button
|
|
variant="ghost"
|
|
size="icon"
|
|
className="text-gray-400 hover:text-gray-900 h-9 w-9"
|
|
onClick={() => toggleStarred(selectedEmail.id)}
|
|
>
|
|
<Star className={`h-4 w-4 ${selectedEmail.starred ? 'fill-yellow-400 text-yellow-400' : ''}`} />
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Scrollable content area */}
|
|
<ScrollArea className="flex-1 p-6">
|
|
<div className="flex items-center gap-4 mb-6">
|
|
<Avatar className="h-10 w-10">
|
|
<AvatarFallback>
|
|
{(selectedEmail.from?.[0]?.name || '').charAt(0) || (selectedEmail.from?.[0]?.address || '').charAt(0) || '?'}
|
|
</AvatarFallback>
|
|
</Avatar>
|
|
<div className="flex-1">
|
|
<p className="font-medium text-gray-900">
|
|
{selectedEmail.from?.[0]?.name || ''} <span className="text-gray-500"><{selectedEmail.from?.[0]?.address || ''}></span>
|
|
</p>
|
|
<p className="text-sm text-gray-500">
|
|
to {selectedEmail.to?.[0]?.address || ''}
|
|
</p>
|
|
{selectedEmail.cc && selectedEmail.cc.length > 0 && (
|
|
<p className="text-sm text-gray-500">
|
|
cc {selectedEmail.cc.map(c => c.address).join(', ')}
|
|
</p>
|
|
)}
|
|
</div>
|
|
<div className="text-sm text-gray-500 whitespace-nowrap">
|
|
{formatDate(selectedEmail.date)}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="prose max-w-none">
|
|
{renderEmailContent(selectedEmail)}
|
|
</div>
|
|
</ScrollArea>
|
|
</>
|
|
) : (
|
|
<div className="flex flex-col items-center justify-center h-full">
|
|
<Mail className="h-12 w-12 text-gray-400 mb-4" />
|
|
<p className="text-gray-500">Select an email to view its contents</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
|
|
// Delete confirmation dialog
|
|
const renderDeleteConfirmDialog = () => (
|
|
<AlertDialog open={showDeleteConfirm} onOpenChange={setShowDeleteConfirm}>
|
|
<AlertDialogContent>
|
|
<AlertDialogHeader>
|
|
<AlertDialogTitle>Delete Emails</AlertDialogTitle>
|
|
<AlertDialogDescription>
|
|
Are you sure you want to delete {selectedEmailIds.length} selected email{selectedEmailIds.length > 1 ? 's' : ''}? This action cannot be undone.
|
|
</AlertDialogDescription>
|
|
</AlertDialogHeader>
|
|
<AlertDialogFooter>
|
|
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
|
<AlertDialogAction onClick={handleDeleteConfirm}>Delete</AlertDialogAction>
|
|
</AlertDialogFooter>
|
|
</AlertDialogContent>
|
|
</AlertDialog>
|
|
);
|
|
|
|
// If there's a critical error, show error dialog
|
|
if (error && !isLoading && emails.length === 0 && !showLoginNeeded) {
|
|
return (
|
|
<div className="flex h-screen items-center justify-center">
|
|
<Alert variant="destructive" className="max-w-md">
|
|
<AlertCircle className="h-4 w-4" />
|
|
<AlertTitle>Error loading emails</AlertTitle>
|
|
<AlertDescription>{error}</AlertDescription>
|
|
</Alert>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<SimplifiedLoadingFix />
|
|
|
|
{/* Login required dialog */}
|
|
<AlertDialog open={showLoginNeeded} onOpenChange={setShowLoginNeeded}>
|
|
<AlertDialogContent>
|
|
<AlertDialogHeader>
|
|
<AlertDialogTitle>Login Required</AlertDialogTitle>
|
|
<AlertDialogDescription>
|
|
You need to configure your email account credentials before you can access your emails.
|
|
</AlertDialogDescription>
|
|
</AlertDialogHeader>
|
|
<AlertDialogFooter>
|
|
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
|
<AlertDialogAction onClick={handleGoToLogin}>Setup Email</AlertDialogAction>
|
|
</AlertDialogFooter>
|
|
</AlertDialogContent>
|
|
</AlertDialog>
|
|
|
|
{/* Main layout */}
|
|
<main className="w-full h-screen bg-black">
|
|
<div className="w-full h-full px-4 pt-12 pb-4">
|
|
<div className="flex h-full bg-carnet-bg">
|
|
{/* Sidebar */}
|
|
<div className={`${sidebarOpen ? 'w-60' : 'w-16'} bg-white/95 backdrop-blur-sm border-r border-gray-100 flex flex-col transition-all duration-300 ease-in-out
|
|
${mobileSidebarOpen ? 'fixed inset-y-0 left-0 z-40' : 'hidden'} md:block`}>
|
|
{/* Courrier Title */}
|
|
<div className="p-3 border-b border-gray-100">
|
|
<div className="flex items-center gap-2">
|
|
<Mail className="h-6 w-6 text-gray-600" />
|
|
<span className="text-xl font-semibold text-gray-900">COURRIER</span>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Compose button and refresh button */}
|
|
<div className="p-2 border-b border-gray-100 flex items-center gap-2">
|
|
<Button
|
|
className="flex-1 bg-blue-600 text-white rounded-lg hover:bg-blue-700 flex items-center justify-center transition-all py-1.5 text-sm"
|
|
onClick={() => {
|
|
setShowCompose(true);
|
|
setComposeTo('');
|
|
setComposeCc('');
|
|
setComposeBcc('');
|
|
setComposeSubject('');
|
|
setComposeBody('');
|
|
setShowCc(false);
|
|
setShowBcc(false);
|
|
}}
|
|
>
|
|
<div className="flex items-center gap-2">
|
|
<PlusIcon className="h-3.5 w-3.5" />
|
|
<span>Compose</span>
|
|
</div>
|
|
</Button>
|
|
<Button
|
|
variant="ghost"
|
|
size="icon"
|
|
onClick={() => handleMailboxChange('INBOX')}
|
|
className="text-gray-600 hover:text-gray-900 hover:bg-gray-100"
|
|
>
|
|
<RefreshCw className="h-4 w-4" />
|
|
</Button>
|
|
</div>
|
|
|
|
{/* Accounts Section */}
|
|
<div className="p-3 border-b border-gray-100">
|
|
<Button
|
|
variant="ghost"
|
|
className="w-full justify-between mb-2 text-sm font-medium text-gray-500"
|
|
onClick={() => setAccountsDropdownOpen(!accountsDropdownOpen)}
|
|
>
|
|
<span>Accounts</span>
|
|
{accountsDropdownOpen ? <ChevronUp className="h-4 w-4" /> : <ChevronDown className="h-4 w-4" />}
|
|
</Button>
|
|
|
|
{accountsDropdownOpen && (
|
|
<div className="space-y-1 pl-2">
|
|
{accounts.map(account => (
|
|
<div key={account.id} className="relative group">
|
|
<Button
|
|
variant="ghost"
|
|
className="w-full justify-between px-2 py-1.5 text-sm group"
|
|
onClick={() => setSelectedAccount(account)}
|
|
>
|
|
<div className="flex flex-col items-start">
|
|
<div className="flex items-center gap-2">
|
|
<div className={`w-2.5 h-2.5 rounded-full ${account.color}`}></div>
|
|
<span className="font-medium">{account.name}</span>
|
|
</div>
|
|
<span className="text-xs text-gray-500 ml-4">{account.email}</span>
|
|
</div>
|
|
</Button>
|
|
</div>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
{/* Navigation */}
|
|
{renderSidebarNav()}
|
|
</div>
|
|
|
|
{/* Main content area */}
|
|
<div className="flex-1 flex overflow-hidden">
|
|
{/* Email list panel */}
|
|
{renderEmailListWrapper()}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
|
|
{/* Compose Email Modal */}
|
|
<ComposeEmail
|
|
showCompose={showCompose}
|
|
setShowCompose={setShowCompose}
|
|
composeTo={composeTo}
|
|
setComposeTo={setComposeTo}
|
|
composeCc={composeCc}
|
|
setComposeCc={setComposeCc}
|
|
composeBcc={composeBcc}
|
|
setComposeBcc={setComposeBcc}
|
|
composeSubject={composeSubject}
|
|
setComposeSubject={setComposeSubject}
|
|
composeBody={composeBody}
|
|
setComposeBody={setComposeBody}
|
|
showCc={showCc}
|
|
setShowCc={setShowCc}
|
|
showBcc={showBcc}
|
|
setShowBcc={setShowBcc}
|
|
attachments={attachments}
|
|
setAttachments={setAttachments}
|
|
handleSend={handleSend}
|
|
replyTo={isReplying ? selectedEmail : null}
|
|
forwardFrom={isForwarding ? selectedEmail : null}
|
|
onSend={async (email: EmailData) => {
|
|
console.log('Email sent:', email);
|
|
setShowCompose(false);
|
|
setIsReplying(false);
|
|
setIsForwarding(false);
|
|
return Promise.resolve();
|
|
}}
|
|
onCancel={() => {
|
|
setShowCompose(false);
|
|
setComposeTo('');
|
|
setComposeCc('');
|
|
setComposeBcc('');
|
|
setComposeSubject('');
|
|
setComposeBody('');
|
|
setShowCc(false);
|
|
setShowBcc(false);
|
|
setAttachments([]);
|
|
setIsReplying(false);
|
|
setIsForwarding(false);
|
|
}}
|
|
/>
|
|
{renderDeleteConfirmDialog()}
|
|
</>
|
|
);
|
|
}
|