feat: add sort toggle to dailies and stories pages

dailies: reverse Twig output to ascending (matching trip default),
add feed-sort-bar above feed, add sort JS using [data-type] + appendChild.

stories: wrap heading in flex header row with sort button inline,
add sort JS targeting .story-card children of .stories-grid.

CSS: feed-sort-bar (right-aligned button above feed),
stories-listing__header (flex row, baseline-aligned), heading margin moved to header.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vgmzx8VTTTmCskSpQtsLTr
This commit is contained in:
2026-06-21 22:27:11 +02:00
parent b6142cee44
commit f94880e758
3 changed files with 57 additions and 3 deletions
+13 -1
View File
@@ -911,6 +911,12 @@ body::after {
/* ── Trip page filter bar ────────────────────────────────────────────────────── */ /* ── Trip page filter bar ────────────────────────────────────────────────────── */
.feed-sort-bar {
display: flex;
justify-content: flex-end;
margin-bottom: var(--space-4);
}
.trip-filter-bar { .trip-filter-bar {
display: flex; display: flex;
align-items: center; align-items: center;
@@ -1738,12 +1744,18 @@ body::after {
/* ── Stories listing ──────────────────────────────────────── */ /* ── Stories listing ──────────────────────────────────────── */
.stories-listing { padding: var(--space-10) 0; } .stories-listing { padding: var(--space-10) 0; }
.stories-listing__header {
display: flex;
align-items: baseline;
justify-content: space-between;
margin-bottom: var(--space-10);
}
.stories-listing__heading { .stories-listing__heading {
font-family: var(--font-display); font-family: var(--font-display);
font-size: var(--text-2xl); font-size: var(--text-2xl);
font-weight: 400; font-weight: 400;
color: var(--color-ink); color: var(--color-ink);
margin-bottom: var(--space-10); margin-bottom: 0;
} }
.stories-grid { .stories-grid {
display: grid; display: grid;
+22 -1
View File
@@ -14,7 +14,8 @@
{% set all_items = all_items|merge([{'type': 'story', 'page': s, 'date': s.date}]) %} {% set all_items = all_items|merge([{'type': 'story', 'page': s, 'date': s.date}]) %}
{% endfor %} {% endfor %}
{# No sort needed: page.collection() returns journal entries date-descending per dailies.md config. Dailies has no stories, so no re-merge sort is needed. #} {# page.collection() returns date-descending; reverse to match ascending default on trip page. #}
{% set all_items = all_items|reverse %}
{# Collect GPS entries for mini-map #} {# Collect GPS entries for mini-map #}
{% set map_entries = [] %} {% set map_entries = [] %}
@@ -87,6 +88,9 @@ feedMap.on('load', function () {
</script> </script>
{% endif %} {% endif %}
<div class="feed-sort-bar">
<button class="trip-stats-btn" id="feed-sort-toggle" aria-label="Sort: oldest first">↑ Oldest first</button>
</div>
<div class="feed"> <div class="feed">
{% if all_items|length > 0 %} {% if all_items|length > 0 %}
{% for item in all_items %} {% for item in all_items %}
@@ -165,4 +169,21 @@ document.querySelectorAll('.journal-photo-wrap').forEach(function (wrap) {
} }
}); });
</script> </script>
<script>
(function() {
var sortBtn = document.getElementById('feed-sort-toggle');
if (!sortBtn) return;
var feed = document.querySelector('.feed');
var ascending = true;
sortBtn.addEventListener('click', function() {
ascending = !ascending;
var entries = Array.from(feed.querySelectorAll('[data-type]'));
entries.reverse().forEach(function(el) { feed.appendChild(el); });
sortBtn.textContent = ascending ? '↑ Oldest first' : '↓ Newest first';
sortBtn.setAttribute('aria-label', ascending ? 'Sort: oldest first' : 'Sort: newest first');
sortBtn.classList.toggle('is-active', !ascending);
});
})();
</script>
{% endblock %} {% endblock %}
@@ -4,7 +4,10 @@
{% set stories = page.children.published().order('date', 'asc') %} {% set stories = page.children.published().order('date', 'asc') %}
<div class="stories-listing"> <div class="stories-listing">
<div class="stories-listing__header">
<h1 class="stories-listing__heading">Stories</h1> <h1 class="stories-listing__heading">Stories</h1>
<button class="trip-stats-btn" id="feed-sort-toggle" aria-label="Sort: oldest first">↑ Oldest first</button>
</div>
{% if stories|length > 0 %} {% if stories|length > 0 %}
<div class="stories-grid"> <div class="stories-grid">
@@ -42,4 +45,22 @@
<p class="stories-empty">No stories yet — check back soon.</p> <p class="stories-empty">No stories yet — check back soon.</p>
{% endif %} {% endif %}
</div> </div>
<script>
(function() {
var sortBtn = document.getElementById('feed-sort-toggle');
if (!sortBtn) return;
var grid = document.querySelector('.stories-grid');
if (!grid) return;
var ascending = true;
sortBtn.addEventListener('click', function() {
ascending = !ascending;
var cards = Array.from(grid.querySelectorAll('.story-card'));
cards.reverse().forEach(function(el) { grid.appendChild(el); });
sortBtn.textContent = ascending ? '↑ Oldest first' : '↓ Newest first';
sortBtn.setAttribute('aria-label', ascending ? 'Sort: oldest first' : 'Sort: newest first');
sortBtn.classList.toggle('is-active', !ascending);
});
})();
</script>
{% endblock %} {% endblock %}