feat: implement initial frontend application with comprehensive styling, theming, and core structure.

This commit is contained in:
Bruno Charest 2026-03-23 21:42:45 -04:00
parent 3b7c59c7be
commit ee77daa6d7
3 changed files with 31 additions and 11 deletions

View File

@ -330,6 +330,7 @@
li.addEventListener("click", () => { li.addEventListener("click", () => {
const input = document.getElementById("search-input"); const input = document.getElementById("search-input");
input.value = entry; input.value = entry;
input.dispatchEvent(new Event('input', { bubbles: true }));
this.hide(); this.hide();
_triggerAdvancedSearch(entry); _triggerAdvancedSearch(entry);
}); });
@ -391,6 +392,7 @@
} else { } else {
input.value = (current ? current + " " : "") + "tag:" + item.tag + " "; input.value = (current ? current + " " : "") + "tag:" + item.tag + " ";
} }
input.dispatchEvent(new Event('input', { bubbles: true }));
this.hide(); this.hide();
input.focus(); input.focus();
_triggerAdvancedSearch(input.value); _triggerAdvancedSearch(input.value);
@ -944,17 +946,22 @@
} }
userMenu.innerHTML = userMenu.innerHTML =
'<span class="user-display-name">' + (user.display_name || user.username) + '</span>' + '<span class="user-display-name">' + (user.display_name || user.username) + '</span>' +
(user.role === 'admin'
? '<button class="user-menu-link" id="admin-btn" title="Administration"><i data-lucide="shield" style="width:14px;height:14px"></i></button>'
: '') +
'<button class="btn-logout" id="logout-btn" title="Déconnexion"><i data-lucide="log-out" style="width:14px;height:14px"></i></button>'; '<button class="btn-logout" id="logout-btn" title="Déconnexion"><i data-lucide="log-out" style="width:14px;height:14px"></i></button>';
safeCreateIcons(); safeCreateIcons();
const logoutBtn = document.getElementById('logout-btn'); const logoutBtn = document.getElementById('logout-btn');
if (logoutBtn) logoutBtn.addEventListener('click', () => AuthManager.logout()); if (logoutBtn) logoutBtn.addEventListener('click', () => AuthManager.logout());
const adminBtn = document.getElementById('admin-btn'); const adminRow = document.getElementById('admin-menu-row');
if (adminBtn) adminBtn.addEventListener('click', () => AdminPanel.show()); if (adminRow) {
if (user.role === 'admin') {
adminRow.classList.remove('hidden');
// Important: use an inline function to ensure we don't bind multiple identical listeners on rerenders, or clean up before
adminRow.onclick = () => { closeHeaderMenu(); AdminPanel.show(); };
} else {
adminRow.classList.add('hidden');
}
}
}, },
// ── Initialization ────────────────────────────────────────────── // ── Initialization ──────────────────────────────────────────────
@ -3862,6 +3869,10 @@
panel.remove(); panel.remove();
return; return;
} }
// Auto reconnect if disconnected when user opens the panel
if (IndexUpdateManager.getState() === "disconnected") {
IndexUpdateManager.connect();
}
panel = document.createElement("div"); panel = document.createElement("div");
panel.id = "sync-panel"; panel.id = "sync-panel";
panel.className = "sync-panel"; panel.className = "sync-panel";

View File

@ -212,6 +212,15 @@
<span class="menu-list-subtitle" id="theme-label">Clair</span> <span class="menu-list-subtitle" id="theme-label">Clair</span>
</span> </span>
</button> </button>
<button class="menu-list-row menu-list-button hidden" id="admin-menu-row" type="button" role="menuitem">
<span class="menu-list-icon" aria-hidden="true">
<i data-lucide="shield" style="width:17px;height:17px"></i>
</span>
<span class="menu-list-content">
<span class="menu-list-title">Administration</span>
<span class="menu-list-subtitle">Gérer les utilisateurs</span>
</span>
</button>
<button class="menu-list-row menu-list-button" id="config-open-btn" type="button" role="menuitem"> <button class="menu-list-row menu-list-button" id="config-open-btn" type="button" role="menuitem">
<span class="menu-list-icon" aria-hidden="true"> <span class="menu-list-icon" aria-hidden="true">
<i data-lucide="settings" style="width:17px;height:17px"></i> <i data-lucide="settings" style="width:17px;height:17px"></i>

View File

@ -2974,7 +2974,7 @@ body.resizing-v {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
background: linear-gradient(135deg, #0f0c29 0%, #1a1a3e 50%, #24243e 100%); background: linear-gradient(135deg, #090e17 0%, #101827 50%, #1b2838 100%);
} }
.login-card { .login-card {
width: 380px; width: 380px;
@ -3008,7 +3008,7 @@ body.resizing-v {
.login-logo-text { .login-logo-text {
font-size: 1.8rem; font-size: 1.8rem;
font-weight: 700; font-weight: 700;
background: linear-gradient(135deg, #a78bfa, #818cf8, #60a5fa); background: linear-gradient(135deg, #7dd3fc, #38bdf8, #0ea5e9);
-webkit-background-clip: text; -webkit-background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
background-clip: text; background-clip: text;
@ -3098,7 +3098,7 @@ body.resizing-v {
padding: 13px 24px; padding: 13px 24px;
border: none; border: none;
border-radius: 10px; border-radius: 10px;
background: linear-gradient(135deg, #7c3aed, #6366f1); background: linear-gradient(135deg, #3b82f6, #2563eb);
color: #fff; color: #fff;
font-size: 0.95rem; font-size: 0.95rem;
font-weight: 600; font-weight: 600;
@ -3124,7 +3124,7 @@ body.resizing-v {
/* Light theme login */ /* Light theme login */
[data-theme="light"] .login-screen { [data-theme="light"] .login-screen {
background: linear-gradient(135deg, #e0e7ff, #f0f5ff, #dbeafe); background: linear-gradient(135deg, #dbeafe, #eff6ff, #bfdbfe);
} }
[data-theme="light"] .login-card { [data-theme="light"] .login-card {
background: rgba(255,255,255,0.9); background: rgba(255,255,255,0.9);
@ -3226,8 +3226,8 @@ body.resizing-v {
letter-spacing: 0.03em; letter-spacing: 0.03em;
} }
.admin-role-admin { .admin-role-admin {
background: rgba(129,140,248,0.15); background: rgba(59,130,246,0.15);
color: #818cf8; color: #3b82f6;
} }
.admin-role-user { .admin-role-user {
background: rgba(34,197,94,0.12); background: rgba(34,197,94,0.12);