143 lines
4.9 KiB
TypeScript
143 lines
4.9 KiB
TypeScript
'use client';
|
|
|
|
import { useEffect, useState } from 'react';
|
|
import { useNotifications } from '@/components/notifications/NotificationProvider';
|
|
import { ApiError } from '@/lib/api/base/ApiError';
|
|
import { connectionMonitor } from '@/lib/api/base/ApiConnectionMonitor';
|
|
|
|
/**
|
|
* 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, autoDismiss } = 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(),
|
|
};
|
|
} |