Files
btpxpress-frontend/components/ConnectionStatus.tsx
2025-10-01 01:39:07 +00:00

121 lines
4.2 KiB
TypeScript

'use client';
import React, { useState, useEffect, useRef } from 'react';
import { Toast } from 'primereact/toast';
import { ProgressSpinner } from 'primereact/progressspinner';
import { getServerStatusService, ServerStatusEvent } from '../services/serverStatusService';
interface ConnectionStatusProps {
showToasts?: boolean;
showIndicator?: boolean;
className?: string;
}
export const ConnectionStatus: React.FC<ConnectionStatusProps> = ({
showToasts = true,
showIndicator = true,
className = ''
}) => {
const [isOnline, setIsOnline] = useState(true);
const [lastEvent, setLastEvent] = useState<ServerStatusEvent | null>(null);
const [isChecking, setIsChecking] = useState(false);
const toast = useRef<Toast>(null);
const lastStatusRef = useRef<boolean | null>(null);
useEffect(() => {
let unsubscribe: (() => void) | null = null;
const handleServerStatusChange = (online: boolean, event?: ServerStatusEvent) => {
const wasOnline = lastStatusRef.current;
if (wasOnline !== null && wasOnline !== online && showToasts) {
if (online) {
toast.current?.show({
severity: 'success',
summary: 'Serveur backend reconnecté',
detail: 'Le serveur backend est de nouveau accessible',
life: 4000
});
} else {
toast.current?.show({
severity: 'error',
summary: 'Serveur backend inaccessible',
detail: 'Le serveur backend ne répond pas. Vérifiez qu\'il est démarré (mvn quarkus:dev).',
sticky: true
});
}
}
setIsOnline(online);
setLastEvent(event || null);
lastStatusRef.current = online;
};
// Obtenir l'instance du service côté client
const service = getServerStatusService();
if (!service) return;
// S'abonner aux changements de statut via SSE
unsubscribe = service.onStatusChange(handleServerStatusChange);
// Statut initial
const currentStatus = service.getCurrentStatus();
setIsOnline(currentStatus);
lastStatusRef.current = currentStatus;
return () => {
if (unsubscribe) {
unsubscribe();
}
};
}, [showToasts]);
const getStatusText = () => {
if (isChecking) return 'Vérification...';
return isOnline ? 'Serveur OK' : 'Serveur KO';
};
const getStatusTooltip = () => {
const baseStatus = isOnline ? 'Serveur backend accessible' : 'Serveur backend indisponible';
const sseInfo = 'Monitoring via Server-Sent Events';
const eventInfo = lastEvent ? `Dernière mise à jour: ${new Date(lastEvent.timestamp).toLocaleTimeString()}` : '';
return `${baseStatus} - ${sseInfo}${eventInfo ? ` - ${eventInfo}` : ''}`;
};
if (!showIndicator && showToasts) {
return <Toast ref={toast} />;
}
if (!showIndicator) {
return null;
}
return (
<div className={`flex align-items-center gap-2 ${className}`}>
<Toast ref={toast} />
<div className="flex align-items-center gap-2">
{isChecking ? (
<ProgressSpinner
style={{ width: '20px', height: '20px' }}
strokeWidth="4"
/>
) : (
<i
className={`pi ${isOnline ? 'pi-circle-fill text-green-500' : 'pi-circle-fill text-red-500'}`}
style={{ fontSize: '12px' }}
/>
)}
<span
className={`text-sm font-medium ${isOnline ? 'text-green-700' : 'text-red-700'}`}
title={getStatusTooltip()}
>
{getStatusText()}
</span>
</div>
</div>
);
};
export default ConnectionStatus;