This repository has been archived on 2022-05-20. You can view files and clone it, but cannot push or open issues or pull requests.
Alley-HSBC-Frontend/src/components/calendar/CalendarPage.tsx

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;