+ {devices.map((device: DeviceResponse) => {
+ const metrics = metricsMap.get(device.id)
+ const cpu = metrics?.cpu ?? null
+ const mem = metrics?.mem ?? null
+
+ return (
+
+
+
+
+ {device.hostname}
+
+
+
+ {/* CPU bar */}
+
+
+ CPU
+ {cpu != null ? `${Math.round(cpu)}%` : '--'}
+
+
+ {cpu != null && (
+
+ )}
+
+
+
+ {/* Memory bar */}
+
+
+ Memory
+ {mem != null ? `${Math.round(mem)}%` : '--'}
+
+
+ {mem != null && (
+
+ )}
+
+
+
+ {/* Uptime */}
+
+ Uptime: {formatUptime(device.uptime_seconds)}
+
+
+ )
+ })}
+
+ )
+}
diff --git a/frontend/src/components/sites/SiteLinksTab.tsx b/frontend/src/components/sites/SiteLinksTab.tsx
new file mode 100644
index 0000000..46b7214
--- /dev/null
+++ b/frontend/src/components/sites/SiteLinksTab.tsx
@@ -0,0 +1,10 @@
+import { WirelessLinksTable } from '@/components/wireless/WirelessLinksTable'
+
+interface SiteLinksTabProps {
+ tenantId: string
+ siteId: string
+}
+
+export function SiteLinksTab({ tenantId, siteId }: SiteLinksTabProps) {
+ return