WebOrbiton
v1.0.0.8

Publisium

173 lines · 8.9 KB
  1. <?php
  2. ​
  3. declare(strict_types=1);
  4. ​
  5. require_once __DIR__ . '/icons.php';
  6. require_once __DIR__ . '/asset.php';
  7. require_once __DIR__ . '/font-library.php';
  8. require_once __DIR__ . '/activity-log.php';
  9. ​
  10. $dashAvailableFonts = FontLibrary::available();
  11. ​
  12. $dashSiteName = Config::get('APP_NAME', 'Publisium');
  13. $dashCurrentUser = Auth::user();
  14. $dashCurrentRole = Auth::role();
  15. $dashIsAdmin = Auth::hasRoleAtLeast(Auth::ROLE_EDITOR_IN_CHIEF);
  16. require_once __DIR__ . '/avatar.php';
  17. require_once __DIR__ . '/author-profile.php';
  18. require_once __DIR__ . '/site-comments.php';
  19. ​
  20. if (!function_exists('dashStatusLabel')) {
  21. function dashStatusLabel(string $status): string
  22. {
  23. return [
  24. 'draft' => 'Draft',
  25. 'pending_review' => 'Waiting for review',
  26. 'scheduled' => 'Scheduled',
  27. 'published' => 'Published',
  28. 'rejected' => 'Needs changes',
  29. 'archived' => 'Archived',
  30. 'pending' => 'Waiting for review',
  31. 'approved' => 'Approved',
  32. ][$status] ?? ucfirst(str_replace('_', ' ', $status));
  33. }
  34. }
  35. ​
  36. ?>
  37. <!DOCTYPE html>
  38. <html lang="en">
  39. ​
  40. <head>
  41. <meta charset="utf-8">
  42. <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
  43. <title><?= htmlspecialchars($dashPageTitle ?? 'Dashboard') ?> - <?= htmlspecialchars($dashSiteName) ?></title>
  44. <?= Asset::favicon() ?>
  45. <?= Asset::css('assets/dashboard.css') ?>
  46. <style>
  47. <?php foreach ($dashAvailableFonts as $dashFont): ?>
  48. <?= FontLibrary::fontFaceCss($dashFont['display_name'], $dashFont['display_name']) ?>
  49. <?php endforeach; ?>
  50. </style>
  51. </head>
  52. ​
  53. <body data-theme="dark">
  54. <script>
  55. (function() {
  56. try {
  57. var t = localStorage.getItem('publisium_dashboard_theme');
  58. if (t === 'dark' || t === 'light') {
  59. document.body.setAttribute('data-theme', t);
  60. } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) {
  61. document.body.setAttribute('data-theme', 'light');
  62. }
  63. } catch (e) {}
  64. })();
  65. </script>
  66. <script>
  67. (function() {
  68. try {
  69. var minimal = localStorage.getItem('publisium_dashboard_minimal') === '1';
  70. if (minimal) {
  71. document.body.classList.add('dash-minimal');
  72. }
  73. if (minimal || localStorage.getItem('publisium_dashboard_glass') === '0') {
  74. document.body.classList.add('dash-no-glass');
  75. }
  76. } catch (e) {}
  77. })();
  78. </script>
  79. <script>
  80. (function() {
  81. try {
  82. var validScales = [80, 90, 100, 110, 120, 130, 140, 150];
  83. var sidebarScale = parseInt(localStorage.getItem('publisium_dashboard_sidebar_scale'), 10);
  84. var mainScale = parseInt(localStorage.getItem('publisium_dashboard_main_scale'), 10);
  85. if (validScales.indexOf(sidebarScale) === -1) {
  86. sidebarScale = 100;
  87. }
  88. if (validScales.indexOf(mainScale) === -1) {
  89. mainScale = 100;
  90. }
  91. if (sidebarScale !== 100 || mainScale !== 100) {
  92. var style = document.createElement('style');
  93. var rules = '';
  94. if (sidebarScale !== 100) {
  95. rules += '.dash-sidebar{zoom:' + (sidebarScale / 100) + ';}';
  96. }
  97. if (mainScale !== 100) {
  98. rules += '.dash-main{zoom:' + (mainScale / 100) + ';}';
  99. }
  100. style.textContent = rules;
  101. document.head.appendChild(style);
  102. }
  103. } catch (e) {}
  104. })();
  105. </script>
  106. <?= Icons::sprite() ?>
  107. ​
  108. <div class="dash-mobile-topbar">
  109. <div class="dash-brand"><span class="dash-brand-dot"></span><?= htmlspecialchars($dashSiteName) ?></div>
  110. <div class="dash-mobile-topbar-right">
  111. <button type="button" class="dash-theme-toggle" aria-label="Toggle theme">
  112. <?= Icons::icon('sun', 'icon icon-sm icon-sun') ?>
  113. <?= Icons::icon('moon', 'icon icon-sm icon-moon') ?>
  114. </button>
  115. <?= Avatar::html($dashCurrentUser, 'dash-user-avatar') ?>
  116. </div>
  117. </div>
  118. ​
  119. <div class="dash-shell">
  120. <aside class="dash-sidebar">
  121. ​
  122. <div class="dash-brand-row">
  123. <div class="dash-brand"><span class="dash-brand-dot"></span><?= htmlspecialchars($dashSiteName) ?></div>
  124. <button type="button" class="dash-theme-toggle" id="dash-theme-toggle-btn" aria-label="Toggle theme">
  125. <?= Icons::icon('sun', 'icon icon-sm icon-sun') ?>
  126. <?= Icons::icon('moon', 'icon icon-sm icon-moon') ?>
  127. </button>
  128. </div>
  129. ​
  130. <nav class="dash-nav">
  131. <a href="dashboard.php?view=overview" class="<?= ($dashView ?? '') === 'overview' ? 'active' : '' ?>"><?= Icons::icon('overview') ?>Overview</a>
  132. <a href="dashboard.php?view=articles" class="<?= in_array($dashView ?? '', ['articles', 'article-edit'], true) ? 'active' : '' ?>"><?= Icons::icon('articles') ?>Articles</a>
  133. <a href="dashboard.php?view=categories" class="<?= ($dashView ?? '') === 'categories' ? 'active' : '' ?>"><?= Icons::icon('categories') ?>Categories</a>
  134. <?php $dashProfilesOn = AuthorProfile::isEnabled(); ?>
  135. <?php if (AuthorProfile::canHaveProfile() && ($dashProfilesOn || $dashIsAdmin)): ?>
  136. <a href="dashboard.php?view=profile" class="<?= ($dashView ?? '') === 'profile' ? 'active' : '' ?>"><?= Icons::icon('user') ?>Artist</a>
  137. <?php endif; ?>
  138. <?php if ($dashProfilesOn && Auth::canModerate()): ?>
  139. <?php $dashPendingProfiles = AuthorProfile::pendingCount(); ?>
  140. <a href="dashboard.php?view=profile-reviews" class="<?= ($dashView ?? '') === 'profile-reviews' ? 'active' : '' ?>"><?= Icons::icon('flag') ?>Artist reviews<?= $dashPendingProfiles > 0 ? ' (' . $dashPendingProfiles . ')' : '' ?></a>
  141. <?php endif; ?>
  142. <?php if (Auth::canModerate() && SiteComments::isActive()): ?>
  143. <?php $dashPendingComments = SiteComments::pendingCount(); ?>
  144. <a href="comments.php" class="<?= ($dashActivePage ?? '') === 'comments' ? 'active' : '' ?>"><?= Icons::icon('message') ?>Comments<?= $dashPendingComments > 0 ? ' (' . $dashPendingComments . ')' : '' ?></a>
  145. <?php endif; ?>
  146. <a href="dashboard.php?view=pages" class="<?= ($dashView ?? '') === 'pages' ? 'active' : '' ?>"><?= Icons::icon('pages') ?>Pages</a>
  147. <a href="dashboard.php?view=stats" class="<?= ($dashView ?? '') === 'stats' ? 'active' : '' ?>"><?= Icons::icon('stats') ?>Statistics</a>
  148. <a href="dashboard.php?view=security" class="<?= ($dashView ?? '') === 'security' ? 'active' : '' ?>"><?= Icons::icon('lock') ?>Security</a>
  149. <a href="interface.php" class="<?= ($dashActivePage ?? '') === 'interface' ? 'active' : '' ?>"><?= Icons::icon('sliders') ?>Interface</a>
  150. <?php if ($dashIsAdmin): ?>
  151. <div class="dash-nav-divider"></div>
  152. <a href="admin.php" class="<?= ($dashActivePage ?? '') === 'admin' ? 'active' : '' ?>"><?= Icons::icon('team') ?>Team</a>
  153. <a href="settings.php" class="<?= ($dashActivePage ?? '') === 'settings' ? 'active' : '' ?>"><?= Icons::icon('settings') ?>Settings</a>
  154. <a href="languages.php" class="<?= ($dashActivePage ?? '') === 'languages' ? 'active' : '' ?>"><?= Icons::icon('translate') ?>Languages</a>
  155. <a href="ads.php" class="<?= ($dashActivePage ?? '') === 'ads' ? 'active' : '' ?>"><?= Icons::icon('ads') ?>Ads</a>
  156. <?php if (ActivityLog::isEnabled()): ?>
  157. <a href="activity.php" class="<?= ($dashActivePage ?? '') === 'activity' ? 'active' : '' ?>"><?= Icons::icon('stats') ?>Activity log</a>
  158. <?php endif; ?>
  159. <a href="analytics.php" class="<?= ($dashActivePage ?? '') === 'analytics' ? 'active' : '' ?>"><?= Icons::icon('analytics') ?>Analytics</a>
  160. <?php endif; ?>
  161. </nav>
  162. ​
  163. <div class="dash-user">
  164. <?= Avatar::html($dashCurrentUser, 'dash-user-avatar') ?>
  165. <div class="dash-user-info">
  166. <div class="dash-user-name"><?= htmlspecialchars($dashCurrentUser['display_name']) ?></div>
  167. <div class="dash-user-role"><?= htmlspecialchars(Auth::roleLabel($dashCurrentRole)) ?></div>
  168. </div>
  169. <a href="team-login.php?logout=1" class="dash-user-logout" aria-label="Log out"><?= Icons::icon('logout', 'icon icon-sm') ?></a>
  170. </div>
  171. ​
  172. </aside>
  173. <main class="dash-main">