"use client" import { useState, useEffect } from "react" import { Card, CardContent, CardHeader, CardTitle } from "./ui/card" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./ui/select" import { AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Legend } from "recharts" import { Loader2, TrendingUp, MemoryStick } from "lucide-react" const TIMEFRAME_OPTIONS = [ { value: "hour", label: "1 Hour" }, { value: "day", label: "24 Hours" }, { value: "week", label: "7 Days" }, { value: "month", label: "30 Days" }, ] interface NodeMetricsData { time: string timestamp: number cpu: number load: number memoryTotal: number memoryUsed: number memoryFree: number memoryZfsArc: number } export function NodeMetricsCharts() { const [timeframe, setTimeframe] = useState("day") const [data, setData] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) useEffect(() => { console.log("[v0] NodeMetricsCharts component mounted") fetchMetrics() }, [timeframe]) const fetchMetrics = async () => { console.log("[v0] fetchMetrics called with timeframe:", timeframe) setLoading(true) setError(null) try { const baseUrl = typeof window !== "undefined" ? `${window.location.protocol}//${window.location.hostname}:8008` : "" const apiUrl = `${baseUrl}/api/node/metrics?timeframe=${timeframe}` console.log("[v0] Fetching node metrics from:", apiUrl) const response = await fetch(apiUrl) console.log("[v0] Response status:", response.status) console.log("[v0] Response ok:", response.ok) if (!response.ok) { const errorText = await response.text() console.log("[v0] Error response text:", errorText) throw new Error(`Failed to fetch node metrics: ${response.status}`) } const result = await response.json() console.log("[v0] Node metrics result:", result) console.log("[v0] Result keys:", Object.keys(result)) console.log("[v0] Data array length:", result.data?.length || 0) if (!result.data || !Array.isArray(result.data)) { console.error("[v0] Invalid data format - data is not an array:", result) throw new Error("Invalid data format received from server") } if (result.data.length === 0) { console.warn("[v0] No data points received") setData([]) setLoading(false) return } console.log("[v0] First data point sample:", result.data[0]) const transformedData = result.data.map((item: any, index: number) => { const date = new Date(item.time * 1000) let timeLabel = "" if (timeframe === "hour") { timeLabel = date.toLocaleString("en-US", { hour: "2-digit", minute: "2-digit", hour12: false, }) } else if (timeframe === "day") { timeLabel = date.toLocaleString("en-US", { hour: "2-digit", minute: "2-digit", hour12: false, }) } else if (timeframe === "week") { timeLabel = date.toLocaleString("en-US", { month: "short", day: "numeric", hour: "2-digit", hour12: false, }) } else { timeLabel = date.toLocaleString("en-US", { month: "short", day: "numeric", }) } const transformed = { time: timeLabel, timestamp: item.time, cpu: item.cpu ? Number((item.cpu * 100).toFixed(2)) : 0, load: item.loadavg ? Number(item.loadavg[0].toFixed(2)) : 0, memoryTotal: item.memtotal ? Number((item.memtotal / 1024 / 1024 / 1024).toFixed(2)) : 0, memoryUsed: item.memused ? Number((item.memused / 1024 / 1024 / 1024).toFixed(2)) : 0, memoryFree: item.memfree ? Number((item.memfree / 1024 / 1024 / 1024).toFixed(2)) : 0, memoryZfsArc: item.zfsarc ? Number((item.zfsarc / 1024 / 1024 / 1024).toFixed(2)) : 0, } if (index === 0) { console.log("[v0] First transformed data point:", transformed) } return transformed }) console.log("[v0] Total transformed data points:", transformedData.length) console.log("[v0] Setting data state with", transformedData.length, "points") setData(transformedData) } catch (err: any) { console.error("[v0] Error fetching node metrics:", err) console.error("[v0] Error message:", err.message) console.error("[v0] Error stack:", err.stack) setError(err.message || "Error loading metrics") } finally { console.log("[v0] fetchMetrics finally block - setting loading to false") setLoading(false) } } const tickInterval = Math.ceil(data.length / 8) console.log("[v0] Render state - loading:", loading, "error:", error, "data length:", data.length) if (loading) { console.log("[v0] Rendering loading state") return (
) } if (error) { console.log("[v0] Rendering error state:", error) return (

Metrics data not available yet

{error}

Metrics data not available yet

{error}

) } if (data.length === 0) { console.log("[v0] Rendering no data state") return (

No metrics data available

No metrics data available

) } console.log("[v0] Rendering charts with", data.length, "data points") return (
{/* Timeframe Selector */}
{/* Charts Grid */}
{/* CPU Usage + Load Average Chart */} CPU Usage & Load Average {/* Memory Usage Chart */} Memory Usage
) }