my website at ewancroft.uk
1<script lang="ts">
2 import { BlogPostCard } from '$lib/components/ui';
3 import type { BlogPost } from '$lib/services/atproto';
4 import { getUserLocale } from '$lib/utils/locale';
5 import { groupPostsByDate, getSortedMonths, getSortedYears } from '$lib/helper/posts';
6
7 interface Props {
8 posts: BlogPost[];
9 locale?: string;
10 filterYear?: string | null;
11 }
12
13 let { posts, locale, filterYear }: Props = $props();
14
15 let userLocale = $derived(locale || getUserLocale());
16
17 // Group posts by date
18 const groupedPosts = $derived(groupPostsByDate(posts, userLocale));
19
20 // If a year is selected, only show that year
21 const sortedYears = $derived(
22 filterYear && filterYear !== 'all'
23 ? [parseInt(filterYear)].filter((year) => groupedPosts.has(year))
24 : getSortedYears(groupedPosts)
25 );
26</script>
27
28<div class="space-y-12">
29 {#each sortedYears as year}
30 {@const yearGroup = groupedPosts.get(year)}
31 {#if yearGroup}
32 {@const sortedMonths = getSortedMonths(yearGroup)}
33 <section>
34 <h2 class="mb-6 text-3xl font-bold text-ink-900 dark:text-ink-50">
35 {year}
36 </h2>
37
38 <div class="space-y-8">
39 {#each sortedMonths as [_, monthData]}
40 <div>
41 <h3 class="mb-4 text-xl font-semibold text-ink-800 dark:text-ink-100">
42 {monthData.monthName}
43 </h3>
44
45 <div class="space-y-3">
46 {#each monthData.posts as post}
47 <BlogPostCard {post} locale={userLocale} />
48 {/each}
49 </div>
50 </div>
51 {/each}
52 </div>
53 </section>
54 {/if}
55 {/each}
56</div>