From cb413e2cf951a7b8243ddabd222c567dc8770506 Mon Sep 17 00:00:00 2001 From: jae Date: Mon, 6 Apr 2026 20:52:58 +0000 Subject: [PATCH] feat: group changelog entries by date into unified cards --- css/changelog.css | 54 ++++++++++++++++++++++++++++++++++++++++--- js/changelog.js | 58 ++++++++++++++++++++++++++++++++++------------- 2 files changed, 93 insertions(+), 19 deletions(-) diff --git a/css/changelog.css b/css/changelog.css index 0c3af93..985958c 100644 --- a/css/changelog.css +++ b/css/changelog.css @@ -161,14 +161,62 @@ margin-left: auto; } -.changelog-entry-title { +/* ─── Grouped Date Header ────────────────────────────── */ +.changelog-date-header { + display: flex; + align-items: center; + justify-content: space-between; + padding-bottom: 0.75rem; + margin-bottom: 0.75rem; + border-bottom: 1px solid var(--border); +} + +.changelog-date-header .changelog-date { font-family: var(--font-display); - font-size: 1.1rem; + font-size: 1rem; + color: var(--status-green); + letter-spacing: 2px; + font-weight: 700; + margin-left: 0; +} + +.changelog-version-range { + font-family: var(--font-mono); + font-size: 0.75rem; + color: var(--text-muted); + letter-spacing: 1px; +} + +/* ─── Sub-entry within date group ────────────────────── */ +.changelog-sub-entry { + padding: 0.6rem 0; + border-bottom: 1px solid rgba(255, 255, 255, 0.04); +} + +.changelog-sub-entry:last-child { + border-bottom: none; + padding-bottom: 0; +} + +.changelog-sub-entry .changelog-entry-header { + margin-bottom: 0.4rem; + gap: 0.6rem; +} + +.changelog-sub-entry .changelog-entry-title { + font-family: var(--font-display); + font-size: 0.95rem; color: var(--text-primary); letter-spacing: 0.5px; - margin-bottom: 0.75rem; + margin-bottom: 0; } +.changelog-sub-entry .changelog-changes { + margin-top: 0.3rem; + padding-left: 0.5rem; +} + + /* ─── Change List ────────────────────────────────────── */ .changelog-changes { list-style: none; diff --git a/js/changelog.js b/js/changelog.js index 83b82b3..936faeb 100644 --- a/js/changelog.js +++ b/js/changelog.js @@ -1,5 +1,6 @@ /* ═══════════════════════════════════════════════════════ CHANGELOG — Mission Update Log Controller + Groups entries by date into unified cards ═══════════════════════════════════════════════════════ */ (function () { 'use strict'; @@ -26,6 +27,17 @@ const totalChanges = entries.reduce((sum, e) => sum + (e.changes ? e.changes.length : 0), 0); const latestVersion = entries.length > 0 ? entries[0].version : '0.0.0'; + // Group entries by date + const grouped = []; + const dateMap = {}; + for (const entry of entries) { + if (!dateMap[entry.date]) { + dateMap[entry.date] = { date: entry.date, entries: [] }; + grouped.push(dateMap[entry.date]); + } + dateMap[entry.date].entries.push(entry); + } + let html = ''; // Header @@ -38,31 +50,45 @@ html += `TOTAL CHANGES: ${totalChanges}`; html += ``; - // Timeline + // Timeline — grouped by date html += `
`; - for (const entry of entries) { - const badge = entry.category || 'update'; + for (const group of grouped) { + // Version range for this date + const versions = group.entries.map(e => e.version); + const versionRange = versions.length > 1 + ? `v${esc(versions[versions.length - 1])} — v${esc(versions[0])}` + : `v${esc(versions[0])}`; + html += `
`; html += `
`; - // Header row - html += `
`; - html += `v${esc(entry.version)}`; - html += `${esc(badge)}`; - html += `${formatDate(entry.date)}`; + // Date header + html += `
`; + html += `${formatDate(group.date)}`; + html += `${versionRange}`; html += `
`; - // Title - html += `
${esc(entry.title)}
`; + // Each sub-entry within this date + for (const entry of group.entries) { + const badge = entry.category || 'update'; - // Changes - if (entry.changes && entry.changes.length > 0) { - html += `
    `; - for (const change of entry.changes) { - html += `
  • ${esc(change)}
  • `; + html += `
    `; + html += `
    `; + html += `v${esc(entry.version)}`; + html += `${esc(badge)}`; + html += `${esc(entry.title)}`; + html += `
    `; + + if (entry.changes && entry.changes.length > 0) { + html += `
      `; + for (const change of entry.changes) { + html += `
    • ${esc(change)}
    • `; + } + html += `
    `; } - html += `
`; + + html += `
`; } html += `
`;