courrier refactor
This commit is contained in:
parent
9befdd60c3
commit
7139d52100
@ -327,27 +327,43 @@ export default function CourrierPage() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 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
|
// Email list wrapper with preview panel
|
||||||
const renderEmailListWrapper = () => (
|
const renderEmailListWrapper = () => (
|
||||||
<div className="flex-1 flex overflow-hidden">
|
<div className="flex-1 flex overflow-hidden">
|
||||||
{/* Email list panel */}
|
{/* Email list panel */}
|
||||||
<EmailList
|
{renderEmailList()}
|
||||||
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}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{/* Preview panel - will automatically take remaining space */}
|
{/* Preview panel - will automatically take remaining space */}
|
||||||
<div className="flex-1 bg-white/95 backdrop-blur-sm flex flex-col">
|
<div className="flex-1 bg-white/95 backdrop-blur-sm flex flex-col">
|
||||||
{selectedEmail ? (
|
{selectedEmail ? (
|
||||||
@ -356,43 +372,88 @@ export default function CourrierPage() {
|
|||||||
<div className="flex-none px-4 py-3 border-b border-gray-100">
|
<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-4">
|
||||||
<div className="flex items-center gap-2 min-w-0 flex-1">
|
<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]">
|
<div className="min-w-0 max-w-[500px]">
|
||||||
<h2 className="text-lg font-semibold text-gray-900 truncate">
|
<h2 className="text-lg font-semibold text-gray-900 truncate">
|
||||||
{selectedEmail.subject || '(No subject)'}
|
{selectedEmail.subject}
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2 flex-shrink-0">
|
<div className="flex items-center gap-1 flex-shrink-0 ml-auto">
|
||||||
<div className="flex items-center border-l border-gray-200 pl-4">
|
<div className="flex items-center border-l border-gray-200 pl-4">
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
className="text-gray-600 hover:text-gray-900 px-2 py-1"
|
size="icon"
|
||||||
|
className="text-gray-400 hover:text-gray-900 h-9 w-9"
|
||||||
onClick={() => handleReplyOrForward('reply')}
|
onClick={() => handleReplyOrForward('reply')}
|
||||||
>
|
>
|
||||||
Reply
|
<Reply className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
className="text-gray-600 hover:text-gray-900 px-2 py-1"
|
size="icon"
|
||||||
|
className="text-gray-400 hover:text-gray-900 h-9 w-9"
|
||||||
onClick={() => handleReplyOrForward('reply-all')}
|
onClick={() => handleReplyOrForward('reply-all')}
|
||||||
>
|
>
|
||||||
Reply All
|
<ReplyAll className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
className="text-gray-600 hover:text-gray-900 px-2 py-1"
|
size="icon"
|
||||||
|
className="text-gray-400 hover:text-gray-900 h-9 w-9"
|
||||||
onClick={() => handleReplyOrForward('forward')}
|
onClick={() => handleReplyOrForward('forward')}
|
||||||
>
|
>
|
||||||
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>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</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>
|
||||||
|
|
||||||
{/* Email content with scroll area */}
|
<div className="prose max-w-none">
|
||||||
<ScrollArea className="flex-1">
|
{renderEmailContent(selectedEmail)}
|
||||||
<EmailContent email={selectedEmail} />
|
</div>
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user