integrate backend meeting structure with calendar, add ability to bring up meeting menu when clicking calendar events
This commit is contained in:
parent
3d0bd5c4d9
commit
dcff2d70ef
@ -1,22 +1,88 @@
|
|||||||
import { Calendar, momentLocalizer } from "react-big-calendar";
|
import { Calendar, momentLocalizer, Views } from "react-big-calendar";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import testEvents from "./Events";
|
|
||||||
|
|
||||||
import "react-big-calendar/lib/css/react-big-calendar.css";
|
import "react-big-calendar/lib/css/react-big-calendar.css";
|
||||||
|
import { Divider } from "@mui/material";
|
||||||
|
import { selectUserUpcomingMeetings } from "../../redux/slices/meetingsAndUserStatusSlice";
|
||||||
|
import { useAppDispatch, useAppSelector } from "../../redux/hooks";
|
||||||
|
import { selectMe } from "../../redux/slices/usersSlice";
|
||||||
|
import { open } from "../../redux/slices/meetingDetailsOpenSlice";
|
||||||
|
import DetailedMeeting from "../../api-bodies/DetailedMeeting";
|
||||||
|
|
||||||
const localizer = momentLocalizer(moment);
|
// clicking meetings opens view
|
||||||
|
|
||||||
|
// per user calendar
|
||||||
|
// full view (all teammates)
|
||||||
|
// match the styles and themes
|
||||||
|
// make an interface for events
|
||||||
|
|
||||||
|
// A superset of DetailedMeeting; contains fields required for the calendar to work
|
||||||
|
interface CalendarEvent {
|
||||||
|
meetingId: string;
|
||||||
|
liveParticipantIds: string[];
|
||||||
|
registrantIds: string[];
|
||||||
|
startIso: string; // names overlap here; this is equivalent to "start" in DetailedMeeting
|
||||||
|
duration: number;
|
||||||
|
timezone: string;
|
||||||
|
joinUrl: string;
|
||||||
|
topic: string;
|
||||||
|
title: string;
|
||||||
|
start: Date;
|
||||||
|
end: Date;
|
||||||
|
}
|
||||||
|
|
||||||
const UserCalendar: React.FC = () => {
|
const UserCalendar: React.FC = () => {
|
||||||
|
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const currentUserUuid = useAppSelector(selectMe); // TODO: per-user
|
||||||
|
const meetings = useAppSelector((state) =>
|
||||||
|
selectUserUpcomingMeetings(state, currentUserUuid)
|
||||||
|
).map(m =>
|
||||||
|
({
|
||||||
|
meetingId: m.meetingId,
|
||||||
|
liveParticipantIds: m.liveParticipantIds,
|
||||||
|
registrantIds: m.registrantIds,
|
||||||
|
startIso: m.start,
|
||||||
|
duration: m.duration,
|
||||||
|
timezone: m.timezone,
|
||||||
|
joinUrl: m.joinUrl,
|
||||||
|
topic: m.topic,
|
||||||
|
// fields needed by calendar
|
||||||
|
title: m.topic,
|
||||||
|
start: new Date(Date.parse(m.start)), // Turns the ISO String into a date object
|
||||||
|
end: new Date(Date.parse(m.start) + m.duration*60000) // result of Date.parse() is milliseconds, and m.duration is given in minutes
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleSelectEvent = (event: CalendarEvent) => {
|
||||||
|
const meeting: DetailedMeeting = {
|
||||||
|
meetingId: event.meetingId,
|
||||||
|
liveParticipantIds: event.liveParticipantIds,
|
||||||
|
registrantIds: event.registrantIds,
|
||||||
|
start: event.startIso,
|
||||||
|
duration: event.duration,
|
||||||
|
timezone: event.timezone,
|
||||||
|
joinUrl: event.joinUrl,
|
||||||
|
topic: event.topic,
|
||||||
|
};
|
||||||
|
dispatch(open(meeting));
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Calendar
|
<>
|
||||||
events={testEvents}
|
<Divider sx={{ my: 1 }} />
|
||||||
views={["month", "week", "day"]}
|
<Calendar
|
||||||
step={60}
|
events={meetings}
|
||||||
showMultiDayTimes
|
views={["month", "week", "day"]}
|
||||||
localizer={localizer}
|
defaultView={Views.WEEK}
|
||||||
style={{ height: "80%" }}
|
onSelectEvent={handleSelectEvent}
|
||||||
/>
|
step={60}
|
||||||
|
showMultiDayTimes
|
||||||
|
localizer={momentLocalizer(moment)}
|
||||||
|
style={{ height: "90%" }}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user