96 lines
3.3 KiB
Svelte
96 lines
3.3 KiB
Svelte
<script lang="ts">
|
|
import dayjs from "dayjs";
|
|
import "dayjs/locale/de";
|
|
import type { ExtendedEvent } from "../types/event";
|
|
import { Button } from "../ui/button";
|
|
import { ChevronLeft, ChevronRight } from "lucide-svelte";
|
|
import * as Card from "../ui/card";
|
|
import EventCard from "./EventCard.svelte";
|
|
import SWButton from "@components/styled/SWButton.svelte";
|
|
|
|
const {
|
|
events,
|
|
}: {
|
|
events: { slug: string; data: { event: ExtendedEvent } }[];
|
|
} = $props();
|
|
|
|
let currentYear = $state(dayjs().year());
|
|
|
|
// Group events by month
|
|
let eventsByMonth = $derived.by(() => {
|
|
const grouped = new Map<string, typeof events>();
|
|
|
|
events.forEach((event) => {
|
|
const eventDate = dayjs(event.data.event.event.start).locale("de");
|
|
if (eventDate.year() === currentYear) {
|
|
const monthKey = eventDate.format("YYYY-MM");
|
|
if (!grouped.has(monthKey)) {
|
|
grouped.set(monthKey, []);
|
|
}
|
|
grouped.get(monthKey)!.push(event);
|
|
}
|
|
});
|
|
|
|
return grouped;
|
|
});
|
|
|
|
// Generate all 12 months for the current year
|
|
let months = $derived.by(() => {
|
|
return Array.from({ length: 12 }, (_, i) => {
|
|
const monthDate = dayjs().locale("de").year(currentYear).month(i);
|
|
const monthKey = monthDate.format("YYYY-MM");
|
|
return {
|
|
date: monthDate,
|
|
key: monthKey,
|
|
name: monthDate.format("MMMM"),
|
|
events: eventsByMonth.get(monthKey) || [],
|
|
};
|
|
});
|
|
});
|
|
|
|
function prevYear() {
|
|
currentYear = currentYear - 1;
|
|
}
|
|
|
|
function nextYear() {
|
|
currentYear = currentYear + 1;
|
|
}
|
|
</script>
|
|
|
|
<div>
|
|
<div class="flex justify-between items-center mb-6">
|
|
<h2 class="text-2xl font-bold text-white">
|
|
{currentYear}
|
|
</h2>
|
|
<div class="flex gap-2">
|
|
<SWButton onclick={prevYear} type="gray">
|
|
<ChevronLeft size={20} />
|
|
</SWButton>
|
|
<SWButton onclick={nextYear} type="gray">
|
|
<ChevronRight size={20} />
|
|
</SWButton>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
|
|
{#each months as month}
|
|
<EventCard title={month.name} unsized={true}>
|
|
{#if month.events.length > 0}
|
|
{#each month.events as event}
|
|
<a href={`/events/${event.slug}/`} class="block p-2 bg-slate-800 hover:bg-slate-700 rounded border border-slate-600 transition-colors group">
|
|
<div class="text-sm font-semibold text-white group-hover:text-blue-400 transition-colors">
|
|
{event.data.event.event.name}
|
|
</div>
|
|
<div class="text-xs text-gray-400 mt-1">
|
|
{dayjs(event.data.event.event.start).format("MMM D, YYYY • HH:mm")}
|
|
</div>
|
|
</a>
|
|
{/each}
|
|
{:else}
|
|
<p class="text-gray-500 text-sm italic">Keine Events für diesen Monat</p>
|
|
{/if}
|
|
</EventCard>
|
|
{/each}
|
|
</div>
|
|
</div>
|