Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

88 рядки
5.9KB

  1. <?php
  2. declare(strict_types=1);
  3. $navigationItems = [
  4. ['label' => 'Home', 'href' => '/'],
  5. ['label' => 'Campaigns', 'href' => '/campaigns'],
  6. ['label' => 'Campaign Types', 'href' => '/campaign-types'],
  7. ['label' => 'Jobs', 'href' => '/jobs'],
  8. ['label' => 'Job Types', 'href' => '/job-types'],
  9. ];
  10. $currentPath = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH);
  11. $currentPath = is_string($currentPath) && $currentPath !== '' ? $currentPath : '/';
  12. $jsVersion = filemtime(__DIR__ . '/../../../public/js/app.js') ?: time();
  13. ?>
  14. <!DOCTYPE html>
  15. <html lang="en">
  16. <head>
  17. <meta charset="UTF-8">
  18. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  19. <title><?= e($pageTitle ?? 'Campaign Tracker') ?></title>
  20. <link rel="preconnect" href="https://fonts.googleapis.com">
  21. <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  22. <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;600&family=IBM+Plex+Sans:wght@400;600&family=Public+Sans:wght@400;600;700;800&display=swap">
  23. <link rel="stylesheet" href="https://unpkg.com/tabulator-tables@6.3.1/dist/css/tabulator.min.css">
  24. <link rel="stylesheet" href="<?= e(asset('css/site.css')) ?>">
  25. <script>window.__csrf = '<?= e(csrf_token()) ?>';</script>
  26. <script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.10/dist/htmx.min.js" integrity="sha384-H5SrcfygHmAuTDZphMHqBJLc3FhssKjG7w/CeCpFReSfwBWDTKpkzPP8c+cLsK+V" crossorigin="anonymous" defer></script>
  27. <script src="https://unpkg.com/tabulator-tables@6.3.1/dist/js/tabulator.min.js" defer></script>
  28. <script src="<?= e(asset('js/app.js')) ?>?v=<?= e((string) $jsVersion) ?>" defer></script>
  29. <script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
  30. </head>
  31. <body>
  32. <div class="page-shell">
  33. <header class="site-header">
  34. <div class="container header-inner">
  35. <a class="brand" href="/">
  36. <span class="brand-mark">CT</span>
  37. <span class="brand-copy">
  38. <strong>Campaign Tracker</strong>
  39. <small>PHP MVC</small>
  40. </span>
  41. </a>
  42. <nav class="site-nav" aria-label="Primary navigation">
  43. <?php
  44. $navIcons = [
  45. '/' => '<svg width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.75" viewBox="0 0 24 24" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"/></svg>',
  46. '/campaigns' => '<svg width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.75" viewBox="0 0 24 24" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2M9 12h6m-6 4h4"/></svg>',
  47. '/campaign-types' => '<svg width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.75" viewBox="0 0 24 24" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M7 7h.01M3 3h7.5L21 12l-9 9-10.5-10.5V3z"/></svg>',
  48. '/jobs' => '<svg width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.75" viewBox="0 0 24 24" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2 2v2m4 6h.01M5 20h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/></svg>',
  49. '/job-types' => '<svg width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.75" viewBox="0 0 24 24" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4"/></svg>',
  50. ];
  51. $prevHref = null;
  52. $group1 = ['/'];
  53. $group2 = ['/campaigns', '/campaign-types'];
  54. $group3 = ['/jobs', '/job-types'];
  55. foreach ($navigationItems as $item):
  56. $isActive = $item['href'] === '/'
  57. ? $currentPath === '/'
  58. : str_starts_with($currentPath, $item['href']);
  59. $needsSep = ($prevHref !== null) && (
  60. (in_array($prevHref, $group1) && in_array($item['href'], $group2)) ||
  61. (in_array($prevHref, $group2) && in_array($item['href'], $group3))
  62. );
  63. if ($needsSep): ?>
  64. <span class="nav-sep" aria-hidden="true"></span>
  65. <?php endif; ?>
  66. <a class="nav-link<?= $isActive ? ' is-active' : '' ?>" href="<?= e($item['href']) ?>">
  67. <?= $navIcons[$item['href']] ?? '' ?>
  68. <?= e($item['label']) ?>
  69. </a>
  70. <?php $prevHref = $item['href'];
  71. endforeach; ?>
  72. <?php if (auth()->check()): ?>
  73. <span class="nav-sep" aria-hidden="true"></span>
  74. <span class="nav-user"><?= e(auth()->user()?->displayName ?: auth()->user()?->username ?? '') ?></span>
  75. <form method="post" action="/logout" class="nav-logout-form">
  76. <?= csrf_field() ?>
  77. <button type="submit" class="nav-logout-btn">Log out</button>
  78. </form>
  79. <?php endif; ?>
  80. </nav>
  81. </div>
  82. </header>

Powered by TurnKey Linux.