panel 2 courier api
This commit is contained in:
parent
ca400fd1af
commit
93875b881f
@ -126,6 +126,15 @@ export async function GET(
|
|||||||
// 9. Parse the email content
|
// 9. Parse the email content
|
||||||
const parsedEmail = await parseEmail(foundMessage.source.toString());
|
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
|
// 10. Prepare the full email object with all needed data
|
||||||
const fullEmail = {
|
const fullEmail = {
|
||||||
id,
|
id,
|
||||||
@ -137,6 +146,7 @@ export async function GET(
|
|||||||
date: foundMessage.envelope.date?.toISOString() || new Date().toISOString(),
|
date: foundMessage.envelope.date?.toISOString() || new Date().toISOString(),
|
||||||
content: parsedEmail.html || parsedEmail.text || '',
|
content: parsedEmail.html || parsedEmail.text || '',
|
||||||
textContent: parsedEmail.text || '',
|
textContent: parsedEmail.text || '',
|
||||||
|
rawContent: foundMessage.source.toString(), // Include raw content for fallback
|
||||||
read: foundMessage.flags.has('\\Seen'),
|
read: foundMessage.flags.has('\\Seen'),
|
||||||
starred: foundMessage.flags.has('\\Flagged'),
|
starred: foundMessage.flags.has('\\Flagged'),
|
||||||
folder: folder,
|
folder: folder,
|
||||||
@ -146,6 +156,15 @@ export async function GET(
|
|||||||
headers: parsedEmail.headers || {}
|
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
|
// 11. Mark as read if not already
|
||||||
if (!foundMessage.flags.has('\\Seen')) {
|
if (!foundMessage.flags.has('\\Seen')) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -49,6 +49,8 @@ export interface Email {
|
|||||||
subject: string;
|
subject: string;
|
||||||
content: string;
|
content: string;
|
||||||
body?: string; // For backward compatibility
|
body?: string; // For backward compatibility
|
||||||
|
textContent?: string;
|
||||||
|
rawContent?: string; // Raw email content for fallback display
|
||||||
date: string;
|
date: string;
|
||||||
read: boolean;
|
read: boolean;
|
||||||
starred: boolean;
|
starred: boolean;
|
||||||
@ -111,7 +113,33 @@ function EmailContent({ email }: { email: Email }) {
|
|||||||
|
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
try {
|
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) {
|
if (mounted) {
|
||||||
setContent(<div className="text-gray-500">No content available</div>);
|
setContent(<div className="text-gray-500">No content available</div>);
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
@ -119,7 +147,8 @@ function EmailContent({ email }: { email: Email }) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const formattedEmail = email.content.trim();
|
// Use the best available content source
|
||||||
|
const formattedEmail = (email.content || email.body || email.rawContent || '').trim();
|
||||||
if (!formattedEmail) {
|
if (!formattedEmail) {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
setContent(<div className="text-gray-500">No content available</div>);
|
setContent(<div className="text-gray-500">No content available</div>);
|
||||||
@ -128,7 +157,15 @@ function EmailContent({ email }: { email: Email }) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Debug the formatted email
|
||||||
|
console.log('Attempting to decode email content, length:', formattedEmail.length);
|
||||||
|
|
||||||
|
try {
|
||||||
const parsedEmail = await decodeEmail(formattedEmail);
|
const parsedEmail = await decodeEmail(formattedEmail);
|
||||||
|
console.log('Parsed email result:', {
|
||||||
|
hasHtml: !!parsedEmail.html,
|
||||||
|
hasText: !!parsedEmail.text,
|
||||||
|
});
|
||||||
|
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
if (parsedEmail.html) {
|
if (parsedEmail.html) {
|
||||||
@ -144,10 +181,36 @@ function EmailContent({ email }: { email: Email }) {
|
|||||||
{parsedEmail.text}
|
{parsedEmail.text}
|
||||||
</div>
|
</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 {
|
} 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);
|
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);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -165,7 +228,7 @@ function EmailContent({ email }: { email: Email }) {
|
|||||||
return () => {
|
return () => {
|
||||||
mounted = false;
|
mounted = false;
|
||||||
};
|
};
|
||||||
}, [email?.content]);
|
}, [email?.content, email?.body, email?.textContent, email?.rawContent]);
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return (
|
return (
|
||||||
@ -183,6 +246,28 @@ function EmailContent({ email }: { email: Email }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function renderEmailContent(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} />;
|
return <EmailContent email={email} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -620,23 +705,37 @@ export default function CourrierPage() {
|
|||||||
return account ? account.color : 'bg-gray-500';
|
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) => {
|
const handleEmailSelect = async (emailId: string) => {
|
||||||
try {
|
try {
|
||||||
// First, set partial selectedEmail to show something immediately
|
// First, set partial selectedEmail to show something immediately
|
||||||
const emailToSelect = emails.find(email => email.id === emailId);
|
const emailToSelect = emails.find(email => email.id === emailId);
|
||||||
if (emailToSelect) {
|
if (emailToSelect) {
|
||||||
|
console.log('Setting preliminary selected email:', {
|
||||||
|
id: emailToSelect.id,
|
||||||
|
subject: emailToSelect.subject,
|
||||||
|
hasContent: !!emailToSelect.content,
|
||||||
|
});
|
||||||
setSelectedEmail(emailToSelect);
|
setSelectedEmail(emailToSelect);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then fetch the full content
|
// Then fetch the full content
|
||||||
|
console.log(`Fetching email content for ID: ${emailId}`);
|
||||||
const response = await fetch(`/api/courrier/${emailId}`);
|
const response = await fetch(`/api/courrier/${emailId}`);
|
||||||
|
|
||||||
if (!response.ok) {
|
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();
|
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
|
// Set the complete selectedEmail with all content
|
||||||
setSelectedEmail(fullEmail);
|
setSelectedEmail(fullEmail);
|
||||||
@ -669,6 +768,10 @@ export default function CourrierPage() {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching email:', 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.');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user