some updates

This commit is contained in:
Vyacheslav K
2025-05-07 15:43:49 +03:00
parent 616199675b
commit b28022c633
5 changed files with 160 additions and 41 deletions

View File

@@ -0,0 +1,36 @@
import React, { useState } from "react";
export default function NetworkMonitor(args) {
const [selectedTab, setSelectedTab] = useState("interfaces");
const tabs = [
{ id: "interfaces", label: "Интерфейсы" },
{ id: "topology", label: "Топология сети" },
];
const handleTabClick = (tabId) => {
setSelectedTab(tabId);
};
return (
<>
<div className="flex justify-center md:justify-start">
{/* Контейнер для вкладок */}
<div className="flex p-2 bg-gray-100 dark:bg-gray-900 gap-2 rounded-lg shadow-sm">
{tabs.map((tab) => (
<button
key={tab.id}
onClick={() => handleTabClick(tab.id)}
className={`rounded-lg px-4 py-2 text-gray-900 dark:text-gray-100 ${selectedTab === tab.id
? "bg-gray-200 dark:bg-gray-800 text-orange-600 font-semibold"
: "hover:bg-gray-200 dark:hover:bg-gray-800 hover:text-orange-600 duration-300"
}`}
>
{tab.label}
</button>
))}
</div>
</div>
<div className="mt-6">
</div>
</>
);
}

View File

@@ -4,17 +4,55 @@ import { InformationCircleIcon, ComputerDesktopIcon, CodeBracketIcon, CpuChipIco
import CpuChart from "../misc/CpuChart"; import CpuChart from "../misc/CpuChart";
const Tabs = () => { const SystemMonitor = () => {
// Состояние для отслеживания выбранной вкладки // Состояние для отслеживания выбранной вкладки
const [selectedTab, setSelectedTab] = useState("system"); const [selectedTab, setSelectedTab] = useState("system");
const [Percent, setPercent] = useState(80); const [Percent, setPercent] = useState(80);
window.setPercent = setPercent; window.setPercent = setPercent;
// Данные для вкладок // Данные для вкладок
const tabs = [ const tabs = [
{ id: "system", label: "Система" }, { id: "system", label: "Основное" },
{ id: "deviceManager", label: "Диспетчер устройств" }, { id: "deviceManager", label: "Диспетчер устройств" },
]; ];
function PercentColor(value) {
if (value <= 40) {
return "green";
}
if (value <= 60) {
return "yellow";
}
if (value <= 85) {
return "orange";
}
return "red";
}
const [SystemInfo, setSystemInfo] = useState({
uptime: "1d 10:30:02",
os: "Windows",
hostname: "DESKTOP-380ABCDE",
os_version: "10.0.19049",
arch: "AMD64",
cpu_load: 20,
mem_load: 80,
cpu_model:"AMD Ryzen 5 5600x 6-core processor",
cpu_cores: 6,
cpu_threads: 12,
memory_gb: 32,
cpu_chart:
{
"10:00":40,
"11:00":34,
"12:00":56,
"13:00":60,
"14:00":80
}
});
// Функция для обработки клика по вкладке // Функция для обработки клика по вкладке
const handleTabClick = (tabId) => { const handleTabClick = (tabId) => {
setSelectedTab(tabId); setSelectedTab(tabId);
@@ -50,48 +88,48 @@ const Tabs = () => {
<ClockIcon className="h-6 text-gray-500" /> <ClockIcon className="h-6 text-gray-500" />
<span className="font-bold text-gray-600 dark:text-gray-400">Время работы:</span> <span className="font-bold text-gray-600 dark:text-gray-400">Время работы:</span>
</div> </div>
<span>1d 15:05:10</span> <span>{SystemInfo.uptime}</span>
</div> </div>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<div className="flex items-start gap-2"> <div className="flex items-start gap-2">
<InformationCircleIcon className="h-6 text-gray-500" /> <InformationCircleIcon className="h-6 text-gray-500" />
<span className="font-bold text-gray-600 dark:text-gray-400">Система:</span> <span className="font-bold text-gray-600 dark:text-gray-400">Система:</span>
</div> </div>
<span>Windows</span> <span>{SystemInfo.os}</span>
</div> </div>
<div className="flex items-start gap-2"> <div className="flex items-start gap-2">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<ComputerDesktopIcon className="h-6 text-gray-500" /> <ComputerDesktopIcon className="h-6 text-gray-500" />
<span className="font-bold text-gray-600 dark:text-gray-400">Hostname:</span> <span className="font-bold text-gray-600 dark:text-gray-400">Hostname:</span>
</div> </div>
<span className="break-normal">DESKTOP-380ABCDE</span> <span className="break-normal">{SystemInfo.hostname}</span>
</div> </div>
<div className="flex items-start gap-2"> <div className="flex items-start gap-2">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<CodeBracketIcon className="h-6 text-gray-500" /> <CodeBracketIcon className="h-6 text-gray-500" />
<span className="font-bold text-gray-600 dark:text-gray-400">Версия:</span> <span className="font-bold text-gray-600 dark:text-gray-400">Версия:</span>
</div> </div>
<span>10.0.19049</span> <span>{SystemInfo.os_version}</span>
</div> </div>
<div className="flex items-start gap-2"> <div className="flex items-start gap-2">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<CpuChipIcon className="h-6 text-gray-500" /> <CpuChipIcon className="h-6 text-gray-500" />
<span className="font-bold text-gray-600 dark:text-gray-400">Архитектура:</span> <span className="font-bold text-gray-600 dark:text-gray-400">Архитектура:</span>
</div> </div>
<span>AMD64</span> <span>{SystemInfo.arch}</span>
</div> </div>
</div> </div>
</div> </div>
<div className="md:basis-1/6 border border-gray-300 dark:border-gray-700 p-4 rounded-lg shadow-sm"> <div className="md:basis-1/6 border border-gray-300 dark:border-gray-700 p-4 rounded-lg shadow-sm">
<h1 className="text-lg font-semibold dark:text-gray-100">Загрузка CPU</h1> <h1 className="text-lg font-semibold dark:text-gray-100">Загрузка CPU</h1>
<div className=" flex flex-col items-center"> <div className=" flex flex-col items-center">
<Gauge value={20} title="%" color="green" className="mt-3" /> <Gauge value={SystemInfo.cpu_load} title="%" color={PercentColor(SystemInfo.cpu_load)} className="mt-3" />
</div> </div>
</div> </div>
<div className="md:basis-1/6 border border-gray-300 dark:border-gray-700 p-4 rounded-lg shadow-sm"> <div className="md:basis-1/6 border border-gray-300 dark:border-gray-700 p-4 rounded-lg shadow-sm">
<h1 className="text-lg font-semibold dark:text-gray-100">Занято ОЗУ</h1> <h1 className="text-lg font-semibold dark:text-gray-100">Занято ОЗУ</h1>
<div className=" flex flex-col items-center"> <div className=" flex flex-col items-center">
<Gauge value={Percent} title="%" color="orange" className="mt-3" /> <Gauge value={SystemInfo.mem_load} title="%" color={PercentColor(SystemInfo.mem_load)} className="mt-3" />
</div> </div>
</div> </div>
@@ -103,7 +141,7 @@ const Tabs = () => {
<CpuChipIcon className="h-6 text-gray-500" /> <CpuChipIcon className="h-6 text-gray-500" />
<span className="font-bold text-gray-600 dark:text-gray-400">Процессор:</span> <span className="font-bold text-gray-600 dark:text-gray-400">Процессор:</span>
</div> </div>
<span>AMD Ryzen 5 5600x 6-core processor</span> <span>{SystemInfo.cpu_model}</span>
</div> </div>
<div className="flex items-start gap-2"> <div className="flex items-start gap-2">
@@ -111,21 +149,21 @@ const Tabs = () => {
<ChevronDoubleRightIcon className="h-6 text-gray-500" /> <ChevronDoubleRightIcon className="h-6 text-gray-500" />
<span className="font-bold text-gray-600 dark:text-gray-400">Физические ядра:</span> <span className="font-bold text-gray-600 dark:text-gray-400">Физические ядра:</span>
</div> </div>
<span>6</span> <span>{SystemInfo.cpu_cores}</span>
</div> </div>
<div className="flex items-start gap-2"> <div className="flex items-start gap-2">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<ChevronDoubleRightIcon className="h-6 text-gray-500" /> <ChevronDoubleRightIcon className="h-6 text-gray-500" />
<span className="font-bold text-gray-600 dark:text-gray-400">Логические ядра:</span> <span className="font-bold text-gray-600 dark:text-gray-400">Логические ядра:</span>
</div> </div>
<span>12</span> <span>{SystemInfo.cpu_threads}</span>
</div> </div>
<div className="flex items-start gap-2"> <div className="flex items-start gap-2">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<ChevronDoubleRightIcon className="h-6 text-gray-500" /> <ChevronDoubleRightIcon className="h-6 text-gray-500" />
<span className="font-bold text-gray-600 dark:text-gray-400">ОЗУ:</span> <span className="font-bold text-gray-600 dark:text-gray-400">ОЗУ:</span>
</div> </div>
<span>32 ГБ</span> <span>{SystemInfo.memory_gb} ГБ</span>
</div> </div>
@@ -134,7 +172,7 @@ const Tabs = () => {
<div className="md:basis-[34.3%] w-full border border-gray-300 dark:border-gray-700 p-4 rounded-lg shadow-sm"> <div className="md:basis-[34.3%] w-full border border-gray-300 dark:border-gray-700 p-4 rounded-lg shadow-sm">
<h1 className="text-lg font-semibold">График загрузки CPU</h1> <h1 className="text-lg font-semibold">График загрузки CPU</h1>
<div className="flex flex-col gap-2 mt-3"> <div className="flex flex-col gap-2 mt-3">
<CpuChart /> <CpuChart chart_dataset={SystemInfo.cpu_chart} />
</div> </div>
</div> </div>
</div> </div>
@@ -149,4 +187,4 @@ const Tabs = () => {
); );
}; };
export default Tabs; export default SystemMonitor;

View File

@@ -5,3 +5,18 @@
body,html, #root{ body,html, #root{
height: 100%; height: 100%;
} }
@keyframes anim-pop {
0% {
transform: scale(.95);
transform: scale(var(--btn-focus-scale, .98));
}
100% {
transform: scale(1);
}
}
.anim-pop {
animation: anim-pop .3s ease-out;
}

View File

@@ -21,7 +21,7 @@ ChartJS.register(
Legend Legend
); );
export const options = { const options = {
responsive: true, responsive: true,
plugins: { plugins: {
legend: { legend: {
@@ -33,20 +33,22 @@ export const options = {
}, },
}; };
const labels = ['10:00',"11:00","12:00","13:00","14:00","15:00","16:00"];
export const data = {
export default function CpuChart({chart_dataset}) {
const labels = Object.keys(chart_dataset);
const data = {
labels, labels,
datasets: [ datasets: [
{ {
label: 'Загрузка CPU', label: 'Загрузка CPU',
data: [10,20,30,10,10,45,20], data: Object.values(chart_dataset),
borderColor: 'rgb(255, 99, 132)', borderColor: '#ff9f43',
backgroundColor: 'rgba(255, 99, 132, 0.5)', backgroundColor: 'rgba(255, 99, 132, 0.5)',
} }
], ],
}; };
export default function CpuChart() {
return <Line options={options} data={data} />; return <Line options={options} data={data} />;
} }

View File

@@ -5,6 +5,8 @@ import { WifiIcon } from '@heroicons/react/16/solid'
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import SystemMonitor from "../dashboard/SystemMonitor" import SystemMonitor from "../dashboard/SystemMonitor"
import NetworkMonitor from "../dashboard/NetworkMonitor"
import React, { useState, useEffect } from "react";
const user = { const user = {
name: 'Administrator', name: 'Administrator',
@@ -13,8 +15,8 @@ const user = {
'https://api.dicebear.com/9.x/thumbs/svg?seed=Amaya', 'https://api.dicebear.com/9.x/thumbs/svg?seed=Amaya',
} }
const navigation = [ const navigation = [
{ name: 'Системный мониторинг', href: '/dashboard', icon: ServerStackIcon, pageName: "dashboard" }, { name: 'Система', href: '/dashboard', icon: ServerStackIcon, pageName: "dashboard" },
{ name: 'Сетевой мониторинг', href: '/dashboard/network', icon: WifiIcon, pageName: "network" }, { name: 'Сеть', href: '/dashboard/network', icon: WifiIcon, pageName: "network" },
] ]
const userNavigation = [ const userNavigation = [
@@ -26,18 +28,23 @@ function classNames(...classes) {
} }
export default function Dashboard(args) { export default function Dashboard(args) {
const [WsLoading, setWsLoading] = useState(true);
let content; let content;
switch (args.CurrentPage) { switch (args.CurrentPage) {
case "dashboard": case "dashboard":
content = <SystemMonitor/>; content = <SystemMonitor />;
break; break;
case "network": case "network":
content = <SystemMonitor/>; content = <NetworkMonitor />;
break; break;
} }
useEffect(() => {
setTimeout(() => {
setWsLoading(false);
}, 1000)
}, []);
return ( return (
<> <>
{/* {/*
@@ -48,7 +55,7 @@ export default function Dashboard(args) {
<body class="h-full"> <body class="h-full">
``` ```
*/} */}
<div className="min-h-full"> <div className="min-h-full dark:bg-gray-800">
<Disclosure as="nav" className="bg-gray-700"> <Disclosure as="nav" className="bg-gray-700">
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8"> <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="flex h-16 items-center justify-between"> <div className="flex h-16 items-center justify-between">
@@ -73,7 +80,7 @@ export default function Dashboard(args) {
'flex gap-2 justify-center' 'flex gap-2 justify-center'
)} )}
> >
<item.icon className='h-6'/> <item.icon className='h-6' />
{item.name} {item.name}
</Link> </Link>
))} ))}
@@ -192,9 +199,30 @@ export default function Dashboard(args) {
</Disclosure> </Disclosure>
<main> <main>
<div className="mx-auto max-w-7xl px-4 py-6 sm:px-6 lg:px-8 dark:bg-gray-800"> <div className="mx-auto max-w-7xl px-4 py-6 sm:px-6 lg:px-8">
{!WsLoading &&
<>
<div className='anim-pop'>
{content} {content}
</div> </div>
</>
}
{WsLoading &&
<>
<div className='flex w-full justify-center md:justify-start'>
<div role="status" class="h-full animate-pulse">
<div class="h-[56px] w-[335px] bg-gray-200 rounded-lg dark:bg-gray-700"></div>
<div class="h-2 bg-gray-200 rounded-full dark:bg-gray-700 max-w-[360px] mb-2.5 mt-6"></div>
<div class="h-2 bg-gray-200 rounded-full dark:bg-gray-700 max-w-[330px] mb-2.5"></div>
<div class="h-2 bg-gray-200 rounded-full dark:bg-gray-700 max-w-[300px] mb-2.5"></div>
<div class="h-2 bg-gray-200 rounded-full dark:bg-gray-700 max-w-[270px] mb-2.5"></div>
</div>
</div>
</>
}
</div>
</main> </main>