import calendarStyles from "react-big-calendar/lib/css/react-big-calendar.css"; import calendarOverrides from "../styles/calendar.css"; import eventStyles from "../styles/events-team.css"; import { Calendar, dayjsLocalizer } from "react-big-calendar"; import dayjs from "dayjs"; import { type LinksFunction } from "@remix-run/cloudflare"; import { Button, Container, Flex, Heading, Modal, ModalBody, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalOverlay, Popover, PopoverArrow, PopoverBody, PopoverCloseButton, PopoverContent, PopoverHeader, PopoverTrigger, Spacer, Text, useDisclosure, VStack, } from "@chakra-ui/react"; import { useLoaderData } from "@remix-run/react"; import { useState } from "react"; import utc from "dayjs/plugin/utc.js"; import { EtMember } from "../../generated/prisma/client.js"; export const links: LinksFunction = () => { return [ { href: calendarStyles, rel: "stylesheet" }, { href: eventStyles, rel: "stylesheet" }, { href: calendarOverrides, 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.data.prisma.event.findMany({ orderBy: { day: "asc", }, select: { answer: true, approved: true, created_by: true, day: true, details: true, id: true, month: true, pending: true, performed_at: true, reached_minimum_player_count: true, type: true, year: true, }, where: { month: now.getUTCMonth() + 1, year: now.getUTCFullYear(), }, }); const calendarData = eventsData.map((e) => { return { id: e.id, title: (e.type as string).toUpperCase(), allDay: true, // A Date object will not survive being passed to the client start: `${e.year}-${(e.month as number).toString().padStart(2, "0")}-${(e.day as number).toString().padStart(2, "0")}T00:00:00.000Z`, end: `${e.year}-${(e.month as number).toString().padStart(2, "0")}-${(e.day as number).toString().padStart(2, "0")}T00:00:00.000Z`, }; }); const memberData = await context.data.prisma.$queryRaw< EtMember[] >`SELECT id, name FROM et_members WHERE id IN (SELECT created_by FROM events WHERE month = ${now.getUTCMonth() + 1} AND year = ${now.getUTCFullYear()});`; return { calendarData, canManage: Boolean( [1 << 4, 1 << 12].find((p) => context.data.current_user.permissions & p), ), eventList: eventsData, memberData, }; } export default function () { const data = useLoaderData(); const [eventData, setEventData] = useState({} as { [k: string]: any }); const { isOpen, onClose, onOpen } = useDisclosure(); dayjs.extend(utc); return ( Event Info Host {data.memberData.find((m) => m.id === eventData.created_by)?.name}
Event Type {eventData?.type?.toUpperCase()}
Details {eventData?.details}
{eventData?.type === "rotw" ? ( <> Answer {eventData.answer} ) : null}
new Date(event.end)} events={data.calendarData} localizer={dayjsLocalizer(dayjs)} onSelectEvent={(e) => { setEventData( data.eventList.find((ev) => ev.id === e.id) as { [k: string]: any }, ); onOpen(); }} popup startAccessor={(event) => new Date(event.start)} style={{ height: 500 }} toolbar={false} views={["month"]} /> {data.canManage ? ( Management Tools ) : null}
); }