Files
server-manager/views/layouts/main.php
Agent 88f3c1f964 refactor: extract inline CSS/JS from views into separate asset files (20+ files)
Phase A — HTML removed from PHP files:
- RateLimitMiddleware.php: heredoc moved to views/errors/429.php
- public/index.php: inline HTML replaced with View::error()
- AuthMiddleware.php: <script> redirect replaced with <meta refresh>

Phase B — Inline CSS/JS extracted from views:
- CSS: landing.css (459 lines), legal.css (shared by terms+privacy)
- JS: 17 new files extracted from ~20 view files
  - main.js (layout sidebar + notifications)
  - dashboard-chart.js, server-show.js, server-services.js
  - nginx-manager.js, database-manager.js
  - terminal.js, team-show.js, team-index.js
  - server-list.js, server-permissions.js (shared by edit+create)
  - server-ssl.js, server-processes.js, system-users.js
  - admin-users.js, audit-log.js, admin-notifications.js, admin-security.js
  - notifications.js

Total: -3264 lines from views, +288 lines in new assets
2026-06-14 08:04:01 -04:00

165 lines
7.8 KiB
PHP
Executable File

<?php
$user = $user ?? null;
$notifications = $notifications ?? [];
$unreadCount = $unreadCount ?? 0;
$teamId = $teamId ?? null;
$title = $title ?? 'ServerManager';
$content = $content ?? '';
$currentRoute = $_SERVER['REQUEST_URI'] ?? '/';
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= htmlspecialchars($title) ?> — ServerManager</title>
<meta name="api-token" content="<?= htmlspecialchars($user['api_token'] ?? '') ?>">
<meta name="csrf-token" content="<?= $this->csrfToken() ?>">
<link rel="stylesheet" href="/assets/css/app.css">
<link rel="icon" type="image/svg+xml" href="/assets/img/favicon.svg">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:opsz,wght@14..32,400;14..32,500;14..32,600;14..32,700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
</head>
<body>
<div class="app-layout">
<!-- Sidebar -->
<aside class="sidebar" id="sidebar">
<div class="sidebar-header">
<a href="/dashboard" class="sidebar-brand">
<i class="fas fa-cubes"></i>
<span>ServerManager</span>
</a>
</div>
<nav class="sidebar-nav">
<!-- Dashboard -->
<a href="/dashboard" class="nav-item <?= str_starts_with($currentRoute, '/dashboard') ? 'active' : '' ?>">
<i class="fas fa-chart-pie"></i>
<span>Dashboard</span>
</a>
<!-- Servers -->
<div class="nav-item-accordion <?= str_starts_with($currentRoute, '/servers') || str_starts_with($currentRoute, '/terminal') ? 'expanded' : '' ?>">
<a href="#" class="nav-item nav-item-toggle <?= str_starts_with($currentRoute, '/servers') ? 'active' : '' ?>" onclick="toggleServerList(event)">
<i class="fas fa-server"></i>
<span>Servers</span>
<i class="fas fa-chevron-right nav-chevron"></i>
</a>
<div class="nav-sublist" id="serverList" style="<?= str_starts_with($currentRoute, '/servers') || str_starts_with($currentRoute, '/terminal') ? '' : '' ?>">
<a href="/servers" class="nav-sub-item"><i class="fas fa-list"></i> All Servers</a>
</div>
</div>
<!-- Teams -->
<a href="/teams" class="nav-item <?= str_starts_with($currentRoute, '/teams') ? 'active' : '' ?>">
<i class="fas fa-users"></i>
<span>Teams</span>
</a>
<!-- Activity Log (admin+) -->
<?php if (is_admin() || is_super_admin()): ?>
<a href="/admin/activity" class="nav-item <?= str_starts_with($currentRoute, '/admin/activity') ? 'active' : '' ?>">
<i class="fas fa-history"></i>
<span>Activity Log</span>
</a>
<?php endif; ?>
<!-- Admin panel (admin+) -->
<?php if (is_admin() || is_super_admin()): ?>
<a href="/admin" class="nav-item <?= str_starts_with($currentRoute, '/admin') ? 'active' : '' ?>">
<i class="fas fa-cog"></i>
<span>Administration</span>
</a>
<?php endif; ?>
<hr class="nav-divider">
<!-- Account -->
<a href="/account" class="nav-item <?= str_starts_with($currentRoute, '/account') ? 'active' : '' ?>">
<i class="fas fa-user"></i>
<span>My Account</span>
</a>
<a href="/logout" class="nav-item nav-item-danger">
<i class="fas fa-sign-out-alt"></i>
<span>Log out</span>
</a>
</nav>
</aside>
<!-- Main Content -->
<div class="main-area">
<!-- Topbar -->
<header class="topbar">
<div class="topbar-left">
<button class="btn btn-icon" id="sidebarToggle" onclick="document.getElementById('sidebar').classList.toggle('collapsed')">
<i class="fas fa-bars"></i>
</button>
</div>
<div class="topbar-right">
<div class="notification-btn-wrapper">
<button class="btn btn-icon notification-btn" onclick="toggleNotifications()" title="Notifications">
<i class="fas fa-bell"></i>
<span class="notification-badge" id="notificationBadge" style="display:<?= $unreadCount > 0 ? 'inline-flex' : 'none' ?>">
<?= $unreadCount > 99 ? '99+' : $unreadCount ?>
</span>
</button>
<div class="notification-dropdown" id="notifDropdown">
<div class="notif-header">
<h3>Notifications</h3>
<button class="btn btn-text btn-sm" id="markAllReadBtn" onclick="markAllRead()"
style="display:<?= $unreadCount > 0 ? 'inline-flex' : 'none' ?>">
<i class="fas fa-check-double"></i> Mark all read
</button>
</div>
<div class="notif-list" id="notifList">
<div style="padding:40px 20px;text-align:center;color:var(--text-muted)">
<i class="fas fa-spinner fa-spin" style="font-size:1.5em;margin-bottom:10px;display:block"></i>
<span>Loading notifications...</span>
</div>
</div>
</div>
</div>
<span class="topbar-user">
<i class="fas fa-user-circle"></i>
<?= htmlspecialchars($user['username'] ?? 'Guest') ?>
</span>
</div>
</header>
<!-- Page Content -->
<main class="page-content">
<div class="container">
<?php if (isset($_SESSION['_flash'])): ?>
<?php foreach ($_SESSION['_flash'] as $type => $messages): ?>
<?php foreach ($messages as $msg): ?>
<div class="alert alert-<?= $type === 'error' ? 'danger' : $type ?>">
<i class="fas fa-<?= $type === 'success' ? 'check-circle' : ($type === 'error' ? 'exclamation-circle' : 'info-circle') ?>"></i>
<?= htmlspecialchars($msg) ?>
</div>
<?php endforeach; ?>
<?php endforeach; ?>
<?php unset($_SESSION['_flash']); ?>
<?php endif; ?>
<?= $content ?? '' ?>
</div>
</main>
</div>
</div>
<div id="toastContainer" class="toast-container"></div>
<script src="/assets/js/app.js"></script>
<?php if (isset($scripts)): ?>
<?php foreach ($scripts as $script): ?>
<script src="<?= htmlspecialchars($script) ?>"></script>
<?php endforeach; ?>
<?php endif; ?>
<script src="/assets/js/main.js"></script>
</body>
</html>