import React, { useMemo, useState } from "react"; import { motion } from "framer-motion"; import { Activity, AlertTriangle, CheckCircle2, Clock, MapPinned, Network, Router, Server, Wifi, Search, BarChart3 } from "lucide-react"; import { Card, CardContent } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; const sedes = [ { id: 1, nombre: "Sede Mitre", ubicacion: "Berazategui", estado: "down", router: "MK-MITRE", ip: "181.30.60.254", disponibilidad: 96.4, caidasHoy: 3, ultimaCaida: "28/04/2026 17:42:10", ultimoUp: "28/04/2026 18:03:55", equipos: [ { nombre: "Uplink ether1", tipo: "puerto", estado: "down" }, { nombre: "Switch Core", tipo: "switch", estado: "down" }, { nombre: "AP Galpón", tipo: "ap", estado: "up" }, { nombre: "Cámara Acceso", tipo: "camara", estado: "unknown" }, ], }, { id: 2, nombre: "Sede Centro", ubicacion: "Quilmes", estado: "up", router: "MK-CENTRO", ip: "10.10.20.1", disponibilidad: 99.8, caidasHoy: 0, ultimaCaida: "27/04/2026 22:11:04", ultimoUp: "27/04/2026 22:12:18", equipos: [ { nombre: "Uplink sfp1", tipo: "puerto", estado: "up" }, { nombre: "Switch Piso 1", tipo: "switch", estado: "up" }, { nombre: "AP Recepción", tipo: "ap", estado: "up" }, ], }, { id: 3, nombre: "Sede Norte", ubicacion: "Hudson", estado: "warning", router: "MK-NORTE", ip: "10.10.30.1", disponibilidad: 98.2, caidasHoy: 1, ultimaCaida: "28/04/2026 09:18:41", ultimoUp: "28/04/2026 09:25:03", equipos: [ { nombre: "Uplink ether2", tipo: "puerto", estado: "up" }, { nombre: "Switch Cámaras", tipo: "switch", estado: "warning" }, { nombre: "AP Patio", tipo: "ap", estado: "up" }, ], }, { id: 4, nombre: "Sede Sur", ubicacion: "Ezpeleta", estado: "up", router: "MK-SUR", ip: "10.10.40.1", disponibilidad: 99.1, caidasHoy: 0, ultimaCaida: "26/04/2026 03:02:10", ultimoUp: "26/04/2026 03:04:22", equipos: [ { nombre: "Uplink sfp1", tipo: "puerto", estado: "up" }, { nombre: "Switch Clientes", tipo: "switch", estado: "up" }, ], }, { id: 5, nombre: "Sede Oeste", ubicacion: "Florencio Varela", estado: "up", router: "MK-OESTE", ip: "10.10.50.1", disponibilidad: 99.5, caidasHoy: 0, ultimaCaida: "25/04/2026 11:44:31", ultimoUp: "25/04/2026 11:45:02", equipos: [ { nombre: "Uplink ether1", tipo: "puerto", estado: "up" }, { nombre: "AP Torre", tipo: "ap", estado: "up" }, ], }, ]; const eventos = [ { fecha: "28/04/2026 18:03:55", sede: "Sede Mitre", equipo: "MK-MITRE", detalle: "Ping volvió a responder", evento: "ping_up" }, { fecha: "28/04/2026 17:42:10", sede: "Sede Mitre", equipo: "Uplink ether1", detalle: "Cable desconectado / link down", evento: "port_down" }, { fecha: "28/04/2026 09:25:03", sede: "Sede Norte", equipo: "Switch Cámaras", detalle: "Equipo volvió a responder", evento: "ping_up" }, { fecha: "28/04/2026 09:18:41", sede: "Sede Norte", equipo: "Switch Cámaras", detalle: "Pérdida de ping", evento: "ping_down" }, { fecha: "27/04/2026 22:12:18", sede: "Sede Centro", equipo: "MK-CENTRO", detalle: "Router online", evento: "ping_up" }, ]; const stateClass = { up: "border-emerald-500/40 bg-emerald-500/10 text-emerald-300", down: "border-red-500/50 bg-red-500/10 text-red-300", warning: "border-amber-500/50 bg-amber-500/10 text-amber-300", unknown: "border-slate-500/50 bg-slate-500/10 text-slate-300", }; const dotClass = { up: "bg-emerald-400", down: "bg-red-400", warning: "bg-amber-400", unknown: "bg-slate-400", }; function Badge({ estado }) { const label = estado === "up" ? "UP" : estado === "down" ? "DOWN" : estado === "warning" ? "WARNING" : "UNKNOWN"; return {label}; } function iconByType(tipo) { if (tipo === "ap") return ; if (tipo === "puerto") return ; if (tipo === "switch") return ; return ; } export default function MonitorMikrotikDemo() { const [selected, setSelected] = useState(sedes[0]); const [query, setQuery] = useState(""); const resumen = useMemo(() => { const up = sedes.filter((s) => s.estado === "up").length; const down = sedes.filter((s) => s.estado === "down").length; const warning = sedes.filter((s) => s.estado === "warning").length; const equipos = sedes.reduce((acc, s) => acc + s.equipos.length, 0); return { up, down, warning, equipos }; }, []); const sedesFiltradas = sedes.filter((s) => `${s.nombre} ${s.ubicacion} ${s.router}`.toLowerCase().includes(query.toLowerCase())); return (
Monitor MikroTik multi-sede

Panel de monitoreo de red

Vista de muestra: 5 sedes, eventos, topología, disponibilidad y estado de puertos.

{resumen.up}
Sedes UP
{resumen.down}
Sedes DOWN
{resumen.warning}
Con alerta
{resumen.equipos}
Equipos / puertos

Topología general

Nodo central conectado a las 5 sedes.

CORE / INTERNET
Monitor central
{sedes.map((s) => ( setSelected(s)} className={`rounded-3xl border p-4 text-left transition ${selected.id === s.id ? "border-cyan-400 bg-cyan-500/10" : "border-slate-800 bg-slate-900/80"}`} >
{s.nombre}
{s.router}
))}

Detalle de sede

{selected.ubicacion} · {selected.ip}

{selected.router}
{selected.nombre}
{selected.disponibilidad}%
Uptime
{selected.caidasHoy}
Caídas hoy
{selected.equipos.length}
Items
{selected.equipos.map((e) => (
{iconByType(e.tipo)}
{e.nombre}
{e.tipo}
))}

Gráfico de disponibilidad

{sedes.map((s) => (
{s.nombre}{s.disponibilidad}%
))}

Sedes monitoreadas

Filtro rápido por nombre, router o ubicación.

setQuery(e.target.value)} placeholder="Buscar sede..." className="bg-transparent text-sm outline-none placeholder:text-slate-600" />
{sedesFiltradas.map((s) => ( ))}
SedeRouterEstadoÚltima caída
{s.nombre}
{s.ubicacion}
{s.router} {s.ultimaCaida}

Últimos eventos

{eventos.map((ev, i) => ( ))}
FechaSedeEquipoEventoDetalle
{ev.fecha} {ev.sede} {ev.equipo} {ev.evento} {ev.detalle}
); }