views/partials/layout.php
1 <?php
2 $_title = isset($PAGE_TITLE) ? e($PAGE_TITLE) . ' — ' : '';
3 $_site = e(cfg('site_name', 'Nexus Forum'));
4 $_unread = unread_count();
5 $_msgs = unread_messages();
6 $_cats = nav_categories();
7 ?>
8 <!DOCTYPE html>
9 <html lang="en">
10 <script>
11 (function(){
12 try{
13 var t=localStorage.getItem('nexus-theme');
14 var p=window.matchMedia&&window.matchMedia('(prefers-color-scheme:dark)').matches;
15 if(t==='dark'||(t===null&&p)) document.documentElement.setAttribute('data-theme','dark');
16 }catch(e){}
17 })();
18 </script>
19 <head>
20 <meta charset="UTF-8">
21 <meta name="viewport" content="width=device-width, initial-scale=1.0">
22 <title><?= $_title . $_site ?></title>
23 <link rel="preconnect" href="https://fonts.googleapis.com">
24 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
25 <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
26 <link rel="stylesheet" href="<?= asset('css/main.css') ?>">
27 <?= active_theme_css() ?>
28 <?= cfg('custom_head') ?>
29 <?php /* ── before_page_head addon hook (collector) ── */
30 echo addon_collect('before_page_head');
31 ?>
32 </head>
33 <body>
34 <header class="site-header">
35 <div class="hdr-inner">
36 <div class="hdr-left">
37 <button class="burger" id="burgerBtn"><span></span><span></span><span></span></button>
38 <a href="<?= u('/') ?>" class="logo">
39 <?php if (cfg('logo_url')): ?>
40 <img src="<?= e(cfg('logo_url')) ?>" alt="<?= $_site ?>" class="logo-img">
41 <?php else: ?>
42 <div class="logo-mark"><?= e(substr(cfg('site_name','N'),0,1)) ?></div>
43 <?php endif; ?>
44 <span class="logo-name"><?= $_site ?></span>
45 </a>
46 </div>
47
48 <div class="hdr-search">
49 <div class="search-wrap">
50 <svg class="srch-icon" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="2"><circle cx="8.5" cy="8.5" r="5.5"/><path d="m13.5 13.5 3 3"/></svg>
51 <input type="text" id="searchInput" placeholder="Search topics…" autocomplete="off">
52 <div class="search-results" id="searchResults"></div>
53 </div>
54 </div>
55
56 <div class="hdr-right">
57 <?php if ($USER): ?>
58
59 <!-- Messages icon -->
60 <a href="<?= u('messages/') ?>" class="icon-btn" title="Messages" style="position:relative">
61 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="18" height="18"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>
62 <?php if ($_msgs > 0): ?>
63 <span class="badge-dot"><?= $_msgs > 9 ? '9+' : $_msgs ?></span>
64 <?php endif; ?>
65 </a>
66
67 <!-- Notifications -->
68 <!-- Dark mode toggle -->
69 <button class="icon-btn" id="themeToggle" onclick="toggleTheme()" title="Toggle dark mode" aria-label="Toggle dark mode">
70 <svg class="theme-icon-light" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="18" height="18"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg>
71 <svg class="theme-icon-dark" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="18" height="18" style="display:none"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>
72 </button>
73 <div class="notif-wrap" id="notifWrap">
74 <button class="icon-btn" id="notifBtn" title="Notifications">
75 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="18" height="18"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/></svg>
76 <?php if ($_unread > 0): ?>
77 <span class="badge-dot"><?= $_unread > 9 ? '9+' : $_unread ?></span>
78 <?php endif; ?>
79 </button>
80 <div class="notif-drop" id="notifDrop">
81 <div class="notif-head"><span>Notifications</span><button id="readAllBtn" class="link-btn">Mark all read</button></div>
82 <div id="notifList"><p class="notif-empty">Loading…</p></div>
83 </div>
84 </div>
85
86 <!-- User menu -->
87 <div class="user-wrap" id="userWrap">
88 <button class="avatar-btn" id="userBtn">
89 <?php if ($USER['avatar']): ?>
90 <img src="<?= e($USER['avatar']) ?>" class="av-sm" alt="">
91 <?php else: ?>
92 <span class="av-sm av-init"><?= strtoupper($USER['username'][0]) ?></span>
93 <?php endif; ?>
94 </button>
95 <div class="user-drop" id="userDrop">
96 <div class="user-drop-top">
97 <strong>@<?= e($USER['username']) ?></strong>
98 <span class="role-tag role-<?= e($USER['role']) ?>"><?= e($USER['role']) ?></span>
99 </div>
100 <a href="<?= u('users/profile.php?u='.urlencode($USER['username'])) ?>">👤 My Profile</a>
101 <a href="<?= u('messages/') ?>">📬 Messages <?php if ($_msgs>0):?><span class="badge-dot" style="position:static;margin-left:4px"><?=$_msgs?></span><?php endif;?></a>
102 <a href="<?= u('users/edit.php') ?>">✏️ Edit Profile</a>
103 <?php if (is_admin()): ?>
104 <a href="<?= u('admin/') ?>" class="admin-lnk">🛡️ Admin Panel</a>
105 <?php endif; ?>
106 <div class="drop-div"></div>
107 <a href="<?= u('auth/logout.php') ?>" class="logout-lnk">🚪 Log Out</a>
108 </div>
109 </div>
110
111 <?php else: ?>
112 <a href="<?= u('auth/login.php') ?>" class="btn-ghost">Log In</a>
113 <a href="<?= u('auth/register.php') ?>" class="btn-primary">Sign Up</a>
114 <?php endif; ?>
115 </div>
116 </div>
117 </header>
118
119 <div class="sb-overlay" id="sbOverlay"></div>
120 <aside class="sidebar" id="sidebar">
121 <nav>
122 <a href="<?= u('/') ?>" class="nav-link">🏠 Home</a>
123 <?php if ($USER): ?>
124 <a href="<?= u('forum/new-topic.php') ?>" class="nav-link new-link">+ New Topic</a>
125 <a href="<?= u('messages/') ?>" class="nav-link">📬 Messages<?php if($_msgs>0):?> <span style="background:#ef4444;color:#fff;border-radius:10px;padding:1px 6px;font-size:10px;font-weight:700"><?=$_msgs?></span><?php endif;?></a>
126 <?php endif; ?>
127 <div class="nav-sep">Categories</div>
128 <?php foreach ($_cats as $c): ?>
129 <a href="<?= u('forum/category.php?slug='.urlencode($c['slug'])) ?>" class="nav-link">
130 <span class="cat-dot" style="background:<?= e($c['color']) ?>"></span>
131 <?= e($c['icon']) ?> <?= e($c['name']) ?>
132 </a>
133 <?php endforeach; ?>
134 <div class="nav-sep">More</div>
135 <a href="<?= u('forum/search.php') ?>" class="nav-link">🔍 Search</a>
136 </nav>
137 </aside>
138
139 <main class="main"><div class="wrap">