panel 2 courier api

This commit is contained in:
alma 2025-04-25 16:42:24 +02:00
parent ca400fd1af
commit 93875b881f
2 changed files with 142 additions and 20 deletions

View File

@ -126,6 +126,15 @@ export async function GET(
// 9. Parse the email content
const parsedEmail = await parseEmail(foundMessage.source.toString());
// Debug the parsed email structure
console.log('Parsed email data structure:', {
hasHtml: !!parsedEmail.html,
hasText: !!parsedEmail.text,
htmlLength: parsedEmail.html ? parsedEmail.html.length : 0,
textLength: parsedEmail.text ? parsedEmail.text.length : 0,
attachmentsCount: parsedEmail.attachments ? parsedEmail.attachments.length : 0
});
// 10. Prepare the full email object with all needed data
const fullEmail = {
id,
@ -137,6 +146,7 @@ export async function GET(
date: foundMessage.envelope.date?.toISOString() || new Date().toISOString(),
content: parsedEmail.html || parsedEmail.text || '',
textContent: parsedEmail.text || '',
rawContent: foundMessage.source.toString(), // Include raw content for fallback
read: foundMessage.flags.has('\\Seen'),
starred: foundMessage.flags.has('\\Flagged'),
folder: folder,
@ -146,6 +156,15 @@ export async function GET(
headers: parsedEmail.headers || {}
};
// Log the structure of the email being returned
console.log('Returning email object with content structure:', {
id: fullEmail.id,
hasContent: !!fullEmail.content,
contentLength: fullEmail.content ? fullEmail.content.length : 0,
hasTextContent: !!fullEmail.textContent,
textContentLength: fullEmail.textContent ? fullEmail.textContent.length : 0
});
// 11. Mark as read if not already
if (!foundMessage.flags.has('\\Seen')) {
try {

View File

@ -49,6 +49,8 @@ export interface Email {
subject: string;
content: string;
body?: string; // For backward compatibility
textContent?: string;
rawContent?: string; // Raw email content for fallback display
date: string;
read: boolean;
starred: boolean;
@ -111,7 +113,33 @@ function EmailContent({ email }: { email: Email }) {
setIsLoading(true);
try {
if (!email.content) {
// Debug the email object
console.log('EmailContent received email:', {
id: email.id,
subject: email.subject,
hasContent: !!email.content,
contentLength: email.content ? email.content.length : 0,
hasTextContent: !!email.textContent,
hasRawContent: !!email.rawContent,
hasBody: !!email.body
});
// First check if we have pre-parsed content
if (email.textContent) {
if (mounted) {
setContent(
<div className="email-content whitespace-pre-wrap">
{email.textContent}
</div>
);
setIsLoading(false);
setError(null);
}
return;
}
// Check if we have any content to parse
if (!email.content && !email.body && !email.rawContent) {
if (mounted) {
setContent(<div className="text-gray-500">No content available</div>);
setIsLoading(false);
@ -119,7 +147,8 @@ function EmailContent({ email }: { email: Email }) {
return;
}
const formattedEmail = email.content.trim();
// Use the best available content source
const formattedEmail = (email.content || email.body || email.rawContent || '').trim();
if (!formattedEmail) {
if (mounted) {
setContent(<div className="text-gray-500">No content available</div>);
@ -128,7 +157,15 @@ function EmailContent({ email }: { email: Email }) {
return;
}
// Debug the formatted email
console.log('Attempting to decode email content, length:', formattedEmail.length);
try {
const parsedEmail = await decodeEmail(formattedEmail);
console.log('Parsed email result:', {
hasHtml: !!parsedEmail.html,
hasText: !!parsedEmail.text,
});
if (mounted) {
if (parsedEmail.html) {
@ -144,10 +181,36 @@ function EmailContent({ email }: { email: Email }) {
{parsedEmail.text}
</div>
);
} else if (email.rawContent) {
// Use raw content directly if available and nothing else worked
setContent(
<div className="email-content whitespace-pre-wrap text-sm bg-gray-50 p-3 rounded">
{email.rawContent}
</div>
);
} else {
setContent(<div className="text-gray-500">No content available</div>);
// Fall back to displaying the raw content
setContent(
<div className="email-content whitespace-pre-wrap text-sm bg-gray-50 p-3 rounded">
{formattedEmail}
</div>
);
}
setError(null);
}
} catch (parseError) {
console.error('Error parsing email:', parseError);
// Fallback to displaying raw content on parse error
if (mounted) {
setContent(
<div className="email-content whitespace-pre-wrap text-sm bg-gray-50 p-3 rounded">
{email.rawContent || formattedEmail}
</div>
);
}
}
if (mounted) {
setIsLoading(false);
}
} catch (err) {
@ -165,7 +228,7 @@ function EmailContent({ email }: { email: Email }) {
return () => {
mounted = false;
};
}, [email?.content]);
}, [email?.content, email?.body, email?.textContent, email?.rawContent]);
if (isLoading) {
return (
@ -183,6 +246,28 @@ function EmailContent({ email }: { email: Email }) {
}
function renderEmailContent(email: Email) {
if (!email) return <div className="text-gray-500">No email selected</div>;
// Some emails might have content directly in HTML format
if (email.content && (email.content.includes('<html') || email.content.includes('<body'))) {
return (
<div
className="email-content prose prose-sm max-w-none dark:prose-invert"
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(email.content) }}
/>
);
}
// If we have textContent, display it directly
if (email.textContent) {
return (
<div className="email-content whitespace-pre-wrap">
{email.textContent}
</div>
);
}
// Use EmailContent component for more complex parsing
return <EmailContent email={email} />;
}
@ -620,23 +705,37 @@ export default function CourrierPage() {
return account ? account.color : 'bg-gray-500';
};
// Update handleEmailSelect to set selectedEmail correctly
// Update handleEmailSelect to set selectedEmail correctly and improve error handling
const handleEmailSelect = async (emailId: string) => {
try {
// First, set partial selectedEmail to show something immediately
const emailToSelect = emails.find(email => email.id === emailId);
if (emailToSelect) {
console.log('Setting preliminary selected email:', {
id: emailToSelect.id,
subject: emailToSelect.subject,
hasContent: !!emailToSelect.content,
});
setSelectedEmail(emailToSelect);
}
// Then fetch the full content
console.log(`Fetching email content for ID: ${emailId}`);
const response = await fetch(`/api/courrier/${emailId}`);
if (!response.ok) {
throw new Error('Failed to fetch full email content');
const errorText = await response.text();
console.error(`Error response (${response.status}): ${errorText}`);
throw new Error(`Failed to fetch email content: ${response.status} ${response.statusText}`);
}
const fullEmail = await response.json();
console.log('Received full email data:', {
id: fullEmail.id,
subject: fullEmail.subject,
hasContent: !!fullEmail.content,
fields: Object.keys(fullEmail),
});
// Set the complete selectedEmail with all content
setSelectedEmail(fullEmail);
@ -669,6 +768,10 @@ export default function CourrierPage() {
}
} catch (error) {
console.error('Error fetching email:', error);
// Keep the selected email if it was set initially
if (!selectedEmail) {
setError('Failed to load email content. Please try again.');
}
}
};