car-crushers-portal/app/routes/events-calendar.tsx

72 lines
1.9 KiB
TypeScript

import calendarStyles from "react-big-calendar/lib/css/react-big-calendar.css";
import { Calendar, dayjsLocalizer } from "react-big-calendar";
import dayjs from "dayjs";
import { type LinksFunction } from "@remix-run/cloudflare";
import { Container } from "@chakra-ui/react";
import { useLoaderData } from "@remix-run/react";
export const links: LinksFunction = () => {
return [{ href: calendarStyles, rel: "stylesheet" }];
};
export async function loader({ context }: { context: RequestContext }) {
if (!context.data.current_user)
throw new Response(null, {
status: 401,
});
if (
[1 << 3, 1 << 4, 1 << 12].find(
(p) => context.data.current_user.permissions & p,
)
)
throw new Response(null, {
status: 403,
});
const now = new Date();
const eventsData = await context.env.D1.prepare(
"SELECT answer, approved, created_by, day, details, id, month, pending, performed_at, reached_minimum_player_count, type, year FROM events WHERE month = ? AND year = ? ORDER BY day;",
)
.bind(now.getUTCMonth() + 1, now.getUTCFullYear())
.all();
if (eventsData.error)
throw new Response(null, {
status: 500,
});
const calendarData = eventsData.results.map((e) => {
return {
id: e.id,
title: (e.type as string).toUpperCase(),
allDay: true,
start: new Date(
e.year as number,
(e.month as number) - 1,
e.day as number,
),
end: new Date(e.year as number, (e.month as number) - 1, e.day as number),
};
});
return {
calendarData,
eventList: eventsData.results,
};
}
export default function () {
const data = useLoaderData<typeof loader>();
return (
<Container maxW="container.lg" h="600px">
<Calendar
events={data?.eventList}
localizer={dayjsLocalizer(dayjs)}
style={{ height: 500 }}
/>
</Container>
);
}