109 lines
3.5 KiB
TypeScript
109 lines
3.5 KiB
TypeScript
import { useState, useEffect, useRef } from 'react';
|
|
import { Mail } from 'lucide-react';
|
|
import { OutlookNotificationData } from '@/components/outlook-notification';
|
|
|
|
/**
|
|
* Hook to manage email notifications and show Outlook-style notifications
|
|
*/
|
|
export function useEmailNotifications() {
|
|
const [emailNotification, setEmailNotification] = useState<OutlookNotificationData | null>(null);
|
|
const lastEmailIdsRef = useRef<Set<string>>(new Set());
|
|
const notificationQueueRef = useRef<OutlookNotificationData[]>([]);
|
|
const isShowingRef = useRef(false);
|
|
|
|
useEffect(() => {
|
|
// Listen for new emails via custom event
|
|
const handleNewEmails = (event: CustomEvent) => {
|
|
const emails = event.detail?.emails || [];
|
|
const accountMap = event.detail?.accountMap || new Map();
|
|
|
|
if (!emails || emails.length === 0) return;
|
|
|
|
// Find new emails (not in lastEmailIdsRef)
|
|
const newEmails = emails.filter((email: any) => {
|
|
const emailId = email.id;
|
|
if (!lastEmailIdsRef.current.has(emailId) && !email.read) {
|
|
lastEmailIdsRef.current.add(emailId);
|
|
return true;
|
|
}
|
|
return false;
|
|
});
|
|
|
|
// Update lastEmailIdsRef with all current emails
|
|
lastEmailIdsRef.current = new Set(emails.map((e: any) => e.id));
|
|
|
|
// If there are new unread emails, queue them for notification
|
|
if (newEmails.length > 0) {
|
|
newEmails.forEach((email: any) => {
|
|
const account = accountMap.get(email.accountId);
|
|
const notification: OutlookNotificationData = {
|
|
id: `email-${email.id}-${Date.now()}`,
|
|
source: 'email',
|
|
title: 'Courrier',
|
|
subtitle: 'Nouvel email',
|
|
message: `${email.subject || 'Sans objet'} - De ${email.fromName || email.from.split('@')[0]}`,
|
|
icon: Mail,
|
|
iconColor: 'text-green-600',
|
|
iconBgColor: 'bg-green-100',
|
|
borderColor: 'border-green-500',
|
|
link: '/courrier',
|
|
timestamp: new Date(email.date),
|
|
autoDismiss: 10000, // 10 seconds for emails
|
|
actions: [
|
|
{
|
|
label: 'Ouvrir',
|
|
onClick: () => {
|
|
window.location.href = '/courrier';
|
|
},
|
|
variant: 'default',
|
|
className: 'bg-green-600 hover:bg-green-700 text-white',
|
|
},
|
|
],
|
|
};
|
|
|
|
notificationQueueRef.current.push(notification);
|
|
});
|
|
|
|
// Show the first notification if none is currently showing
|
|
if (!isShowingRef.current && notificationQueueRef.current.length > 0) {
|
|
showNextNotification();
|
|
}
|
|
}
|
|
};
|
|
|
|
window.addEventListener('new-emails-detected', handleNewEmails as EventListener);
|
|
|
|
return () => {
|
|
window.removeEventListener('new-emails-detected', handleNewEmails as EventListener);
|
|
};
|
|
}, []);
|
|
|
|
const showNextNotification = () => {
|
|
if (notificationQueueRef.current.length === 0) {
|
|
isShowingRef.current = false;
|
|
return;
|
|
}
|
|
|
|
const nextNotification = notificationQueueRef.current.shift();
|
|
if (nextNotification) {
|
|
isShowingRef.current = true;
|
|
setEmailNotification(nextNotification);
|
|
}
|
|
};
|
|
|
|
const handleDismiss = () => {
|
|
setEmailNotification(null);
|
|
isShowingRef.current = false;
|
|
|
|
// Show next notification after a short delay
|
|
setTimeout(() => {
|
|
showNextNotification();
|
|
}, 500);
|
|
};
|
|
|
|
return {
|
|
emailNotification,
|
|
setEmailNotification: handleDismiss,
|
|
};
|
|
}
|