From f011bfc43eaba8dd42ce5de42e1f1789a0227b8c Mon Sep 17 00:00:00 2001 From: alma Date: Wed, 30 Apr 2025 15:43:16 +0200 Subject: [PATCH] courrier formatting --- components/email/EmailLayout.tsx | 174 ++++++++++------------------- components/email/EmailList.tsx | 62 ++++++---- components/email/EmailListItem.tsx | 24 ++-- 3 files changed, 117 insertions(+), 143 deletions(-) diff --git a/components/email/EmailLayout.tsx b/components/email/EmailLayout.tsx index e0640f5f..935edb21 100644 --- a/components/email/EmailLayout.tsx +++ b/components/email/EmailLayout.tsx @@ -15,12 +15,19 @@ 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 = '' }: EmailLayoutProps) { +export default function EmailLayout({ + className = '', + previewModeEnabled = false +}: EmailLayoutProps) { // Email state const [emails, setEmails] = useState([]); const [selectedEmail, setSelectedEmail] = useState<{ @@ -243,131 +250,70 @@ export default function EmailLayout({ className = '' }: EmailLayoutProps) { }; return ( -
- {/* Sidebar */} -
- {/* 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()} - /> -
-
- {/* Email list */} + {/* Folder navigation */} - {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 - - - )} -
-
- ))} -
- )} +
+ {folders.map((folder) => ( + + ))} +
+ {/* 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 0c6a1baa..8c58db66 100644 --- a/components/email/EmailList.tsx +++ b/components/email/EmailList.tsx @@ -23,6 +23,7 @@ interface EmailListProps { onToggleStarred: (emailId: string) => void; onLoadMore: () => void; onSearch?: (query: string) => void; + previewMode?: boolean; } export default function EmailList({ @@ -39,33 +40,44 @@ export default function EmailList({ onBulkAction, onToggleStarred, onLoadMore, - onSearch + onSearch, + previewMode = false }: EmailListProps) { const [scrollPosition, setScrollPosition] = useState(0); const [searchQuery, setSearchQuery] = useState(''); - // 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; - + // 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; setScrollPosition(scrollTop); - // If user scrolls near the bottom and we have more emails, load more - if (scrollHeight - scrollTop - clientHeight < 200 && hasMoreEmails && !isLoading) { + // 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) { onLoadMore(); } }; - // Handle search + // Handle search form submission const handleSearch = (e: React.FormEvent) => { e.preventDefault(); - onSearch?.(searchQuery); + + if (onSearch && searchQuery.trim()) { + onSearch(searchQuery.trim()); + } }; + // Clear search const clearSearch = () => { setSearchQuery(''); - onSearch?.(''); + if (onSearch) { + onSearch(''); + } }; // Render loading state @@ -126,16 +138,27 @@ export default function EmailList({
- + {/* Only show selection UI if not in preview mode */} + {!previewMode ? ( + + ) : ( +
+

Messages

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