95 lines
3.0 KiB
TypeScript
95 lines
3.0 KiB
TypeScript
"use client";
|
|
|
|
import { useQueryState, parseAsStringLiteral } from "nuqs";
|
|
import { EventItem } from "./EventItem";
|
|
import { EventFilter } from "./EventFilter";
|
|
import {
|
|
EventFragment,
|
|
getSingularEvents,
|
|
organizeEventsByDate,
|
|
} from "@/lib/event";
|
|
import { isTodayOrFuture } from "@/lib/date";
|
|
import styles from "./eventContainer.module.scss";
|
|
import { formatDate, formatYearMonth } from "@/lib/date";
|
|
import { getYear, parse } from "date-fns";
|
|
|
|
type EventContainerMode = "list" | "calendar";
|
|
|
|
export const EventContainer = ({ events }: { events: EventFragment[] }) => {
|
|
const [mode, setMode] = useQueryState(
|
|
"mode",
|
|
parseAsStringLiteral(["list", "calendar"]).withDefault("list")
|
|
);
|
|
return (
|
|
<div className={styles.events}>
|
|
<EventFilter />
|
|
<div className={styles.eventWrapper}>
|
|
<div className={styles.displayOptions}>
|
|
<button onClick={() => setMode(null)}>Vis liste</button>
|
|
<button onClick={() => setMode("calendar")}>Vis kalender</button>
|
|
</div>
|
|
{mode === "list" && <EventList events={events} />}
|
|
{mode === "calendar" && <EventCalendar events={events} />}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
const EventList = ({ events }: { events: EventFragment[] }) => {
|
|
return (
|
|
<ul className={styles.eventList}>
|
|
{events.map((event) => (
|
|
<EventItem key={event.id} event={event} mode="list" />
|
|
))}
|
|
</ul>
|
|
);
|
|
};
|
|
|
|
const EventCalendar = ({ events }: { events: EventFragment[] }) => {
|
|
const futureSingularEvents = getSingularEvents(events).filter(
|
|
(x) => x.occurrence?.start && isTodayOrFuture(x.occurrence.start)
|
|
);
|
|
|
|
const eventsByDate = organizeEventsByDate(futureSingularEvents);
|
|
|
|
return (
|
|
<div className={styles.eventCalendar}>
|
|
{Object.keys(eventsByDate).map((yearMonth) => (
|
|
<div key={yearMonth} className={styles.calendarYearMonth}>
|
|
<h2>{formatYearMonth(yearMonth)}</h2>
|
|
{Object.keys(eventsByDate[yearMonth]).map((week) => (
|
|
<div key={week} className={styles.calendarWeek}>
|
|
{Object.keys(eventsByDate[yearMonth][week]).map((day) => (
|
|
<div
|
|
key={day}
|
|
className={`${styles.calendarDay} ${
|
|
eventsByDate[yearMonth][week][day].length === 0 &&
|
|
styles.empty
|
|
}`}
|
|
>
|
|
<h3>
|
|
{formatDate(
|
|
parse(day, "yyyy-MM-dd", new Date()),
|
|
"eeee dd.MM."
|
|
)}
|
|
</h3>
|
|
<ul>
|
|
{eventsByDate[yearMonth][week][day].map((event) => (
|
|
<EventItem
|
|
key={event.id}
|
|
event={event}
|
|
mode="calendar"
|
|
size="small"
|
|
/>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
))}
|
|
</div>
|
|
))}
|
|
</div>
|
|
))}
|
|
</div>
|
|
);
|
|
};
|