paginate stats page

This commit is contained in:
Davide Scaini
2026-03-30 21:51:01 +02:00
parent 5bbc3d07d2
commit 9bc9a1d10f
+28 -4
View File
@@ -3,21 +3,30 @@
import type { ActivitySummary, BASIndex, Sport } from '../lib/types';
import { formatDistance, formatDuration, sportIcon, sportColor, sportLabel } from '../lib/format';
const PAGE_YEARS = 4;
let all: ActivitySummary[] = [];
let sport: Sport | 'all' = 'all';
let page = 0;
let loading = true;
let theme = 'dark';
let mounted = false;
$: totalPages = Math.ceil(allYears.length / PAGE_YEARS);
$: years = allYears.slice(page * PAGE_YEARS, (page + 1) * PAGE_YEARS);
$: if (mounted) {
const params = new URLSearchParams(window.location.search);
if (sport === 'all') params.delete('sport'); else params.set('sport', sport);
if (page === 0) params.delete('page'); else params.set('page', String(page));
const qs = params.toString();
history.replaceState(null, '', qs ? `?${qs}` : window.location.pathname);
}
onMount(async () => {
sport = (new URLSearchParams(window.location.search).get('sport') as Sport | 'all') ?? 'all';
const params = new URLSearchParams(window.location.search);
sport = (params.get('sport') as Sport | 'all') ?? 'all';
page = parseInt(params.get('page') ?? '0', 10) || 0;
mounted = true;
const res = await fetch(`${import.meta.env.BASE_URL}data/index.json`);
const index: BASIndex = await res.json();
@@ -209,8 +218,6 @@
: ([] as Sport[]);
// ── Calendar helpers ──────────────────────────────────────────────────────
const now = new Date();
const years = [now.getFullYear(), now.getFullYear()-1, now.getFullYear()-2, now.getFullYear()-3];
function localISO(d: Date): string {
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
@@ -277,9 +284,26 @@
<div class="h-64 rounded-xl bg-zinc-800 animate-pulse mb-6"></div>
{:else}
<!-- Pagination controls -->
{#if totalPages > 1}
<div class="flex items-center justify-between mb-6">
<button
class="px-3 py-1.5 rounded-lg border border-zinc-700 text-sm text-zinc-400 hover:border-zinc-500 hover:text-white transition-colors disabled:opacity-30 disabled:cursor-not-allowed"
disabled={page === 0}
on:click={() => page -= 1}
>← Newer</button>
<span class="text-sm text-zinc-500">{years[years.length - 1]} {years[0]}</span>
<button
class="px-3 py-1.5 rounded-lg border border-zinc-700 text-sm text-zinc-400 hover:border-zinc-500 hover:text-white transition-colors disabled:opacity-30 disabled:cursor-not-allowed"
disabled={page >= totalPages - 1}
on:click={() => page += 1}
>Older →</button>
</div>
{/if}
<!-- Year totals -->
<div class="grid grid-cols-2 sm:grid-cols-4 gap-4 mb-8">
{#each allYears.slice(0, 4) as year}
{#each years as year}
{@const t = totalsByYear.get(year)}
<div class="bg-zinc-900 rounded-xl border border-zinc-800 p-4">
<p class="text-xs text-zinc-500 mb-1">{year}</p>