use empty placeholder cells for weekdays that are not part of the shown month

This commit is contained in:
2024-08-06 01:24:27 +02:00
parent 5ac05114ce
commit 8f30c9e983
2 changed files with 44 additions and 17 deletions

View File

@ -14,7 +14,12 @@ import {
import { isTodayOrFuture } from "@/lib/date";
import styles from "./eventContainer.module.scss";
import { formatDate, formatYearMonth } from "@/lib/date";
import { parse } from "date-fns";
import {
startOfWeek,
endOfWeek,
differenceInCalendarDays,
parse,
} from "date-fns";
import { unique } from "@/lib/common";
import Icon from "../general/Icon";
import { useState } from "react";
@ -178,6 +183,10 @@ const EventList = ({ events }: { events: EventFragment[] }) => {
);
};
const EmptyCalendarCell = () => (
<div className={`${styles.calendarDay} ${styles.empty}`} />
);
const CalendarDay = ({
day,
events,
@ -197,6 +206,32 @@ const CalendarDay = ({
</div>
);
const CalendarWeek = ({ days }: { days: Record<string, SingularEvent[]> }) => {
const daysInWeek = Object.keys(days);
const firstDay = daysInWeek[0];
const lastDay = daysInWeek[daysInWeek.length - 1];
const weekStart = startOfWeek(firstDay, { weekStartsOn: 1 });
const weekEnd = endOfWeek(lastDay, { weekStartsOn: 1 });
const emptyCellsBefore = differenceInCalendarDays(firstDay, weekStart);
const emptyCellsAfter = differenceInCalendarDays(weekEnd, lastDay);
return (
<div className={styles.calendarWeek}>
{[...Array(emptyCellsBefore)].map((_, idx) => (
<EmptyCalendarCell key={`before-${idx}`} />
))}
{Object.keys(days).map((day) => (
<CalendarDay key={day} day={day} events={days[day]} />
))}
{[...Array(emptyCellsAfter)].map((_, idx) => (
<EmptyCalendarCell key={`after-${idx}`} />
))}
</div>
);
};
const EventCalendar = ({ events }: { events: EventFragment[] }) => {
const futureSingularEvents = getSingularEvents(events).filter(
(x) => x.occurrence?.start && isTodayOrFuture(x.occurrence.start)
@ -227,15 +262,7 @@ const EventCalendar = ({ events }: { events: EventFragment[] }) => {
>
<h2>{formatYearMonth(yearMonth)}</h2>
{Object.keys(eventsByDate[yearMonth]).map((week) => (
<div key={week} className={styles.calendarWeek}>
{Object.keys(eventsByDate[yearMonth][week]).map((day) => (
<CalendarDay
key={day}
day={day}
events={eventsByDate[yearMonth][week][day]}
/>
))}
</div>
<CalendarWeek key={week} days={eventsByDate[yearMonth][week]} />
))}
</div>
))}

View File

@ -168,20 +168,20 @@ export function organizeEventsInCalendar(
let currentDate = startOfWeek(minDate, { weekStartsOn: 1 });
while (currentDate <= maxDate) {
const yearMonth = formatDate(currentDate, "yyyy-MM");
const week = formatDate(currentDate, "w");
const daysOfWeek = eachDayOfInterval({
start: currentDate,
end: endOfWeek(currentDate, { weekStartsOn: 1 }),
});
daysOfWeek.forEach((day) => {
const yearMonth = formatDate(day, "yyyy-MM");
if (!calendar[yearMonth]) {
calendar[yearMonth] = {};
}
if (!calendar[yearMonth][week]) {
calendar[yearMonth][week] = {};
}
daysOfWeek.forEach((day) => {
const formattedDay = formatDate(day, "yyyy-MM-dd");
if (!calendar[yearMonth][week][formattedDay]) {
calendar[yearMonth][week][formattedDay] = [];