use empty placeholder cells for weekdays that are not part of the shown month
This commit is contained in:
@ -14,7 +14,12 @@ import {
|
|||||||
import { isTodayOrFuture } from "@/lib/date";
|
import { isTodayOrFuture } from "@/lib/date";
|
||||||
import styles from "./eventContainer.module.scss";
|
import styles from "./eventContainer.module.scss";
|
||||||
import { formatDate, formatYearMonth } from "@/lib/date";
|
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 { unique } from "@/lib/common";
|
||||||
import Icon from "../general/Icon";
|
import Icon from "../general/Icon";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
@ -178,6 +183,10 @@ const EventList = ({ events }: { events: EventFragment[] }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const EmptyCalendarCell = () => (
|
||||||
|
<div className={`${styles.calendarDay} ${styles.empty}`} />
|
||||||
|
);
|
||||||
|
|
||||||
const CalendarDay = ({
|
const CalendarDay = ({
|
||||||
day,
|
day,
|
||||||
events,
|
events,
|
||||||
@ -197,6 +206,32 @@ const CalendarDay = ({
|
|||||||
</div>
|
</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 EventCalendar = ({ events }: { events: EventFragment[] }) => {
|
||||||
const futureSingularEvents = getSingularEvents(events).filter(
|
const futureSingularEvents = getSingularEvents(events).filter(
|
||||||
(x) => x.occurrence?.start && isTodayOrFuture(x.occurrence.start)
|
(x) => x.occurrence?.start && isTodayOrFuture(x.occurrence.start)
|
||||||
@ -227,15 +262,7 @@ const EventCalendar = ({ events }: { events: EventFragment[] }) => {
|
|||||||
>
|
>
|
||||||
<h2>{formatYearMonth(yearMonth)}</h2>
|
<h2>{formatYearMonth(yearMonth)}</h2>
|
||||||
{Object.keys(eventsByDate[yearMonth]).map((week) => (
|
{Object.keys(eventsByDate[yearMonth]).map((week) => (
|
||||||
<div key={week} className={styles.calendarWeek}>
|
<CalendarWeek key={week} days={eventsByDate[yearMonth][week]} />
|
||||||
{Object.keys(eventsByDate[yearMonth][week]).map((day) => (
|
|
||||||
<CalendarDay
|
|
||||||
key={day}
|
|
||||||
day={day}
|
|
||||||
events={eventsByDate[yearMonth][week][day]}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
@ -168,20 +168,20 @@ export function organizeEventsInCalendar(
|
|||||||
|
|
||||||
let currentDate = startOfWeek(minDate, { weekStartsOn: 1 });
|
let currentDate = startOfWeek(minDate, { weekStartsOn: 1 });
|
||||||
while (currentDate <= maxDate) {
|
while (currentDate <= maxDate) {
|
||||||
const yearMonth = formatDate(currentDate, "yyyy-MM");
|
|
||||||
const week = formatDate(currentDate, "w");
|
const week = formatDate(currentDate, "w");
|
||||||
const daysOfWeek = eachDayOfInterval({
|
const daysOfWeek = eachDayOfInterval({
|
||||||
start: currentDate,
|
start: currentDate,
|
||||||
end: endOfWeek(currentDate, { weekStartsOn: 1 }),
|
end: endOfWeek(currentDate, { weekStartsOn: 1 }),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
daysOfWeek.forEach((day) => {
|
||||||
|
const yearMonth = formatDate(day, "yyyy-MM");
|
||||||
if (!calendar[yearMonth]) {
|
if (!calendar[yearMonth]) {
|
||||||
calendar[yearMonth] = {};
|
calendar[yearMonth] = {};
|
||||||
}
|
}
|
||||||
if (!calendar[yearMonth][week]) {
|
if (!calendar[yearMonth][week]) {
|
||||||
calendar[yearMonth][week] = {};
|
calendar[yearMonth][week] = {};
|
||||||
}
|
}
|
||||||
daysOfWeek.forEach((day) => {
|
|
||||||
const formattedDay = formatDate(day, "yyyy-MM-dd");
|
const formattedDay = formatDate(day, "yyyy-MM-dd");
|
||||||
if (!calendar[yearMonth][week][formattedDay]) {
|
if (!calendar[yearMonth][week][formattedDay]) {
|
||||||
calendar[yearMonth][week][formattedDay] = [];
|
calendar[yearMonth][week][formattedDay] = [];
|
||||||
|
Reference in New Issue
Block a user