From b4c386f30d2a4fcb4f8fe1be24c64d4be5252545 Mon Sep 17 00:00:00 2001 From: alma Date: Wed, 16 Apr 2025 11:21:08 +0200 Subject: [PATCH] mail page ui correction maj --- app/mail/page.tsx | 502 ++++++++++++++++++---------------------------- 1 file changed, 192 insertions(+), 310 deletions(-) diff --git a/app/mail/page.tsx b/app/mail/page.tsx index 576274c..4a9c732 100644 --- a/app/mail/page.tsx +++ b/app/mail/page.tsx @@ -537,52 +537,73 @@ export default function MailPage() { return account ? account.color : 'bg-gray-500'; }; - // Update email click handler to work without mark-read endpoint + // Add email action handlers const handleEmailSelect = (emailId: string) => { - setSelectedEmails(prev => { - if (prev.includes(emailId)) { - return prev.filter(id => id !== emailId); + const email = emails.find(e => e.id === emailId); + if (email) { + setSelectedEmail(email); + // Mark as read if not already + if (!email.read) { + const updatedEmails = emails.map(e => + e.id === emailId ? { ...e, read: true } : e + ); + setEmails(updatedEmails); } - return [...prev, emailId]; - }); + } }; - // Toggle starred status const toggleStarred = async (emailId: string, e: React.MouseEvent) => { e.stopPropagation(); - // Toggle star in IMAP try { await fetch('/api/mail/toggle-star', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ emailId }) }); + + const updatedEmails = emails.map(email => + email.id === emailId ? { ...email, starred: !email.starred } : email + ); + setEmails(updatedEmails); } catch (error) { console.error('Error toggling star:', error); } - - const updatedEmails = emails.map(email => - email.id === emailId ? { ...email, starred: !email.starred } : email - ); - setEmails(updatedEmails); }; - // Handle bulk selection - const toggleSelectAll = () => { - if (selectedEmails.length === filteredEmails.length) { - setSelectedEmails([]); - } else { - setSelectedEmails(filteredEmails.map(email => email.id)); + const handleReply = async (type: 'reply' | 'replyAll' | 'forward') => { + const selectedEmailData = selectedEmail; + if (!selectedEmailData) return; + + setShowCompose(true); + const subject = `${type === 'forward' ? 'Fwd: ' : 'Re: '}${selectedEmailData.subject}`; + let to = ''; + let content = ''; + + switch (type) { + case 'reply': + to = selectedEmailData.from; + content = `\n\nOn ${new Date(selectedEmailData.date).toLocaleString()}, ${selectedEmailData.fromName} wrote:\n> ${selectedEmailData.body.split('\n').join('\n> ')}`; + break; + case 'replyAll': + to = selectedEmailData.from; + content = `\n\nOn ${new Date(selectedEmailData.date).toLocaleString()}, ${selectedEmailData.fromName} wrote:\n> ${selectedEmailData.body.split('\n').join('\n> ')}`; + break; + case 'forward': + content = `\n\n---------- Forwarded message ----------\nFrom: ${selectedEmailData.fromName} <${selectedEmailData.from}>\nDate: ${new Date(selectedEmailData.date).toLocaleString()}\nSubject: ${selectedEmailData.subject}\n\n${selectedEmailData.body}`; + break; } + + setComposeSubject(subject); + setComposeTo(to); + setComposeBody(content); }; - // Handle bulk delete const handleBulkDelete = () => { + setDeleteType('emails'); setShowDeleteConfirm(true); }; - // Handle delete confirmation const handleDeleteConfirm = async () => { try { if (selectedEmails.length > 0) { @@ -601,60 +622,6 @@ export default function MailPage() { setShowDeleteConfirm(false); }; - // Get selected email - const getSelectedEmail = () => { - return emails.find(email => email.id === selectedEmail?.id); - }; - - // Add account management functions - const handleAddAccount = () => { - // Implementation for adding a new account - }; - - const handleEditAccount = (accountId: number, newName: string) => { - setAccounts(accounts.map(acc => - acc.id === accountId ? { ...acc, name: newName } : acc - )); - }; - - const handleEmailCheckbox = (e: React.ChangeEvent, emailId: string) => { - e.stopPropagation(); - if (e.target.checked) { - setSelectedEmails([...selectedEmails, emailId]); - } else { - setSelectedEmails(selectedEmails.filter(id => id !== emailId)); - } - }; - - // Handle reply - const handleReply = async (type: 'reply' | 'replyAll' | 'forward') => { - const selectedEmailData = getSelectedEmail(); - if (!selectedEmailData) return; - - setShowCompose(true); - const subject = `${type === 'forward' ? 'Fwd: ' : 'Re: '}${selectedEmailData.subject}`; - let to = ''; - let content = ''; - - switch (type) { - case 'reply': - to = selectedEmailData.from; - content = `\n\nOn ${new Date(selectedEmailData.date).toLocaleString()}, ${selectedEmailData.fromName} wrote:\n> ${selectedEmailData.body.split('\n').join('\n> ')}`; - break; - case 'replyAll': - to = selectedEmailData.from; // You would also need to add CC recipients here - content = `\n\nOn ${new Date(selectedEmailData.date).toLocaleString()}, ${selectedEmailData.fromName} wrote:\n> ${selectedEmailData.body.split('\n').join('\n> ')}`; - break; - case 'forward': - content = `\n\n---------- Forwarded message ----------\nFrom: ${selectedEmailData.fromName} <${selectedEmailData.from}>\nDate: ${new Date(selectedEmailData.date).toLocaleString()}\nSubject: ${selectedEmailData.subject}\n\n${selectedEmailData.body}`; - break; - } - - setComposeSubject(subject); - setComposeTo(to); - setComposeBody(content); - }; - const handleAccountAction = (accountId: number, action: 'edit' | 'delete') => { setShowAccountActions(null); if (action === 'delete') { @@ -686,7 +653,7 @@ export default function MailPage() {
{/* Sidebar */}
+ ${mobileSidebarOpen ? 'fixed inset-y-0 left-0 z-40' : 'hidden'} md:block`}> {/* Courrier Title */}
@@ -699,7 +666,7 @@ export default function MailPage() {
- {/* Accounts Section with Scrollable Content */} + {/* Accounts Section */}
- {foldersOpen && ( + {foldersDropdownOpen && (
- {/* All Accounts Option */} - - - {/* Mail Accounts List */} {accounts.map(account => (
{/* Account Actions Dropdown */} - {showSettings && ( + {showAccountActions === account.id && (
- - + + + Remove account +
)}
@@ -794,7 +744,7 @@ export default function MailPage() {
- {/* Scrollable Navigation */} -
- -
+ {/* Navigation */} +
- {/* Main content */} + {/* Main content area */}
{/* Email list */}
+ {/* Email list header */}
- {filteredEmails.length > 0 && ( - 0 && ( + )}

@@ -908,7 +819,7 @@ export default function MailPage() {

- {filteredEmails.length} emails + {emails.length} emails
@@ -917,17 +828,6 @@ export default function MailPage() {
{selectedEmails.length} selected
- -
- ) : emails.length === 0 ? ( -
-
No emails found
-
- ) : ( -
    - {filteredEmails.map((email) => ( -
  • handleEmailSelect(email.id)} - > -
    -
    -
    - handleEmailCheckbox(e, email.id)} - onClick={(e) => e.stopPropagation()} - className="h-4 w-4 text-blue-600 rounded border-gray-300 focus:ring-blue-500" - /> -
    -

    - {email.fromName || email.from} -

    -
    -

    - {email.subject} -

    - - {formatDate(email.date)} - -
    -
    -
    - + {loading ? ( +
    +
    +
    + ) : ( +
      + {emails.map((email) => ( +
    • handleEmailSelect(email.id)} + > +
      +
      +
      + e.stopPropagation()} + onCheckedChange={(checked) => { + if (checked) { + setSelectedEmails([...selectedEmails, email.id]); + } else { + setSelectedEmails(selectedEmails.filter(id => id !== email.id)); + } + }} + /> +
      +

      + {email.fromName || email.from} +

      +

      {email.subject}

      -
    • - ))} -
    - )} -
    -
    +
    + {formatDate(email.date)} + +
    +
+
+ + ))} + + )}
{/* Email preview panel */} @@ -1055,26 +931,9 @@ export default function MailPage() { variant="ghost" size="icon" className="text-gray-400 hover:text-gray-900" - onClick={(e) => { - e.stopPropagation(); - toggleStarred(selectedEmail.id, e); - }} + onClick={(e) => toggleStarred(selectedEmail.id, e)} > - {selectedEmail.starred ? ( - - ) : ( - - )} - -
@@ -1110,6 +969,29 @@ export default function MailPage() { )}
+ + {/* Delete Confirmation Dialog */} + + + + Are you sure? + + {deleteType === 'email' && "This email will be moved to trash."} + {deleteType === 'emails' && `${selectedEmails.length} emails will be moved to trash.`} + {deleteType === 'account' && "This account will be permanently removed. This action cannot be undone."} + + + + setShowDeleteConfirm(false)}>Cancel + + {deleteType === 'account' ? 'Delete Account' : 'Move to Trash'} + + + + ); } \ No newline at end of file