Remove standalone Network page, add as future tab on Infrastructure
Drop the /network route, page, and sidebar entry. Network will instead become a tab alongside Overview on the Infrastructure page later, so add a disabled placeholder tab for now. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BbJV5nm8KPVH1oNJYKpnoF
This commit is contained in:
parent
f29bce550f
commit
106af334a3
5 changed files with 18 additions and 388 deletions
|
|
@ -4,7 +4,6 @@ import Sidebar from './components/Sidebar'
|
|||
import TopBar from './components/TopBar'
|
||||
import Glance from './pages/Glance'
|
||||
import Infrastructure from './pages/Infrastructure'
|
||||
import Network from './pages/Network'
|
||||
|
||||
function App() {
|
||||
const [sidebarCollapsed, setSidebarCollapsed] = useState(false)
|
||||
|
|
@ -56,7 +55,6 @@ function App() {
|
|||
<Routes>
|
||||
<Route path="/" element={<Glance />} />
|
||||
<Route path="/infrastructure" element={<Infrastructure />} />
|
||||
<Route path="/network" element={<Network />} />
|
||||
</Routes>
|
||||
</section>
|
||||
</main>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ import { useLocation, Link } from 'react-router-dom'
|
|||
import {
|
||||
LayoutGrid,
|
||||
Server,
|
||||
Globe,
|
||||
Bookmark,
|
||||
Terminal,
|
||||
Settings,
|
||||
|
|
@ -18,7 +17,6 @@ interface SidebarProps {
|
|||
const navItems = [
|
||||
{ icon: LayoutGrid, label: 'Glance', route: '/' },
|
||||
{ icon: Server, label: 'Infrastructure', route: '/infrastructure' },
|
||||
{ icon: Globe, label: 'Network', route: '/network' },
|
||||
{ icon: Bookmark, label: 'BookNest', route: '/booknest' },
|
||||
{ icon: Terminal, label: 'Terminal', route: '/terminal' },
|
||||
{ icon: Settings, label: 'Settings', route: '/settings' },
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import { Search, Bell, ChevronDown, User, Palette, LogOut, Shield, HelpCircle }
|
|||
const pageTitles: Record<string, string> = {
|
||||
'/': 'Glance',
|
||||
'/infrastructure': 'Infrastructure',
|
||||
'/network': 'Network',
|
||||
'/booknest': 'BookNest',
|
||||
'/terminal': 'Terminal',
|
||||
'/settings': 'Settings',
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { PieChart, Pie, Cell, ResponsiveContainer, LineChart, Line, XAxis } from
|
|||
import { Plus, Server, Activity, AlertTriangle, DollarSign } from 'lucide-react'
|
||||
|
||||
const subTabs = ['Overview']
|
||||
const futureSubTabs = ['Network']
|
||||
|
||||
const statusCards = [
|
||||
{ label: 'Total Resources', value: '128', icon: Server, sub: '+4 this week' },
|
||||
|
|
@ -174,6 +175,23 @@ export default function Infrastructure() {
|
|||
</button>
|
||||
)
|
||||
})}
|
||||
{futureSubTabs.map((tab) => (
|
||||
<button
|
||||
key={tab}
|
||||
disabled
|
||||
title="Coming soon"
|
||||
className="cursor-not-allowed bg-transparent border-none whitespace-nowrap"
|
||||
style={{
|
||||
fontSize: '12px',
|
||||
fontWeight: 500,
|
||||
padding: '8px 14px',
|
||||
borderRadius: '8px',
|
||||
color: '#4A4D55',
|
||||
}}
|
||||
>
|
||||
{tab}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<button
|
||||
className="flex items-center gap-2 cursor-pointer transition-colors whitespace-nowrap"
|
||||
|
|
|
|||
|
|
@ -1,383 +0,0 @@
|
|||
import { useState } from 'react'
|
||||
import { PieChart, Pie, Cell, ResponsiveContainer, AreaChart, Area, XAxis } from 'recharts'
|
||||
import { Activity, Gauge, ShieldAlert, Radio, Zap, Download, ChevronDown, Globe2 } from 'lucide-react'
|
||||
|
||||
const subTabs = ['Overview']
|
||||
|
||||
const statusCards = [
|
||||
{ label: 'Network Health', value: '98.7%', icon: Activity, sub: '↑ 2.3% yesterday', color: '#2ECC71' },
|
||||
{ label: 'Total Traffic', value: '1.23 Tbps', icon: Radio, sub: '↑ 18.6% yesterday' },
|
||||
{ label: 'Packet Loss', value: '0.02%', icon: Gauge, sub: '↓ 0.01% yesterday', color: '#2ECC71' },
|
||||
{ label: 'Active Connections', value: '28,457', icon: Zap, sub: '↑ 6.7% yesterday' },
|
||||
{ label: 'Threats Blocked', value: '152', icon: ShieldAlert, sub: '↑ 12.4% yesterday', color: '#E67E22' },
|
||||
{ label: 'Avg. Latency', value: '12.4 ms', icon: Activity, sub: '↓ 8.1% yesterday', color: '#2ECC71' },
|
||||
]
|
||||
|
||||
const topTalkers = [
|
||||
{ name: 'web-app-01', rate: '203.4 Gbps' },
|
||||
{ name: 'db-primary', rate: '156.7 Gbps' },
|
||||
{ name: 'cache-cluster', rate: '98.3 Gbps' },
|
||||
{ name: 'api-gateway', rate: '76.1 Gbps' },
|
||||
{ name: 'backup-server', rate: '54.8 Gbps' },
|
||||
]
|
||||
|
||||
const regions = [
|
||||
{ name: 'us-east-1', x: '22%', y: '38%', status: 'live' },
|
||||
{ name: 'us-west-2', x: '12%', y: '42%', status: 'live' },
|
||||
{ name: 'eu-west-1', x: '48%', y: '30%', status: 'warning' },
|
||||
{ name: 'ap-southeast-1', x: '78%', y: '58%', status: 'live' },
|
||||
{ name: 'sa-east-1', x: '32%', y: '72%', status: 'live' },
|
||||
{ name: 'ap-northeast-1', x: '85%', y: '40%', status: 'critical' },
|
||||
]
|
||||
|
||||
const regionStatusColor: Record<string, string> = {
|
||||
live: '#2ECC71',
|
||||
warning: '#E67E22',
|
||||
critical: '#E74C3C',
|
||||
}
|
||||
|
||||
const interfaces = [
|
||||
{ name: 'ethernet1/1', percentage: 85 },
|
||||
{ name: 'ethernet1/2', percentage: 72 },
|
||||
{ name: 'ethernet1/3', percentage: 68 },
|
||||
{ name: 'ethernet1/4', percentage: 55 },
|
||||
{ name: 'ethernet1/5', percentage: 48 },
|
||||
]
|
||||
|
||||
const alertSummary = [
|
||||
{ label: 'Critical', value: 2, color: '#E74C3C' },
|
||||
{ label: 'Warning', value: 5, color: '#E67E22' },
|
||||
{ label: 'Info', value: 12, color: '#2ECC71' },
|
||||
]
|
||||
|
||||
const trafficData = Array.from({ length: 12 }, (_, i) => ({
|
||||
hour: i * 2,
|
||||
inbound: 500 + i * 40 + Math.sin(i / 2) * 60,
|
||||
outbound: 350 + i * 30 + Math.cos(i / 3) * 50,
|
||||
total: 900 + i * 60 + Math.sin(i / 2.5) * 80,
|
||||
}))
|
||||
|
||||
const protocolData = [
|
||||
{ name: 'TCP', value: 65, color: '#C8A434' },
|
||||
{ name: 'UDP', value: 19, color: '#E67E22' },
|
||||
{ name: 'ICMP', value: 7, color: '#2ECC71' },
|
||||
{ name: 'DNS', value: 4, color: '#7A7D85' },
|
||||
{ name: 'Others', value: 5, color: '#3B82F6' },
|
||||
]
|
||||
|
||||
const recentEvents = [
|
||||
{ title: 'ethernet1/2 UP', source: 'Interface restored', time: '2m ago' },
|
||||
{ title: 'High bandwidth detected', source: 'web-app-01', time: '8m ago' },
|
||||
{ title: 'New device joined', source: '10.0.1.45', time: '15m ago' },
|
||||
{ title: 'VPN tunnel established', source: 'us-west-2', time: '22m ago' },
|
||||
{ title: 'Blocked threat', source: '185.199.108.153', time: '35m ago' },
|
||||
]
|
||||
|
||||
const cardBase: React.CSSProperties = {
|
||||
backgroundColor: 'rgba(10, 10, 12, 0.92)',
|
||||
border: '1px solid rgba(200, 164, 52, 0.08)',
|
||||
borderRadius: '12px',
|
||||
padding: '20px',
|
||||
boxShadow: '0 0 20px rgba(200, 164, 52, 0.03)',
|
||||
transition: 'border-color 0.2s ease',
|
||||
position: 'relative',
|
||||
overflow: 'hidden',
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
}
|
||||
|
||||
const sectionTitle: React.CSSProperties = {
|
||||
fontSize: '11px',
|
||||
textTransform: 'uppercase',
|
||||
letterSpacing: '1.5px',
|
||||
color: '#7A7D85',
|
||||
fontWeight: 500,
|
||||
marginBottom: '16px',
|
||||
}
|
||||
|
||||
function framedCard(bgUrl: string): React.CSSProperties {
|
||||
return {
|
||||
backgroundImage: `url(${bgUrl})`,
|
||||
backgroundSize: '100% 100%',
|
||||
backgroundPosition: 'center',
|
||||
backgroundRepeat: 'no-repeat',
|
||||
position: 'relative',
|
||||
overflow: 'hidden',
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
padding: '20px 20px 64px 20px',
|
||||
}
|
||||
}
|
||||
|
||||
const cardVignette: React.CSSProperties = {
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
pointerEvents: 'none',
|
||||
background: 'radial-gradient(ellipse closest-side at center, transparent 70%, var(--color-page) 100%)',
|
||||
}
|
||||
|
||||
const cardDim: React.CSSProperties = {
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
pointerEvents: 'none',
|
||||
backgroundColor: 'rgba(8, 8, 10, 0.45)',
|
||||
}
|
||||
|
||||
function Donut({ data, centerLabel }: { data: { name: string; value: number; color: string }[]; centerLabel?: string }) {
|
||||
return (
|
||||
<div className="flex flex-1 items-center gap-4">
|
||||
<div className="relative" style={{ width: '120px', height: '120px', flexShrink: 0 }}>
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
<PieChart>
|
||||
<Pie data={data} dataKey="value" innerRadius={38} outerRadius={56} paddingAngle={2} isAnimationActive animationDuration={1000}>
|
||||
{data.map((entry) => (
|
||||
<Cell key={entry.name} fill={entry.color} stroke="none" />
|
||||
))}
|
||||
</Pie>
|
||||
</PieChart>
|
||||
</ResponsiveContainer>
|
||||
{centerLabel && (
|
||||
<div className="absolute inset-0 flex items-center justify-center pointer-events-none">
|
||||
<span style={{ fontSize: '18px', fontWeight: 700, color: '#E8E6E0' }}>{centerLabel}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
{data.map((entry) => (
|
||||
<div key={entry.name} className="flex items-center gap-2">
|
||||
<span style={{ width: '8px', height: '8px', borderRadius: '50%', backgroundColor: entry.color, flexShrink: 0 }} />
|
||||
<span style={{ fontSize: '12px', color: '#E8E6E0', width: '60px' }}>{entry.name}</span>
|
||||
<span style={{ fontSize: '12px', color: '#7A7D85' }}>{entry.value}%</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default function Network() {
|
||||
const [activeTab, setActiveTab] = useState('Overview')
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Sub-tabs + Actions */}
|
||||
<div className="flex items-center justify-between shrink-0">
|
||||
<div className="flex items-center gap-1 overflow-x-auto" style={{ scrollbarWidth: 'none' }}>
|
||||
{subTabs.map((tab) => {
|
||||
const active = tab === activeTab
|
||||
return (
|
||||
<button
|
||||
key={tab}
|
||||
onClick={() => setActiveTab(tab)}
|
||||
className="cursor-pointer bg-transparent border-none transition-colors whitespace-nowrap"
|
||||
style={{
|
||||
fontSize: '12px',
|
||||
fontWeight: 500,
|
||||
padding: '8px 14px',
|
||||
borderRadius: '8px',
|
||||
color: active ? '#C8A434' : '#7A7D85',
|
||||
backgroundColor: active ? 'rgba(200,164,52,0.1)' : 'transparent',
|
||||
}}
|
||||
>
|
||||
{tab}
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<button
|
||||
className="flex items-center gap-2 cursor-pointer transition-colors whitespace-nowrap"
|
||||
style={{
|
||||
fontSize: '12px',
|
||||
fontWeight: 500,
|
||||
color: '#E8E6E0',
|
||||
backgroundColor: 'rgba(255,255,255,0.04)',
|
||||
border: '1px solid rgba(200,164,52,0.12)',
|
||||
borderRadius: '8px',
|
||||
padding: '9px 14px',
|
||||
}}
|
||||
>
|
||||
Last 24 Hours
|
||||
<ChevronDown size={13} />
|
||||
</button>
|
||||
<button
|
||||
className="flex items-center gap-2 cursor-pointer transition-colors whitespace-nowrap"
|
||||
style={{
|
||||
fontSize: '12px',
|
||||
fontWeight: 600,
|
||||
color: '#0A0B0D',
|
||||
backgroundColor: '#C8A434',
|
||||
border: 'none',
|
||||
borderRadius: '8px',
|
||||
padding: '9px 16px',
|
||||
boxShadow: '0 0 14px rgba(200,164,52,0.2)',
|
||||
}}
|
||||
>
|
||||
<Download size={14} />
|
||||
Export Report
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Status Cards */}
|
||||
<div className="grid w-full grid-cols-6 gap-4 shrink-0" style={{ marginTop: '8px', height: '110px' }}>
|
||||
{statusCards.map((card) => {
|
||||
const Icon = card.icon
|
||||
return (
|
||||
<div
|
||||
key={card.label}
|
||||
style={{ ...cardBase, backgroundColor: 'rgba(10, 10, 12, 0.5)', padding: '14px', justifyContent: 'center', alignItems: 'center', gap: '8px' }}
|
||||
className="hover:!border-gold/20"
|
||||
>
|
||||
<h3 style={{ fontSize: '9.5px', textTransform: 'uppercase', letterSpacing: '1.2px', color: '#7A7D85', fontWeight: 500, textAlign: 'center' }}>
|
||||
{card.label}
|
||||
</h3>
|
||||
<div className="flex items-center gap-1.5">
|
||||
<Icon size={16} style={{ color: card.color ?? '#C8A434' }} />
|
||||
<span style={{ fontSize: '20px', fontWeight: 700, color: '#E8E6E0', lineHeight: 1 }}>{card.value}</span>
|
||||
</div>
|
||||
<p style={{ fontSize: '9.5px', color: card.color ?? '#7A7D85', textAlign: 'center' }}>{card.sub}</p>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
{/* Middle Row */}
|
||||
<div className="min-h-0 flex-1">
|
||||
<div className="grid h-full w-full grid-cols-[1fr_2fr_1fr] gap-6">
|
||||
{/* Top Talkers */}
|
||||
<div style={{ ...cardBase }} className="hover:!border-gold/15">
|
||||
<div className="relative z-10 flex flex-1 flex-col">
|
||||
<h3 style={sectionTitle}>Top Talkers</h3>
|
||||
<div className="flex flex-1 flex-col justify-around gap-3">
|
||||
{topTalkers.map((t) => (
|
||||
<div key={t.name} className="flex items-center justify-between">
|
||||
<span style={{ fontSize: '12px', color: '#E8E6E0' }}>{t.name}</span>
|
||||
<span style={{ fontSize: '11px', color: '#C8A434', fontWeight: 600 }}>{t.rate}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Network Topology */}
|
||||
<div style={framedCard('/network-kpi-bg.png')}>
|
||||
<div style={cardDim} />
|
||||
<div style={cardVignette} />
|
||||
<div className="relative z-10 flex flex-1 flex-col">
|
||||
<div className="flex items-center justify-between">
|
||||
<h3 style={{ ...sectionTitle, marginBottom: 0 }}>Network Topology</h3>
|
||||
<div className="flex items-center gap-3" style={{ fontSize: '10px', color: '#7A7D85' }}>
|
||||
<span className="flex items-center gap-1"><span style={{ width: '6px', height: '6px', borderRadius: '50%', backgroundColor: '#2ECC71' }} />Live</span>
|
||||
<span className="flex items-center gap-1"><span style={{ width: '6px', height: '6px', borderRadius: '50%', backgroundColor: '#E67E22' }} />Warning</span>
|
||||
<span className="flex items-center gap-1"><span style={{ width: '6px', height: '6px', borderRadius: '50%', backgroundColor: '#E74C3C' }} />Critical</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative flex-1" style={{ minHeight: '140px', marginTop: '12px' }}>
|
||||
<Globe2 size={170} strokeWidth={0.6} style={{ position: 'absolute', left: '50%', top: '50%', transform: 'translate(-50%, -50%)', color: 'rgba(200,164,52,0.1)' }} />
|
||||
{regions.map((r) => (
|
||||
<div key={r.name} className="absolute" style={{ left: r.x, top: r.y, transform: 'translate(-50%, -50%)' }} title={r.name}>
|
||||
<div style={{ width: '8px', height: '8px', borderRadius: '50%', backgroundColor: regionStatusColor[r.status], boxShadow: `0 0 10px ${regionStatusColor[r.status]}` }} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Interface Utilization + Alert Summary, stacked */}
|
||||
<div className="flex h-full flex-col gap-6">
|
||||
<div style={{ ...cardBase, height: 'auto', flex: 1 }} className="hover:!border-gold/15">
|
||||
<h3 style={sectionTitle}>Interface Utilization</h3>
|
||||
<div className="flex flex-1 flex-col justify-around gap-2.5">
|
||||
{interfaces.map((iface) => (
|
||||
<div key={iface.name}>
|
||||
<div className="flex items-center justify-between mb-1">
|
||||
<span style={{ fontSize: '11px', color: '#E8E6E0' }}>{iface.name}</span>
|
||||
<span style={{ fontSize: '10px', color: '#7A7D85' }}>{iface.percentage}%</span>
|
||||
</div>
|
||||
<div style={{ height: '5px', backgroundColor: 'rgba(30,32,37,0.8)', borderRadius: '3px', overflow: 'hidden' }}>
|
||||
<div style={{ height: '100%', width: `${iface.percentage}%`, backgroundColor: '#C8A434', borderRadius: '3px', transition: 'width 0.8s ease' }} />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ ...cardBase, height: 'auto', flex: 1 }} className="hover:!border-gold/15">
|
||||
<h3 style={sectionTitle}>Alert Summary</h3>
|
||||
<div className="flex flex-1 items-center justify-around">
|
||||
{alertSummary.map((a) => (
|
||||
<div key={a.label} className="flex flex-col items-center gap-1">
|
||||
<span style={{ fontSize: '22px', fontWeight: 700, color: a.color }}>{a.value}</span>
|
||||
<span style={{ fontSize: '10px', color: '#7A7D85' }}>{a.label}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Bottom Row */}
|
||||
<div className="shrink-0">
|
||||
<div className="grid w-full grid-cols-[1.4fr_1fr_1fr] gap-6">
|
||||
{/* Traffic Over Time */}
|
||||
<div style={{ ...cardBase, height: 'auto' }} className="hover:!border-gold/15">
|
||||
<h3 style={sectionTitle}>Traffic Over Time</h3>
|
||||
<div style={{ height: '100px' }}>
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
<AreaChart data={trafficData} margin={{ top: 0, right: 0, left: 0, bottom: 0 }}>
|
||||
<XAxis dataKey="hour" hide />
|
||||
<Area type="monotone" dataKey="total" stroke="#7A7D85" fill="rgba(122,125,133,0.08)" strokeWidth={1} dot={false} isAnimationActive animationDuration={1000} />
|
||||
<Area type="monotone" dataKey="inbound" stroke="#C8A434" fill="rgba(200,164,52,0.12)" strokeWidth={1.5} dot={false} isAnimationActive animationDuration={1000} />
|
||||
<Area type="monotone" dataKey="outbound" stroke="#E67E22" fill="rgba(230,126,34,0.1)" strokeWidth={1.5} dot={false} isAnimationActive animationDuration={1000} />
|
||||
</AreaChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Protocol Distribution */}
|
||||
<div style={{ ...cardBase, height: 'auto' }} className="hover:!border-gold/15">
|
||||
<h3 style={sectionTitle}>Protocol Distribution</h3>
|
||||
<Donut data={protocolData} centerLabel="1.23 Tbps" />
|
||||
</div>
|
||||
|
||||
{/* Recent Events */}
|
||||
<div style={{ ...cardBase, height: 'auto' }} className="hover:!border-gold/15">
|
||||
<h3 style={sectionTitle}>Recent Events</h3>
|
||||
<div className="flex flex-col gap-3">
|
||||
{recentEvents.map((item, i) => (
|
||||
<div key={i} className="flex items-start justify-between gap-3">
|
||||
<div style={{ flex: 1, minWidth: 0 }}>
|
||||
<p style={{ fontSize: '12px', color: '#E8E6E0', fontWeight: 500, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{item.title}</p>
|
||||
<p style={{ fontSize: '11px', color: '#7A7D85', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{item.source}</p>
|
||||
</div>
|
||||
<span style={{ fontSize: '11px', color: '#7A7D85', flexShrink: 0 }}>{item.time}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Footer stats bar */}
|
||||
<div
|
||||
className="shrink-0 flex items-center justify-center gap-3"
|
||||
style={{
|
||||
fontSize: '11px',
|
||||
color: '#7A7D85',
|
||||
padding: '8px 0',
|
||||
borderTop: '1px solid rgba(200,164,52,0.08)',
|
||||
}}
|
||||
>
|
||||
<span>6 Regions</span><span style={{ color: 'rgba(200,164,52,0.3)' }}>|</span>
|
||||
<span>42 Sites</span><span style={{ color: 'rgba(200,164,52,0.3)' }}>|</span>
|
||||
<span>248 Devices</span><span style={{ color: 'rgba(200,164,52,0.3)' }}>|</span>
|
||||
<span>1,245 Interfaces</span><span style={{ color: 'rgba(200,164,52,0.3)' }}>|</span>
|
||||
<span>28,457 Connections</span><span style={{ color: 'rgba(200,164,52,0.3)' }}>|</span>
|
||||
<span style={{ color: '#2ECC71' }}>98.7% Health</span>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue