Saltar al contenido principal

Sistema de Dashboard

En el complejo ecosistema de KodeChain, donde múltiples nodos operan en armonía produciendo bloques y procesando transacciones, el dashboard emerge como el puente entre el código subyacente y la comprensión humana. Implementado como una aplicación web moderna en monitoring/html/index.html, este sistema transforma datos técnicos en una experiencia visual intuitiva y atractiva.

La Arquitectura Visual

HTML5 como Fundación

<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>KodeChain Node Validator v2 - Dashboard</title>
<!-- Estilos integrados -->
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
}
</style>
</head>
<body>
<!-- Contenido dinámico -->
</body>
</html>

La estructura HTML5 moderna establece las bases para una interfaz responsive y accesible.

CSS3: El Arte Visual

.container {
max-width: 1200px;
margin: 0 auto;
}

.nodes-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
gap: 20px;
margin-bottom: 30px;
}

.node-card {
background: white;
border-radius: 15px;
padding: 25px;
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.node-card:hover {
transform: translateY(-5px);
box-shadow: 0 15px 40px rgba(0,0,0,0.3);
}

CSS Grid y Flexbox crean un layout adaptable que se ajusta automáticamente a diferentes tamaños de pantalla.

Componentes Interactivos

Tarjetas de Nodo Dinámicas

<div class="node-card" id="bootstrap-card">
<div class="node-header">
<div class="node-icon bootstrap">🚀</div>
<div class="node-info">
<h3>Nodo Bootstrap</h3>
<p><span class="status-indicator status-unknown" id="bootstrap-status"></span>Estado: <span id="bootstrap-status-text">Verificando...</span></p>
</div>
</div>

<div class="metrics">
<div class="metric">
<div class="metric-value" id="bootstrap-height">-</div>
<div class="metric-label">Altura</div>
</div>
<div class="metric">
<div class="metric-value" id="bootstrap-consensus">NONE</div>
<div class="metric-label">Consenso</div>
</div>
</div>

<div class="actions">
<a href="/bootstrap/" target="_blank" class="btn btn-primary">API Bootstrap</a>
<button class="btn btn-secondary" onclick="checkNodeStatus('bootstrap')">Verificar</button>
</div>
</div>

Cada tarjeta representa un nodo con información vital: estado, métricas y acciones disponibles.

Indicadores de Estado Visuales

.status-indicator {
display: inline-block;
width: 12px;
height: 12px;
border-radius: 50%;
margin-right: 8px;
}

.status-online { background: #4CAF50; }
.status-offline { background: #f44336; }
.status-unknown { background: #ff9800; }

Indicadores de color intuitivos permiten identificación rápida del estado de cada componente.

JavaScript: La Lógica Interactiva

Configuración de Nodos

const nodes = ['bootstrap', 'dpos', 'pbft'];
const nodeConfigs = {
bootstrap: { port: 8080, consensus: 'NONE' },
dpos: { port: 8081, consensus: 'DPOS' },
pbft: { port: 8082, consensus: 'PBFT' }
};

Configuración centralizada que define las características de cada tipo de nodo.

Verificación de Estado Asíncrona

async function checkNodeStatus(nodeName) {
const card = document.getElementById(`${nodeName}-card`);
const statusIndicator = document.getElementById(`${nodeName}-status`);
const statusText = document.getElementById(`${nodeName}-status-text`);
const heightElement = document.getElementById(`${nodeName}-height`);

card.classList.add('loading');
statusText.textContent = 'Verificando...';

try {
const response = await fetch(`/api/status`, {
headers: {
'X-Consensus-Type': nodeConfigs[nodeName].consensus
}
});

if (response.ok) {
const data = await response.json();
statusIndicator.className = 'status-indicator status-online';
statusText.textContent = 'En línea';
heightElement.textContent = data.height || '0';
} else {
throw new Error(`HTTP ${response.status}`);
}
} catch (error) {
console.error(`Error verificando ${nodeName}:`, error);
statusIndicator.className = 'status-indicator status-offline';
statusText.textContent = 'Fuera de línea';
heightElement.textContent = '-';
} finally {
card.classList.remove('loading');
}
}

Función asíncrona que maneja la comunicación con las APIs de los nodos, actualizando la UI en consecuencia.

Actualización Automática

async function refreshAllNodes() {
const refreshBtn = document.querySelector('.refresh-btn');
refreshBtn.textContent = '⏳';
refreshBtn.disabled = true;

for (const node of nodes) {
await checkNodeStatus(node);
await new Promise(resolve => setTimeout(resolve, 500));
}

refreshBtn.textContent = '🔄';
refreshBtn.disabled = false;
}

document.addEventListener('DOMContentLoaded', function() {
refreshAllNodes();
setInterval(refreshAllNodes, 30000);
});

Sistema de actualización automática cada 30 segundos, con delays controlados para evitar sobrecarga.

Diseño Responsive

Adaptabilidad Móvil

@media (max-width: 768px) {
.nodes-grid {
grid-template-columns: 1fr;
}

.metrics {
grid-template-columns: 1fr;
}
}

Media queries que transforman el layout para dispositivos móviles, manteniendo usabilidad.

Estados Interactivos

.btn {
padding: 10px 20px;
border: none;
border-radius: 8px;
cursor: pointer;
font-size: 0.9rem;
font-weight: 500;
transition: all 0.3s ease;
text-decoration: none;
display: inline-block;
text-align: center;
}

.btn-primary {
background: #667eea;
color: white;
}

.btn-primary:hover {
background: #5a6fd8;
transform: translateY(-2px);
}

Botones con efectos hover y transiciones suaves que mejoran la experiencia de usuario.

Arquitectura de Comunicación

API Endpoints

El dashboard se comunica con los nodos a través de endpoints específicos:

  • Bootstrap: /bootstrap/ - Infraestructura inicial
  • DPOS: /dpos/ - Consenso Delegated Proof of Stake
  • PBFT: /pbft/ - Consenso Practical Byzantine Fault Tolerance

Headers Personalizados

headers: {
'X-Consensus-Type': nodeConfigs[nodeName].consensus
}

Headers que permiten a los nodos identificar el tipo de consulta y responder apropiadamente.

Estados y Feedback Visual

Loading States

.loading {
opacity: 0.6;
pointer-events: none;
}

Estados de carga que deshabilitan interacciones durante verificaciones.

Botón de Refresh Flotante

.refresh-btn {
position: fixed;
bottom: 30px;
right: 30px;
width: 60px;
height: 60px;
border-radius: 50%;
background: #667eea;
color: white;
border: none;
cursor: pointer;
font-size: 1.5rem;
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
transition: all 0.3s ease;
}

.refresh-btn:hover {
background: #5a6fd8;
transform: scale(1.1);
}

Botón flotante que permite actualización manual en cualquier momento.

Manejo de Errores

Try-Catch Robusto

} catch (error) {
console.error(`Error verificando ${nodeName}:`, error);
statusIndicator.className = 'status-indicator status-offline';
statusText.textContent = 'Fuera de línea';
heightElement.textContent = '-';
}

Manejo de errores que actualiza la UI para reflejar problemas de conectividad.

Logging para Debugging

console.error(`Error verificando ${nodeName}:`, error);

Logs en consola que ayudan en el debugging y monitoreo del sistema.

El Rol en las Operaciones

Monitoreo en Tiempo Real

El dashboard proporciona:

  • Estado de conectividad: Nodos online/offline
  • Métricas de blockchain: Altura actual
  • Tipo de consenso: Identificación del rol
  • Acciones directas: Enlaces a APIs específicas

Toma de Decisiones

Los operadores pueden:

  • Identificar problemas: Nodos offline o desincronizados
  • Acceder rápidamente: APIs directas desde el dashboard
  • Monitorear tendencias: Cambios en altura de blockchain

Experiencia de Usuario

  • Intuitivo: Diseño claro y moderno
  • Responsive: Funciona en cualquier dispositivo
  • Actualización automática: Información siempre fresca
  • Acciones contextuales: Botones relevantes por nodo

El Arte de la Visualización

Cada pixel del dashboard, cada transición CSS, cada llamada AJAX representa la transformación de datos técnicos complejos en información accesible. El sistema no solo muestra el estado del sistema; cuenta la historia de una red blockchain viva y dinámica.

Desde el primer DOMContentLoaded hasta la actualización automática cada 30 segundos, el dashboard transforma el monitoreo de sistemas en una experiencia visual atractiva y funcional.

En KodeChain, el dashboard no es solo una interfaz; es el espejo que refleja la salud y vitalidad de toda la red distribuida, permitiendo que operadores y desarrolladores mantengan el pulso del sistema con confianza y claridad.