This commit is contained in:
2026-03-19 14:36:35 +07:00
parent 6d7d86befd
commit 96635dbcf2
28 changed files with 4332 additions and 1683 deletions

View File

@@ -0,0 +1,164 @@
<!-- Admin Panel Module -->
<div id="adminModule" class="admin-module hidden h-screen flex flex-col">
<!-- Header (same as dashboard) -->
<header class="bg-white dark:bg-slate-900 border-b border-slate-200 dark:border-slate-800 h-16 flex items-center justify-between px-4 sm:px-6 shadow-sm z-10">
<div class="flex items-center gap-4">
<button id="toggleAdminSidebar" class="p-2 hover:bg-slate-100 dark:hover:bg-slate-800 rounded-lg md:hidden">
<i data-lucide="menu" class="w-6 h-6"></i>
</button>
<div class="flex items-center gap-2 text-blue-600 dark:text-blue-400">
<i data-lucide="shield-admin" class="w-6 h-6"></i>
<span class="font-bold text-lg hidden sm:inline">Администрирование</span>
</div>
</div>
<div class="flex items-center gap-3">
<button id="toggleAdminTheme" class="p-2 hover:bg-slate-100 dark:hover:bg-slate-800 rounded-lg transition-colors" title="Переключить тему">
<i data-lucide="moon" class="w-5 h-5 dark:hidden"></i>
<i data-lucide="sun" class="w-5 h-5 hidden dark:block"></i>
</button>
<div class="h-6 w-px bg-slate-200 dark:bg-slate-700 hidden sm:block"></div>
<button id="adminLogoutBtn" class="p-2 hover:bg-red-50 dark:hover:bg-red-900/20 rounded-lg transition-colors" title="Выход">
<i data-lucide="log-out" class="w-5 h-5 text-red-500"></i>
</button>
</div>
</header>
<div class="flex flex-1 overflow-hidden">
<!-- Admin Sidebar -->
<aside id="adminSidebar" class="fixed md:static inset-y-16 left-0 w-64 bg-white dark:bg-slate-900 border-r border-slate-200 dark:border-slate-800 overflow-y-auto transform -translate-x-full md:translate-x-0 transition-transform z-40">
<nav class="p-4 space-y-2">
<h3 class="px-4 py-2 text-xs font-semibold text-slate-500 dark:text-slate-400 uppercase tracking-wider">Управление</h3>
<a href="#admin-overview" class="nav-item active flex items-center gap-3 px-4 py-3 rounded-lg font-medium transition-colors">
<i data-lucide="layout-dashboard" class="w-5 h-5"></i>
<span>Обзор</span>
</a>
<a href="#admin-users" class="nav-item flex items-center gap-3 px-4 py-3 rounded-lg font-medium transition-colors">
<i data-lucide="users" class="w-5 h-5"></i>
<span>Пользователи</span>
</a>
<a href="#admin-roles" class="nav-item flex items-center gap-3 px-4 py-3 rounded-lg font-medium transition-colors">
<i data-lucide="shield" class="w-5 h-5"></i>
<span>Роли и права</span>
</a>
<a href="#admin-logs" class="nav-item flex items-center gap-3 px-4 py-3 rounded-lg font-medium transition-colors">
<i data-lucide="file-text" class="w-5 h-5"></i>
<span>Логи</span>
</a>
<div class="my-4 h-px bg-slate-200 dark:bg-slate-700"></div>
<h3 class="px-4 py-2 text-xs font-semibold text-slate-500 dark:text-slate-400 uppercase tracking-wider">Система</h3>
<a href="#admin-database" class="nav-item flex items-center gap-3 px-4 py-3 rounded-lg font-medium transition-colors">
<i data-lucide="database" class="w-5 h-5"></i>
<span>База данных</span>
</a>
<a href="#admin-settings" class="nav-item flex items-center gap-3 px-4 py-3 rounded-lg font-medium transition-colors">
<i data-lucide="settings" class="w-5 h-5"></i>
<span>Настройки</span>
</a>
<a href="#admin-backups" class="nav-item flex items-center gap-3 px-4 py-3 rounded-lg font-medium transition-colors">
<i data-lucide="download" class="w-5 h-5"></i>
<span>Резервные копии</span>
</a>
<a href="#dashboard" class="nav-item flex items-center gap-3 px-4 py-3 rounded-lg font-medium transition-colors text-blue-600 dark:text-blue-400">
<i data-lucide="arrow-left" class="w-5 h-5"></i>
<span>К панели</span>
</a>
</nav>
</aside>
<!-- Admin Content -->
<main id="adminContent" class="flex-1 overflow-auto">
<div class="p-4 sm:p-6 space-y-6">
<!-- Users Section -->
<section id="usersSection" class="space-y-4">
<div class="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4 mb-4">
<div>
<h2 class="text-2xl font-bold text-slate-900 dark:text-white flex items-center gap-2">
<i data-lucide="users" class="w-6 h-6"></i>
Управление пользователями
</h2>
<p class="text-slate-500 dark:text-slate-400 text-sm mt-1">Добавляйте, редактируйте и удаляйте администраторов</p>
</div>
<button id="addUserBtn" class="btn btn-primary whitespace-nowrap flex items-center gap-2">
<i data-lucide="plus" class="w-5 h-5"></i>
<span class="hidden sm:inline">Добавить пользователя</span>
<span class="sm:hidden">Добавить</span>
</button>
</div>
<!-- Users Table -->
<div class="card overflow-x-auto">
<table class="w-full text-sm">
<thead class="border-b border-slate-200 dark:border-slate-700">
<tr>
<th class="text-left py-3 px-4 font-semibold text-slate-600 dark:text-slate-300">Имя</th>
<th class="text-left py-3 px-4 font-semibold text-slate-600 dark:text-slate-300 hidden sm:table-cell">Email</th>
<th class="text-left py-3 px-4 font-semibold text-slate-600 dark:text-slate-300">Роль</th>
<th class="text-left py-3 px-4 font-semibold text-slate-600 dark:text-slate-300">Статус</th>
<th class="text-right py-3 px-4 font-semibold text-slate-600 dark:text-slate-300">Действия</th>
</tr>
</thead>
<tbody id="usersList" class="divide-y divide-slate-200 dark:divide-slate-700">
<tr>
<td colspan="5" class="py-8 px-4 text-center text-slate-500 dark:text-slate-400">
Загрузка пользователей...
</td>
</tr>
</tbody>
</table>
</div>
</section>
<!-- Add/Edit User Modal -->
<div id="userModal" class="hidden fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50">
<div class="bg-white dark:bg-slate-900 rounded-2xl shadow-xl max-w-md w-full max-h-[90vh] overflow-y-auto">
<div class="sticky top-0 bg-white dark:bg-slate-900 p-6 border-b border-slate-200 dark:border-slate-700 flex items-center justify-between">
<h3 class="text-xl font-bold text-slate-900 dark:text-white" id="userModalTitle">Добавить пользователя</h3>
<button id="closeUserModal" class="p-1 hover:bg-slate-100 dark:hover:bg-slate-800 rounded-lg">
<i data-lucide="x" class="w-6 h-6"></i>
</button>
</div>
<form id="userForm" class="p-6 space-y-4">
<div>
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">Полное имя</label>
<input type="text" id="userNameInput" class="input-field" required>
</div>
<div>
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">Email</label>
<input type="email" id="userEmailInput" class="input-field" required>
</div>
<div>
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">Роль</label>
<select id="userRoleSelect" class="input-field">
<option value="superadmin">Суперадминистратор</option>
<option value="admin">Администратор</option>
<option value="moderator">Модератор</option>
<option value="viewer">Только просмотр</option>
</select>
</div>
<div>
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">Пароль</label>
<input type="password" id="userPasswordInput" class="input-field" placeholder="Оставить пусто, чтобы оставить без изменений">
</div>
<div class="flex gap-3 pt-4">
<button type="submit" class="flex-1 btn btn-primary">Сохранить</button>
<button type="button" id="cancelUserEdit" class="flex-1 btn btn-secondary">Отмена</button>
</div>
</form>
</div>
</div>
</div>
</main>
</div>
</div>

View File

@@ -0,0 +1,98 @@
<!-- Auth Module - Login/Register Screen -->
<div id="authModule" class="auth-module hidden">
<!-- Login Screen -->
<div id="loginScreen" class="fixed inset-0 z-50 flex items-center justify-center">
<div class="absolute inset-0 bg-gradient-to-br from-slate-900 via-blue-900 to-slate-900 dark:from-slate-950 dark:via-blue-950 dark:to-slate-950"></div>
<div class="relative w-full max-w-md px-4 sm:px-0">
<div class="glass-panel glass-panel-light dark:glass-panel-dark rounded-2xl shadow-2xl p-8">
<!-- Header -->
<div class="text-center mb-8">
<div class="inline-flex items-center justify-center w-16 h-16 bg-gradient-to-br from-blue-600 to-blue-700 rounded-2xl mb-4 shadow-lg shadow-blue-600/30">
<i data-lucide="database" class="w-8 h-8 text-white"></i>
</div>
<h1 class="text-2xl sm:text-3xl font-bold text-slate-900 dark:text-white">PostgreSQL SensoLab</h1>
<p class="text-slate-500 dark:text-slate-400 mt-2 text-sm sm:text-base">Управление базой данных</p>
</div>
<!-- Tab Navigation -->
<div class="flex gap-2 mb-8 bg-slate-100 dark:bg-slate-800 p-1 rounded-lg">
<button class="auth-tab-btn active flex-1 py-2 px-4 rounded-md font-medium transition-all text-sm sm:text-base" data-tab="login">
Вход
</button>
<button class="auth-tab-btn flex-1 py-2 px-4 rounded-md font-medium transition-all text-sm sm:text-base" data-tab="register">
Регистрация
</button>
</div>
<!-- Login Form -->
<form id="loginForm" class="auth-form space-y-4">
<div>
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">
Email или логин
</label>
<input type="text" id="loginEmail" class="input-field" placeholder="admin@example.com" required>
</div>
<div>
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">
Пароль
</label>
<input type="password" id="loginPassword" class="input-field" placeholder="••••••••" required>
</div>
<button type="submit" class="w-full btn btn-primary mt-6">
<span class="login-text">Войти</span>
<div class="login-loader hidden" style="width: 20px; height: 20px; border: 2px solid rgba(255,255,255,0.3); border-top: 2px solid white; border-radius: 50%; animation: spin 1s linear infinite;"></div>
</button>
</form>
<!-- Register Form -->
<form id="registerForm" class="auth-form hidden space-y-4">
<div>
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">
Полное имя
</label>
<input type="text" id="registerName" class="input-field" placeholder="Иван Петров" required>
</div>
<div>
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">
Email
</label>
<input type="email" id="registerEmail" class="input-field" placeholder="admin@example.com" required>
</div>
<div>
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">
Пароль
</label>
<input type="password" id="registerPassword" class="input-field" placeholder="••••••••" required>
</div>
<div>
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">
Подтверждение пароля
</label>
<input type="password" id="registerPasswordConfirm" class="input-field" placeholder="••••••••" required>
</div>
<button type="submit" class="w-full btn btn-primary mt-6">
<span class="register-text">Создать аккаунт</span>
<div class="register-loader hidden" style="width: 20px; height: 20px; border: 2px solid rgba(255,255,255,0.3); border-top: 2px solid white; border-radius: 50%; animation: spin 1s linear infinite;"></div>
</button>
</form>
<!-- Error Message -->
<div id="authError" class="mt-4 p-4 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg text-red-600 dark:text-red-400 text-sm hidden flex items-center gap-2">
<i data-lucide="alert-circle" class="w-4 h-4"></i>
<span id="authErrorText"></span>
</div>
<!-- Demo Info -->
<div class="mt-6 p-4 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg text-blue-600 dark:text-blue-400 text-xs sm:text-sm">
<p class="font-semibold mb-2 flex items-center gap-2">
<i data-lucide="info" class="w-4 h-4"></i>
Демо учетные данные:
</p>
<p>Email: <code class="bg-white/50 dark:bg-slate-900 px-2 py-1 rounded text-xs">admin@example.com</code></p>
<p>Пароль: <code class="bg-white/50 dark:bg-slate-900 px-2 py-1 rounded text-xs">admin123</code></p>
</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,146 @@
<!-- Dashboard Module -->
<div id="dashboardModule" class="dashboard-module hidden h-screen flex flex-col">
<!-- Header -->
<header class="bg-white dark:bg-slate-900 border-b border-slate-200 dark:border-slate-800 h-16 flex items-center justify-between px-4 sm:px-6 shadow-sm z-10">
<div class="flex items-center gap-2 sm:gap-4">
<button id="toggleSidebar" class="p-2 hover:bg-slate-100 dark:hover:bg-slate-800 rounded-lg md:hidden">
<i data-lucide="menu" class="w-6 h-6"></i>
</button>
<div class="flex items-center gap-2 text-blue-600 dark:text-blue-400">
<i data-lucide="database" class="w-6 h-6"></i>
<span class="font-bold text-lg hidden sm:inline">SensoLab</span>
</div>
</div>
<div class="flex items-center gap-3">
<button id="toggleTheme" class="p-2 hover:bg-slate-100 dark:hover:bg-slate-800 rounded-lg transition-colors" title="Переключить тему">
<i data-lucide="moon" class="w-5 h-5 dark:hidden"></i>
<i data-lucide="sun" class="w-5 h-5 hidden dark:block"></i>
</button>
<div class="h-6 w-px bg-slate-200 dark:bg-slate-700 hidden sm:block"></div>
<div class="flex items-center gap-2 text-sm">
<div class="w-8 h-8 bg-blue-600 rounded-full flex items-center justify-center text-white font-semibold hidden sm:flex" id="avatarCircle">A</div>
<div class="hidden sm:block">
<p class="font-semibold text-slate-900 dark:text-white text-sm" id="userName">Admin</p>
<p class="text-xs text-slate-500 dark:text-slate-400" id="userRole">Администратор</p>
</div>
</div>
<button id="logoutBtn" class="p-2 hover:bg-red-50 dark:hover:bg-red-900/20 rounded-lg transition-colors" title="Выход">
<i data-lucide="log-out" class="w-5 h-5 text-red-500"></i>
</button>
</div>
</header>
<div class="flex flex-1 overflow-hidden">
<!-- Sidebar -->
<aside id="sidebar" class="fixed md:static inset-y-16 left-0 w-64 bg-white dark:bg-slate-900 border-r border-slate-200 dark:border-slate-800 overflow-y-auto transform -translate-x-full md:translate-x-0 transition-transform z-40">
<nav class="p-4 space-y-2">
<h3 class="px-4 py-2 text-xs font-semibold text-slate-500 dark:text-slate-400 uppercase tracking-wider">Меню</h3>
<a href="#dashboard" class="nav-item active flex items-center gap-3 px-4 py-3 rounded-lg font-medium transition-colors">
<i data-lucide="home" class="w-5 h-5"></i>
<span>Панель управления</span>
</a>
<a href="#databases" class="nav-item flex items-center gap-3 px-4 py-3 rounded-lg font-medium transition-colors">
<i data-lucide="database" class="w-5 h-5"></i>
<span>Базы данных</span>
</a>
<a href="#tables" class="nav-item flex items-center gap-3 px-4 py-3 rounded-lg font-medium transition-colors">
<i data-lucide="table" class="w-5 h-5"></i>
<span>Таблицы</span>
</a>
<a href="#queries" class="nav-item flex items-center gap-3 px-4 py-3 rounded-lg font-medium transition-colors">
<i data-lucide="terminal" class="w-5 h-5"></i>
<span>SQL Запросы</span>
</a>
<div class="my-4 h-px bg-slate-200 dark:bg-slate-700"></div>
<h3 class="px-4 py-2 text-xs font-semibold text-slate-500 dark:text-slate-400 uppercase tracking-wider">Администрирование</h3>
<a href="#admin-users" class="nav-item flex items-center gap-3 px-4 py-3 rounded-lg font-medium transition-colors">
<i data-lucide="users" class="w-5 h-5"></i>
<span>Пользователи</span>
</a>
<a href="#admin-settings" class="nav-item flex items-center gap-3 px-4 py-3 rounded-lg font-medium transition-colors">
<i data-lucide="settings" class="w-5 h-5"></i>
<span>Настройки</span>
</a>
</nav>
</aside>
<!-- Main Content -->
<main class="flex-1 overflow-auto">
<div id="dashboardContent" class="p-4 sm:p-6 space-y-6">
<!-- Stats Row -->
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
<div class="card">
<div class="flex items-center justify-between">
<div>
<p class="text-sm text-slate-500 dark:text-slate-400">Таблиц</p>
<p class="text-2xl font-bold text-slate-900 dark:text-white" id="statsTableCount">0</p>
</div>
<div class="p-3 bg-blue-100 dark:bg-blue-900/30 rounded-lg">
<i data-lucide="table" class="w-6 h-6 text-blue-600 dark:text-blue-400"></i>
</div>
</div>
</div>
<div class="card">
<div class="flex items-center justify-between">
<div>
<p class="text-sm text-slate-500 dark:text-slate-400">Записей</p>
<p class="text-2xl font-bold text-slate-900 dark:text-white" id="statsRecordCount">0</p>
</div>
<div class="p-3 bg-green-100 dark:bg-green-900/30 rounded-lg">
<i data-lucide="database" class="w-6 h-6 text-green-600 dark:text-green-400"></i>
</div>
</div>
</div>
<div class="card">
<div class="flex items-center justify-between">
<div>
<p class="text-sm text-slate-500 dark:text-slate-400">Пользователей</p>
<p class="text-2xl font-bold text-slate-900 dark:text-white" id="statsUserCount">0</p>
</div>
<div class="p-3 bg-purple-100 dark:bg-purple-900/30 rounded-lg">
<i data-lucide="users" class="w-6 h-6 text-purple-600 dark:text-purple-400"></i>
</div>
</div>
</div>
<div class="card">
<div class="flex items-center justify-between">
<div>
<p class="text-sm text-slate-500 dark:text-slate-400">Размер БД</p>
<p class="text-2xl font-bold text-slate-900 dark:text-white" id="statsDbSize">-</p>
</div>
<div class="p-3 bg-orange-100 dark:bg-orange-900/30 rounded-lg">
<i data-lucide="hard-drive" class="w-6 h-6 text-orange-600 dark:text-orange-400"></i>
</div>
</div>
</div>
</div>
<!-- Tables Preview -->
<div class="card">
<div class="flex items-center justify-between mb-4">
<h2 class="text-lg font-semibold text-slate-900 dark:text-white flex items-center gap-2">
<i data-lucide="table" class="w-5 h-5"></i>
Таблицы
</h2>
<a href="#tables" class="text-sm text-blue-600 dark:text-blue-400 hover:underline">Все таблицы</a>
</div>
<div id="tablesList" class="space-y-2">
<p class="text-slate-500 dark:text-slate-400 text-sm">Загрузка...</p>
</div>
</div>
</div>
</main>
</div>
</div>