/** * 밍글 스튜디오 DevLog 목록 페이지 * devlog/index.json에서 글 목록을 불러와 렌더링 */ (function() { 'use strict'; var grid = document.getElementById('blogGrid'); var filtersWrap = document.getElementById('blogFilters'); var loadingEl = document.getElementById('blogLoading'); if (!grid) return; var allPosts = []; var currentFilter = 'all'; function init() { fetch('/devlog/index.json?t=' + Date.now()) .then(function(res) { return res.json(); }) .then(function(posts) { allPosts = posts; if (loadingEl) loadingEl.style.display = 'none'; buildFilters(); renderPosts(); }) .catch(function() { if (loadingEl) loadingEl.style.display = 'none'; grid.innerHTML = '

아직 작성된 글이 없습니다.

'; }); } function buildFilters() { if (!filtersWrap || allPosts.length === 0) return; var categories = {}; allPosts.forEach(function(p) { if (p.category) categories[p.category] = true; }); var cats = Object.keys(categories).sort(); if (cats.length < 2) { filtersWrap.style.display = 'none'; return; } var html = ''; cats.forEach(function(c) { html += ''; }); filtersWrap.innerHTML = html; filtersWrap.addEventListener('click', function(e) { var btn = e.target.closest('.blog-filter-btn'); if (!btn) return; filtersWrap.querySelectorAll('.blog-filter-btn').forEach(function(b) { b.classList.remove('active'); }); btn.classList.add('active'); currentFilter = btn.getAttribute('data-cat'); renderPosts(); }); } function renderPosts() { var filtered = currentFilter === 'all' ? allPosts : allPosts.filter(function(p) { return p.category === currentFilter; }); if (filtered.length === 0) { grid.innerHTML = '

아직 작성된 글이 없습니다.

'; return; } var html = ''; filtered.forEach(function(post) { var title = post.title || post.slug; var desc = post.description || ''; var thumb = post.thumbnail ? '/blog/posts/' + post.slug + '/' + post.thumbnail : ''; var url = '/devlog/' + post.slug; var date = formatDate(post.date); html += '
'; html += ''; if (thumb) { html += '' + escapeHtml(title) + ''; } else { html += '
'; } html += '
'; html += '
'; if (post.category) html += '' + escapeHtml(post.category) + ''; html += '

' + escapeHtml(title) + '

'; html += '

' + escapeHtml(desc) + '

'; html += '
'; }); grid.innerHTML = html; } function formatDate(dateStr) { if (!dateStr) return ''; var d = new Date(dateStr + 'T00:00:00'); if (isNaN(d)) return dateStr; return d.getFullYear() + '.' + (d.getMonth() + 1) + '.' + d.getDate(); } function escapeHtml(str) { var div = document.createElement('div'); div.textContent = str; return div.innerHTML; } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();