Files
csf-web/src/components/FirewallStatusCard.tsx
2025-09-20 18:42:04 +02:00

126 líneas
4.2 KiB
TypeScript
Original Blame Histórico

Este archivo contiene caracteres Unicode invisibles
Este archivo contiene caracteres Unicode invisibles que son indistinguibles para los humanos, pero que pueden ser procesados de forma diferente por un ordenador. Si crees que esto es intencional, puedes ignorar esta advertencia. Usa el botón de Escape para revelarlos.
import { useState, useEffect } from 'react'
import { useCSFApi } from '@/hooks/use-csf-api'
interface FirewallStatusCardProps {
className?: string
}
export function FirewallStatusCard({ className = '' }: FirewallStatusCardProps) {
const {
status,
getStatus,
startFirewall,
stopFirewall,
restartFirewall,
loading,
error
} = useCSFApi()
const [actionLoading, setActionLoading] = useState(false)
useEffect(() => {
getStatus()
}, [getStatus])
const handleAction = async (action: () => Promise<boolean>) => {
setActionLoading(true)
try {
await action()
} finally {
setActionLoading(false)
}
}
const getStatusColor = () => {
if (!status) return 'bg-gray-500'
return status.running ? 'bg-green-500' : 'bg-red-500'
}
const getStatusText = () => {
if (!status) return 'Desconocido'
return status.running ? 'Activo' : 'Inactivo'
}
return (
<div className={`bg-white rounded-lg shadow-md p-6 ${className}`}>
<div className="flex items-center justify-between mb-4">
<h3 className="text-lg font-semibold text-gray-900">Estado del Firewall</h3>
<div className={`w-3 h-3 rounded-full ${getStatusColor()}`}></div>
</div>
{error && (
<div className="bg-red-50 border border-red-200 rounded-md p-3 mb-4">
<p className="text-red-600 text-sm">{error}</p>
</div>
)}
<div className="space-y-3">
<div className="flex justify-between">
<span className="text-gray-600">Estado:</span>
<span className={`font-medium ${status?.running ? 'text-green-600' : 'text-red-600'}`}>
{getStatusText()}
</span>
</div>
{status && (
<>
<div className="flex justify-between">
<span className="text-gray-600">Versión:</span>
<span className="font-medium">{status.version}</span>
</div>
<div className="flex justify-between">
<span className="text-gray-600">IPv4:</span>
<span className={`font-medium ${status.ipv4_active ? 'text-green-600' : 'text-red-600'}`}>
{status.ipv4_active ? 'Activo' : 'Inactivo'}
</span>
</div>
<div className="flex justify-between">
<span className="text-gray-600">IPv6:</span>
<span className={`font-medium ${status.ipv6_active ? 'text-green-600' : 'text-red-600'}`}>
{status.ipv6_active ? 'Activo' : 'Inactivo'}
</span>
</div>
{status.testing_mode && (
<div className="bg-yellow-50 border border-yellow-200 rounded-md p-3">
<p className="text-yellow-700 text-sm font-medium">
Modo de prueba activado
</p>
</div>
)}
</>
)}
</div>
<div className="mt-6 space-y-2">
<div className="flex gap-2">
<button
onClick={() => handleAction(startFirewall)}
disabled={loading || actionLoading || status?.running}
className="flex-1 bg-green-600 text-white px-4 py-2 rounded-md hover:bg-green-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
>
{actionLoading ? 'Procesando...' : 'Iniciar'}
</button>
<button
onClick={() => handleAction(stopFirewall)}
disabled={loading || actionLoading || !status?.running}
className="flex-1 bg-red-600 text-white px-4 py-2 rounded-md hover:bg-red-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
>
{actionLoading ? 'Procesando...' : 'Detener'}
</button>
</div>
<button
onClick={() => handleAction(restartFirewall)}
disabled={loading || actionLoading}
className="w-full bg-blue-600 text-white px-4 py-2 rounded-md hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
>
{actionLoading ? 'Reiniciando...' : 'Reiniciar'}
</button>
</div>
</div>
)
}