From e02ee396dcc3ccb0c27e6bf06b1f023717e9d3fa Mon Sep 17 00:00:00 2001 From: alma Date: Wed, 30 Apr 2025 15:44:06 +0200 Subject: [PATCH] courrier formatting --- components/email/EmailLayout.tsx | 174 +++++++++++++++++++---------- components/email/EmailList.tsx | 62 ++++------ components/email/EmailListItem.tsx | 24 ++-- 3 files changed, 143 insertions(+), 117 deletions(-) diff --git a/components/email/EmailLayout.tsx b/components/email/EmailLayout.tsx index 935edb21..e0640f5f 100644 --- a/components/email/EmailLayout.tsx +++ b/components/email/EmailLayout.tsx @@ -15,19 +15,12 @@ import { EmailMessage } from '@/lib/services/email-service'; import { useToast } from "@/hooks/use-toast"; import { sendEmail } from '@/lib/services/email-service'; import { useSession } from "next-auth/react"; -import { cn } from '@/lib/utils'; -import EmailList from './EmailList'; -import { Email } from '@/hooks/use-courrier'; interface EmailLayoutProps { className?: string; - previewModeEnabled?: boolean; } -export default function EmailLayout({ - className = '', - previewModeEnabled = false -}: EmailLayoutProps) { +export default function EmailLayout({ className = '' }: EmailLayoutProps) { // Email state const [emails, setEmails] = useState([]); const [selectedEmail, setSelectedEmail] = useState<{ @@ -250,70 +243,131 @@ export default function EmailLayout({ }; return ( -
- {/* Main email interface */} -
- {/* Sidebar */} -
- {/* Sidebar content */} - {/* New email button */} -
- +
+ + {/* Folder navigation */} + +
+ {folders.map((folder) => ( + + ))} +
+
+
+ + {/* Main content */} +
+ {/* Email list */} +
+ {/* Search and refresh */} +
+
+ + setSearchQuery(e.target.value)} + onKeyDown={(e) => e.key === 'Enter' && handleSearch()} + /> +
+
- {/* Folder navigation */} + {/* Email list */} -
- {folders.map((folder) => ( - - ))} -
+ {loading && emails.length === 0 ? ( +
+ +
+ ) : emails.length === 0 ? ( +
+ No emails found +
+ ) : ( +
+ {emails.map((email) => ( +
handleEmailSelect(email.id, email.accountId || '', email.folder || '')} + > +
+
+ {email.flags.seen ? ( + + ) : ( + + )} +
+
+
+

+ {email.from[0]?.name || email.from[0]?.address || 'Unknown'} +

+ + {formatDate(email.date.toString())} + +
+

{email.subject}

+

{email.preview}

+
+
+ + {/* Email indicators */} +
+ {email.hasAttachments && ( + + + + + + Attachment + + + )} +
+
+ ))} +
+ )}
- {/* Email list */} -
- {}} - onToggleSelectAll={() => {}} - onBulkAction={() => {}} - onToggleStarred={() => {}} - onLoadMore={loadEmails} - onSearch={handleSearch} - previewMode={previewModeEnabled} - /> -
- {/* Email preview */}
diff --git a/components/email/EmailList.tsx b/components/email/EmailList.tsx index 8c58db66..0c6a1baa 100644 --- a/components/email/EmailList.tsx +++ b/components/email/EmailList.tsx @@ -23,7 +23,6 @@ interface EmailListProps { onToggleStarred: (emailId: string) => void; onLoadMore: () => void; onSearch?: (query: string) => void; - previewMode?: boolean; } export default function EmailList({ @@ -40,44 +39,33 @@ export default function EmailList({ onBulkAction, onToggleStarred, onLoadMore, - onSearch, - previewMode = false + onSearch }: EmailListProps) { const [scrollPosition, setScrollPosition] = useState(0); const [searchQuery, setSearchQuery] = useState(''); - // Handle scroll to detect when user is near the bottom - const handleScroll = (e: React.UIEvent) => { - const target = e.target as HTMLDivElement; - const scrollTop = target.scrollTop; + // Handle scroll to detect when user reaches the bottom + const handleScroll = (event: React.UIEvent) => { + const target = event.target as HTMLDivElement; + const { scrollTop, scrollHeight, clientHeight } = target; + setScrollPosition(scrollTop); - // Check if we're near the bottom - const scrollHeight = target.scrollHeight; - const clientHeight = target.clientHeight; - const scrollPosition = scrollTop + clientHeight; - - // If we're within 100px of the bottom, load more - if (scrollHeight - scrollPosition < 100 && !isLoading && hasMoreEmails) { + // If user scrolls near the bottom and we have more emails, load more + if (scrollHeight - scrollTop - clientHeight < 200 && hasMoreEmails && !isLoading) { onLoadMore(); } }; - // Handle search form submission + // Handle search const handleSearch = (e: React.FormEvent) => { e.preventDefault(); - - if (onSearch && searchQuery.trim()) { - onSearch(searchQuery.trim()); - } + onSearch?.(searchQuery); }; - // Clear search const clearSearch = () => { setSearchQuery(''); - if (onSearch) { - onSearch(''); - } + onSearch?.(''); }; // Render loading state @@ -138,27 +126,16 @@ export default function EmailList({
- {/* Only show selection UI if not in preview mode */} - {!previewMode ? ( - - ) : ( -
-

Messages

- - {totalEmails} {totalEmails === 1 ? 'email' : 'emails'} - -
- )} +
- {/* Only show bulk actions if not in preview mode and there are selected emails */} - {!previewMode && selectedEmailIds.length > 0 && ( + {selectedEmailIds.length > 0 && ( ))} diff --git a/components/email/EmailListItem.tsx b/components/email/EmailListItem.tsx index 57f1f606..81fcd411 100644 --- a/components/email/EmailListItem.tsx +++ b/components/email/EmailListItem.tsx @@ -15,7 +15,6 @@ interface EmailListItemProps { onSelect: () => void; onToggleSelect: (e: React.MouseEvent) => void; onToggleStarred: (e: React.MouseEvent) => void; - previewMode?: boolean; } const PREVIEW_LENGTH = 70; @@ -26,8 +25,7 @@ export default function EmailListItem({ isActive, onSelect, onToggleSelect, - onToggleStarred, - previewMode = false + onToggleStarred }: EmailListItemProps) { // Format the date in a readable way const formatDate = (dateString: string) => { @@ -127,34 +125,32 @@ export default function EmailListItem({ className={cn( 'flex items-center gap-3 px-4 py-2 hover:bg-gray-50/80 cursor-pointer', isActive ? 'bg-blue-50/50' : '', - !email.flags?.seen ? 'bg-blue-50/20' : '' + !email.read ? 'bg-blue-50/20' : '' )} onClick={onSelect} > - {!previewMode && ( - - )} +
- + {getSenderName()}
- {formatDate(typeof email.date === 'string' ? email.date : email.date.toString())} + {formatDate(email.date)}