diff --git a/package-lock.json b/package-lock.json
index a42fb96..b56fd65 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,6 +11,7 @@
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
+ "primereact": "^10.8.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-scripts": "5.0.1",
@@ -4751,6 +4752,15 @@
"@types/react": "*"
}
},
+ "node_modules/@types/react-transition-group": {
+ "version": "4.4.11",
+ "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.11.tgz",
+ "integrity": "sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/react": "*"
+ }
+ },
"node_modules/@types/resolve": {
"version": "1.17.1",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
@@ -7605,6 +7615,16 @@
"utila": "~0.4"
}
},
+ "node_modules/dom-helpers": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
+ "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.8.7",
+ "csstype": "^3.0.2"
+ }
+ },
"node_modules/dom-serializer": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
@@ -15762,6 +15782,29 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
+ "node_modules/primereact": {
+ "version": "10.8.3",
+ "resolved": "https://registry.npmjs.org/primereact/-/primereact-10.8.3.tgz",
+ "integrity": "sha512-LYa7DL1TDmWWrPCeh3CMsx89LXgcf4+rYhJ6YiA7z164WsdzJK388Bp1Qdv5cfpyL/Nm0eIWxIApxwWBv8kwuA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/react-transition-group": "^4.4.1",
+ "react-transition-group": "^4.4.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
+ "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
@@ -16288,6 +16331,22 @@
}
}
},
+ "node_modules/react-transition-group": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
+ "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@babel/runtime": "^7.5.5",
+ "dom-helpers": "^5.0.1",
+ "loose-envify": "^1.4.0",
+ "prop-types": "^15.6.2"
+ },
+ "peerDependencies": {
+ "react": ">=16.6.0",
+ "react-dom": ">=16.6.0"
+ }
+ },
"node_modules/read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
diff --git a/package.json b/package.json
index 20a994b..3522925 100644
--- a/package.json
+++ b/package.json
@@ -6,6 +6,7 @@
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
+ "primereact": "^10.8.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-scripts": "5.0.1",
diff --git a/public/logo192.png b/public/logo192.png
deleted file mode 100644
index fc44b0a..0000000
Binary files a/public/logo192.png and /dev/null differ
diff --git a/public/logo512.png b/public/logo512.png
deleted file mode 100644
index a4e47a6..0000000
Binary files a/public/logo512.png and /dev/null differ
diff --git a/src/App.js b/src/App.js
index 3784575..538e2b0 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,25 +1,23 @@
-import logo from './logo.svg';
-import './App.css';
+import React, { useState } from 'react';
+import DeviceGroups from "./components/DeviceGroups"
+import Devices from "./components/Devices"
+import Sidebar from "./components/Sidebar"
+
+const App = () => {
+ const [activeTab, setActiveTab] = useState('map'); // По умолчанию активная вкладка "Карта"
-function App() {
return (
-
-
+
+
{/* Передаем активную вкладку */}
+
+ {activeTab === 'map' &&
Карта в реальном времени
}
+ {activeTab === 'connection' &&
Подключение
}
+ {activeTab === 'account' &&
Аккаунт пользователя
}
+ {activeTab === 'groups' &&
} {/* Группы устройств */}
+ {activeTab === 'devices' &&
} {/* Устройства */}
+
);
-}
+};
-export default App;
+export default App;
\ No newline at end of file
diff --git a/src/DeviceGroups.css b/src/DeviceGroups.css
new file mode 100644
index 0000000..a421135
--- /dev/null
+++ b/src/DeviceGroups.css
@@ -0,0 +1,49 @@
+.device-groups {
+ padding: 20px;
+ }
+
+ .device-groups h2 {
+ margin-bottom: 20px;
+ }
+
+ .group-creation {
+ margin-bottom: 20px;
+ }
+
+ .group-creation input {
+ padding: 5px;
+ margin-right: 10px;
+ }
+
+ .group-creation button {
+ padding: 5px 10px;
+ }
+
+ ul {
+ list-style-type: none;
+ padding: 0;
+ }
+
+ li {
+ margin-bottom: 20px;
+ padding: 10px;
+ border: 1px solid #ddd;
+ border-radius: 5px;
+ }
+
+ .active {
+ background-color: #e8f5e9;
+ }
+
+ .inactive {
+ background-color: #ffebee;
+ }
+
+ li div {
+ margin-bottom: 10px;
+ }
+
+ li button {
+ margin-right: 10px;
+ }
+
\ No newline at end of file
diff --git a/src/Devices.css b/src/Devices.css
new file mode 100644
index 0000000..ca645f5
--- /dev/null
+++ b/src/Devices.css
@@ -0,0 +1,39 @@
+.devices {
+ padding: 20px;
+ }
+
+ .devices h2 {
+ margin-bottom: 20px;
+ }
+
+ .devices table {
+ width: 100%;
+ border-collapse: collapse;
+ }
+
+ .devices table, .devices th, .devices td {
+ border: 1px solid #ddd;
+ }
+
+ .devices th, .devices td {
+ padding: 8px;
+ text-align: left;
+ }
+
+ .devices th {
+ background-color: #34495e;
+ color: white;
+ }
+
+ .devices tr:hover {
+ background-color: #f1f1f1;
+ }
+
+ .buttons {
+ margin-top: 20px;
+ }
+
+ .buttons button {
+ margin-right: 10px;
+ }
+
\ No newline at end of file
diff --git a/src/Sidebar.css b/src/Sidebar.css
new file mode 100644
index 0000000..28d059c
--- /dev/null
+++ b/src/Sidebar.css
@@ -0,0 +1,52 @@
+.sidebar {
+ width: 250px;
+ height: 100vh;
+ background-color: #2c3e50;
+ color: white;
+ padding: 20px;
+ box-shadow: 2px 0 5px rgba(0, 0, 0, 0.5);
+ }
+
+ .sidebar h2 {
+ font-size: 24px;
+ margin-bottom: 20px;
+ }
+
+ .sidebar ul {
+ list-style-type: none;
+ padding: 0;
+ }
+
+ .sidebar li {
+ margin: 15px 0;
+ cursor: pointer;
+ }
+
+ .sidebar li:hover {
+ background-color: #34495e;
+ padding: 10px;
+ border-radius: 5px;
+ }
+ .sidebar ul {
+ list-style-type: none;
+ padding: 0;
+ }
+
+ .sidebar li {
+ margin: 15px 0;
+ cursor: pointer;
+ padding: 10px;
+ border-radius: 5px;
+ transition: background-color 0.3s;
+ }
+
+ .sidebar li:hover {
+ background-color: #34495e;
+ }
+
+ .sidebar li.active {
+ background-color: #2980b9;
+ color: white;
+ }
+
+
\ No newline at end of file
diff --git a/src/components/DeviceGroups.js b/src/components/DeviceGroups.js
new file mode 100644
index 0000000..1390cd3
--- /dev/null
+++ b/src/components/DeviceGroups.js
@@ -0,0 +1,88 @@
+import React, { useState } from 'react';
+import '../DeviceGroups.css';
+
+const DeviceGroups = () => {
+ const [groups, setGroups] = useState([]);
+ const [selectedGroup, setSelectedGroup] = useState(null);
+ const [newGroupName, setNewGroupName] = useState('');
+
+ const createGroup = () => {
+ if (newGroupName) {
+ const newGroup = {
+ name: newGroupName,
+ devices: [],
+ active: true,
+ };
+ setGroups([...groups, newGroup]);
+ setNewGroupName('');
+ }
+ };
+
+ const deleteGroup = (groupName) => {
+ setGroups(groups.filter(group => group.name !== groupName));
+ };
+
+ const toggleGroupStatus = (groupName) => {
+ setGroups(groups.map(group =>
+ group.name === groupName ? { ...group, active: !group.active } : group
+ ));
+ };
+
+ const addDeviceToGroup = (groupName, device) => {
+ setGroups(groups.map(group =>
+ group.name === groupName ? { ...group, devices: [...group.devices, device] } : group
+ ));
+ };
+
+ const removeDeviceFromGroup = (groupName, device) => {
+ setGroups(groups.map(group =>
+ group.name === groupName ? { ...group, devices: group.devices.filter(d => d !== device) } : group
+ ));
+ };
+
+ return (
+
+
Группы устройств
+
+
+ setNewGroupName(e.target.value)}
+ placeholder="Название новой группы"
+ />
+
+
+
+
+
+ );
+};
+
+export default DeviceGroups;
diff --git a/src/components/Devices.js b/src/components/Devices.js
new file mode 100644
index 0000000..0bf6977
--- /dev/null
+++ b/src/components/Devices.js
@@ -0,0 +1,56 @@
+import React, { useState } from 'react';
+import '../Devices.css';
+
+const Devices = () => {
+ const [devices, setDevices] = useState([]);
+ const [selectedDevice, setSelectedDevice] = useState(null);
+
+ const addDevice = () => {
+ // Логика добавления устройства
+ };
+
+ const removeDevice = () => {
+ // Логика удаления выбранного устройства
+ };
+
+ const editDevice = () => {
+ // Логика редактирования устройства
+ };
+
+ const generateQR = () => {
+ // Логика генерации QR-кода
+ };
+
+ return (
+
+
Устройства
+
+
+
+ Название |
+ Статус |
+ Действия |
+
+
+
+ {devices.map((device, index) => (
+ setSelectedDevice(device)}>
+ {device.name} |
+ {device.status} |
+
+
+ |
+
+ ))}
+
+
+
+
+
+
+
+
+ );
+};
+
+export default Devices;
diff --git a/src/components/Sidebar.js b/src/components/Sidebar.js
new file mode 100644
index 0000000..4559352
--- /dev/null
+++ b/src/components/Sidebar.js
@@ -0,0 +1,29 @@
+import React from 'react';
+import '../Sidebar.css';
+
+const Sidebar = ({ onSelectTab, activeTab }) => {
+ return (
+
+
Меню
+
+ - onSelectTab('map')}>
+ Карта в реальном времени
+
+ - onSelectTab('connection')}>
+ Подключение
+
+ - onSelectTab('account')}>
+ Аккаунт пользователя
+
+ - onSelectTab('groups')}>
+ Группы устройств
+
+ - onSelectTab('devices')}>
+ Устройства
+
+
+
+ );
+};
+
+export default Sidebar;
diff --git a/src/logo.svg b/src/logo.svg
deleted file mode 100644
index 9dfc1c0..0000000
--- a/src/logo.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file