Files
pg-adminus/public/js/router.js
2026-03-19 14:36:35 +07:00

206 lines
7.4 KiB
JavaScript

// Router - Single Page Application routing
class Router {
constructor() {
this.routes = {
'login': { module: 'authModule', handler: this.handleLogin.bind(this) },
'register': { module: 'authModule', handler: this.handleLogin.bind(this) },
'dashboard': { module: 'dashboardModule', requireAuth: true, handler: this.handleDashboard.bind(this) },
'databases': { module: 'dashboardModule', requireAuth: true, handler: this.handleDatabases.bind(this) },
'tables': { module: 'dashboardModule', requireAuth: true, handler: this.handleTables.bind(this) },
'queries': { module: 'dashboardModule', requireAuth: true, handler: this.handleQueries.bind(this) },
'admin-users': { module: 'adminModule', requireAuth: true, requireAdmin: true, handler: this.handleAdminUsers.bind(this) },
'admin-roles': { module: 'adminModule', requireAuth: true, requireAdmin: true, handler: this.handleAdminRoles.bind(this) },
'admin-settings': { module: 'adminModule', requireAuth: true, requireAdmin: true, handler: this.handleAdminSettings.bind(this) },
'admin-logs': { module: 'adminModule', requireAuth: true, requireAdmin: true, handler: this.handleAdminLogs.bind(this) },
'admin-database': { module: 'adminModule', requireAuth: true, requireAdmin: true, handler: this.handleAdminDatabase.bind(this) },
'admin-backups': { module: 'adminModule', requireAuth: true, requireAdmin: true, handler: this.handleAdminBackups.bind(this) },
};
this.currentRoute = null;
this.modules = {};
this.init();
}
async init() {
// Load modules
await this.loadModules();
// Setup hash change listener
window.addEventListener('hashchange', () => this.navigate());
// Initial navigation
this.navigate();
}
async loadModules() {
const modules = ['auth', 'dashboard', 'admin'];
for (const module of modules) {
try {
const response = await fetch(`/modules/${module}/${module === 'auth' ? 'login' : module === 'admin' ? 'admin-panel' : 'dashboard'}.html`);
if (response.ok) {
const html = await response.text();
const container = document.createElement('div');
container.innerHTML = html;
document.getElementById('app').appendChild(container);
}
} catch (error) {
console.error(`Failed to load ${module} module:`, error);
}
}
// Update Lucide icons after loading modules
if (typeof lucide !== 'undefined') {
lucide.createIcons();
}
}
navigate() {
const hash = window.location.hash.slice(1) || 'login';
const route = this.routes[hash];
if (!route) {
window.location.hash = '#login';
return;
}
// Check authentication
if (route.requireAuth && !auth.isAuthenticated) {
window.location.hash = '#login';
return;
}
// Check admin permission
if (route.requireAdmin && !auth.isAdmin()) {
window.location.hash = '#dashboard';
return;
}
// Hide all modules
document.querySelectorAll('[id$="Module"]').forEach(mod => {
mod.classList.add('hidden');
});
// Show target module
const module = document.getElementById(route.module);
if (module) {
module.classList.remove('hidden');
}
// Close sidebars on mobile when navigating
const sidebars = document.querySelectorAll('[id$="Sidebar"]');
sidebars.forEach(sidebar => {
sidebar.classList.add('hidden');
});
// Call route handler
if (route.handler) {
route.handler();
}
// Setup navigation event listeners for current route
this.setupNavigation();
// Update Lucide icons
if (typeof lucide !== 'undefined') {
lucide.createIcons();
}
this.currentRoute = hash;
}
setupNavigation() {
// Sidebar toggle
const toggleBtn = document.getElementById('toggleSidebar');
const sidebar = document.getElementById('sidebar');
if (toggleBtn && sidebar) {
toggleBtn.onclick = () => sidebar.classList.toggle('-translate-x-full');
}
// Admin sidebar toggle
const toggleAdminBtn = document.getElementById('toggleAdminSidebar');
const adminSidebar = document.getElementById('adminSidebar');
if (toggleAdminBtn && adminSidebar) {
toggleAdminBtn.onclick = () => adminSidebar.classList.toggle('-translate-x-full');
}
// Logout buttons
const logoutBtn = document.getElementById('logoutBtn');
if (logoutBtn) {
logoutBtn.onclick = () => {
if (confirm('Вы уверены, что хотите выйти?')) {
auth.logout();
}
};
}
const adminLogoutBtn = document.getElementById('adminLogoutBtn');
if (adminLogoutBtn) {
adminLogoutBtn.onclick = () => {
if (confirm('Вы уверены, что хотите выйти?')) {
auth.logout();
}
};
}
// Update user info
if (auth.isAuthenticated && auth.user) {
const userName = document.getElementById('userName');
const userRole = document.getElementById('userRole');
const avatarCircle = document.getElementById('avatarCircle');
if (userName) userName.textContent = auth.user.name || 'User';
if (userRole) userRole.textContent = this.getRoleName(auth.user.role);
if (avatarCircle) avatarCircle.textContent = (auth.user.name || 'A').charAt(0).toUpperCase();
}
// Navigation items
const navItems = document.querySelectorAll('.nav-item');
navItems.forEach(item => {
item.classList.remove('active');
if (item.getAttribute('href') === `#${this.currentRoute}`) {
item.classList.add('active');
}
item.addEventListener('click', () => {
navItems.forEach(n => n.classList.remove('active'));
item.classList.add('active');
// Close sidebar on mobile
const sidebar = document.getElementById('sidebar') || document.getElementById('adminSidebar');
if (sidebar) {
sidebar.classList.add('-translate-x-full');
}
});
});
}
getRoleName(role) {
const names = {
'superadmin': 'Суперадминистратор',
'admin': 'Администратор',
'moderator': 'Модератор',
'viewer': 'Только просмотр'
};
return names[role] || role;
}
// Route handlers
handleLogin() { }
handleDashboard() { }
handleDatabases() { }
handleTables() { }
handleQueries() { }
handleAdminUsers() { }
handleAdminRoles() { }
handleAdminSettings() { }
handleAdminLogs() { }
handleAdminDatabase() { }
handleAdminBackups() { }
}
// Initialize router
const router = new Router();