"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, Users, 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 } const generateDemoSystemData = (): SystemData => ({ cpu_usage: Math.floor(Math.random() * 20) + 60, // 60-80% memory_usage: Math.floor(Math.random() * 10) + 45, // 45-55% memory_total: 32.0, memory_used: 15.8 + Math.random() * 2, // 15.8-17.8 GB temperature: Math.floor(Math.random() * 8) + 48, // 48-56°C uptime: "15d 7h 23m", load_average: [1.23, 1.45, 1.67], hostname: "proxmox-demo", node_id: "pve-demo-node", timestamp: new Date().toISOString(), }) const demVMData: VMData[] = [ { vmid: 100, name: "web-server-01", status: "running", cpu: 0.45, mem: 8589934592, maxmem: 17179869184, disk: 53687091200, maxdisk: 107374182400, uptime: 1324800, }, { vmid: 101, name: "database-server", status: "running", cpu: 0.23, mem: 4294967296, maxmem: 8589934592, disk: 26843545600, maxdisk: 53687091200, uptime: 864000, }, { vmid: 102, name: "backup-server", status: "stopped", cpu: 0, mem: 0, maxmem: 4294967296, disk: 10737418240, maxdisk: 21474836480, uptime: 0, }, ] const fetchSystemData = async (): Promise<{ data: SystemData | null; isDemo: boolean }> => { try { console.log("[v0] Attempting to fetch system data from Flask server...") const response = await fetch("/api/system", { method: "GET", headers: { "Content-Type": "application/json", }, signal: AbortSignal.timeout(3000), // Reduced timeout for faster fallback }) if (!response.ok) { 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) return { data, isDemo: false } } catch (error) { console.log("[v0] Flask server not available, using demo data for development") return { data: generateDemoSystemData(), isDemo: true } } } const fetchVMData = async (): Promise<{ data: VMData[]; isDemo: boolean }> => { try { console.log("[v0] Attempting to fetch VM data from Flask server...") const response = await fetch("/api/vms", { method: "GET", headers: { "Content-Type": "application/json", }, signal: AbortSignal.timeout(3000), // Reduced timeout for faster fallback }) if (!response.ok) { 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 { data: data.vms || [], isDemo: false } } catch (error) { console.log("[v0] Flask server not available, using demo VM data") return { data: demVMData, isDemo: true } } } const generateChartData = (systemData?: SystemData) => { const cpuData = [] const memoryData = [] for (let i = 0; i < 24; i += 4) { const time = `${i.toString().padStart(2, "0")}:00` // Use real CPU data as base if available, otherwise use random data const baseCpu = systemData?.cpu_usage || 60 cpuData.push({ time, value: Math.max(0, Math.min(100, baseCpu + (Math.random() - 0.5) * 20)), }) // Use real memory data as base if available const baseMemory = systemData?.memory_used || 15.8 const totalMemory = systemData?.memory_total || 32 memoryData.push({ time, used: Math.max(0, baseMemory + (Math.random() - 0.5) * 4), available: Math.max(0, totalMemory - (baseMemory + (Math.random() - 0.5) * 4)), }) } 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 [isDemo, setIsDemo] = useState(false) // Added demo mode state useEffect(() => { const fetchData = async () => { try { setLoading(true) const [systemResult, vmResult] = await Promise.all([fetchSystemData(), fetchVMData()]) setSystemData(systemResult.data) setVmData(vmResult.data) setIsDemo(systemResult.isDemo || vmResult.isDemo) // Set demo mode if either fetch is demo if (systemResult.data) { setChartData(generateChartData(systemResult.data)) } } catch (err) { console.error("[v0] Error fetching data:", err) const fallbackData = generateDemoSystemData() setSystemData(fallbackData) setVmData(demVMData) setChartData(generateChartData(fallbackData)) setIsDemo(true) } finally { setLoading(false) } } fetchData() const interval = setInterval(() => { if (!isDemo) { fetchData() } else { // In demo mode, just update with new random data const newDemoData = generateDemoSystemData() setSystemData(newDemoData) setChartData(generateChartData(newDemoData)) } }, 30000) // Update every 30 seconds instead of 5 return () => { clearInterval(interval) } }, [isDemo]) if (loading) { return (
Connecting to ProxMenux Monitor...
Fetching real-time system data
{[...Array(4)].map((_, i) => (
))}
) } if (!systemData) return null 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 < 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 (
{isDemo && (
Demo Mode: Flask server not available. Showing simulated data for development. In the AppImage, this will connect to the real Flask server.
)} {/* Key Metrics Cards */}
CPU Usage
{systemData.cpu_usage}%

{isDemo ? "Simulated data" : "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}°C
{tempStatus.status}

{isDemo ? "Simulated temperature" : "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 (24h) Memory Usage (24h)
{/* System Information */}
System Information
Hostname: {systemData.hostname}
Uptime: {systemData.uptime}
Node ID: {systemData.node_id}
Last Update: {new Date(systemData.timestamp).toLocaleTimeString()}
Active Sessions
Web Console: 3 active
SSH Sessions: 1 active
API Calls: 247/hour
Power & Performance
Power State: Running
Load Average: {systemData.load_average.map((avg) => avg.toFixed(2)).join(", ")}
Boot Time: 2.3s
) }