Files
gridpilot.gg/apps/website/components/errors/NotificationIntegration.tsx
2026-01-24 12:47:49 +01:00

143 lines
4.9 KiB
TypeScript

'use client';
import { useNotifications } from '@/components/notifications/NotificationProvider';
import { connectionMonitor } from '@/lib/gateways/api/base/ApiConnectionMonitor';
import { ApiError } from '@/lib/gateways/api/base/ApiError';
import { useEffect, useState } from 'react';
/**
* Integration component that listens for API errors and shows notifications
* Should be placed at the root level of the app
*/
export function NotificationIntegration() {
const { addNotification } = useNotifications();
const [lastConnectionStatus, setLastConnectionStatus] = useState<string | null>(null);
useEffect(() => {
// Listen for custom notification events from error reporter
const handleNotificationEvent = (event: CustomEvent) => {
const { type, title, message, variant } = event.detail;
addNotification({
type: type || 'error',
title: title || 'Error',
message,
variant: variant || 'toast',
requiresResponse: variant === 'modal',
});
};
// Listen for connection status changes
const handleConnectionChange = () => {
const status = connectionMonitor.getStatus();
if (status === 'disconnected' && lastConnectionStatus !== 'disconnected') {
addNotification({
type: 'connection_lost',
title: 'Connection Lost',
message: 'Unable to connect to the server. Please check your internet connection.',
variant: 'modal',
requiresResponse: true,
});
} else if (status === 'degraded' && lastConnectionStatus !== 'degraded') {
addNotification({
type: 'connection_degraded',
title: 'Connection Issues',
message: 'API connection is experiencing issues. Some features may be limited.',
variant: 'toast',
requiresResponse: false,
});
} else if (status === 'connected' && lastConnectionStatus === 'disconnected') {
addNotification({
type: 'connection_restored',
title: 'Connection Restored',
message: 'API connection has been restored.',
variant: 'toast',
requiresResponse: false,
});
}
setLastConnectionStatus(status);
};
// Listen for gridpilot notification events
if (typeof window !== 'undefined') {
window.addEventListener('gridpilot-notification', handleNotificationEvent as EventListener);
}
// Monitor connection status changes
connectionMonitor.on('disconnected', handleConnectionChange);
connectionMonitor.on('degraded', handleConnectionChange);
connectionMonitor.on('connected', handleConnectionChange);
return () => {
if (typeof window !== 'undefined') {
window.removeEventListener('gridpilot-notification', handleNotificationEvent as EventListener);
}
connectionMonitor.off('disconnected', handleConnectionChange);
connectionMonitor.off('degraded', handleConnectionChange);
connectionMonitor.off('connected', handleConnectionChange);
};
}, [addNotification, lastConnectionStatus]);
return null; // This component doesn't render anything
}
/**
* Hook to manually trigger API error notifications
*/
export function useApiErrorNotifications() {
const { addNotification } = useNotifications();
const showApiError = (error: ApiError) => {
const isConnectivity = error.isConnectivityIssue();
addNotification({
type: error.type.toLowerCase(),
title: error.type.replace('_', ' ').toUpperCase(),
message: error.getUserMessage(),
variant: isConnectivity ? 'modal' : 'toast',
requiresResponse: isConnectivity,
actionUrl: isConnectivity ? undefined : '/support',
});
};
const showConnectionStatus = () => {
const status = connectionMonitor.getStatus();
const health = connectionMonitor.getHealth();
if (status === 'disconnected') {
addNotification({
type: 'connection_lost',
title: 'API Unavailable',
message: 'The API server is not responding. Please try again later.',
variant: 'modal',
requiresResponse: true,
});
} else if (status === 'degraded') {
const reliability = ((health.successfulRequests / Math.max(health.totalRequests, 1)) * 100).toFixed(1);
addNotification({
type: 'connection_degraded',
title: 'Degraded Performance',
message: `API reliability is at ${reliability}%. Some features may not work correctly.`,
variant: 'toast',
requiresResponse: false,
});
} else {
addNotification({
type: 'connection_ok',
title: 'Connection OK',
message: 'API connection is healthy.',
variant: 'toast',
requiresResponse: false,
});
}
};
return {
showApiError,
showConnectionStatus,
getHealth: () => connectionMonitor.getHealth(),
getStatus: () => connectionMonitor.getStatus(),
};
}