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
This commit is contained in:
parent
252c7b95b3
commit
2ca01d2b3a
5 changed files with 32 additions and 14 deletions
|
|
@ -26,7 +26,7 @@
|
||||||
<label class="login-label">PASSPHRASE</label>
|
<label class="login-label">PASSPHRASE</label>
|
||||||
<input type="password" id="loginPassword" class="login-input" placeholder="Enter password..." autocomplete="current-password">
|
<input type="password" id="loginPassword" class="login-input" placeholder="Enter password..." autocomplete="current-password">
|
||||||
</div>
|
</div>
|
||||||
<button id="loginBtn" class="login-btn" onclick="AdminApp.login()">▶ AUTHENTICATE</button>
|
<button id="loginBtn" class="login-btn">▶ AUTHENTICATE</button>
|
||||||
<div id="loginError" class="login-error"></div>
|
<div id="loginError" class="login-error"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="login-footer">SECURE CHANNEL // AES-256 ENCRYPTED</div>
|
<div class="login-footer">SECURE CHANNEL // AES-256 ENCRYPTED</div>
|
||||||
|
|
|
||||||
23
js/admin.js
23
js/admin.js
|
|
@ -25,11 +25,22 @@ const AdminApp = {
|
||||||
/* ───────────────────────── AUTH ───────────────────────── */
|
/* ───────────────────────── AUTH ───────────────────────── */
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
// Login form
|
// Login form - support both <form> submit and button click
|
||||||
const loginForm = document.getElementById('loginForm');
|
const loginForm = document.getElementById('loginForm');
|
||||||
if (loginForm) {
|
if (loginForm) {
|
||||||
loginForm.addEventListener('submit', (e) => this.login(e));
|
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
|
// Check auth state
|
||||||
if (this.checkAuth()) {
|
if (this.checkAuth()) {
|
||||||
|
|
@ -111,14 +122,14 @@ const AdminApp = {
|
||||||
},
|
},
|
||||||
|
|
||||||
async login(e) {
|
async login(e) {
|
||||||
e.preventDefault();
|
if (e && e.preventDefault) e.preventDefault();
|
||||||
const user = document.getElementById('loginUser').value.trim();
|
const user = document.getElementById('loginUsername').value.trim();
|
||||||
const pass = document.getElementById('loginPass').value;
|
const pass = document.getElementById('loginPassword').value;
|
||||||
const errEl = document.getElementById('loginError');
|
const errEl = document.getElementById('loginError');
|
||||||
errEl.textContent = '';
|
if (errEl) errEl.textContent = '';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await fetch(this.API + '/auth', {
|
const res = await fetch(this.API + '/auth/login', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ username: user, password: pass })
|
body: JSON.stringify({ username: user, password: pass })
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@
|
||||||
// ─── Render Post Card ───
|
// ─── Render Post Card ───
|
||||||
function renderPostCard(post) {
|
function renderPostCard(post) {
|
||||||
return `
|
return `
|
||||||
<article class="post-card" onclick="window.location='post.html?slug=${post.slug}'" data-tags="${(post.tags || []).join(',')}">
|
<article class="post-card" onclick="window.location='/blog/post/${post.slug}'" data-tags="${(post.tags || []).join(',')}">
|
||||||
<div class="post-card-content">
|
<div class="post-card-content">
|
||||||
<div class="post-card-meta">
|
<div class="post-card-meta">
|
||||||
<span class="post-date">${post.date}</span>
|
<span class="post-date">${post.date}</span>
|
||||||
|
|
|
||||||
|
|
@ -800,7 +800,7 @@
|
||||||
<p class="blog-excerpt">${post.excerpt || (post.content || '').substring(0, 120) + '...'}</p>
|
<p class="blog-excerpt">${post.excerpt || (post.content || '').substring(0, 120) + '...'}</p>
|
||||||
<div class="blog-footer">
|
<div class="blog-footer">
|
||||||
<span class="blog-read-time">◷ ${Math.max(1, Math.ceil((post.word_count || 300) / 250))} MIN READ</span>
|
<span class="blog-read-time">◷ ${Math.max(1, Math.ceil((post.word_count || 300) / 250))} MIN READ</span>
|
||||||
<a href="post.html?slug=${post.slug}" class="blog-link">READ →</a>
|
<a href="/blog/post/${post.slug}" class="blog-link">READ →</a>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
`).join('');
|
`).join('');
|
||||||
|
|
|
||||||
15
js/post.js
15
js/post.js
|
|
@ -227,7 +227,7 @@
|
||||||
|
|
||||||
if (idx > 0) {
|
if (idx > 0) {
|
||||||
const prev = sorted[idx - 1];
|
const prev = sorted[idx - 1];
|
||||||
navHtml += `<a href="post.html?slug=${prev.slug}" class="post-nav-link nav-newer">
|
navHtml += `<a href="/blog/post/${prev.slug}" class="post-nav-link nav-newer">
|
||||||
<span class="nav-dir">← NEWER</span>
|
<span class="nav-dir">← NEWER</span>
|
||||||
<span class="nav-post-title">${prev.title}</span>
|
<span class="nav-post-title">${prev.title}</span>
|
||||||
</a>`;
|
</a>`;
|
||||||
|
|
@ -235,13 +235,13 @@
|
||||||
|
|
||||||
if (idx < sorted.length - 1) {
|
if (idx < sorted.length - 1) {
|
||||||
const next = sorted[idx + 1];
|
const next = sorted[idx + 1];
|
||||||
navHtml += `<a href="post.html?slug=${next.slug}" class="post-nav-link nav-older">
|
navHtml += `<a href="/blog/post/${next.slug}" class="post-nav-link nav-older">
|
||||||
<span class="nav-dir">OLDER →</span>
|
<span class="nav-dir">OLDER →</span>
|
||||||
<span class="nav-post-title">${next.title}</span>
|
<span class="nav-post-title">${next.title}</span>
|
||||||
</a>`;
|
</a>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
navHtml += `<a href="blog.html" class="post-nav-link nav-all">
|
navHtml += `<a href="/blog" class="post-nav-link nav-all">
|
||||||
<span class="nav-dir">⟐ ALL TRANSMISSIONS</span>
|
<span class="nav-dir">⟐ ALL TRANSMISSIONS</span>
|
||||||
</a>`;
|
</a>`;
|
||||||
|
|
||||||
|
|
@ -250,8 +250,15 @@
|
||||||
|
|
||||||
// ─── Load Post ───
|
// ─── Load Post ───
|
||||||
async function loadPost() {
|
async function loadPost() {
|
||||||
|
// 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);
|
const params = new URLSearchParams(window.location.search);
|
||||||
const slug = params.get('slug');
|
slug = params.get('slug');
|
||||||
|
}
|
||||||
|
|
||||||
if (!slug) {
|
if (!slug) {
|
||||||
document.getElementById('postContent').innerHTML =
|
document.getElementById('postContent').innerHTML =
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue