171 lines
5.0 KiB
TypeScript
171 lines
5.0 KiB
TypeScript
import { Calendar, momentLocalizer, Views } from "react-big-calendar";
|
|
import moment from "moment";
|
|
|
|
import "react-big-calendar/lib/css/react-big-calendar.css";
|
|
import {
|
|
Box,
|
|
Divider,
|
|
FormControl,
|
|
InputLabel,
|
|
MenuItem,
|
|
Select,
|
|
SelectChangeEvent,
|
|
Toolbar,
|
|
Typography,
|
|
} from "@mui/material";
|
|
import { selectMeetings } from "../../redux/slices/meetingsAndUserStatusSlice";
|
|
import { useAppDispatch, useAppSelector } from "../../redux/hooks";
|
|
import {
|
|
selectMe,
|
|
selectTeam,
|
|
selectUser,
|
|
selectUsers,
|
|
} from "../../redux/slices/usersSlice";
|
|
import { open } from "../../redux/slices/meetingDetailsOpenSlice";
|
|
import DetailedMeeting from "../../api-bodies/DetailedMeeting";
|
|
import { useState } from "react";
|
|
import UserLite from "../../api-bodies/UserLite";
|
|
|
|
// TODO: match the styles and themes
|
|
|
|
// 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;
|
|
}
|
|
|
|
enum CalendarTaskView {
|
|
ViewAll = "VIEWALL",
|
|
}
|
|
|
|
const CalendarPage: React.FC = () => {
|
|
const dispatch = useAppDispatch();
|
|
|
|
const currentUserUuid: string = useAppSelector(selectMe);
|
|
const currentUser: UserLite | undefined = useAppSelector((state) =>
|
|
selectUser(state, currentUserUuid)
|
|
);
|
|
const teamUuids: string[] = useAppSelector(selectTeam);
|
|
const team: UserLite[] = useAppSelector((state) =>
|
|
selectUsers(state, teamUuids)
|
|
);
|
|
const meetings: CalendarEvent[] = useAppSelector((state) =>
|
|
selectMeetings(state)
|
|
).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 [selectedUserUuid, setSelectedUserUuid] = useState(currentUserUuid);
|
|
|
|
// turns calendar event back into DetailedMeeting then opens meeting view
|
|
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));
|
|
};
|
|
|
|
// dropdown selection event
|
|
const handleUserChange = (event: SelectChangeEvent) => {
|
|
setSelectedUserUuid(event.target.value);
|
|
};
|
|
|
|
// filter the meetings based on the uuid
|
|
const getUserMeetings = (uuid: string): CalendarEvent[] => {
|
|
if (uuid == CalendarTaskView.ViewAll) {
|
|
// "View all team member meetings" option
|
|
return meetings;
|
|
} else {
|
|
return meetings.filter((meeting) => meeting.registrantIds.includes(uuid));
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Box sx={{
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
width: "98.5%",
|
|
height: "99.5%",
|
|
ml: 1,
|
|
mt: 1}}>
|
|
|
|
<Toolbar />
|
|
|
|
<FormControl fullWidth>
|
|
<InputLabel id="calendar-user-select-label">
|
|
<Typography color="black">User</Typography>
|
|
</InputLabel>
|
|
<Select
|
|
labelId="calendar-user-select-label"
|
|
id="calendar-user-select"
|
|
value={selectedUserUuid}
|
|
label="User"
|
|
onChange={handleUserChange}
|
|
>
|
|
<MenuItem value={CalendarTaskView.ViewAll}>
|
|
View all team member meetings
|
|
</MenuItem>
|
|
{currentUser ? (
|
|
<MenuItem value={currentUserUuid}>
|
|
{currentUser.name + " (Me)"}
|
|
</MenuItem>
|
|
) : null}
|
|
{team.map((user) => (
|
|
<MenuItem key={user.uuid} value={user.uuid}>
|
|
{user.name}
|
|
</MenuItem>
|
|
))}
|
|
</Select>
|
|
</FormControl>
|
|
|
|
<Divider sx={{ my: 1 }} />
|
|
|
|
<Calendar
|
|
events={getUserMeetings(selectedUserUuid)}
|
|
views={["month", "week", "day"]}
|
|
defaultView={Views.MONTH}
|
|
onSelectEvent={handleSelectEvent}
|
|
step={60}
|
|
showMultiDayTimes
|
|
localizer={momentLocalizer(moment)}
|
|
style={{ height: "83%" }}
|
|
eventPropGetter = {() => {
|
|
const backgroundColor = "IndianRed";
|
|
const borderColor = "White";
|
|
return { style: { backgroundColor, borderColor } };
|
|
}}
|
|
/>
|
|
|
|
</Box>
|
|
);
|
|
};
|
|
|
|
export default CalendarPage;
|