"use client"; import { Network, Router, Shield, Wifi } from "@/components/icons/platform-icons"; import { formatBytesCompact } from "@/lib/client/format"; import type { NetworkInterfaceKind, NetworkInterfaceOverview } from "@/lib/shared/contracts/network"; import { PANEL_INSET } from "@/lib/ui/surface-tokens"; import { cn } from "@/lib/utils"; const KIND_LABEL: Record = { wired: "Wired", wireless: "Wi-Fi", vpn: "VPN", other: "Other", }; const KIND_ICON: Record> = { wired: Router, wireless: Wifi, vpn: Shield, other: Network, }; export function formatMbps(value: number) { return `${value < 10 ? value.toFixed(2) : value.toFixed(1)} Mbps`; } function Row({ label, value, warn }: { label: string; value: string; warn?: boolean }) { return (
{label} {value}
); } type NetworkInterfaceCardProps = { iface: NetworkInterfaceOverview; /** Wi-Fi details, when this interface is the connected wireless one. */ wifi?: { ssid: string | null; signalPercent: number | null } | null; }; export function NetworkInterfaceCard({ iface, wifi }: NetworkInterfaceCardProps) { const Icon = KIND_ICON[iface.kind]; const errors = (iface.rxErrors ?? 0) + (iface.txErrors ?? 0); const dropped = (iface.rxDropped ?? 0) + (iface.txDropped ?? 0); const rows: { label: string; value: string; warn?: boolean }[] = []; if (wifi?.ssid) rows.push({ label: "Network", value: wifi.ssid }); if (wifi?.signalPercent !== undefined && wifi?.signalPercent !== null) { rows.push({ label: "Signal", value: `${wifi.signalPercent}%` }); } if (iface.ip4) { rows.push({ label: "IPv4", value: iface.ip4Subnet ? `${iface.ip4} / ${iface.ip4Subnet}` : iface.ip4 }); } if (iface.ip6) rows.push({ label: "IPv6", value: iface.ip6 }); if (iface.mac) rows.push({ label: "MAC", value: iface.mac }); if (iface.speedMbps !== null) { rows.push({ label: "Link", value: `${iface.speedMbps} Mbps${iface.duplex ? ` ยท ${iface.duplex}` : ""}` }); } if (iface.ip4) rows.push({ label: "Address", value: iface.dhcp ? "DHCP" : "Static" }); if (iface.rxBytes !== null) rows.push({ label: "Received", value: formatBytesCompact(iface.rxBytes) }); if (iface.txBytes !== null) rows.push({ label: "Sent", value: formatBytesCompact(iface.txBytes) }); if (iface.rxErrors !== null || iface.txErrors !== null) { rows.push({ label: "Errors / dropped", value: `${errors} / ${dropped}`, warn: errors > 0 }); } return (
{iface.iface} {iface.isDefault ? ( Default ) : null}
{KIND_LABEL[iface.kind]}
{iface.up === true ? "Up" : iface.up === false ? "Down" : "Unknown"}
{iface.up !== false ? (
{[ { label: "Download", value: iface.downloadMbps, color: "text-status-green" }, { label: "Upload", value: iface.uploadMbps, color: "text-sky-400" }, ].map(({ label, value, color }) => (
{label} {value === null ? "--" : formatMbps(value)}
))}
) : null}
{rows.map((row) => ( ))}
); }