diff --git a/frontend/app.js b/frontend/app.js index 89ec9ae..8ff8729 100644 --- a/frontend/app.js +++ b/frontend/app.js @@ -94,9 +94,15 @@ document.documentElement.setAttribute("data-theme", theme); localStorage.setItem("obsigate-theme", theme); - const icon = document.getElementById("theme-icon"); - if (icon) { - icon.setAttribute("data-lucide", theme === "dark" ? "moon" : "sun"); + // Update theme button icon and label + const themeBtn = document.getElementById("theme-toggle"); + const themeLabel = document.getElementById("theme-label"); + if (themeBtn && themeLabel) { + const icon = themeBtn.querySelector("i"); + if (icon) { + icon.setAttribute("data-lucide", theme === "dark" ? "moon" : "sun"); + } + themeLabel.textContent = theme === "dark" ? "Sombre" : "Clair"; safeCreateIcons(); } @@ -114,6 +120,32 @@ applyTheme(current === "dark" ? "light" : "dark"); } + function initHeaderMenu() { + const menuBtn = document.getElementById("header-menu-btn"); + const menuDropdown = document.getElementById("header-menu-dropdown"); + + if (!menuBtn || !menuDropdown) return; + + menuBtn.addEventListener("click", (e) => { + e.stopPropagation(); + menuBtn.classList.toggle("active"); + menuDropdown.classList.toggle("active"); + }); + + // Close menu when clicking outside + document.addEventListener("click", (e) => { + if (!menuDropdown.contains(e.target) && e.target !== menuBtn) { + menuBtn.classList.remove("active"); + menuDropdown.classList.remove("active"); + } + }); + + // Prevent menu from closing when clicking inside + menuDropdown.addEventListener("click", (e) => { + e.stopPropagation(); + }); + } + // --------------------------------------------------------------------------- // API helpers // --------------------------------------------------------------------------- @@ -948,6 +980,7 @@ // --------------------------------------------------------------------------- async function init() { initTheme(); + initHeaderMenu(); document.getElementById("theme-toggle").addEventListener("click", toggleTheme); document.getElementById("header-logo").addEventListener("click", goHome); initSearch(); diff --git a/frontend/index.html b/frontend/index.html index 208e8bb..cc678bc 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -12,11 +12,43 @@ @@ -39,13 +71,27 @@ - - - +
+ +
+ + + +
+
diff --git a/frontend/style.css b/frontend/style.css index 71a9c55..1aeb43c 100644 --- a/frontend/style.css +++ b/frontend/style.css @@ -157,19 +157,11 @@ a:hover { pointer-events: none; } -.search-vault-filter { - padding: 6px 10px; - border: 1px solid var(--border); - border-radius: 8px; - background: var(--search-bg); - color: var(--text-primary); - font-family: 'JetBrains Mono', monospace; - font-size: 0.8rem; - outline: none; - cursor: pointer; +.header-menu { + position: relative; } -.theme-toggle { +.header-menu-btn { background: none; border: 1px solid var(--border); border-radius: 8px; @@ -180,10 +172,90 @@ a:hover { align-items: center; transition: color 200ms ease, border-color 200ms ease; } -.theme-toggle:hover { +.header-menu-btn:hover { color: var(--accent); border-color: var(--accent); } +.header-menu-btn.active { + color: var(--accent); + border-color: var(--accent); + background: var(--tag-bg); +} + +.header-menu-dropdown { + display: none; + position: absolute; + top: calc(100% + 8px); + right: 0; + background: var(--bg-secondary); + border: 1px solid var(--border); + border-radius: 8px; + box-shadow: 0 4px 16px rgba(0,0,0,0.3); + min-width: 220px; + z-index: 100; + padding: 8px; +} +.header-menu-dropdown.active { + display: block; +} + +.menu-section { + padding: 8px; +} + +.menu-label { + font-family: 'JetBrains Mono', monospace; + font-size: 0.7rem; + color: var(--text-muted); + text-transform: uppercase; + letter-spacing: 0.5px; + margin-bottom: 6px; + font-weight: 600; +} + +.menu-select { + width: 100%; + padding: 6px 10px; + border: 1px solid var(--border); + border-radius: 6px; + background: var(--search-bg); + color: var(--text-primary); + font-family: 'JetBrains Mono', monospace; + font-size: 0.8rem; + outline: none; + cursor: pointer; + transition: border-color 200ms ease; +} +.menu-select:hover, .menu-select:focus { + border-color: var(--accent); +} + +.menu-divider { + height: 1px; + background: var(--border); + margin: 4px 0; +} + +.menu-theme-btn { + width: 100%; + background: none; + border: 1px solid var(--border); + border-radius: 6px; + padding: 8px 12px; + cursor: pointer; + color: var(--text-primary); + display: flex; + align-items: center; + gap: 8px; + font-family: 'JetBrains Mono', monospace; + font-size: 0.8rem; + transition: all 200ms ease; +} +.menu-theme-btn:hover { + background: var(--bg-hover); + border-color: var(--accent); + color: var(--accent); +} /* --- Main body --- */ .main-body { @@ -938,9 +1010,13 @@ body.resizing-v { font-size: 0.8rem; } - .search-vault-filter { - font-size: 0.7rem; - padding: 4px 6px; + .header-menu-btn { + padding: 5px 8px; + } + + .header-menu-dropdown { + right: -8px; + min-width: 200px; } .sidebar {