121 lines
4.2 KiB
TypeScript
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; |