NeahStable/hooks/use-widget-notification.ts
2026-01-16 00:12:15 +01:00

97 lines
2.8 KiB
TypeScript

import { useCallback, useRef } from 'react';
import { useSession } from 'next-auth/react';
import { logger } from '@/lib/logger';
export interface NotificationItem {
id: string;
title: string;
message: string;
link?: string;
timestamp: Date;
metadata?: Record<string, any>;
}
export interface WidgetNotificationData {
source: 'email' | 'rocketchat' | 'leantime' | 'calendar';
count: number;
items?: NotificationItem[];
}
/**
* Hook to trigger notifications from widgets
* Use this when widgets detect new items (emails, messages, tasks, events)
*/
export function useWidgetNotification() {
const { data: session } = useSession();
const lastUpdateRef = useRef<Record<string, number>>({});
const DEBOUNCE_MS = 1000; // 1 second debounce per source
const triggerNotification = useCallback(async (data: WidgetNotificationData) => {
if (!session?.user?.id) {
logger.debug('[useWidgetNotification] No session, skipping notification');
return;
}
const { source, count, items } = data;
const now = Date.now();
const lastUpdate = lastUpdateRef.current[source] || 0;
// Debounce per source to avoid excessive API calls
if (now - lastUpdate < DEBOUNCE_MS) {
logger.debug('[useWidgetNotification] Debouncing notification', { source, count });
return;
}
lastUpdateRef.current[source] = now;
try {
logger.debug('[useWidgetNotification] Triggering notification update', {
source,
count,
itemsCount: items?.length || 0,
});
// Send notification data to the registry
const response = await fetch('/api/notifications/update', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify({
source,
count,
items: items?.map(item => ({
...item,
timestamp: item.timestamp.toISOString(),
})) || [],
}),
});
if (!response.ok) {
const errorText = await response.text();
logger.error('[useWidgetNotification] Failed to update notification', {
source,
status: response.status,
error: errorText,
});
return;
}
// Dispatch event for immediate UI update
window.dispatchEvent(new CustomEvent('notification-updated', {
detail: { source, count }
}));
logger.debug('[useWidgetNotification] Notification updated successfully', {
source,
count,
});
} catch (error) {
logger.error('[useWidgetNotification] Error updating notification', {
source,
error: error instanceof Error ? error.message : String(error),
});
}
}, [session?.user?.id]);
return { triggerNotification };
}