Update AppImage

This commit is contained in:
MacRimi
2025-10-26 14:31:10 +01:00
parent e4b57e6ca3
commit 6e2348eb06
3 changed files with 123 additions and 162 deletions

View File

@@ -1,26 +0,0 @@
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"
import { NetworkTrafficChart } from "@/components/charts/network-traffic-chart"
const Page = ({ params }) => {
const { id } = params
const timeframe = "1h" // Example value, you may need to adjust this based on your application logic
return (
<div>
{/* Other components or code here */}
<Card>
<CardHeader>
<CardTitle>Network Traffic</CardTitle>
</CardHeader>
<CardContent>
<NetworkTrafficChart timeframe={timeframe} interfaceName={id} refreshInterval={30000} />
</CardContent>
</Card>
{/* Other components or code here */}
</div>
)
}
export default Page

View File

@@ -1,28 +0,0 @@
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"
import NetworkTrafficChart from "@/components/NetworkTrafficChart" // Ensure this path is correct
const timeframe = "1h" // Declare timeframe variable
const handleTotalsCalculated = (totals) => {
console.log("Totals calculated:", totals)
} // Declare handleTotalsCalculated function
export default function Page({ id }) {
return (
<>
{/* ... other code here ... */}
<Card>
<CardHeader>
<CardTitle>Network Traffic</CardTitle>
</CardHeader>
<CardContent>
<NetworkTrafficChart
timeframe={timeframe}
onTotalsCalculated={handleTotalsCalculated}
refreshInterval={30000}
/>
</CardContent>
</Card>
{/* ... rest of code here ... */}
</>
)
}

View File

@@ -15,6 +15,7 @@ interface NetworkTrafficChartProps {
timeframe: string timeframe: string
interfaceName?: string interfaceName?: string
onTotalsCalculated?: (totals: { received: number; sent: number }) => void onTotalsCalculated?: (totals: { received: number; sent: number }) => void
refreshInterval?: number // En milisegundos, por defecto 60000 (60 segundos)
} }
const CustomNetworkTooltip = ({ active, payload, label }: any) => { const CustomNetworkTooltip = ({ active, payload, label }: any) => {
@@ -37,7 +38,12 @@ const CustomNetworkTooltip = ({ active, payload, label }: any) => {
return null return null
} }
export const NetworkTrafficChart = ({ timeframe, interfaceName, onTotalsCalculated }: NetworkTrafficChartProps) => { export function NetworkTrafficChart({
timeframe,
interfaceName,
onTotalsCalculated,
refreshInterval = 60000,
}: NetworkTrafficChartProps) {
const [data, setData] = useState<NetworkMetricsData[]>([]) const [data, setData] = useState<NetworkMetricsData[]>([])
const [loading, setLoading] = useState(true) const [loading, setLoading] = useState(true)
const [error, setError] = useState<string | null>(null) const [error, setError] = useState<string | null>(null)
@@ -48,116 +54,125 @@ export const NetworkTrafficChart = ({ timeframe, interfaceName, onTotalsCalculat
}) })
useEffect(() => { useEffect(() => {
const fetchMetrics = async () => { setIsInitialLoad(true)
if (isInitialLoad) {
setLoading(true)
}
setError(null)
try {
const baseUrl =
typeof window !== "undefined" ? `${window.location.protocol}//${window.location.hostname}:8008` : ""
const apiUrl = interfaceName
? `${baseUrl}/api/network/${interfaceName}/metrics?timeframe=${timeframe}`
: `${baseUrl}/api/node/metrics?timeframe=${timeframe}`
const response = await fetch(apiUrl)
if (!response.ok) {
throw new Error(`Failed to fetch network metrics: ${response.status}`)
}
const result = await response.json()
if (!result.data || !Array.isArray(result.data)) {
throw new Error("Invalid data format received from server")
}
if (result.data.length === 0) {
setData([])
setLoading(false)
return
}
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 if (timeframe === "year") {
timeLabel = date.toLocaleString("en-US", {
month: "short",
day: "numeric",
year: "numeric",
})
} else {
timeLabel = date.toLocaleString("en-US", {
month: "short",
day: "numeric",
})
}
let intervalSeconds = 60
if (index > 0) {
intervalSeconds = item.time - result.data[index - 1].time
}
const netInBytes = (item.netin || 0) * intervalSeconds
const netOutBytes = (item.netout || 0) * intervalSeconds
return {
time: timeLabel,
timestamp: item.time,
netIn: Number((netInBytes / 1024 / 1024 / 1024).toFixed(4)),
netOut: Number((netOutBytes / 1024 / 1024 / 1024).toFixed(4)),
}
})
setData(transformedData)
const totalReceived = transformedData.reduce((sum: number, item: NetworkMetricsData) => sum + item.netIn, 0)
const totalSent = transformedData.reduce((sum: number, item: NetworkMetricsData) => sum + item.netOut, 0)
if (onTotalsCalculated) {
onTotalsCalculated({ received: totalReceived, sent: totalSent })
}
if (isInitialLoad) {
setIsInitialLoad(false)
}
} catch (err: any) {
console.error("Error fetching network metrics:", err)
setError(err.message || "Error loading metrics")
} finally {
setLoading(false)
}
}
fetchMetrics() fetchMetrics()
}, [timeframe, interfaceName])
const interval = setInterval(fetchMetrics, 60000) useEffect(() => {
if (refreshInterval > 0) {
const interval = setInterval(() => {
fetchMetrics()
}, refreshInterval)
return () => clearInterval(interval) return () => clearInterval(interval)
}, [timeframe, interfaceName, isInitialLoad, onTotalsCalculated]) }
}, [timeframe, interfaceName, refreshInterval])
const fetchMetrics = async () => {
if (isInitialLoad) {
setLoading(true)
}
setError(null)
try {
const baseUrl =
typeof window !== "undefined" ? `${window.location.protocol}//${window.location.hostname}:8008` : ""
const apiUrl = interfaceName
? `${baseUrl}/api/network/${interfaceName}/metrics?timeframe=${timeframe}`
: `${baseUrl}/api/node/metrics?timeframe=${timeframe}`
console.log("[v0] Fetching network metrics from:", apiUrl)
const response = await fetch(apiUrl)
if (!response.ok) {
throw new Error(`Failed to fetch network metrics: ${response.status}`)
}
const result = await response.json()
if (!result.data || !Array.isArray(result.data)) {
throw new Error("Invalid data format received from server")
}
if (result.data.length === 0) {
setData([])
setLoading(false)
return
}
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 if (timeframe === "year") {
timeLabel = date.toLocaleString("en-US", {
month: "short",
day: "numeric",
year: "numeric",
})
} else {
timeLabel = date.toLocaleString("en-US", {
month: "short",
day: "numeric",
})
}
let intervalSeconds = 60
if (index > 0) {
intervalSeconds = item.time - result.data[index - 1].time
}
const netInBytes = (item.netin || 0) * intervalSeconds
const netOutBytes = (item.netout || 0) * intervalSeconds
return {
time: timeLabel,
timestamp: item.time,
netIn: Number((netInBytes / 1024 / 1024 / 1024).toFixed(4)),
netOut: Number((netOutBytes / 1024 / 1024 / 1024).toFixed(4)),
}
})
setData(transformedData)
const totalReceived = transformedData.reduce((sum: number, item: NetworkMetricsData) => sum + item.netIn, 0)
const totalSent = transformedData.reduce((sum: number, item: NetworkMetricsData) => sum + item.netOut, 0)
if (onTotalsCalculated) {
onTotalsCalculated({ received: totalReceived, sent: totalSent })
}
if (isInitialLoad) {
setIsInitialLoad(false)
}
} catch (err: any) {
console.error("[v0] Error fetching network metrics:", err)
setError(err.message || "Error loading metrics")
} finally {
setLoading(false)
}
}
const tickInterval = Math.ceil(data.length / 8) const tickInterval = Math.ceil(data.length / 8)