"use client" import { Card } from "@/components/ui/card" import { Badge } from "@/components/ui/badge" import { Progress } from "@/components/ui/progress" import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@/components/ui/dialog" import { Cpu, MemoryStick, HardDrive, Network, Thermometer, Fan, Battery, Server, CpuIcon } from "lucide-react" import useSWR from "swr" import { useState } from "react" const fetcher = (url: string) => fetch(url).then((res) => res.json()) interface CPUInfo { model?: string total_threads?: number cores_per_socket?: number sockets?: number current_mhz?: number max_mhz?: number virtualization?: string l1d_cache?: string l2_cache?: string l3_cache?: string } interface MotherboardInfo { manufacturer?: string model?: string version?: string serial?: string bios?: { vendor?: string version?: string date?: string } } interface MemoryModule { size: string type: string speed: string manufacturer?: string slot?: string } interface StorageDevice { name: string size: string model: string temperature: number health: string power_on_hours: number rotation_rate: number } interface NetworkCard { name: string type: string } interface GraphicsCard { name: string memory?: string temperature?: number power_draw?: string vendor: string } interface TemperatureSensor { name: string current: number high?: number critical?: number } interface FanSensor { name: string current_rpm: number } interface UPSInfo { model?: string status?: string battery_charge?: string time_left?: string load_percent?: string line_voltage?: string } interface IPMIFan { name: string speed: number unit: string } interface IPMIPowerSupply { name: string watts: number unit: string status: string } interface IPMIPower { power_supplies: IPMIPowerSupply[] power_meter?: { name: string watts: number unit: string } } interface UPSData { model?: string status?: string battery_charge?: string time_left?: string load_percent?: string line_voltage?: string real_power?: string } interface PCIDevice { slot: string type: string vendor: string device: string class: string driver?: string kernel_module?: string irq?: string memory_address?: string link_speed?: string capabilities?: string[] } interface HardwareData { cpu: CPUInfo motherboard: MotherboardInfo memory_modules: MemoryModule[] storage_devices: StorageDevice[] network_cards: NetworkCard[] graphics_cards: GraphicsCard[] pci_devices: PCIDevice[] sensors: { temperatures: TemperatureSensor[] fans: FanSensor[] } power: UPSInfo ipmi_fans?: IPMIFan[] ipmi_power?: IPMIPower ups?: UPSData } export default function Hardware() { const { data: hardwareData, error } = useSWR("/api/hardware", fetcher, { refreshInterval: 5000, }) const [selectedPCIDevice, setSelectedPCIDevice] = useState(null) if (error) { return (

Failed to load hardware information

) } if (!hardwareData) { return (
) } const getHealthColor = (health: string) => { switch (health.toLowerCase()) { case "healthy": return "text-green-500" case "warning": return "text-yellow-500" case "critical": case "failed": return "text-red-500" default: return "text-muted-foreground" } } const getHealthBadge = (health: string) => { switch (health.toLowerCase()) { case "healthy": return Healthy case "warning": return Warning case "critical": case "failed": return Critical default: return Unknown } } const getTempColor = (temp: number, high?: number, critical?: number) => { if (critical && temp >= critical) return "text-red-500" if (high && temp >= high) return "text-yellow-500" if (temp >= 70) return "text-red-500" if (temp >= 60) return "text-yellow-500" return "text-green-500" } const getTempProgress = (temp: number, critical?: number) => { const max = critical || 100 return (temp / max) * 100 } const hasSensors = hardwareData.sensors.temperatures.length > 0 || hardwareData.sensors.fans.length > 0 const hasUPS = hardwareData.power && Object.keys(hardwareData.power).length > 0 const hasIPMIFans = hardwareData.ipmi_fans && hardwareData.ipmi_fans.length > 0 const hasIPMIPower = hardwareData.ipmi_power && (hardwareData.ipmi_power.power_supplies?.length > 0 || hardwareData.ipmi_power.power_meter) const hasUPSData = hardwareData.ups && Object.keys(hardwareData.ups).length > 0 const storageSummary = hardwareData.storage_devices.reduce( (acc, disk) => { const sizeMatch = disk.size.match(/(\d+\.?\d*)\s*([KMGT]?B?)/) if (sizeMatch) { let sizeInTB = Number.parseFloat(sizeMatch[1]) const unit = sizeMatch[2] if (unit === "TB" || unit === "T") sizeInTB *= 1 else if (unit === "GB" || unit === "G") sizeInTB /= 1024 else if (unit === "MB" || unit === "M") sizeInTB /= 1024 * 1024 else if (unit === "KB" || unit === "K") sizeInTB /= 1024 * 1024 * 1024 acc.totalCapacity += sizeInTB } if (disk.rotation_rate === 0) acc.ssd++ else if (disk.rotation_rate > 0) acc.hdd++ return acc }, { totalCapacity: 0, ssd: 0, hdd: 0 }, ) const networkControllers = hardwareData.pci_devices?.filter((device) => device.type === "Network Controller") || [] return (
{/* System Information */}

System Information

{/* CPU */} {hardwareData.cpu.model && (

CPU

Model {hardwareData.cpu.model}
{hardwareData.cpu.sockets && hardwareData.cpu.cores_per_socket && (
Cores {hardwareData.cpu.sockets} × {hardwareData.cpu.cores_per_socket} ={" "} {hardwareData.cpu.sockets * hardwareData.cpu.cores_per_socket} cores
)} {hardwareData.cpu.total_threads && (
Threads {hardwareData.cpu.total_threads}
)} {hardwareData.cpu.current_mhz && (
Frequency {hardwareData.cpu.current_mhz.toFixed(0)} MHz
)} {hardwareData.cpu.l3_cache && (
L3 Cache {hardwareData.cpu.l3_cache}
)} {hardwareData.cpu.virtualization && (
Virtualization {hardwareData.cpu.virtualization}
)}
)} {/* Motherboard */} {hardwareData.motherboard.manufacturer && (

Motherboard

Manufacturer {hardwareData.motherboard.manufacturer}
{hardwareData.motherboard.model && (
Model {hardwareData.motherboard.model}
)} {hardwareData.motherboard.bios && ( <>
BIOS {hardwareData.motherboard.bios.vendor}
Version {hardwareData.motherboard.bios.version}
{hardwareData.motherboard.bios.date && (
Date {hardwareData.motherboard.bios.date}
)} )}
)}
{/* Memory Modules */} {hardwareData.memory_modules.length > 0 && (

Memory Modules

{hardwareData.memory_modules.length} installed
{hardwareData.memory_modules.map((module, index) => (
{module.slot &&
{module.slot}
}
Size {module.size}
Type {module.type}
Speed {module.speed}
{module.manufacturer && module.manufacturer !== "Unknown" && (
Manufacturer {module.manufacturer}
)}
))}
)} {/* Storage Summary */} {hardwareData.storage_devices.length > 0 && (

Storage Summary

{hardwareData.storage_devices.length} devices

Total Capacity

{storageSummary.totalCapacity >= 1 ? `${storageSummary.totalCapacity.toFixed(1)} TB` : `${(storageSummary.totalCapacity * 1024).toFixed(1)} GB`}

{storageSummary.ssd > 0 && (

SSD/NVMe Drives

{storageSummary.ssd}

)} {storageSummary.hdd > 0 && (

HDD Drives

{storageSummary.hdd}

)}

For detailed storage information, see the Storage section

)} {/* Network Summary */} {networkControllers.length > 0 && (

Network Summary

{networkControllers.length} interfaces
{networkControllers.map((nic, index) => (
{nic.device} Ethernet
))}

For detailed network information, see the Network section

)} {/* PCI Devices */} {hardwareData.pci_devices && hardwareData.pci_devices.length > 0 && (

PCI Devices

{hardwareData.pci_devices.length} devices
{hardwareData.pci_devices.map((device, index) => (
setSelectedPCIDevice(device)} className="flex cursor-pointer items-start justify-between rounded-lg border border-border/30 bg-background/50 p-4 transition-colors hover:border-primary/50 hover:bg-background/80" >
{device.type} {device.slot}

{device.device}

{device.vendor}

))}
)} {/* Thermal Monitoring */} {hardwareData.sensors.temperatures.length > 0 && (

Thermal Monitoring

{hardwareData.sensors.temperatures.map((sensor, index) => (
{sensor.name} {sensor.current.toFixed(1)}°C
))}
)} {/* Fan Monitoring */} {hardwareData.sensors.fans.length > 0 && (

Fan Monitoring

{hardwareData.sensors.fans.map((fan, index) => (
{fan.name}
{fan.current_rpm} RPM
))}
)} {/* IPMI Fan Monitoring */} {hasIPMIFans && (

Server Fans (IPMI)

{hardwareData.ipmi_fans?.map((fan, index) => (
{fan.name}
{fan.speed.toFixed(1)} {fan.unit}
))}
)} {/* IPMI Power Supplies */} {hasIPMIPower && (

Power Supplies (IPMI)

{/* Power Meter */} {hardwareData.ipmi_power?.power_meter && (
Total Power Consumption {hardwareData.ipmi_power.power_meter.watts.toFixed(0)} W
)} {/* Individual Power Supplies */} {hardwareData.ipmi_power?.power_supplies && hardwareData.ipmi_power.power_supplies.length > 0 && (
{hardwareData.ipmi_power.power_supplies.map((psu, index) => (
{psu.name}
{psu.status}
{psu.watts.toFixed(0)} {psu.unit}
))}
)}
)} {/* Power Supply / UPS */} {hasUPS && (

Power Supply / UPS

{hardwareData.power.model && (
Model {hardwareData.power.model}
)} {hardwareData.power.status && (
Status {hardwareData.power.status}
)} {hardwareData.power.battery_charge && (
Battery Charge {hardwareData.power.battery_charge}
)} {hardwareData.power.time_left && (
Time Left {hardwareData.power.time_left}
)} {hardwareData.power.load_percent && (
Load {hardwareData.power.load_percent}
)} {hardwareData.power.line_voltage && (
Line Voltage {hardwareData.power.line_voltage}
)}
)} {/* UPS Information */} {hasUPSData && (

UPS / SAI

{hardwareData.ups?.model && (
Model {hardwareData.ups.model}
)} {hardwareData.ups?.status && (
Status {hardwareData.ups.status}
)} {hardwareData.ups?.battery_charge && (
Battery Charge {hardwareData.ups.battery_charge}
)} {hardwareData.ups?.time_left && (
Runtime Left {hardwareData.ups.time_left}
)} {hardwareData.ups?.load_percent && (
Load {hardwareData.ups.load_percent}
)} {hardwareData.ups?.line_voltage && (
Input Voltage {hardwareData.ups.line_voltage}
)} {hardwareData.ups?.real_power && (
Real Power {hardwareData.ups.real_power}
)}
)} {/* PCI Device Details Modal */} setSelectedPCIDevice(null)}> PCI Device Details Detailed information about the selected PCI device {selectedPCIDevice && (
Device Type {selectedPCIDevice.type}
PCI Slot {selectedPCIDevice.slot}
Device Name {selectedPCIDevice.device}
Vendor {selectedPCIDevice.vendor}
Class {selectedPCIDevice.class}
{selectedPCIDevice.driver && (
Driver {selectedPCIDevice.driver}
)} {selectedPCIDevice.kernel_module && (
Kernel Module {selectedPCIDevice.kernel_module}
)} {selectedPCIDevice.irq && (
IRQ {selectedPCIDevice.irq}
)} {selectedPCIDevice.memory_address && (
Memory Address {selectedPCIDevice.memory_address}
)} {selectedPCIDevice.link_speed && (
Link Speed {selectedPCIDevice.link_speed}
)} {selectedPCIDevice.capabilities && selectedPCIDevice.capabilities.length > 0 && (
Capabilities
{selectedPCIDevice.capabilities.map((cap, idx) => ( {cap} ))}
)}
)}
) }