From 74f78f09f8ff3fed23f2122975b430a9e3332360 Mon Sep 17 00:00:00 2001 From: alma Date: Fri, 25 Apr 2025 17:20:37 +0200 Subject: [PATCH] panel 2 courier api restore --- app/api/courrier/[id]/mark-read/route.ts | 77 ++++++++++++++++++++++++ app/api/parse-email/route.ts | 6 +- app/courrier/page.tsx | 71 ++++++++++++---------- 3 files changed, 119 insertions(+), 35 deletions(-) create mode 100644 app/api/courrier/[id]/mark-read/route.ts diff --git a/app/api/courrier/[id]/mark-read/route.ts b/app/api/courrier/[id]/mark-read/route.ts new file mode 100644 index 00000000..fa54c2db --- /dev/null +++ b/app/api/courrier/[id]/mark-read/route.ts @@ -0,0 +1,77 @@ +import { NextResponse } from 'next/server'; +import { ImapFlow } from 'imapflow'; +import { getServerSession } from 'next-auth'; +import { authOptions } from '@/app/api/auth/[...nextauth]/route'; +import { prisma } from '@/lib/prisma'; + +export async function POST( + request: Request, + { params }: { params: { id: string } } +) { + try { + const id = params.id; + + // Authentication check + const session = await getServerSession(authOptions); + if (!session?.user?.id) { + return NextResponse.json( + { error: 'Unauthorized' }, + { status: 401 } + ); + } + + // Get credentials from database + const credentials = await prisma.mailCredentials.findUnique({ + where: { + userId: session.user.id + } + }); + + if (!credentials) { + return NextResponse.json( + { error: 'No mail credentials found. Please configure your email account.' }, + { status: 401 } + ); + } + + // Create IMAP client + const client = new ImapFlow({ + host: credentials.host, + port: credentials.port, + secure: true, + auth: { + user: credentials.email, + pass: credentials.password, + }, + logger: false, + emitLogs: false, + tls: { + rejectUnauthorized: false + } + }); + + try { + await client.connect(); + + // Open INBOX + await client.mailboxOpen('INBOX'); + + // Mark the email as read + await client.messageFlagsAdd(id, ['\\Seen'], { uid: true }); + + return NextResponse.json({ success: true }); + } finally { + try { + await client.logout(); + } catch (e) { + console.error('Error during IMAP logout:', e); + } + } + } catch (error) { + console.error('Error marking email as read:', error); + return NextResponse.json( + { error: 'Failed to mark email as read' }, + { status: 500 } + ); + } +} \ No newline at end of file diff --git a/app/api/parse-email/route.ts b/app/api/parse-email/route.ts index ad03828d..80246be7 100644 --- a/app/api/parse-email/route.ts +++ b/app/api/parse-email/route.ts @@ -12,16 +12,16 @@ function getEmailAddress(address: AddressObject | AddressObject[] | undefined): export async function POST(request: Request) { try { const body = await request.json(); - const { email } = body; + const emailContent = body.email || body.emailContent; - if (!email || typeof email !== 'string') { + if (!emailContent || typeof emailContent !== 'string') { return NextResponse.json( { error: 'Invalid email content' }, { status: 400 } ); } - const parsed = await simpleParser(email); + const parsed = await simpleParser(emailContent); return NextResponse.json({ subject: parsed.subject || null, diff --git a/app/courrier/page.tsx b/app/courrier/page.tsx index 42e06a8f..642b7bd7 100644 --- a/app/courrier/page.tsx +++ b/app/courrier/page.tsx @@ -620,10 +620,20 @@ export default function CourrierPage() { return account ? account.color : 'bg-gray-500'; }; - // Update handleEmailSelect to set selectedEmail correctly + // Update handleEmailSelect to set selectedEmail correctly and ensure content is loaded const handleEmailSelect = async (emailId: string) => { try { - // Make sure it's using this: + setContentLoading(true); + + // Find the email in the current list first + const emailInList = emails.find(email => email.id === emailId); + + // Set selected email immediately with what we have + if (emailInList) { + setSelectedEmail(emailInList); + } + + // Fetch the full email content const response = await fetch(`/api/courrier/${emailId}`); if (!response.ok) { @@ -631,49 +641,46 @@ export default function CourrierPage() { } const fullEmail = await response.json(); + console.log('Fetched email content:', fullEmail); - // Update the email in the list and selected email with full content + // Create a complete email object by combining what we have + const completeEmail = { + ...(emailInList || {}), + ...fullEmail, + id: emailId, + content: fullEmail.content || '', + }; + + // Update the email in the list setEmails(prevEmails => prevEmails.map(email => - email.id === emailId - ? { ...email, content: fullEmail.content || fullEmail.body || email.content } - : email + email.id === emailId ? completeEmail : email )); - setSelectedEmail(prev => prev ? { - ...prev, - content: fullEmail.content || fullEmail.body || prev.content - } : prev); - + // Update the selected email + setSelectedEmail(completeEmail); + // Try to mark as read in the background try { - const markReadResponse = await fetch(`/api/mail/mark-read`, { + await fetch(`/api/courrier/${emailId}/mark-read`, { method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - emailId, - isRead: true, - }), }); - - if (markReadResponse.ok) { - // Only update the emails list if the API call was successful - setEmails((prevEmails: Email[]) => - prevEmails.map((email: Email): Email => - email.id === emailId - ? { ...email, read: true } - : email - ) - ); - } else { - console.error('Failed to mark email as read:', await markReadResponse.text()); - } + + // Update read status in the list + setEmails(prevEmails => + prevEmails.map(email => + email.id === emailId + ? { ...email, read: true } + : email + ) + ); } catch (error) { console.error('Error marking email as read:', error); } } catch (error) { console.error('Error fetching email:', error); + setError('Failed to load email content. Please try again.'); + } finally { + setContentLoading(false); } };