diff --git a/app/api/courrier/[id]/route.ts b/app/api/courrier/[id]/route.ts
index 49c021b6..550aa556 100644
--- a/app/api/courrier/[id]/route.ts
+++ b/app/api/courrier/[id]/route.ts
@@ -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 {
diff --git a/app/courrier/page.tsx b/app/courrier/page.tsx
index 7ac93298..e264eb7a 100644
--- a/app/courrier/page.tsx
+++ b/app/courrier/page.tsx
@@ -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(
+
+ {email.textContent}
+
+ );
+ setIsLoading(false);
+ setError(null);
+ }
+ return;
+ }
+
+ // Check if we have any content to parse
+ if (!email.content && !email.body && !email.rawContent) {
if (mounted) {
setContent(No content available
);
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(No content available
);
@@ -128,26 +157,60 @@ function EmailContent({ email }: { email: Email }) {
return;
}
- const parsedEmail = await decodeEmail(formattedEmail);
+ // Debug the formatted email
+ console.log('Attempting to decode email content, length:', formattedEmail.length);
- if (mounted) {
- if (parsedEmail.html) {
+ try {
+ const parsedEmail = await decodeEmail(formattedEmail);
+ console.log('Parsed email result:', {
+ hasHtml: !!parsedEmail.html,
+ hasText: !!parsedEmail.text,
+ });
+
+ if (mounted) {
+ if (parsedEmail.html) {
+ setContent(
+
+ );
+ } else if (parsedEmail.text) {
+ setContent(
+
+ {parsedEmail.text}
+
+ );
+ } else if (email.rawContent) {
+ // Use raw content directly if available and nothing else worked
+ setContent(
+
+ {email.rawContent}
+
+ );
+ } else {
+ // Fall back to displaying the raw content
+ setContent(
+
+ {formattedEmail}
+
+ );
+ }
+ setError(null);
+ }
+ } catch (parseError) {
+ console.error('Error parsing email:', parseError);
+ // Fallback to displaying raw content on parse error
+ if (mounted) {
setContent(
-
- );
- } else if (parsedEmail.text) {
- setContent(
-
- {parsedEmail.text}
+
+ {email.rawContent || formattedEmail}
);
- } else {
- setContent(
No content available
);
}
- setError(null);
+ }
+
+ 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
No email selected
;
+
+ // Some emails might have content directly in HTML format
+ if (email.content && (email.content.includes('
+ );
+ }
+
+ // If we have textContent, display it directly
+ if (email.textContent) {
+ return (
+
+ {email.textContent}
+
+ );
+ }
+
+ // Use EmailContent component for more complex parsing
return ;
}
@@ -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.');
+ }
}
};