Header improvements

This commit is contained in:
Olaf
2026-08-24 20:17:46 +02:00
parent 12f3580f60
commit f96a4ab3ad
11 changed files with 183 additions and 93 deletions
-8
View File
@@ -4,8 +4,6 @@ const userList = document.querySelector('#user-list');
const userForm = document.querySelector('#user-form');
const adminControls = document.querySelector('#admin-controls');
const adminAuthNotice = document.querySelector('#admin-auth-notice');
const adminLoginButton = document.querySelector('#admin-login-button');
const adminLogoutButton = document.querySelector('#logout-button');
const accessToken = localStorage.getItem('linklogAccessToken');
function authHeaders(includeJson = false) {
@@ -66,22 +64,16 @@ async function loadUsers() {
function showAdminState(isAdmin) {
adminControls.classList.toggle('hidden', !isAdmin);
adminAuthNotice.classList.toggle('hidden', isAdmin);
adminLoginButton.classList.toggle('hidden', isAdmin);
adminLogoutButton.classList.toggle('hidden', !accessToken);
}
function showSignedOutState() {
showAdminState(false);
adminAuthNotice.innerHTML = 'Administrator sign-in required. <a href="/login">Sign in</a>';
adminLoginButton.classList.remove('hidden');
adminLogoutButton.classList.add('hidden');
}
function showUnauthorizedState() {
showAdminState(false);
adminAuthNotice.textContent = 'You are signed in, but you are not authorized to access this page.';
adminLoginButton.classList.add('hidden');
adminLogoutButton.classList.remove('hidden');
}
async function loadAdminState() {
+20 -15
View File
@@ -1,34 +1,39 @@
(() => {
const loginButton = document.querySelector('#auth-login-button');
const profileLink = document.querySelector('#auth-profile-link');
const adminLink = document.querySelector('#auth-admin-link');
const session = document.querySelector('#auth-session');
const avatar = document.querySelector('#auth-avatar');
const username = document.querySelector('#auth-username');
const token = localStorage.getItem('linklogAccessToken');
if (!loginButton || !session || !avatar || !username) return;
const menu = document.querySelector('#auth-menu');
const menuToggle = document.querySelector('.menu-toggle');
const logoutButton = document.querySelector('#logout-button');
if (!loginButton || !profileLink || !adminLink || !session || !username || !menu || !menuToggle || !logoutButton) return;
menuToggle.addEventListener('click', () => {
const isOpen = !menu.classList.contains('hidden');
menu.classList.toggle('hidden', isOpen);
menuToggle.setAttribute('aria-expanded', String(!isOpen));
});
function showSignedOut() {
loginButton.classList.remove('hidden');
profileLink.classList.add('hidden');
adminLink.classList.add('hidden');
session.classList.add('hidden');
logoutButton.classList.add('hidden');
}
function showSignedIn(user) {
loginButton.classList.add('hidden');
profileLink.classList.remove('hidden');
adminLink.classList.toggle('hidden', !user.is_admin);
session.classList.remove('hidden');
logoutButton.classList.remove('hidden');
username.textContent = user.username || '';
const initial = (user.username || 'U').slice(0, 1).toUpperCase();
avatar.textContent = initial;
if (user.avatar_url) {
const image = document.createElement('img');
image.src = user.avatar_url;
image.alt = `${user.username || 'User'} avatar`;
image.addEventListener('error', () => {
image.remove();
avatar.textContent = initial;
});
avatar.textContent = '';
avatar.appendChild(image);
}
username.href = `/${encodeURIComponent(user.username || '')}/`;
}
if (!token) {
+62 -33
View File
@@ -51,7 +51,7 @@ body::selection {
.site-header {
position: relative;
overflow: hidden;
z-index: 20;
padding: 56px 0 48px;
background:
linear-gradient(115deg, rgba(203, 166, 247, 0.18), transparent 45%),
@@ -103,18 +103,67 @@ body::selection {
flex: 0 0 auto;
align-items: center;
gap: 8px;
position: relative;
}
.menu-toggle {
min-width: 0;
padding: 10px 13px;
border-color: var(--surface-2);
background: var(--surface-0);
color: var(--text);
}
.menu-toggle::before {
content: '\2630';
margin-right: 7px;
font-size: 1.1em;
}
.auth-menu {
position: absolute;
z-index: 30;
top: calc(100% + 10px);
right: 0;
display: grid;
min-width: 190px;
gap: 4px;
padding: 8px;
background: var(--surface-0);
border: 1px solid var(--surface-1);
border-radius: 10px;
box-shadow: var(--shadow);
}
.auth-menu a,
.auth-menu button {
display: block;
width: 100%;
min-width: 0;
padding: 9px 10px;
border: 0;
border-radius: 6px;
background: transparent;
color: var(--text);
text-align: left;
text-decoration: none;
}
.auth-menu a:hover,
.auth-menu button:hover {
background: var(--surface-1);
color: var(--lavender);
}
.auth-menu .hidden {
display: none;
}
.auth-session {
display: flex;
align-items: center;
gap: 9px;
}
.auth-session .avatar {
width: 32px;
height: 32px;
flex-basis: 32px;
padding: 7px 10px;
border-bottom: 1px solid var(--border);
}
.auth-session .user-name {
@@ -124,28 +173,8 @@ body::selection {
white-space: nowrap;
}
.login-button {
flex: 0 0 auto;
margin-top: 2px;
padding: 10px 16px;
border: 1px solid var(--surface-2);
border-radius: 8px;
background: var(--surface-0);
color: var(--text);
font-weight: 700;
text-decoration: none;
transition: background 160ms ease, border-color 160ms ease;
}
.login-button:hover {
border-color: var(--lavender);
background: var(--surface-1);
color: var(--text);
}
.logout-button {
min-width: 0;
padding: 10px 13px;
border-color: rgba(243, 139, 168, 0.45);
background: transparent;
color: var(--red);
@@ -158,6 +187,8 @@ body::selection {
}
main.container {
position: relative;
z-index: 1;
padding-top: 28px;
padding-bottom: 64px;
}
@@ -462,21 +493,19 @@ button:disabled {
}
.header-actions {
align-items: stretch;
flex-direction: column;
align-items: flex-end;
}
.auth-session {
flex-direction: column;
align-items: flex-start;
}
.login-button {
.menu-toggle {
padding: 8px 11px;
font-size: 0.9rem;
}
.logout-button {
padding: 8px 11px;
font-size: 0.9rem;
}