finish ui design

This commit is contained in:
csehviktor
2025-07-10 05:19:22 +02:00
parent aa6b171614
commit e7dda680ad
16 changed files with 653 additions and 86 deletions

View File

@@ -1,15 +1,19 @@
import {
type WebsocketStatus,
ConnectionStatus,
WebsocketStatus,
} from "@/components/ConnectionStatus";
import type { StatusMessage } from "@/services/types";
import { Header } from "@/components/Header";
import { DonutChart } from "@/components/DonutChart";
import { LineChartCard } from "@/components/LineChartCard";
import { MetricCard } from "@/components/MetricCard";
import { SysinfoCard } from "@/components/SysinfoCard";
import { useChartData } from "@/hooks/useChartData";
import { getLastMessage, setLastMessage } from "@/services/store";
import { StatusMessage } from "@/services/types";
import {
formatBytes,
calcPercentage,
formatPercentage,
breakdownMetrics,
} from "@/services/utils";
import { initializeConnection } from "@/services/websocket";
import { useEffect, useState } from "react";
@@ -39,9 +43,10 @@ export function AgentPage() {
});
}, [agent]);
const { metrics } = message || {};
const { metrics } = message ?? {};
const { cpuData, memoryData, networkData } = useChartData(message);
const getMetricsStatus = (percentage: number | undefined) => {
const getMetricStatus = (percentage: number | undefined) => {
if (!percentage) return "nil";
if (percentage < 50) return "good";
@@ -49,17 +54,20 @@ export function AgentPage() {
return "critical";
};
const cpuUsage = metrics?.cpu.usage ?? 0;
const memoryUsage = calcPercentage(
metrics?.memory.used,
metrics?.memory.total,
);
const diskUsage = calcPercentage(
(metrics?.disk.total ?? 0) - (metrics?.disk.free ?? 0),
metrics?.disk.total,
);
const networkUsage =
(metrics?.network.up ?? 0) + (metrics?.network.down ?? 0);
const {
cpuThreads,
cpuUsage,
memoryUsage,
memoryUsed,
memoryTotal,
diskUsage,
diskFree,
diskTotal,
networkUp,
networkDown,
} = breakdownMetrics(message?.metrics);
const networkUsage = networkUp + networkDown;
return (
<div>
@@ -76,64 +84,103 @@ export function AgentPage() {
),
}}
/>
<main className="max-w-7xl mx-auto py-8">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">
<MetricCard
props={{
title: "CPU USAGE",
value: formatPercentage(cpuUsage),
status: getMetricsStatus(cpuUsage),
subtitle: `${metrics?.cpu.threads ?? 0} threads`,
}}
>
<h1>cpu chart</h1>
</MetricCard>
<div className="mx-2">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">
<MetricCard
props={{
title: "CPU USAGE",
value: formatPercentage(cpuUsage),
status: getMetricStatus(cpuUsage),
subtitle: `${cpuThreads} threads`,
}}
>
<DonutChart
data={{
labels: ["Usage", "Total"],
values: [cpuUsage, 100 - cpuUsage],
colors: ["#3b82f6", "#262626"],
}}
centerText={formatPercentage(cpuUsage)}
size="sm"
/>
</MetricCard>
<MetricCard
props={{
title: "MEMORY USAGE",
value: formatPercentage(memoryUsage),
status: getMetricsStatus(memoryUsage),
subtitle: `${formatBytes(metrics?.memory.used)} / ${formatBytes(metrics?.memory.total)}`,
}}
>
<h1>memory chart</h1>
</MetricCard>
<MetricCard
props={{
title: "MEMORY USAGE",
value: formatPercentage(memoryUsage),
status: getMetricStatus(memoryUsage),
subtitle: `${formatBytes(memoryUsed)} / ${formatBytes(memoryTotal)}`,
}}
>
<DonutChart
data={{
labels: ["Used", "Free"],
values: [memoryUsage, 100 - memoryUsage],
colors: ["#3b82f6", "#262626"],
}}
centerText={formatPercentage(memoryUsage)}
size="sm"
/>
</MetricCard>
<MetricCard
props={{
title: "NETWORK ACTIVITY",
value: formatBytes(networkUsage),
status: getMetricsStatus(networkUsage),
subtitle: `${formatBytes(metrics?.network.up)}/s ↓ ${formatBytes(metrics?.network.down)}/s`,
}}
>
<h1>network chart</h1>
</MetricCard>
</div>
<MetricCard
props={{
title: "DISK USAGE",
value: formatPercentage(diskUsage),
status: getMetricsStatus(diskUsage),
subtitle: `${formatBytes(metrics?.disk.free)} free of ${formatBytes(metrics?.disk.total)}`,
}}
>
<div className="w-full bg-[#141414] rounded-full h-4">
<div
className={`h-4 rounded-full transition-all duration-500 ${
getMetricsStatus(diskUsage) == "good"
? "bg-green-500"
: getMetricsStatus(diskUsage) == "warning"
? "bg-yellow-500"
: "bg-red-500"
}`}
style={{ width: `${diskUsage}%` }}
/>
<MetricCard
props={{
title: "NETWORK ACTIVITY",
value: formatBytes(networkUsage),
status: "nil",
subtitle: `${formatBytes(networkUp)}/s ↓ ${formatBytes(networkDown)}/s`,
}}
>
<DonutChart
data={{
labels: ["Upload", "Download"],
values: [
message ? networkUp : 1,
message ? networkDown : 1,
],
colors: ["#ef4444", "#3b82f6"],
}}
size="sm"
/>
</MetricCard>
</div>
</MetricCard>
<MetricCard
props={{
title: "DISK USAGE",
value: formatPercentage(diskUsage),
status: getMetricStatus(diskUsage),
subtitle: `${formatBytes(diskFree)} free of ${formatBytes(diskTotal)}`,
}}
>
<div className="w-full bg-[#141414] rounded-full h-4">
<div
className={`h-4 rounded-full transition-all duration-500 ${
getMetricStatus(diskUsage) == "good"
? "bg-green-500"
: getMetricStatus(diskUsage) ==
"warning"
? "bg-yellow-500"
: "bg-red-500"
}`}
style={{ width: `${diskUsage}%` }}
/>
</div>
</MetricCard>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 my-8">
<LineChartCard title="CPU Usage" data={cpuData} />
<LineChartCard title="Memory Usage" data={memoryData} />
<LineChartCard
title="Network Activity"
data={networkData}
/>
<SysinfoCard sysinfo={metrics?.system_info} />
</div>
</div>
</main>
</div>
);