From 2ca01d2b3a8d2a1e186afb95c8e9767dc9f1cc69 Mon Sep 17 00:00:00 2001 From: jae Date: Tue, 31 Mar 2026 22:55:45 +0000 Subject: [PATCH] fix: admin login, clean URLs, blog links - Fix admin login: ID mismatch (loginUser->loginUsername, loginPass->loginPassword) - Fix auth URL: /api/auth -> /api/auth/login - Fix init() structure: broken if/else for checkAuth - Remove onclick from login button (JS handles via addEventListener) - Clean URLs: /blog/post/slug instead of post.html?slug=slug - Updated blog.js, post.js, main.js with clean URL links - post.js supports both /blog/post/slug and ?slug=x formats - nginx configured for /blog/post/* rewrite --- admin.html | 2 +- js/admin.js | 23 +++++++++++++++++------ js/blog.js | 2 +- js/main.js | 2 +- js/post.js | 17 ++++++++++++----- 5 files changed, 32 insertions(+), 14 deletions(-) diff --git a/admin.html b/admin.html index 7c3b014..4c0d6a6 100644 --- a/admin.html +++ b/admin.html @@ -26,7 +26,7 @@ - +
diff --git a/js/admin.js b/js/admin.js index 489369a..558049b 100644 --- a/js/admin.js +++ b/js/admin.js @@ -25,11 +25,22 @@ const AdminApp = { /* ───────────────────────── AUTH ───────────────────────── */ init() { - // Login form + // Login form - support both
submit and button click const loginForm = document.getElementById('loginForm'); if (loginForm) { loginForm.addEventListener('submit', (e) => this.login(e)); } + const loginBtn = document.getElementById('loginBtn'); + if (loginBtn && !loginForm) { + loginBtn.addEventListener('click', (e) => this.login(e)); + } + // Also handle Enter key in password field + const loginPass = document.getElementById('loginPassword'); + if (loginPass) { + loginPass.addEventListener('keydown', (e) => { + if (e.key === 'Enter') this.login(e); + }); + } // Check auth state if (this.checkAuth()) { @@ -111,14 +122,14 @@ const AdminApp = { }, async login(e) { - e.preventDefault(); - const user = document.getElementById('loginUser').value.trim(); - const pass = document.getElementById('loginPass').value; + if (e && e.preventDefault) e.preventDefault(); + const user = document.getElementById('loginUsername').value.trim(); + const pass = document.getElementById('loginPassword').value; const errEl = document.getElementById('loginError'); - errEl.textContent = ''; + if (errEl) errEl.textContent = ''; try { - const res = await fetch(this.API + '/auth', { + const res = await fetch(this.API + '/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: user, password: pass }) diff --git a/js/blog.js b/js/blog.js index 0312ee7..aa1c43a 100644 --- a/js/blog.js +++ b/js/blog.js @@ -57,7 +57,7 @@ // ─── Render Post Card ─── function renderPostCard(post) { return ` -
+
diff --git a/js/main.js b/js/main.js index d117536..758ac94 100644 --- a/js/main.js +++ b/js/main.js @@ -800,7 +800,7 @@

${post.excerpt || (post.content || '').substring(0, 120) + '...'}

`).join(''); diff --git a/js/post.js b/js/post.js index 0ec109c..06f71d7 100644 --- a/js/post.js +++ b/js/post.js @@ -227,7 +227,7 @@ if (idx > 0) { const prev = sorted[idx - 1]; - navHtml += ` + navHtml += ` ← NEWER ${prev.title} `; @@ -235,13 +235,13 @@ if (idx < sorted.length - 1) { const next = sorted[idx + 1]; - navHtml += ` + navHtml += ` OLDER → ${next.title} `; } - navHtml += ` + navHtml += ` ⟐ ALL TRANSMISSIONS `; @@ -250,8 +250,15 @@ // ─── Load Post ─── async function loadPost() { - const params = new URLSearchParams(window.location.search); - const slug = params.get('slug'); + // Support both /blog/post/slug and ?slug=x formats + let slug = null; + const pathMatch = window.location.pathname.match(/\/blog\/post\/([^\/]+)/); + if (pathMatch) { + slug = decodeURIComponent(pathMatch[1]); + } else { + const params = new URLSearchParams(window.location.search); + slug = params.get('slug'); + } if (!slug) { document.getElementById('postContent').innerHTML =