67 lines
1.9 KiB
TypeScript
67 lines
1.9 KiB
TypeScript
"use client"
|
|
|
|
import { useState, useEffect } from "react"
|
|
|
|
const RAM_LIMIT_MB = 8192
|
|
const CPU_LIMIT_PCT = 400
|
|
|
|
interface SystemMonitorProps {
|
|
collapsed: boolean
|
|
}
|
|
|
|
export function SystemMonitor({ collapsed }: SystemMonitorProps) {
|
|
const [rssMB, setRssMB] = useState(0)
|
|
const [cpuPct, setCpuPct] = useState(0)
|
|
|
|
useEffect(() => {
|
|
const fetchStats = async () => {
|
|
try {
|
|
const res = await fetch("/api/system/monitor")
|
|
if (!res.ok) return
|
|
const data = await res.json()
|
|
setRssMB(data.rssMB)
|
|
setCpuPct(data.cpuPct)
|
|
} catch {
|
|
console.warn("Failed to fetch system stats")
|
|
}
|
|
}
|
|
|
|
fetchStats()
|
|
const interval = setInterval(fetchStats, 3000)
|
|
return () => clearInterval(interval)
|
|
}, [])
|
|
|
|
const ramOver = rssMB > RAM_LIMIT_MB
|
|
const cpuOver = cpuPct > CPU_LIMIT_PCT
|
|
|
|
if (collapsed) {
|
|
return (
|
|
<div className="border-t border-sidebar-border px-1 py-1.5 flex flex-col items-center text-[10px] leading-tight">
|
|
<span className={ramOver ? "text-red-400" : "text-[var(--theme-primary,#3b91f7)]"}>
|
|
{rssMB}
|
|
</span>
|
|
<span className={cpuOver ? "text-red-400" : "text-[var(--theme-primary,#3b91f7)]"}>
|
|
{cpuPct}%
|
|
</span>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<div className="border-t border-sidebar-border px-3 py-2.5">
|
|
<div className="flex items-center justify-between text-[11px] font-mono">
|
|
<span className="text-sidebar-foreground/50">RAM</span>
|
|
<span className={ramOver ? "text-red-400 font-semibold" : "text-sidebar-foreground/80"}>
|
|
{rssMB}MB / {RAM_LIMIT_MB}MB
|
|
</span>
|
|
</div>
|
|
<div className="flex items-center justify-between text-[11px] font-mono mt-1">
|
|
<span className="text-sidebar-foreground/50">CPU</span>
|
|
<span className={cpuOver ? "text-red-400 font-semibold" : "text-sidebar-foreground/80"}>
|
|
{cpuPct}%
|
|
</span>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|