panel 2 courier api restore
This commit is contained in:
parent
522683b599
commit
a9beba1bd9
113
app/courrier/loading-fix.tsx
Normal file
113
app/courrier/loading-fix.tsx
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
/**
|
||||||
|
* This is a debugging component that provides troubleshooting tools
|
||||||
|
* for the email loading process in the Courrier application.
|
||||||
|
*/
|
||||||
|
'use client';
|
||||||
|
|
||||||
|
import { Button } from '@/components/ui/button';
|
||||||
|
import { RefreshCw, AlertCircle, CheckCircle } from 'lucide-react';
|
||||||
|
|
||||||
|
interface LoadingFixProps {
|
||||||
|
loading: boolean;
|
||||||
|
isLoadingInitial: boolean;
|
||||||
|
setLoading: (value: boolean) => void;
|
||||||
|
setIsLoadingInitial: (value: boolean) => void;
|
||||||
|
setEmails: (emails: any[]) => void;
|
||||||
|
loadEmails: () => void;
|
||||||
|
emails: any[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function LoadingFix({
|
||||||
|
loading,
|
||||||
|
isLoadingInitial,
|
||||||
|
setLoading,
|
||||||
|
setIsLoadingInitial,
|
||||||
|
setEmails,
|
||||||
|
loadEmails,
|
||||||
|
emails
|
||||||
|
}: LoadingFixProps) {
|
||||||
|
const forceResetLoadingStates = () => {
|
||||||
|
console.log('[DEBUG] Force resetting loading states to false');
|
||||||
|
// Force both loading states to false
|
||||||
|
setLoading(false);
|
||||||
|
setIsLoadingInitial(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const forceTriggerLoad = () => {
|
||||||
|
console.log('[DEBUG] Force triggering a new email load');
|
||||||
|
setLoading(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
loadEmails();
|
||||||
|
}, 100);
|
||||||
|
};
|
||||||
|
|
||||||
|
const resetEmailState = () => {
|
||||||
|
console.log('[DEBUG] Resetting email state to empty array');
|
||||||
|
setEmails([]);
|
||||||
|
setTimeout(() => {
|
||||||
|
forceTriggerLoad();
|
||||||
|
}, 100);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="fixed bottom-4 right-4 z-50 p-4 bg-white shadow-lg rounded-lg border border-gray-200">
|
||||||
|
<div className="text-sm font-medium mb-2">Debug Tools</div>
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<div className="flex items-center text-xs">
|
||||||
|
<span className="inline-block w-28">Loading State:</span>
|
||||||
|
{loading ? (
|
||||||
|
<span className="text-yellow-500 flex items-center">
|
||||||
|
<AlertCircle className="h-3 w-3 mr-1" /> Active
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
<span className="text-green-500 flex items-center">
|
||||||
|
<CheckCircle className="h-3 w-3 mr-1" /> Inactive
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center text-xs">
|
||||||
|
<span className="inline-block w-28">Initial Loading:</span>
|
||||||
|
{isLoadingInitial ? (
|
||||||
|
<span className="text-yellow-500 flex items-center">
|
||||||
|
<AlertCircle className="h-3 w-3 mr-1" /> Active
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
<span className="text-green-500 flex items-center">
|
||||||
|
<CheckCircle className="h-3 w-3 mr-1" /> Inactive
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center text-xs">
|
||||||
|
<span className="inline-block w-28">Emails Loaded:</span>
|
||||||
|
<span className={emails.length > 0 ? "text-green-500" : "text-red-500"}>
|
||||||
|
{emails.length}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
className="text-xs h-8"
|
||||||
|
onClick={forceResetLoadingStates}
|
||||||
|
>
|
||||||
|
Reset Loading States
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
className="text-xs h-8"
|
||||||
|
onClick={forceTriggerLoad}
|
||||||
|
>
|
||||||
|
Force Reload Emails
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
className="text-xs h-8"
|
||||||
|
onClick={resetEmailState}
|
||||||
|
>
|
||||||
|
Reset Email State
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -33,6 +33,7 @@ import DOMPurify from 'isomorphic-dompurify';
|
|||||||
import ComposeEmail from '@/components/ComposeEmail';
|
import ComposeEmail from '@/components/ComposeEmail';
|
||||||
import { decodeEmail, cleanHtml } from '@/lib/mail-parser-wrapper';
|
import { decodeEmail, cleanHtml } from '@/lib/mail-parser-wrapper';
|
||||||
import { Attachment as MailParserAttachment } from 'mailparser';
|
import { Attachment as MailParserAttachment } from 'mailparser';
|
||||||
|
import { LoadingFix } from './loading-fix';
|
||||||
|
|
||||||
export interface Account {
|
export interface Account {
|
||||||
id: number;
|
id: number;
|
||||||
@ -585,15 +586,17 @@ export default function CourrierPage() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const loadInitialData = async () => {
|
const loadInitialData = async () => {
|
||||||
try {
|
try {
|
||||||
console.log('Loading initial email data...');
|
console.log('[DEBUG] Starting initial email data loading...');
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setIsLoadingInitial(true);
|
setIsLoadingInitial(true);
|
||||||
|
|
||||||
// Check credentials first
|
// Check credentials first
|
||||||
|
console.log('[DEBUG] Checking credentials...');
|
||||||
const credResponse = await fetch('/api/courrier');
|
const credResponse = await fetch('/api/courrier');
|
||||||
if (!credResponse.ok) {
|
if (!credResponse.ok) {
|
||||||
const errorData = await credResponse.json();
|
const errorData = await credResponse.json();
|
||||||
if (errorData.error === 'No stored credentials found') {
|
if (errorData.error === 'No stored credentials found') {
|
||||||
|
console.log('[DEBUG] No credentials found, redirecting to login');
|
||||||
router.push('/courrier/login');
|
router.push('/courrier/login');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -603,8 +606,13 @@ export default function CourrierPage() {
|
|||||||
try {
|
try {
|
||||||
// Try to get user email from credentials
|
// Try to get user email from credentials
|
||||||
const credsData = await credResponse.json();
|
const credsData = await credResponse.json();
|
||||||
|
console.log('[DEBUG] Credentials response:', {
|
||||||
|
hasEmail: !!credsData.email,
|
||||||
|
status: credResponse.status
|
||||||
|
});
|
||||||
|
|
||||||
if (credsData.email) {
|
if (credsData.email) {
|
||||||
console.log('Got email from credentials:', credsData.email);
|
console.log('[DEBUG] Got email from credentials:', credsData.email);
|
||||||
setAccounts(prev => prev.map(account =>
|
setAccounts(prev => prev.map(account =>
|
||||||
account.id === 1
|
account.id === 1
|
||||||
? {
|
? {
|
||||||
@ -616,15 +624,20 @@ export default function CourrierPage() {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('Error getting email from credentials:', error);
|
console.warn('[DEBUG] Error getting email from credentials:', error);
|
||||||
}
|
}
|
||||||
|
|
||||||
// First do a quick request just for folders
|
// First do a quick request just for folders
|
||||||
try {
|
try {
|
||||||
|
console.log('[DEBUG] Preloading folders...');
|
||||||
const folderResponse = await fetch('/api/courrier?folder=INBOX&page=1&limit=1');
|
const folderResponse = await fetch('/api/courrier?folder=INBOX&page=1&limit=1');
|
||||||
if (folderResponse.ok) {
|
if (folderResponse.ok) {
|
||||||
const folderData = await folderResponse.json();
|
const folderData = await folderResponse.json();
|
||||||
console.log('Preloading folders:', folderData.folders);
|
console.log('[DEBUG] Folder data:', {
|
||||||
|
folders: folderData.folders?.length || 0,
|
||||||
|
emails: folderData.emails?.length || 0
|
||||||
|
});
|
||||||
|
|
||||||
if (folderData.folders && folderData.folders.length > 0) {
|
if (folderData.folders && folderData.folders.length > 0) {
|
||||||
setAvailableFolders(folderData.folders);
|
setAvailableFolders(folderData.folders);
|
||||||
setAccounts(prev => prev.map(account =>
|
setAccounts(prev => prev.map(account =>
|
||||||
@ -635,10 +648,11 @@ export default function CourrierPage() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('Error preloading folders:', error);
|
console.warn('[DEBUG] Error preloading folders:', error);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then load emails (forced fetch with timestamp)
|
// Then load emails (forced fetch with timestamp)
|
||||||
|
console.log('[DEBUG] Fetching emails...');
|
||||||
const timestamp = Date.now();
|
const timestamp = Date.now();
|
||||||
const emailResponse = await fetch(
|
const emailResponse = await fetch(
|
||||||
`/api/courrier?folder=${encodeURIComponent(currentView)}&page=${page}&limit=${emailsPerPage}&_t=${timestamp}`,
|
`/api/courrier?folder=${encodeURIComponent(currentView)}&page=${page}&limit=${emailsPerPage}&_t=${timestamp}`,
|
||||||
@ -650,20 +664,16 @@ export default function CourrierPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const data = await emailResponse.json();
|
const data = await emailResponse.json();
|
||||||
console.log(`Loaded ${data.emails?.length || 0} emails`);
|
console.log(`[DEBUG] Loaded ${data.emails?.length || 0} emails, response status: ${emailResponse.status}`);
|
||||||
console.log('API response data:', {
|
|
||||||
emailCount: data.emails?.length || 0,
|
|
||||||
folderCount: data.folders?.length || 0
|
|
||||||
});
|
|
||||||
|
|
||||||
// Set available folders if present
|
// Set available folders if present
|
||||||
if (data.folders) {
|
if (data.folders) {
|
||||||
console.log('Setting folders from initialization:', data.folders);
|
console.log('[DEBUG] Setting folders from initialization:', data.folders.length);
|
||||||
setAvailableFolders(data.folders);
|
setAvailableFolders(data.folders);
|
||||||
|
|
||||||
// Update the mail account with folders
|
// Update the mail account with folders
|
||||||
setAccounts(prev => {
|
setAccounts(prev => {
|
||||||
console.log('Updating accounts with folders');
|
console.log('[DEBUG] Updating accounts with folders');
|
||||||
return prev.map(account =>
|
return prev.map(account =>
|
||||||
account.id === 1
|
account.id === 1
|
||||||
? { ...account, folders: data.folders }
|
? { ...account, folders: data.folders }
|
||||||
@ -671,10 +681,11 @@ export default function CourrierPage() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.warn('No folders returned from API during initialization');
|
console.warn('[DEBUG] No folders returned from API during initialization');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process emails and sort by date
|
// Process emails and sort by date
|
||||||
|
console.log('[DEBUG] Processing emails...');
|
||||||
const processedEmails = (data.emails || [])
|
const processedEmails = (data.emails || [])
|
||||||
.map((email: any) => {
|
.map((email: any) => {
|
||||||
// Add proper handling for from field which might be an array or object
|
// Add proper handling for from field which might be an array or object
|
||||||
@ -772,6 +783,7 @@ export default function CourrierPage() {
|
|||||||
to: toText,
|
to: toText,
|
||||||
subject: email.subject || '(No subject)',
|
subject: email.subject || '(No subject)',
|
||||||
content: email.content || '',
|
content: email.content || '',
|
||||||
|
preview: email.preview || '',
|
||||||
date: email.date || new Date().toISOString(),
|
date: email.date || new Date().toISOString(),
|
||||||
read: email.read || false,
|
read: email.read || false,
|
||||||
starred: email.starred || false,
|
starred: email.starred || false,
|
||||||
@ -785,6 +797,7 @@ export default function CourrierPage() {
|
|||||||
.sort((a: Email, b: Email) => new Date(b.date).getTime() - new Date(a.date).getTime());
|
.sort((a: Email, b: Email) => new Date(b.date).getTime() - new Date(a.date).getTime());
|
||||||
|
|
||||||
// Set emails
|
// Set emails
|
||||||
|
console.log('[DEBUG] Setting emails state with', processedEmails.length, 'emails');
|
||||||
setEmails(processedEmails);
|
setEmails(processedEmails);
|
||||||
|
|
||||||
// Update unread count for inbox
|
// Update unread count for inbox
|
||||||
@ -798,10 +811,12 @@ export default function CourrierPage() {
|
|||||||
// Update pagination
|
// Update pagination
|
||||||
setHasMore(data.hasMore);
|
setHasMore(data.hasMore);
|
||||||
setError(null);
|
setError(null);
|
||||||
|
console.log('[DEBUG] Initial load complete, setting loading states to false');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error loading initial data:', err);
|
console.error('[DEBUG] Error loading initial data:', err);
|
||||||
setError(err instanceof Error ? err.message : 'Failed to load data');
|
setError(err instanceof Error ? err.message : 'Failed to load data');
|
||||||
} finally {
|
} finally {
|
||||||
|
console.log('[DEBUG] Setting loading state to false in finally block');
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
setIsLoadingInitial(false);
|
setIsLoadingInitial(false);
|
||||||
}
|
}
|
||||||
@ -1016,7 +1031,7 @@ export default function CourrierPage() {
|
|||||||
|
|
||||||
// Update the email list to use filtered emails
|
// Update the email list to use filtered emails
|
||||||
const renderEmailList = () => {
|
const renderEmailList = () => {
|
||||||
console.log('Rendering email list with state:', {
|
console.log('[DEBUG] Rendering email list with state:', {
|
||||||
loading,
|
loading,
|
||||||
isLoadingInitial,
|
isLoadingInitial,
|
||||||
emailCount: emails.length,
|
emailCount: emails.length,
|
||||||
@ -1039,6 +1054,10 @@ export default function CourrierPage() {
|
|||||||
<div className="flex flex-col items-center">
|
<div className="flex flex-col items-center">
|
||||||
<div className="animate-spin rounded-full h-8 w-8 border-t-2 border-b-2 border-blue-500 mb-4"></div>
|
<div className="animate-spin rounded-full h-8 w-8 border-t-2 border-b-2 border-blue-500 mb-4"></div>
|
||||||
<p className="text-sm text-gray-500">Loading emails...</p>
|
<p className="text-sm text-gray-500">Loading emails...</p>
|
||||||
|
<p className="text-xs text-gray-400 mt-2">
|
||||||
|
{loading ? 'Loading state: true' : ''}
|
||||||
|
{isLoadingInitial ? 'Loading initial: true' : ''}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : filteredEmails.length === 0 ? (
|
) : filteredEmails.length === 0 ? (
|
||||||
@ -1057,6 +1076,7 @@ export default function CourrierPage() {
|
|||||||
size="sm"
|
size="sm"
|
||||||
className="mt-5 bg-blue-600 hover:bg-blue-700"
|
className="mt-5 bg-blue-600 hover:bg-blue-700"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
console.log('[DEBUG] Manual refresh clicked');
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
loadEmails();
|
loadEmails();
|
||||||
}}
|
}}
|
||||||
@ -1637,11 +1657,11 @@ export default function CourrierPage() {
|
|||||||
try {
|
try {
|
||||||
// Skip if already loading
|
// Skip if already loading
|
||||||
if (isLoadingInitial || isLoadingMore) {
|
if (isLoadingInitial || isLoadingMore) {
|
||||||
console.log('Skipping loadEmails - already loading');
|
console.log('[DEBUG] Skipping loadEmails - already loading');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`Loading emails for folder: ${currentView}, page: ${page}, isLoadMore: ${isLoadMore}`);
|
console.log(`[DEBUG] Loading emails for folder: ${currentView}, page: ${page}, isLoadMore: ${isLoadMore}`);
|
||||||
|
|
||||||
if (isLoadMore) {
|
if (isLoadMore) {
|
||||||
setIsLoadingMore(true);
|
setIsLoadingMore(true);
|
||||||
@ -1651,175 +1671,184 @@ export default function CourrierPage() {
|
|||||||
|
|
||||||
// Fetch emails with timestamp for cache busting
|
// Fetch emails with timestamp for cache busting
|
||||||
const timestamp = Date.now();
|
const timestamp = Date.now();
|
||||||
const response = await fetch(
|
try {
|
||||||
`/api/courrier?folder=${encodeURIComponent(currentView)}&page=${page}&limit=${emailsPerPage}&_t=${timestamp}`,
|
const response = await fetch(
|
||||||
{ cache: 'no-store' }
|
`/api/courrier?folder=${encodeURIComponent(currentView)}&page=${page}&limit=${emailsPerPage}&_t=${timestamp}`,
|
||||||
);
|
{ cache: 'no-store' }
|
||||||
|
);
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
console.error('API response error:', response.status, response.statusText);
|
console.error('[DEBUG] API response error:', response.status, response.statusText);
|
||||||
throw new Error('Failed to load emails');
|
throw new Error('Failed to load emails');
|
||||||
}
|
|
||||||
|
|
||||||
const data = await response.json();
|
|
||||||
console.log('API response:', {
|
|
||||||
emailCount: data.emails?.length || 0,
|
|
||||||
folderCount: data.folders?.length || 0,
|
|
||||||
hasMore: data.hasMore,
|
|
||||||
total: data.total
|
|
||||||
});
|
|
||||||
|
|
||||||
// Set available folders
|
|
||||||
if (data.folders) {
|
|
||||||
console.log('Setting available folders:', data.folders);
|
|
||||||
setAvailableFolders(data.folders);
|
|
||||||
|
|
||||||
// Update the mail account with folders
|
|
||||||
setAccounts(prev => prev.map(account =>
|
|
||||||
account.id === 1
|
|
||||||
? { ...account, folders: data.folders }
|
|
||||||
: account
|
|
||||||
));
|
|
||||||
} else {
|
|
||||||
console.warn('No folders returned from API');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process and sort emails
|
|
||||||
const processedEmails = (data.emails || [])
|
|
||||||
.map((email: any) => {
|
|
||||||
// Add proper handling for from field which might be an array or object
|
|
||||||
let fromText = '';
|
|
||||||
let fromName = '';
|
|
||||||
let toText = '';
|
|
||||||
let ccText = '';
|
|
||||||
let bccText = '';
|
|
||||||
|
|
||||||
// Handle 'from' field
|
|
||||||
if (email.from) {
|
|
||||||
if (Array.isArray(email.from)) {
|
|
||||||
if (email.from.length > 0) {
|
|
||||||
if (typeof email.from[0] === 'object') {
|
|
||||||
fromText = email.from[0].address || '';
|
|
||||||
fromName = email.from[0].name || email.from[0].address?.split('@')[0] || '';
|
|
||||||
} else {
|
|
||||||
fromText = email.from[0] || '';
|
|
||||||
fromName = fromText.split('@')[0] || '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (typeof email.from === 'object') {
|
|
||||||
fromText = email.from.address || '';
|
|
||||||
fromName = email.from.name || email.from.address?.split('@')[0] || '';
|
|
||||||
}
|
|
||||||
else if (typeof email.from === 'string') {
|
|
||||||
fromText = email.from;
|
|
||||||
fromName = email.fromName || email.from.split('@')[0] || '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle 'to' field
|
|
||||||
if (email.to) {
|
|
||||||
if (Array.isArray(email.to)) {
|
|
||||||
if (email.to.length > 0) {
|
|
||||||
if (typeof email.to[0] === 'object') {
|
|
||||||
toText = email.to.map((t: any) => t.address || '').join(', ');
|
|
||||||
} else {
|
|
||||||
toText = email.to.join(', ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (typeof email.to === 'object') {
|
|
||||||
toText = email.to.address || '';
|
|
||||||
}
|
|
||||||
else if (typeof email.to === 'string') {
|
|
||||||
toText = email.to;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle 'cc' field
|
|
||||||
if (email.cc) {
|
|
||||||
if (Array.isArray(email.cc)) {
|
|
||||||
if (email.cc.length > 0) {
|
|
||||||
if (typeof email.cc[0] === 'object') {
|
|
||||||
ccText = email.cc.map((c: any) => c.address || '').join(', ');
|
|
||||||
} else {
|
|
||||||
ccText = email.cc.join(', ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (typeof email.cc === 'object') {
|
|
||||||
ccText = email.cc.address || '';
|
|
||||||
}
|
|
||||||
else if (typeof email.cc === 'string') {
|
|
||||||
ccText = email.cc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle 'bcc' field
|
|
||||||
if (email.bcc) {
|
|
||||||
if (Array.isArray(email.bcc)) {
|
|
||||||
if (email.bcc.length > 0) {
|
|
||||||
if (typeof email.bcc[0] === 'object') {
|
|
||||||
bccText = email.bcc.map((b: any) => b.address || '').join(', ');
|
|
||||||
} else {
|
|
||||||
bccText = email.bcc.join(', ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (typeof email.bcc === 'object') {
|
|
||||||
bccText = email.bcc.address || '';
|
|
||||||
}
|
|
||||||
else if (typeof email.bcc === 'string') {
|
|
||||||
bccText = email.bcc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
id: email.id,
|
|
||||||
accountId: 1,
|
|
||||||
from: fromText,
|
|
||||||
fromName: fromName,
|
|
||||||
to: toText,
|
|
||||||
subject: email.subject || '(No subject)',
|
|
||||||
content: email.content || '',
|
|
||||||
date: email.date || new Date().toISOString(),
|
|
||||||
read: email.read || false,
|
|
||||||
starred: email.starred || false,
|
|
||||||
folder: email.folder || currentView,
|
|
||||||
cc: ccText,
|
|
||||||
bcc: bccText,
|
|
||||||
flags: email.flags || [],
|
|
||||||
hasAttachments: email.hasAttachments || false
|
|
||||||
};
|
|
||||||
})
|
|
||||||
.sort((a: Email, b: Email) => new Date(b.date).getTime() - new Date(a.date).getTime());
|
|
||||||
|
|
||||||
// Set emails appropriately
|
|
||||||
setEmails(prev => {
|
|
||||||
if (isLoadMore) {
|
|
||||||
// Filter out duplicates when appending
|
|
||||||
const existingIds = new Set(prev.map(email => email.id));
|
|
||||||
const uniqueNewEmails = processedEmails.filter((email: Email) => !existingIds.has(email.id));
|
|
||||||
return [...prev, ...uniqueNewEmails];
|
|
||||||
} else {
|
|
||||||
return processedEmails;
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
// Update unread count
|
const data = await response.json();
|
||||||
if (currentView === 'INBOX') {
|
console.log('[DEBUG] API response:', {
|
||||||
const unreadInboxEmails = processedEmails.filter(
|
emailCount: data.emails?.length || 0,
|
||||||
(email: Email) => !email.read && email.folder === 'INBOX'
|
folderCount: data.folders?.length || 0,
|
||||||
).length;
|
hasMore: data.hasMore,
|
||||||
setUnreadCount(unreadInboxEmails);
|
total: data.total
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set available folders
|
||||||
|
if (data.folders) {
|
||||||
|
console.log('[DEBUG] Setting available folders:', data.folders.length);
|
||||||
|
setAvailableFolders(data.folders);
|
||||||
|
|
||||||
|
// Update the mail account with folders
|
||||||
|
setAccounts(prev => prev.map(account =>
|
||||||
|
account.id === 1
|
||||||
|
? { ...account, folders: data.folders }
|
||||||
|
: account
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
console.warn('[DEBUG] No folders returned from API');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process and sort emails
|
||||||
|
const processedEmails = (data.emails || [])
|
||||||
|
.map((email: any) => {
|
||||||
|
// Add proper handling for from field which might be an array or object
|
||||||
|
let fromText = '';
|
||||||
|
let fromName = '';
|
||||||
|
let toText = '';
|
||||||
|
let ccText = '';
|
||||||
|
let bccText = '';
|
||||||
|
|
||||||
|
// Handle 'from' field
|
||||||
|
if (email.from) {
|
||||||
|
if (Array.isArray(email.from)) {
|
||||||
|
if (email.from.length > 0) {
|
||||||
|
if (typeof email.from[0] === 'object') {
|
||||||
|
fromText = email.from[0].address || '';
|
||||||
|
fromName = email.from[0].name || email.from[0].address?.split('@')[0] || '';
|
||||||
|
} else {
|
||||||
|
fromText = email.from[0] || '';
|
||||||
|
fromName = fromText.split('@')[0] || '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (typeof email.from === 'object') {
|
||||||
|
fromText = email.from.address || '';
|
||||||
|
fromName = email.from.name || email.from.address?.split('@')[0] || '';
|
||||||
|
}
|
||||||
|
else if (typeof email.from === 'string') {
|
||||||
|
fromText = email.from;
|
||||||
|
fromName = email.fromName || email.from.split('@')[0] || '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle 'to' field
|
||||||
|
if (email.to) {
|
||||||
|
if (Array.isArray(email.to)) {
|
||||||
|
if (email.to.length > 0) {
|
||||||
|
if (typeof email.to[0] === 'object') {
|
||||||
|
toText = email.to.map((t: any) => t.address || '').join(', ');
|
||||||
|
} else {
|
||||||
|
toText = email.to.join(', ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (typeof email.to === 'object') {
|
||||||
|
toText = email.to.address || '';
|
||||||
|
}
|
||||||
|
else if (typeof email.to === 'string') {
|
||||||
|
toText = email.to;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle 'cc' field
|
||||||
|
if (email.cc) {
|
||||||
|
if (Array.isArray(email.cc)) {
|
||||||
|
if (email.cc.length > 0) {
|
||||||
|
if (typeof email.cc[0] === 'object') {
|
||||||
|
ccText = email.cc.map((c: any) => c.address || '').join(', ');
|
||||||
|
} else {
|
||||||
|
ccText = email.cc.join(', ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (typeof email.cc === 'object') {
|
||||||
|
ccText = email.cc.address || '';
|
||||||
|
}
|
||||||
|
else if (typeof email.cc === 'string') {
|
||||||
|
ccText = email.cc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle 'bcc' field
|
||||||
|
if (email.bcc) {
|
||||||
|
if (Array.isArray(email.bcc)) {
|
||||||
|
if (email.bcc.length > 0) {
|
||||||
|
if (typeof email.bcc[0] === 'object') {
|
||||||
|
bccText = email.bcc.map((b: any) => b.address || '').join(', ');
|
||||||
|
} else {
|
||||||
|
bccText = email.bcc.join(', ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (typeof email.bcc === 'object') {
|
||||||
|
bccText = email.bcc.address || '';
|
||||||
|
}
|
||||||
|
else if (typeof email.bcc === 'string') {
|
||||||
|
bccText = email.bcc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: email.id,
|
||||||
|
accountId: 1,
|
||||||
|
from: fromText,
|
||||||
|
fromName: fromName,
|
||||||
|
to: toText,
|
||||||
|
subject: email.subject || '(No subject)',
|
||||||
|
content: email.content || '',
|
||||||
|
preview: email.preview || '',
|
||||||
|
date: email.date || new Date().toISOString(),
|
||||||
|
read: email.read || false,
|
||||||
|
starred: email.starred || false,
|
||||||
|
folder: email.folder || currentView,
|
||||||
|
cc: ccText,
|
||||||
|
bcc: bccText,
|
||||||
|
flags: email.flags || [],
|
||||||
|
hasAttachments: email.hasAttachments || false
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.sort((a: Email, b: Email) => new Date(b.date).getTime() - new Date(a.date).getTime());
|
||||||
|
|
||||||
|
// Set emails appropriately
|
||||||
|
console.log('[DEBUG] Setting emails state with', processedEmails.length, 'emails');
|
||||||
|
setEmails(prev => {
|
||||||
|
if (isLoadMore) {
|
||||||
|
// Filter out duplicates when appending
|
||||||
|
const existingIds = new Set(prev.map(email => email.id));
|
||||||
|
const uniqueNewEmails = processedEmails.filter((email: Email) => !existingIds.has(email.id));
|
||||||
|
return [...prev, ...uniqueNewEmails];
|
||||||
|
} else {
|
||||||
|
return processedEmails;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update unread count
|
||||||
|
if (currentView === 'INBOX') {
|
||||||
|
const unreadInboxEmails = processedEmails.filter(
|
||||||
|
(email: Email) => !email.read && email.folder === 'INBOX'
|
||||||
|
).length;
|
||||||
|
setUnreadCount(unreadInboxEmails);
|
||||||
|
}
|
||||||
|
|
||||||
|
setHasMore(data.hasMore);
|
||||||
|
setError(null);
|
||||||
|
} catch (err) {
|
||||||
|
console.error('[DEBUG] Error in fetch emails:', err);
|
||||||
|
setError('Failed to load emails');
|
||||||
|
throw err; // Rethrow to ensure the finally block still runs
|
||||||
}
|
}
|
||||||
|
|
||||||
setHasMore(data.hasMore);
|
|
||||||
setError(null);
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error loading emails:', err);
|
console.error('[DEBUG] Error loading emails:', err);
|
||||||
setError('Failed to load emails');
|
setError('Failed to load emails');
|
||||||
} finally {
|
} finally {
|
||||||
|
console.log('[DEBUG] Setting loading states to false in loadEmails finally block');
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
setIsLoadingMore(false);
|
setIsLoadingMore(false);
|
||||||
setIsLoadingInitial(false);
|
setIsLoadingInitial(false);
|
||||||
@ -2146,6 +2175,19 @@ export default function CourrierPage() {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{renderDeleteConfirmDialog()}
|
{renderDeleteConfirmDialog()}
|
||||||
|
|
||||||
|
{/* Debug tools - only shown in development mode */}
|
||||||
|
{process.env.NODE_ENV !== 'production' && (
|
||||||
|
<LoadingFix
|
||||||
|
loading={loading}
|
||||||
|
isLoadingInitial={isLoadingInitial}
|
||||||
|
setLoading={setLoading}
|
||||||
|
setIsLoadingInitial={setIsLoadingInitial}
|
||||||
|
setEmails={setEmails}
|
||||||
|
loadEmails={loadEmails}
|
||||||
|
emails={emails}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user