joerglohrerde/app/src/routes/archiv/+page.svelte

81 lines
2.0 KiB
Svelte
Raw Normal View History

<script lang="ts">
import { onMount } from 'svelte';
import type { NostrEvent } from '$lib/nostr/loaders';
import { loadPostList } from '$lib/nostr/loaders';
import PostCard from '$lib/components/PostCard.svelte';
import LoadingOrError from '$lib/components/LoadingOrError.svelte';
let posts: NostrEvent[] = $state([]);
let loading = $state(true);
let error: string | null = $state(null);
onMount(async () => {
try {
posts = await loadPostList();
loading = false;
if (posts.length === 0) {
error = 'Keine Posts gefunden auf den abgefragten Relays.';
}
} catch (e) {
loading = false;
error = e instanceof Error ? e.message : 'Unbekannter Fehler';
}
});
// Posts nach Jahr gruppieren (neueste zuerst)
type YearGroup = { year: number; posts: NostrEvent[] };
const groupsByYear = $derived.by<YearGroup[]>(() => {
const byYear = new Map<number, NostrEvent[]>();
for (const p of posts) {
const ts = Number(p.tags.find((t) => t[0] === 'published_at')?.[1] ?? p.created_at);
const year = new Date(ts * 1000).getUTCFullYear();
if (!byYear.has(year)) byYear.set(year, []);
byYear.get(year)!.push(p);
}
return [...byYear.entries()]
.map(([year, p]) => ({ year, posts: p }))
.sort((a, b) => b.year - a.year);
});
</script>
<svelte:head>
<title>Archiv Jörg Lohrer</title>
</svelte:head>
<h1 class="title">Archiv</h1>
<p class="meta">Alle Beiträge, nach Jahr gruppiert.</p>
<LoadingOrError {loading} {error} />
{#each groupsByYear as group (group.year)}
<section class="year-group">
<h2 class="year">{group.year}</h2>
{#each group.posts as post (post.id)}
<PostCard event={post} />
{/each}
</section>
{/each}
<style>
.title {
margin: 0 0 0.3rem;
font-size: 1.8rem;
}
.meta {
color: var(--muted);
margin: 0 0 2rem;
font-size: 0.95rem;
}
.year-group {
margin-bottom: 2.5rem;
}
.year {
font-size: 1.2rem;
font-weight: 600;
margin: 0 0 1rem;
padding-bottom: 0.3rem;
border-bottom: 1px solid var(--border);
color: var(--muted);
}
</style>