логин + ещё какая-то хуета
This commit is contained in:
parent
519bea1a98
commit
c8475752e0
35
src/App.js
35
src/App.js
@ -3,20 +3,37 @@ import DeviceGroups from "./pages/DeviceGroups";
|
|||||||
import Devices from "./pages/Devices";
|
import Devices from "./pages/Devices";
|
||||||
import Sidebar from "./Sidebar";
|
import Sidebar from "./Sidebar";
|
||||||
import Dashboard from './pages/Dashboard';
|
import Dashboard from './pages/Dashboard';
|
||||||
import UserAccount from './pages/UserAccount'; // Импортируем страницу аккаунта
|
import UserAccount from './pages/UserAccount'; // Импортируем компонент UserAccount
|
||||||
|
import Login from './pages/Login'; // Импортируем страницу логина
|
||||||
|
import Connections from './pages/Connections'; // Импортируем страницу подключений
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
const [activeTab, setActiveTab] = useState('map'); // По умолчанию активная вкладка "Карта"
|
const [activeTab, setActiveTab] = useState('map'); // По умолчанию активная вкладка "Карта"
|
||||||
|
const [isAuthenticated, setIsAuthenticated] = useState(false); // Статус авторизации
|
||||||
|
|
||||||
|
const handleLogin = () => {
|
||||||
|
setIsAuthenticated(true); // Устанавливаем авторизацию
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleLogout = () => {
|
||||||
|
setIsAuthenticated(false); // Сбрасываем авторизацию
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!isAuthenticated) {
|
||||||
|
return <Login onLogin={handleLogin} />; // Показываем страницу логина
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ display: 'flex' }}>
|
<div style={{ display: 'flex', flexDirection: 'column', height: '100vh' }}>
|
||||||
<Sidebar onSelectTab={setActiveTab} activeTab={activeTab} /> {/* Передаем активную вкладку */}
|
<div style={{ display: 'flex', flex: 1 }}>
|
||||||
<div style={{ padding: '20px', flex: 1 }}>
|
<Sidebar onSelectTab={setActiveTab} activeTab={activeTab} onLogout={handleLogout} /> {/* Передаем onLogout */}
|
||||||
{activeTab === 'map' && <Dashboard />} {/* Подключаем компонент Dashboard */}
|
<div style={{ padding: '20px', flex: 1 }}>
|
||||||
{activeTab === 'connection' && <div>Подключение</div>}
|
{activeTab === 'map' && <Dashboard />} {/* Подключаем компонент Dashboard */}
|
||||||
{activeTab === 'account' && <UserAccount />} {/* Подключаем компонент аккаунта */}
|
{activeTab === 'connection' && <Connections />} {/* Страница подключений */}
|
||||||
{activeTab === 'groups' && <DeviceGroups />} {/* Группы устройств */}
|
{activeTab === 'account' && <UserAccount />} {/* Подключаем компонент UserAccount */}
|
||||||
{activeTab === 'devices' && <Devices />} {/* Устройства */}
|
{activeTab === 'groups' && <DeviceGroups />} {/* Группы устройств */}
|
||||||
|
{activeTab === 'devices' && <Devices />} {/* Устройства */}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
34
src/Connections.scss
Normal file
34
src/Connections.scss
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
.section {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
form {
|
||||||
|
input {
|
||||||
|
margin-right: 10px;
|
||||||
|
padding: 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 8px 12px;
|
||||||
|
background-color: #2980b9;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #3498db;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
70
src/Login.scss
Normal file
70
src/Login.scss
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
// styles/Login.scss
|
||||||
|
|
||||||
|
.login-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
|
||||||
|
.login-box {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 40px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
max-width: 400px;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column; // Выровнять элементы по колонке
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.input-group {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
label {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
color: #666;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 16px;
|
||||||
|
transition: border-color 0.3s ease;
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: #007bff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 12px;
|
||||||
|
background-color: #007bff;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,12 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react'; // Ensure useState is imported
|
||||||
import './Sidebar.css';
|
import './Sidebar.css'; // Change this to Sidebar.scss if using SCSS
|
||||||
|
|
||||||
const Sidebar = ({ onSelectTab, activeTab }) => {
|
const Sidebar = ({ onSelectTab, activeTab, onLogout }) => {
|
||||||
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
const [isSubMenuOpen, setIsSubMenuOpen] = useState(false); // For managing dropdown items
|
||||||
|
|
||||||
const toggleDropdown = () => {
|
const toggleSubMenu = () => {
|
||||||
setIsDropdownOpen(!isDropdownOpen); // Переключаем состояние выпадающего списка
|
setIsSubMenuOpen(!isSubMenuOpen);
|
||||||
|
onSelectTab('account'); // Keep the logic to display the account when clicking on "Аккаунт пользователя"
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -18,17 +19,10 @@ const Sidebar = ({ onSelectTab, activeTab }) => {
|
|||||||
<li className={activeTab === 'connection' ? 'active' : ''} onClick={() => onSelectTab('connection')}>
|
<li className={activeTab === 'connection' ? 'active' : ''} onClick={() => onSelectTab('connection')}>
|
||||||
Подключение
|
Подключение
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li className={activeTab === 'account' ? 'active' : ''} onClick={toggleSubMenu}>
|
||||||
className={activeTab === 'account' ? 'active' : ''}
|
|
||||||
onClick={() => {
|
|
||||||
onSelectTab('account');
|
|
||||||
toggleDropdown();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Аккаунт пользователя
|
Аккаунт пользователя
|
||||||
</li>
|
</li>
|
||||||
{/* Выпадающий список для групп и устройств */}
|
{isSubMenuOpen && ( // Dropdown menu
|
||||||
{isDropdownOpen && (
|
|
||||||
<>
|
<>
|
||||||
<li className={activeTab === 'groups' ? 'active' : ''} onClick={() => onSelectTab('groups')}>
|
<li className={activeTab === 'groups' ? 'active' : ''} onClick={() => onSelectTab('groups')}>
|
||||||
Группы устройств
|
Группы устройств
|
||||||
@ -38,6 +32,9 @@ const Sidebar = ({ onSelectTab, activeTab }) => {
|
|||||||
</li>
|
</li>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
<li className="logout" onClick={onLogout}>
|
||||||
|
Выйти
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
63
src/pages/Connections.js
Normal file
63
src/pages/Connections.js
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import '../Connections.scss';
|
||||||
|
|
||||||
|
const Connections = () => {
|
||||||
|
const [webhooks, setWebhooks] = useState([]);
|
||||||
|
const [websocketUrl, setWebsocketUrl] = useState('');
|
||||||
|
|
||||||
|
const addWebhook = (newWebhook) => {
|
||||||
|
setWebhooks([...webhooks, newWebhook]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleWebhookSubmit = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const newWebhook = {
|
||||||
|
url: e.target.webhookUrl.value,
|
||||||
|
groups: e.target.groups.value.split(','),
|
||||||
|
};
|
||||||
|
addWebhook(newWebhook);
|
||||||
|
e.target.reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h2>Подключения</h2>
|
||||||
|
|
||||||
|
{/* Webhook подключение */}
|
||||||
|
<div className="section">
|
||||||
|
<h3>Подключения Webhooks</h3>
|
||||||
|
<form onSubmit={handleWebhookSubmit}>
|
||||||
|
<input type="text" name="webhookUrl" placeholder="URL Webhook" required />
|
||||||
|
<input type="text" name="groups" placeholder="Группы (через запятую)" required />
|
||||||
|
<button type="submit">Добавить Webhook</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
{webhooks.map((webhook, index) => (
|
||||||
|
<li key={index}>
|
||||||
|
Webhook: {webhook.url} (Группы: {webhook.groups.join(', ')})
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* WebSocket подключение */}
|
||||||
|
<div className="section">
|
||||||
|
<h3>Подключения WebSockets</h3>
|
||||||
|
<form
|
||||||
|
onSubmit={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setWebsocketUrl(e.target.websocketUrl.value);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<input type="text" name="websocketUrl" placeholder="URL WebSocket" required />
|
||||||
|
<button type="submit">Подключиться</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{websocketUrl && <p>Подключено по WebSocket: {websocketUrl}</p>}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Connections;
|
@ -1,42 +1,52 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import './Login.css';
|
import '../Login.scss';
|
||||||
|
|
||||||
const Login = ({ onLogin }) => {
|
const Login = ({ onLogin }) => {
|
||||||
const [username, setUsername] = useState('');
|
const [username, setUsername] = useState('');
|
||||||
const [password, setPassword] = useState('');
|
const [password, setPassword] = useState('');
|
||||||
const [error, setError] = useState('');
|
const [error, setError] = useState('');
|
||||||
|
|
||||||
const handleSubmit = (e) => {
|
const handleSubmit = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
// Простейшая проверка логина/пароля
|
// Simple login/password check
|
||||||
if (username === 'admin' && password === 'admin') {
|
if (username === 'admin' && password === 'admin') {
|
||||||
onLogin(); // Вызываем функцию при успешной авторизации
|
onLogin(); // Call function on successful login
|
||||||
} else {
|
} else {
|
||||||
setError('Неверный логин или пароль');
|
setError('Неверный логин или пароль');
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="login-container">
|
||||||
|
<div className="login-box"> {/* Added a wrapper for styling */}
|
||||||
|
<h2>Вход</h2>
|
||||||
|
{error && <p className="error">{error}</p>}
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
<div className="input-group">
|
||||||
|
<label htmlFor="username">Логин</label>
|
||||||
|
<input
|
||||||
|
id="username"
|
||||||
|
type="text"
|
||||||
|
placeholder="Логин"
|
||||||
|
value={username}
|
||||||
|
onChange={(e) => setUsername(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="input-group">
|
||||||
|
<label htmlFor="password">Пароль</label>
|
||||||
|
<input
|
||||||
|
id="password"
|
||||||
|
type="password"
|
||||||
|
placeholder="Пароль"
|
||||||
|
value={password}
|
||||||
|
onChange={(e) => setPassword(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<button type="submit">Войти</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
export default Login;
|
||||||
<div className="login-container">
|
|
||||||
<form onSubmit={handleSubmit}>
|
|
||||||
<h2>Вход</h2>
|
|
||||||
{error && <p className="error">{error}</p>}
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
placeholder="Логин"
|
|
||||||
value={username}
|
|
||||||
onChange={(e) => setUsername(e.target.value)}
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
type="password"
|
|
||||||
placeholder="Пароль"
|
|
||||||
value={password}
|
|
||||||
onChange={(e) => setPassword(e.target.value)}
|
|
||||||
/>
|
|
||||||
<button type="submit">Войти</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Login;
|
|
Loading…
Reference in New Issue
Block a user