/* =================================================== JAESWIFT BLOG — Post loader + Cyberpunk stats =================================================== */ (function () { 'use strict'; const API = window.location.hostname === 'localhost' ? 'http://localhost:5000' : '/api'; // ─── Clock ─── function initClock() { const el = document.getElementById('navClock'); if (!el) return; const tick = () => { const d = new Date(); el.textContent = d.toLocaleTimeString('en-GB', { hour12: false }) + ' UTC' + (d.getTimezoneOffset() <= 0 ? '+' : '') + (-d.getTimezoneOffset() / 60); }; tick(); setInterval(tick, 1000); } // ─── Navbar ─── function initNavbar() { const toggle = document.getElementById('navToggle'); const menu = document.getElementById('navMenu'); if (toggle && menu) { toggle.addEventListener('click', () => menu.classList.toggle('active')); } window.addEventListener('scroll', () => { document.getElementById('navbar')?.classList.toggle('scrolled', window.scrollY > 50); }, { passive: true }); } // ─── Build Stat Pips ─── function buildPips(val, max = 5) { let html = '
'; for (let i = 0; i < max; i++) { const filled = i < val; let cls = 'stat-pip'; if (filled) { cls += ' filled'; if (val <= 2) cls += ' danger'; else if (val <= 3) cls += ' warn'; } html += `
`; } html += '
'; return html; } // ─── Coffee Icons ─── function buildCoffee(val) { return '' + '☕'.repeat(val) + '' + '☕'.repeat(5 - val) + ''; } // ─── Render Post Card ─── function renderPostCard(post) { return `
${post.threat_level} ${post.time_written || ''}

${post.title}

${post.excerpt}

${(post.tags || []).map(t => ``).join('')}
OPERATOR STATUS
MOOD ${buildPips(post.mood)}
ENERGY ${buildPips(post.energy)}
MOTIVE ${buildPips(post.motivation)}
FOCUS ${buildPips(post.focus)}
${post.heart_rate} BPM
${buildCoffee(post.coffee)}
`; } // ─── Load Posts ─── async function loadPosts() { const grid = document.getElementById('blogPosts'); if (!grid) return; try { const res = await fetch(API + '/posts'); if (!res.ok) throw new Error('API error'); const posts = await res.json(); if (posts.length === 0) { grid.innerHTML = '
NO TRANSMISSIONS FOUND
'; return; } // Sort by date descending posts.sort((a, b) => new Date(b.date) - new Date(a.date)); grid.innerHTML = posts.map(renderPostCard).join(''); // Animate cards in const cards = grid.querySelectorAll('.post-card'); cards.forEach((card, i) => { card.style.opacity = '0'; card.style.transform = 'translateY(20px)'; card.style.transition = 'all 0.5s ease'; setTimeout(() => { card.style.opacity = '1'; card.style.transform = 'translateY(0)'; }, 100 + i * 150); }); } catch (err) { // Fallback: load from static JSON try { const res2 = await fetch('api/data/posts.json'); const posts = await res2.json(); posts.sort((a, b) => new Date(b.date) - new Date(a.date)); grid.innerHTML = posts.map(renderPostCard).join(''); const cards = grid.querySelectorAll('.post-card'); cards.forEach((card, i) => { card.style.opacity = '0'; card.style.transform = 'translateY(20px)'; card.style.transition = 'all 0.5s ease'; setTimeout(() => { card.style.opacity = '1'; card.style.transform = 'translateY(0)'; }, 100 + i * 150); }); } catch (e2) { grid.innerHTML = '
TRANSMISSION ERROR — RETRY LATER
'; } } } // ─── Filters ─── function initFilters() { const btns = document.querySelectorAll('.filter-btn'); btns.forEach(btn => { btn.addEventListener('click', () => { btns.forEach(b => b.classList.remove('active')); btn.classList.add('active'); const filter = btn.dataset.filter; const cards = document.querySelectorAll('.post-card'); cards.forEach(card => { const tags = card.dataset.tags || ''; if (filter === 'all' || tags.includes(filter)) { card.style.display = ''; card.style.opacity = '1'; } else { card.style.opacity = '0'; setTimeout(() => { card.style.display = 'none'; }, 300); } }); }); }); } // ─── Init ─── document.addEventListener('DOMContentLoaded', () => { initClock(); initNavbar(); loadPosts(); initFilters(); }); })();