Pages corrections pages health
This commit is contained in:
parent
e23965b0fd
commit
d1e34c5081
@ -40,6 +40,8 @@ export function Email() {
|
|||||||
const [accountErrors, setAccountErrors] = useState<Record<string, string>>({});
|
const [accountErrors, setAccountErrors] = useState<Record<string, string>>({});
|
||||||
const { triggerNotification } = useWidgetNotification();
|
const { triggerNotification } = useWidgetNotification();
|
||||||
const lastUnreadCountRef = useRef<number>(-1);
|
const lastUnreadCountRef = useRef<number>(-1);
|
||||||
|
const lastEmailIdsRef = useRef<Set<string>>(new Set());
|
||||||
|
const isInitializedRef = useRef(false);
|
||||||
|
|
||||||
// Create a map for quick account lookup by ID (recalculated when accounts change)
|
// Create a map for quick account lookup by ID (recalculated when accounts change)
|
||||||
const accountMap = useMemo(() => {
|
const accountMap = useMemo(() => {
|
||||||
@ -173,64 +175,87 @@ export function Email() {
|
|||||||
|
|
||||||
// Calculate unread count
|
// Calculate unread count
|
||||||
const currentUnreadCount = transformedEmails.filter(e => !e.read).length;
|
const currentUnreadCount = transformedEmails.filter(e => !e.read).length;
|
||||||
|
const currentEmailIds = new Set(transformedEmails.map(e => e.id));
|
||||||
|
|
||||||
// Trigger notification if count changed
|
// Detect new emails by comparing IDs (more reliable than count)
|
||||||
if (currentUnreadCount !== lastUnreadCountRef.current) {
|
const newEmailIds = new Set(
|
||||||
const previousCount = lastUnreadCountRef.current;
|
Array.from(currentEmailIds).filter(id => !lastEmailIdsRef.current.has(id))
|
||||||
lastUnreadCountRef.current = currentUnreadCount;
|
);
|
||||||
|
const hasNewEmails = newEmailIds.size > 0;
|
||||||
|
|
||||||
// Prepare notification items (unread emails only, max 10)
|
// On first load, just store email IDs without triggering notifications
|
||||||
const notificationItems = transformedEmails
|
if (!isInitializedRef.current) {
|
||||||
.filter(e => !e.read)
|
console.log('[Email Widget] 📧 Initializing - storing existing email IDs without notifications', {
|
||||||
.slice(0, 10)
|
emailCount: transformedEmails.length,
|
||||||
.map(email => {
|
unreadCount: currentUnreadCount,
|
||||||
const account = accountMap.get((email as any).accountId);
|
|
||||||
return {
|
|
||||||
id: email.id,
|
|
||||||
title: email.subject || 'Sans objet',
|
|
||||||
message: `De ${email.fromName || email.from.split('@')[0]}`,
|
|
||||||
link: '/courrier',
|
|
||||||
timestamp: new Date(email.date),
|
|
||||||
metadata: {
|
|
||||||
accountId: (email as any).accountId,
|
|
||||||
accountEmail: account?.email,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// Trigger notification update (for badge)
|
|
||||||
await triggerNotification({
|
|
||||||
source: 'email',
|
|
||||||
count: currentUnreadCount,
|
|
||||||
items: notificationItems,
|
|
||||||
});
|
});
|
||||||
|
lastEmailIdsRef.current = currentEmailIds;
|
||||||
|
lastUnreadCountRef.current = currentUnreadCount;
|
||||||
|
isInitializedRef.current = true;
|
||||||
|
} else {
|
||||||
|
// Trigger notification if count changed or new emails detected
|
||||||
|
if (currentUnreadCount !== lastUnreadCountRef.current || hasNewEmails) {
|
||||||
|
const previousCount = lastUnreadCountRef.current;
|
||||||
|
lastUnreadCountRef.current = currentUnreadCount;
|
||||||
|
|
||||||
// Dispatch event for Outlook-style notifications (only for new emails)
|
// Prepare notification items (unread emails only, max 10)
|
||||||
if (previousCount >= 0 && currentUnreadCount > previousCount) {
|
const notificationItems = transformedEmails
|
||||||
// Get only the newly arrived emails (the difference)
|
|
||||||
const newEmails = transformedEmails
|
|
||||||
.filter(e => !e.read)
|
.filter(e => !e.read)
|
||||||
.slice(0, currentUnreadCount - previousCount); // Only the new ones
|
.slice(0, 10)
|
||||||
|
.map(email => {
|
||||||
if (newEmails.length > 0) {
|
const account = accountMap.get((email as any).accountId);
|
||||||
console.log('[Email Widget] 📧 Dispatching new emails event', {
|
return {
|
||||||
newEmailsCount: newEmails.length,
|
id: email.id,
|
||||||
previousCount,
|
title: email.subject || 'Sans objet',
|
||||||
currentCount: currentUnreadCount,
|
message: `De ${email.fromName || email.from.split('@')[0]}`,
|
||||||
|
link: '/courrier',
|
||||||
|
timestamp: new Date(email.date),
|
||||||
|
metadata: {
|
||||||
|
accountId: (email as any).accountId,
|
||||||
|
accountEmail: account?.email,
|
||||||
|
},
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
window.dispatchEvent(new CustomEvent('new-emails-detected', {
|
// Trigger notification update (for badge)
|
||||||
detail: {
|
await triggerNotification({
|
||||||
emails: transformedEmails,
|
source: 'email',
|
||||||
accountMap: accountMap,
|
count: currentUnreadCount,
|
||||||
|
items: notificationItems,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Dispatch event for Outlook-style notifications (for new emails detected by ID)
|
||||||
|
if (hasNewEmails) {
|
||||||
|
// Get only the newly arrived emails (by ID comparison)
|
||||||
|
const newEmails = transformedEmails
|
||||||
|
.filter(e => newEmailIds.has(e.id) && !e.read)
|
||||||
|
.slice(0, 5); // Limit to 5 most recent new emails
|
||||||
|
|
||||||
|
if (newEmails.length > 0) {
|
||||||
|
console.log('[Email Widget] 📧 Dispatching new emails event', {
|
||||||
|
newEmailsCount: newEmails.length,
|
||||||
|
newEmailIds: Array.from(newEmailIds),
|
||||||
previousCount,
|
previousCount,
|
||||||
currentCount: currentUnreadCount,
|
currentCount: currentUnreadCount,
|
||||||
}
|
previousEmailIds: Array.from(lastEmailIdsRef.current),
|
||||||
}));
|
});
|
||||||
|
|
||||||
|
window.dispatchEvent(new CustomEvent('new-emails-detected', {
|
||||||
|
detail: {
|
||||||
|
emails: transformedEmails,
|
||||||
|
accountMap: accountMap,
|
||||||
|
previousCount,
|
||||||
|
currentCount: currentUnreadCount,
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Always update lastEmailIdsRef to track current state
|
||||||
|
lastEmailIdsRef.current = currentEmailIds;
|
||||||
|
|
||||||
// Show error only if all accounts failed
|
// Show error only if all accounts failed
|
||||||
if (allEmails.length === 0 && accounts.length > 0 && Object.keys(accountErrors).length === accounts.length) {
|
if (allEmails.length === 0 && accounts.length > 0 && Object.keys(accountErrors).length === accounts.length) {
|
||||||
setError('Failed to load emails from all accounts');
|
setError('Failed to load emails from all accounts');
|
||||||
@ -272,12 +297,14 @@ export function Email() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Integrate unified refresh for automatic polling
|
// Integrate unified refresh for automatic polling
|
||||||
|
// Use forceRefresh=true to ensure we get the latest emails immediately
|
||||||
const { refresh } = useUnifiedRefresh({
|
const { refresh } = useUnifiedRefresh({
|
||||||
resource: 'email',
|
resource: 'email',
|
||||||
interval: REFRESH_INTERVALS.EMAIL, // 30 seconds (harmonized)
|
interval: REFRESH_INTERVALS.EMAIL, // 30 seconds (harmonized)
|
||||||
enabled: status === 'authenticated',
|
enabled: status === 'authenticated',
|
||||||
onRefresh: async () => {
|
onRefresh: async () => {
|
||||||
await fetchEmails(false); // Use cache for auto-refresh
|
// Use forceRefresh to bypass cache and get latest emails immediately
|
||||||
|
await fetchEmails(true); // Force refresh to get new emails immediately
|
||||||
await fetchUnreadCount();
|
await fetchUnreadCount();
|
||||||
},
|
},
|
||||||
priority: 'high',
|
priority: 'high',
|
||||||
|
|||||||
@ -30,62 +30,69 @@ export function useEmailNotifications() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only show notifications if the count increased (new emails arrived)
|
// Find new emails by comparing IDs (more reliable than count comparison)
|
||||||
// AND we have a previous count to compare with
|
// This works even if previousCount is -1 (first load after initialization)
|
||||||
if (previousCount >= 0 && currentCount > previousCount) {
|
const newEmails = emails
|
||||||
// Find new emails (not in lastEmailIdsRef) - these are the ones that just arrived
|
.filter((email: any) => {
|
||||||
const newEmails = emails
|
const emailId = email.id;
|
||||||
.filter((email: any) => {
|
return !lastEmailIdsRef.current.has(emailId) && !email.read;
|
||||||
const emailId = email.id;
|
})
|
||||||
return !lastEmailIdsRef.current.has(emailId) && !email.read;
|
.slice(0, 5); // Limit to 5 most recent new emails
|
||||||
})
|
|
||||||
.slice(0, 5); // Limit to 5 most recent new emails
|
|
||||||
|
|
||||||
// Update lastEmailIdsRef with all current emails
|
// Update lastEmailIdsRef with all current emails
|
||||||
lastEmailIdsRef.current = new Set(emails.map((e: any) => e.id));
|
lastEmailIdsRef.current = new Set(emails.map((e: any) => e.id));
|
||||||
|
|
||||||
// If there are new unread emails, queue them for notification
|
// If there are new unread emails, queue them for notification
|
||||||
if (newEmails.length > 0) {
|
// This works regardless of previousCount value
|
||||||
console.log('[useEmailNotifications] 📧 New emails detected:', newEmails.length);
|
if (newEmails.length > 0) {
|
||||||
|
console.log('[useEmailNotifications] 📧 New emails detected:', {
|
||||||
|
newEmailsCount: newEmails.length,
|
||||||
|
previousCount,
|
||||||
|
currentCount,
|
||||||
|
newEmailIds: newEmails.map((e: any) => e.id),
|
||||||
|
});
|
||||||
|
|
||||||
newEmails.forEach((email: any) => {
|
newEmails.forEach((email: any) => {
|
||||||
const account = accountMap.get(email.accountId);
|
const account = accountMap.get(email.accountId);
|
||||||
const notification: OutlookNotificationData = {
|
const notification: OutlookNotificationData = {
|
||||||
id: `email-${email.id}-${Date.now()}`,
|
id: `email-${email.id}-${Date.now()}`,
|
||||||
source: 'email',
|
source: 'email',
|
||||||
title: 'Courrier',
|
title: 'Courrier',
|
||||||
subtitle: 'Nouvel email',
|
subtitle: 'Nouvel email',
|
||||||
message: `${email.subject || 'Sans objet'} - De ${email.fromName || email.from.split('@')[0]}`,
|
message: `${email.subject || 'Sans objet'} - De ${email.fromName || email.from.split('@')[0]}`,
|
||||||
icon: Mail,
|
icon: Mail,
|
||||||
iconColor: 'text-green-600',
|
iconColor: 'text-green-600',
|
||||||
iconBgColor: 'bg-green-100',
|
iconBgColor: 'bg-green-100',
|
||||||
borderColor: 'border-green-500',
|
borderColor: 'border-green-500',
|
||||||
link: '/courrier',
|
link: '/courrier',
|
||||||
timestamp: new Date(email.date),
|
timestamp: new Date(email.date),
|
||||||
autoDismiss: 10000, // 10 seconds for emails
|
autoDismiss: 10000, // 10 seconds for emails
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
label: 'Ouvrir',
|
label: 'Ouvrir',
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
window.location.href = '/courrier';
|
window.location.href = '/courrier';
|
||||||
},
|
|
||||||
variant: 'default',
|
|
||||||
className: 'bg-green-600 hover:bg-green-700 text-white',
|
|
||||||
},
|
},
|
||||||
],
|
variant: 'default',
|
||||||
};
|
className: 'bg-green-600 hover:bg-green-700 text-white',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
notificationQueueRef.current.push(notification);
|
notificationQueueRef.current.push(notification);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Show the first notification if none is currently showing
|
// Show the first notification if none is currently showing
|
||||||
if (!isShowingRef.current && notificationQueueRef.current.length > 0) {
|
if (!isShowingRef.current && notificationQueueRef.current.length > 0) {
|
||||||
showNextNotification();
|
showNextNotification();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Just update the email IDs without showing notifications
|
console.log('[useEmailNotifications] ⏭️ No new emails detected', {
|
||||||
lastEmailIdsRef.current = new Set(emails.map((e: any) => e.id));
|
previousCount,
|
||||||
|
currentCount,
|
||||||
|
totalEmails: emails.length,
|
||||||
|
lastEmailIdsCount: lastEmailIdsRef.current.size,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user