diff --git a/package.json b/package.json
index 92a3a00..8a3d352 100755
--- a/package.json
+++ b/package.json
@@ -11,7 +11,9 @@
},
"dependencies": {
"react": "^18.3.1",
- "react-dom": "^18.3.1"
+ "react-dom": "^18.3.1",
+ "chart.js": "^4.0.0",
+ "react-chartjs-2": "^5.0.0"
},
"devDependencies": {
"@eslint/js": "^9.17.0",
@@ -25,4 +27,4 @@
"globals": "^15.14.0",
"vite": "^6.0.5"
}
-}
+}
\ No newline at end of file
diff --git a/src/App.jsx b/src/App.jsx
index f1652d7..8c0ccf5 100755
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -1,13 +1,32 @@
import React from "react";
import SidebarMenu from "./SidebarMenu/SidebarMenu"; // Импорт компонента бокового меню
-
+import CpuTemperatureChart from './Charts/CpuTemperatureChart';
+import ErrorIndicator from "./SidebarMenu/ErrorIndicator"; // Индикатор ошибок
+import GpuTemperatureChart from './Charts/GpuTemperatureChart';
+import RamUsageChart from './Charts/RamUsageChart'
+import Dashboard from "./SidebarMenu/Dashboard";
function App() {
return (
-
Рабочая область
+
+
Мониторинг состояния системы
+
+ {/* Индикатор ошибок */}
+
Индикатор ошибок:
+
+
+ {/* График температуры CPU
+
+
+
+
+
*/}
+
+
);
}
-export default App;
\ No newline at end of file
+export default App;
+
diff --git a/src/Charts/CpuTemperatureChart.jsx b/src/Charts/CpuTemperatureChart.jsx
new file mode 100644
index 0000000..97ff723
--- /dev/null
+++ b/src/Charts/CpuTemperatureChart.jsx
@@ -0,0 +1,75 @@
+import React, { useEffect, useRef, useState } from "react";
+import { Line } from "react-chartjs-2";
+import {
+ Chart as ChartJS,
+ LineElement,
+ PointElement,
+ LinearScale,
+ CategoryScale,
+} from "chart.js";
+import ExpandableInfo from "../SidebarMenu/ExpandableInfo"
+
+ChartJS.register(LineElement, PointElement, LinearScale, CategoryScale);
+
+const CpuTemperatureChart = () => {
+ const chartRef = useRef(null);
+ const [data, setData] = useState({
+ labels: Array(10).fill("").map((_, i) => i), // 20 точек по X
+ datasets: [
+ {
+ label: "Температура CPU (°C)",
+ data: Array(20).fill(50), // Начальные значения (например, 50°C)
+ borderColor: "red",
+ borderWidth: 2,
+ fill: false,
+ cubicInterpolationMode: "monotone", // Сглаживание
+ tension: 0.4, // Делаем линию плавнее
+ },
+ ],
+ });
+
+ useEffect(() => {
+ const interval = setInterval(() => {
+ setData((prevData) => {
+ const newTemp = Math.floor(Math.random() * 20) + 50; // Генерируем новую температуру (50-70°C)
+ const newLabels = [...prevData.labels.slice(1), prevData.labels[prevData.labels.length - 1] + 1]; // Сдвигаем ось X
+ const newDataset = [...prevData.datasets[0].data.slice(1), newTemp]; // Сдвигаем данные влево
+
+ return {
+ labels: newLabels,
+ datasets: [{ ...prevData.datasets[0], data: newDataset }],
+ };
+ });
+ }, 1000); // Обновление каждую секунду
+
+ return () => clearInterval(interval);
+ }, []);
+
+ // Пример данных для меню "Подробнее"
+ const details = [
+ { label: "Использование", value: " 45%" },
+ { label: "Скорость", value: " 3.6 GHz" },
+ { label: "Процессы", value: " 120" },
+ { label: "Время работы", value: " 2 ч 30 мин" },
+ ];
+
+ return (
+
+
График температуры ЦП
+
+
+
+ );
+};
+
+export default CpuTemperatureChart;
\ No newline at end of file
diff --git a/src/Charts/GpuTemperatureChart.jsx b/src/Charts/GpuTemperatureChart.jsx
new file mode 100644
index 0000000..7831195
--- /dev/null
+++ b/src/Charts/GpuTemperatureChart.jsx
@@ -0,0 +1,74 @@
+import React, { useEffect, useRef, useState } from "react";
+import { Line } from "react-chartjs-2";
+import {
+ Chart as ChartJS,
+ LineElement,
+ PointElement,
+ LinearScale,
+ CategoryScale,
+} from "chart.js";
+import ExpandableInfo from "../SidebarMenu/ExpandableInfo"
+
+ChartJS.register(LineElement, PointElement, LinearScale, CategoryScale);
+
+const GpuTemperatureChart = () => {
+ const chartRef = useRef(null);
+ const [data, setData] = useState({
+ labels: Array(10).fill("").map((_, i) => i), // 20 точек по X
+ datasets: [
+ {
+ label: "Температура GPU (°C)",
+ data: Array(20).fill(50), // Начальные значения (например, 50°C)
+ borderColor: "blue",
+ borderWidth: 2,
+ fill: false,
+ cubicInterpolationMode: "monotone", // Сглаживание
+ tension: 0.4, // Делаем линию плавнее
+ },
+ ],
+ });
+
+ useEffect(() => {
+ const interval = setInterval(() => {
+ setData((prevData) => {
+ const newTemp = Math.floor(Math.random() * 20) + 40; // Генерируем новую температуру (50-600°C)
+ const newLabels = [...prevData.labels.slice(1), prevData.labels[prevData.labels.length - 1] + 1]; // Сдвигаем ось X
+ const newDataset = [...prevData.datasets[0].data.slice(1), newTemp]; // Сдвигаем данные влево
+
+ return {
+ labels: newLabels,
+ datasets: [{ ...prevData.datasets[0], data: newDataset }],
+ };
+ });
+ }, 1000); // Обновление каждую секунду
+
+ return () => clearInterval(interval);
+ }, []);
+
+ // Пример данных для меню "Подробнее"
+ const details = [
+ { label: "Использование", value: " 20%" },
+ { label: "Оперативная память ГП", value: " 1,2/7,9 ГБ" },
+ { label: "Общая память ГП", value: " 1,2/7,9 ГБ" },
+ ];
+
+ return (
+
+
График температуры ГП
+
+
+
+ );
+};
+
+export default GpuTemperatureChart;
\ No newline at end of file
diff --git a/src/Charts/RamUsageChart.jsx b/src/Charts/RamUsageChart.jsx
new file mode 100644
index 0000000..4651f7a
--- /dev/null
+++ b/src/Charts/RamUsageChart.jsx
@@ -0,0 +1,76 @@
+import React, { useEffect, useRef, useState } from "react";
+import { Line } from "react-chartjs-2";
+import {
+ Chart as ChartJS,
+ LineElement,
+ PointElement,
+ LinearScale,
+ CategoryScale,
+} from "chart.js";
+import ExpandableInfo from "../SidebarMenu/ExpandableInfo"
+
+ChartJS.register(LineElement, PointElement, LinearScale, CategoryScale);
+
+const RamUsageChart = () => {
+ const chartRef = useRef(null);
+ const [data, setData] = useState({
+ labels: Array(10).fill("").map((_, i) => i), // 20 точек по X
+ datasets: [
+ {
+ label: "Загруженность RAM (%)",
+ data: Array(20).fill(50), // Начальные значения (например, 50%)
+ borderColor: "green",
+ borderWidth: 2,
+ fill: false,
+ cubicInterpolationMode: "monotone", // Сглаживание
+ tension: 0.4, // Делаем линию плавнее
+ },
+ ],
+ });
+
+ useEffect(() => {
+ const interval = setInterval(() => {
+ setData((prevData) => {
+ const newTemp = Math.floor(Math.random() * 20) + 40; // Генерируем новую температуру (50-600°C)
+ const newLabels = [...prevData.labels.slice(1), prevData.labels[prevData.labels.length - 1] + 1]; // Сдвигаем ось X
+ const newDataset = [...prevData.datasets[0].data.slice(1), newTemp]; // Сдвигаем данные влево
+
+ return {
+ labels: newLabels,
+ datasets: [{ ...prevData.datasets[0], data: newDataset }],
+ };
+ });
+ }, 1000); // Обновление каждую секунду
+
+ return () => clearInterval(interval);
+ }, []);
+
+ // Пример данных для меню "Подробнее"
+ const details = [
+ { label: "Используется", value: " 6,2 ГБ" },
+ { label: "Доступно", value: " 9,5 ГБ" },
+ { label: "Выделено", value: " 6,8/18,2 ГБ" },
+ { label: "Скорость", value: " 3200 МГц" },
+
+ ];
+
+ return (
+
+
График загруженности ОЗУ
+
+
+
+ );
+};
+
+export default RamUsageChart;
\ No newline at end of file
diff --git a/src/SidebarMenu/Dashboard.jsx b/src/SidebarMenu/Dashboard.jsx
new file mode 100644
index 0000000..138951e
--- /dev/null
+++ b/src/SidebarMenu/Dashboard.jsx
@@ -0,0 +1,46 @@
+import React from "react";
+import CpuTemperatureChart from "../Charts/CpuTemperatureChart";
+import GpuTemperatureChart from "../Charts/GpuTemperatureChart";
+import RamUsageChart from "../Charts/RamUsageChart";
+
+import "../Style/Dashboard.css"; // Подключаем стили
+
+const Dashboard = () => {
+ return (
+
+ {/* Левая колонка (Графики) */}
+
+
+ {/* Можно заменить на другие графики */}
+
+
+
+ {/* Правая колонка (Информационный блок) */}
+
+
Информационный блок
+
Здесь можно выводить любые данные о системе.
+
+
+ Температура CPU:
+ 65°C
+
+
+
+ Загрузка процессора:
+ 45%
+
+
+
+ Ошибки аппаратного обеспечения:
+ 2
+
+
+ Ошибки программного обеспечения:
+ 1
+
+
+
+ );
+};
+
+export default Dashboard;
\ No newline at end of file
diff --git a/src/SidebarMenu/ErrorIndicator.jsx b/src/SidebarMenu/ErrorIndicator.jsx
new file mode 100644
index 0000000..7d71840
--- /dev/null
+++ b/src/SidebarMenu/ErrorIndicator.jsx
@@ -0,0 +1,24 @@
+import React from "react";
+import criticalIcon from "../assets/images/critical.png"; // Красный треугольник
+import warningIcon from "../assets/images/warning.png"; // Желтый треугольник
+import "../Style/ErrorIndicator.css"; // Подключаем стили
+
+const ErrorIndicator = ({ criticalCount, warningCount }) => {
+ return (
+
+ {/* Красный индикатор (критические ошибки) */}
+
+

+
{criticalCount}
+
+
+ {/* Желтый индикатор (предупреждения) */}
+
+

+
{warningCount}
+
+
+ );
+};
+
+export default ErrorIndicator;
\ No newline at end of file
diff --git a/src/SidebarMenu/ExpandableInfo.jsx b/src/SidebarMenu/ExpandableInfo.jsx
new file mode 100644
index 0000000..1c550c0
--- /dev/null
+++ b/src/SidebarMenu/ExpandableInfo.jsx
@@ -0,0 +1,30 @@
+import React, { useState } from "react";
+import "../Style/Expandable.css"
+
+const ExpandableInfo = ({ details }) => {
+ const [isExpanded, setIsExpanded] = useState(false);
+
+ const toggleExpand = () => {
+ setIsExpanded(!isExpanded);
+ };
+
+ return (
+
+
+ {isExpanded && (
+
+ {details.map((detail, index) => (
+
+ {detail.label}:
+ {detail.value}
+
+ ))}
+
+ )}
+
+ );
+};
+
+export default ExpandableInfo;
\ No newline at end of file
diff --git a/src/SidebarMenu/SidebarMenu.jsx b/src/SidebarMenu/SidebarMenu.jsx
index 9f43d8e..9c15a40 100644
--- a/src/SidebarMenu/SidebarMenu.jsx
+++ b/src/SidebarMenu/SidebarMenu.jsx
@@ -1,6 +1,5 @@
import React, { useState } from "react";
-import "./SidebarMenu.css"; // Импортируем стили для компонента
-
+import "../Style/SidebarMenu.css"; // Импортируем стили для компонента
const menuItems = [
{
title: "Выбор сервиса",
diff --git a/src/Style/Dashboard.css b/src/Style/Dashboard.css
new file mode 100644
index 0000000..7b6a12b
--- /dev/null
+++ b/src/Style/Dashboard.css
@@ -0,0 +1,42 @@
+.dashboard-container {
+ display: flex;
+ gap: 20px;
+ padding: 20px;
+ }
+
+ .left-column {
+ flex: 2;
+ }
+
+ .right-column {
+ flex: 1;
+ background: #f3f3f3;
+ padding: 20px;
+ border-radius: 8px;
+ box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
+ }
+
+ h2 {
+ font-size: 20px;
+ margin-bottom: 10px;
+ }
+
+ .info-item {
+ display: flex;
+ justify-content: space-between;
+ padding: 10px 0;
+ border-bottom: 1px solid #ddd;
+ }
+
+ .label {
+ font-weight: bold;
+ }
+
+ .value {
+ color: #007bff;
+ font-weight: bold;
+ }
+
+ .value.error {
+ color: red;
+ }
\ No newline at end of file
diff --git a/src/Style/ErrorIndicator.css b/src/Style/ErrorIndicator.css
new file mode 100644
index 0000000..477ded5
--- /dev/null
+++ b/src/Style/ErrorIndicator.css
@@ -0,0 +1,29 @@
+.error-indicator {
+ display: flex;
+ align-items: center;
+ gap: 15px;
+}
+
+.error-item {
+ display: flex;
+ align-items: center;
+ gap: 5px;
+}
+
+.error-item img {
+ width: 30px;
+ height: 30px;
+}
+
+.error-item span {
+ font-size: 18px;
+ font-weight: bold;
+}
+
+.critical span {
+ color: red;
+}
+
+.warning span {
+ color: orange;
+}
\ No newline at end of file
diff --git a/src/Style/Expandable.css b/src/Style/Expandable.css
new file mode 100644
index 0000000..a9daf79
--- /dev/null
+++ b/src/Style/Expandable.css
@@ -0,0 +1,38 @@
+.expandable-info {
+ margin-top: 10px;
+ }
+
+ .expand-button {
+ background-color: #444;
+ color: white;
+ border: none;
+ padding: 8px 16px;
+ cursor: pointer;
+ border-radius: 4px;
+ }
+
+ .expand-button:hover {
+ background-color: #333;
+ }
+
+ .details-menu {
+ margin-top: 10px;
+ padding: 10px;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ background-color: #f9f9f9;
+ }
+
+ .detail-item {
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: 5px;
+ }
+
+ .label {
+ font-weight: bold;
+ }
+
+ .value {
+ color: #555;
+ }
\ No newline at end of file
diff --git a/src/SidebarMenu/SidebarMenu.css b/src/Style/SidebarMenu.css
similarity index 77%
rename from src/SidebarMenu/SidebarMenu.css
rename to src/Style/SidebarMenu.css
index ca1819b..8c476ef 100644
--- a/src/SidebarMenu/SidebarMenu.css
+++ b/src/Style/SidebarMenu.css
@@ -1,7 +1,10 @@
/* SidebarMenu.css */
+
.sidebar {
- width: 250px;
+ position: fixed;
height: 100vh;
+ width: 250px;
+ /* height: 100vh; */
background-color: #333;
color: white;
padding: 20px;
@@ -14,6 +17,12 @@
margin-bottom: 20px;
}
+.sidebar-indicator {
+ font-size: 18px;
+ font-weight: bold;
+ margin-bottom: 15px;
+}
+
.sidebar-section {
margin-bottom: 15px;
}
@@ -48,4 +57,10 @@
.sidebar-item:hover {
color: #ccc;
+}
+
+.indicator-container {
+ display: flex;
+ align-items: center;
+ gap: 15px;
}
\ No newline at end of file
diff --git a/src/assets/images/critical.png b/src/assets/images/critical.png
new file mode 100644
index 0000000..6ce21e5
Binary files /dev/null and b/src/assets/images/critical.png differ
diff --git a/src/assets/images/warning.png b/src/assets/images/warning.png
new file mode 100644
index 0000000..21e4ff7
Binary files /dev/null and b/src/assets/images/warning.png differ