"use client" import { useState, useEffect } from "react" import { Card, CardContent, CardHeader, CardTitle } from "./ui/card" import { Progress } from "./ui/progress" import { Badge } from "./ui/badge" import { XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, AreaChart, Area } from "recharts" import { Cpu, MemoryStick, Thermometer, Activity, Server, Zap, AlertCircle } from "lucide-react" interface SystemData { cpu_usage: number memory_usage: number memory_total: number memory_used: number temperature: number uptime: string load_average: number[] hostname: string node_id: string timestamp: string } interface VMData { vmid: number name: string status: string cpu: number mem: number maxmem: number disk: number maxdisk: number uptime: number } interface HistoricalData { timestamp: string cpu_usage: number memory_used: number memory_total: number } const historicalDataStore: HistoricalData[] = [] const MAX_HISTORICAL_POINTS = 24 // Store 24 data points for 24h view const fetchSystemData = async (): Promise => { try { console.log("[v0] Fetching system data from Flask server...") const apiUrl = "/api/system" console.log("[v0] Fetching from URL:", apiUrl) const response = await fetch(apiUrl, { method: "GET", headers: { "Content-Type": "application/json", }, cache: "no-store", }) console.log("[v0] Response status:", response.status) console.log("[v0] Response ok:", response.ok) if (!response.ok) { const errorText = await response.text() console.error("[v0] Flask server error response:", errorText) throw new Error(`Flask server responded with status: ${response.status}`) } const data = await response.json() console.log("[v0] Successfully fetched real system data from Flask:", data) // Store historical data historicalDataStore.push({ timestamp: data.timestamp, cpu_usage: data.cpu_usage, memory_used: data.memory_used, memory_total: data.memory_total, }) // Keep only last MAX_HISTORICAL_POINTS if (historicalDataStore.length > MAX_HISTORICAL_POINTS) { historicalDataStore.shift() } return data } catch (error) { console.error("[v0] Failed to fetch system data from Flask server:", error) console.error("[v0] Error type:", error instanceof Error ? error.constructor.name : typeof error) console.error("[v0] Error message:", error instanceof Error ? error.message : String(error)) return null } } const fetchVMData = async (): Promise => { try { console.log("[v0] Fetching VM data from Flask server...") const apiUrl = "/api/vms" console.log("[v0] Fetching from URL:", apiUrl) const response = await fetch(apiUrl, { method: "GET", headers: { "Content-Type": "application/json", }, cache: "no-store", }) console.log("[v0] VM Response status:", response.status) if (!response.ok) { const errorText = await response.text() console.error("[v0] Flask server error response:", errorText) throw new Error(`Flask server responded with status: ${response.status}`) } const data = await response.json() console.log("[v0] Successfully fetched VM data from Flask:", data) return Array.isArray(data) ? data : data.vms || [] } catch (error) { console.error("[v0] Failed to fetch VM data from Flask server:", error) console.error("[v0] Error type:", error instanceof Error ? error.constructor.name : typeof error) console.error("[v0] Error message:", error instanceof Error ? error.message : String(error)) return [] } } const generateChartData = () => { if (historicalDataStore.length === 0) { return { cpuData: [], memoryData: [] } } const cpuData = historicalDataStore.map((point) => ({ time: new Date(point.timestamp).toLocaleTimeString("en-US", { hour: "2-digit", minute: "2-digit" }), value: point.cpu_usage, })) const memoryData = historicalDataStore.map((point) => ({ time: new Date(point.timestamp).toLocaleTimeString("en-US", { hour: "2-digit", minute: "2-digit" }), used: point.memory_used, available: point.memory_total - point.memory_used, })) return { cpuData, memoryData } } export function SystemOverview() { const [systemData, setSystemData] = useState(null) const [vmData, setVmData] = useState([]) const [chartData, setChartData] = useState(generateChartData()) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) useEffect(() => { const fetchData = async () => { try { setLoading(true) setError(null) const [systemResult, vmResult] = await Promise.all([fetchSystemData(), fetchVMData()]) if (!systemResult) { setError("Flask server not available. Please ensure the server is running.") setLoading(false) return } setSystemData(systemResult) setVmData(vmResult) setChartData(generateChartData()) } catch (err) { console.error("[v0] Error fetching data:", err) setError("Failed to connect to Flask server. Please check your connection.") } finally { setLoading(false) } } fetchData() const interval = setInterval(() => { fetchData() }, 30000) // Update every 30 seconds return () => { clearInterval(interval) } }, []) if (loading) { return (
Connecting to ProxMenux Monitor...
Fetching real-time system data
{[...Array(4)].map((_, i) => (
))}
) } if (error || !systemData) { return (
Flask Server Not Available
{error || "Unable to connect to the Flask server. Please ensure the server is running and try again."}
Troubleshooting:
  • Check if the Flask server is running on the correct port
  • Verify network connectivity
  • Check server logs for errors
) } const vmStats = { total: vmData.length, running: vmData.filter((vm) => vm.status === "running").length, stopped: vmData.filter((vm) => vm.status === "stopped").length, lxc: 0, } const getTemperatureStatus = (temp: number) => { if (temp === 0) return { status: "N/A", color: "bg-gray-500/10 text-gray-500 border-gray-500/20" } if (temp < 60) return { status: "Normal", color: "bg-green-500/10 text-green-500 border-green-500/20" } if (temp < 75) return { status: "Warm", color: "bg-yellow-500/10 text-yellow-500 border-yellow-500/20" } return { status: "Hot", color: "bg-red-500/10 text-red-500 border-red-500/20" } } const tempStatus = getTemperatureStatus(systemData.temperature) return (
{/* Key Metrics Cards */}
CPU Usage
{systemData.cpu_usage}%

Real-time data from Flask server

Memory Usage
{systemData.memory_used.toFixed(1)} GB

{systemData.memory_usage.toFixed(1)}% of {systemData.memory_total} GB

Temperature
{systemData.temperature === 0 ? "N/A" : `${systemData.temperature}°C`}
{tempStatus.status}

{systemData.temperature === 0 ? "No sensor available" : "Live temperature reading"}

Active VMs
{vmStats.running}
{vmStats.running} Running {vmStats.stopped > 0 && ( {vmStats.stopped} Stopped )}

Total: {vmStats.total} VMs configured

{/* Charts Section */}
CPU Usage (Last {historicalDataStore.length} readings) {chartData.cpuData.length > 0 ? ( ) : (
Collecting data... Check back in a few minutes
)}
Memory Usage (Last {historicalDataStore.length} readings) {chartData.memoryData.length > 0 ? ( ) : (
Collecting data... Check back in a few minutes
)}
{/* System Information */}
System Information
Hostname: {systemData.hostname}
Uptime: {systemData.uptime}
Node ID: {systemData.node_id}
Last Update: {new Date(systemData.timestamp).toLocaleTimeString()}
Performance Metrics
Load Average: {systemData.load_average.map((avg) => avg.toFixed(2)).join(", ")}
Total Memory: {systemData.memory_total} GB
Available Memory: {(systemData.memory_total - systemData.memory_used).toFixed(1)} GB
CPU Cores: {navigator.hardwareConcurrency || "N/A"}
) }