diff --git a/src/api-bodies/MockData.tsx b/src/api-bodies/MockData.tsx
index e85a51e..8bed897 100644
--- a/src/api-bodies/MockData.tsx
+++ b/src/api-bodies/MockData.tsx
@@ -74,6 +74,86 @@ const meetings = [
joinUrl: "",
topic: "Back-end Meeting",
},
+ {
+ meetingId: "3",
+ liveParticipantIds: [],
+ registrantIds: ["0", "1"],
+ start: "2022-03-10T07:27:27",
+ duration: 727,
+ timezone: "",
+ joinUrl: "",
+ topic: "WHEN YOU",
+ },
+ {
+ meetingId: "4",
+ liveParticipantIds: [],
+ registrantIds: ["0", "2", "3"],
+ start: "2022-03-10T12:30:00",
+ duration: 120,
+ timezone: "",
+ joinUrl: "",
+ topic: "Bathroom Break",
+ },
+ {
+ meetingId: "5",
+ liveParticipantIds: ["0"],
+ registrantIds: ["0"],
+ start: "2022-03-24T23:11:11",
+ duration: 11,
+ timezone: "",
+ joinUrl: "",
+ topic: "Drink Coffee",
+ },
+ {
+ meetingId: "6",
+ liveParticipantIds: ["0", "1"],
+ registrantIds: ["0", "1", "2", "3", "4", "5"],
+ start: "2022-03-25T09:00:00",
+ duration: 360,
+ timezone: "",
+ joinUrl: "",
+ topic: "Get grilled by Jerry",
+ },
+ {
+ meetingId: "7",
+ liveParticipantIds: [],
+ registrantIds: ["0", "5"],
+ start: "2022-03-25T15:00:00",
+ duration: 150,
+ timezone: "",
+ joinUrl: "",
+ topic: "Get grilled by Arthur",
+ },
+ {
+ meetingId: "8",
+ liveParticipantIds: ["2"],
+ registrantIds: ["0", "5", "2", "3"],
+ start: "2022-03-25T17:45:00",
+ duration: 60,
+ timezone: "",
+ joinUrl: "",
+ topic: "Jerry comes back for round 2",
+ },
+ {
+ meetingId: "9",
+ liveParticipantIds: ["2", "5"],
+ registrantIds: ["0", "4"],
+ start: "2022-03-25T18:15:30",
+ duration: 75,
+ timezone: "",
+ joinUrl: "",
+ topic: "Tag team!",
+ },
+ {
+ meetingId: "10",
+ liveParticipantIds: [],
+ registrantIds: ["0", "1", "2", "3", "4", "5", "6"],
+ start: "2022-04-04T18:30:00",
+ duration: 90,
+ timezone: "",
+ joinUrl: "",
+ topic: "MVP Deadline",
+ }
];
const team = {
diff --git a/src/components/calendar/CalendarPage.tsx b/src/components/calendar/CalendarPage.tsx
index 340e0fe..4e78494 100644
--- a/src/components/calendar/CalendarPage.tsx
+++ b/src/components/calendar/CalendarPage.tsx
@@ -1,12 +1,154 @@
-import { Toolbar } from "@mui/material";
-import UserCalendar from "./UserCalendar";
+import { Calendar, momentLocalizer, Views } from "react-big-calendar";
+import moment from "moment";
+
+import "react-big-calendar/lib/css/react-big-calendar.css";
+import {
+ 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 (
<>
-
+
+
+
+ User
+
+
+
+
+
+
+
>
);
};
diff --git a/src/components/calendar/Events.tsx b/src/components/calendar/Events.tsx
deleted file mode 100644
index 6b62d47..0000000
--- a/src/components/calendar/Events.tsx
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
-Test data from
-https://github.com/jquense/react-big-calendar/blob/master/examples/events.js
-*/
-
-const now = new Date();
-
-export default [
- {
- id: 0,
- title: "All Day Event very long title",
- allDay: true,
- start: new Date(2022, 2, 0),
- end: new Date(2022, 2, 1),
- },
- {
- id: 1,
- title: "Long Event",
- start: new Date(2022, 2, 7),
- end: new Date(2022, 2, 10),
- },
-
- {
- id: 2,
- title: "DTS STARTS",
- start: new Date(2022, 1, 13, 0, 0, 0),
- end: new Date(2022, 1, 20, 0, 0, 0),
- },
-
- {
- id: 3,
- title: "DTS ENDS",
- start: new Date(2022, 9, 6, 0, 0, 0),
- end: new Date(2022, 9, 13, 0, 0, 0),
- },
-
- {
- id: 4,
- title: "Some Event",
- start: new Date(2022, 2, 9, 0, 0, 0),
- end: new Date(2022, 2, 10, 0, 0, 0),
- },
- {
- id: 5,
- title: "Conference",
- start: new Date(2022, 2, 11),
- end: new Date(2022, 2, 13),
- desc: "Big conference for important people",
- },
- {
- id: 6,
- title: "Meeting",
- start: new Date(2022, 2, 12, 10, 30, 0, 0),
- end: new Date(2022, 2, 12, 12, 30, 0, 0),
- desc: "Pre-meeting meeting, to prepare for the meeting",
- },
- {
- id: 7,
- title: "Lunch",
- start: new Date(2022, 2, 12, 12, 0, 0, 0),
- end: new Date(2022, 2, 12, 13, 0, 0, 0),
- desc: "Power lunch",
- },
- {
- id: 8,
- title: "Meeting",
- start: new Date(2022, 2, 12, 14, 0, 0, 0),
- end: new Date(2022, 2, 12, 15, 0, 0, 0),
- },
- {
- id: 9,
- title: "Happy Hour",
- start: new Date(2022, 2, 12, 17, 0, 0, 0),
- end: new Date(2022, 2, 12, 17, 30, 0, 0),
- desc: "Most important meal of the day",
- },
- {
- id: 10,
- title: "Dinner",
- start: new Date(2022, 2, 12, 20, 0, 0, 0),
- end: new Date(2022, 2, 12, 21, 0, 0, 0),
- },
- {
- id: 11,
- title: "Planning Meeting with Paige",
- start: new Date(2022, 2, 13, 8, 0, 0),
- end: new Date(2022, 2, 13, 10, 30, 0),
- },
- {
- id: 11.1,
- title: "Inconvenient multi-day Conference Call",
- start: new Date(2022, 2, 13, 9, 30, 0),
- end: new Date(2022, 2, 14, 1, 0, 0),
- },
- {
- id: 11.2,
- title: "Project Kickoff - Lou's Shoes",
- start: new Date(2022, 2, 13, 11, 30, 0),
- end: new Date(2022, 2, 13, 14, 0, 0),
- },
- {
- id: 11.3,
- title: "Quote Follow-up - Tea by Tina",
- start: new Date(2022, 2, 13, 15, 30, 0),
- end: new Date(2022, 2, 13, 16, 0, 0),
- },
- {
- id: 12,
- title: "Late Night Event",
- start: new Date(2022, 2, 17, 19, 30, 0),
- end: new Date(2022, 2, 18, 2, 0, 0),
- },
- {
- id: 12.5,
- title: "Late Same Night Event",
- start: new Date(2022, 2, 17, 19, 30, 0),
- end: new Date(2022, 2, 17, 23, 30, 0),
- },
- {
- id: 13,
- title: "Multi-day Event",
- start: new Date(2022, 2, 20, 19, 30, 0),
- end: new Date(2022, 2, 22, 2, 0, 0),
- },
- {
- id: 14,
- title: "Today",
- start: new Date(new Date().setHours(new Date().getHours() - 3)),
- end: new Date(new Date().setHours(new Date().getHours() + 3)),
- },
- {
- id: 15,
- title: "Point in Time Event",
- start: now,
- end: now,
- },
- {
- id: 16,
- title: "Video Record",
- start: new Date(2022, 2, 14, 15, 30, 0),
- end: new Date(2022, 2, 14, 19, 0, 0),
- },
- {
- id: 17,
- title: "Dutch Song Producing",
- start: new Date(2022, 2, 14, 16, 30, 0),
- end: new Date(2022, 2, 14, 20, 0, 0),
- },
- {
- id: 18,
- title: "Itaewon Halloween Meeting",
- start: new Date(2022, 2, 14, 16, 30, 0),
- end: new Date(2022, 2, 14, 17, 30, 0),
- },
- {
- id: 19,
- title: "Online Coding Test",
- start: new Date(2022, 2, 14, 17, 30, 0),
- end: new Date(2022, 2, 14, 20, 30, 0),
- },
- {
- id: 20,
- title: "An overlapped Event",
- start: new Date(2022, 2, 14, 17, 0, 0),
- end: new Date(2022, 2, 14, 18, 30, 0),
- },
- {
- id: 21,
- title: "Phone Interview",
- start: new Date(2022, 2, 14, 17, 0, 0),
- end: new Date(2022, 2, 14, 18, 30, 0),
- },
- {
- id: 22,
- title: "Cooking Class",
- start: new Date(2022, 2, 14, 17, 30, 0),
- end: new Date(2022, 2, 14, 19, 0, 0),
- },
- {
- id: 23,
- title: "Go to the gym",
- start: new Date(2022, 2, 14, 18, 30, 0),
- end: new Date(2022, 2, 14, 20, 0, 0),
- },
-];
\ No newline at end of file
diff --git a/src/components/calendar/UserCalendar.tsx b/src/components/calendar/UserCalendar.tsx
deleted file mode 100644
index d6a7797..0000000
--- a/src/components/calendar/UserCalendar.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-import { Calendar, momentLocalizer } from "react-big-calendar";
-import moment from "moment";
-import testEvents from "./Events";
-
-import "react-big-calendar/lib/css/react-big-calendar.css";
-
-const localizer = momentLocalizer(moment);
-
-const UserCalendar: React.FC = () => {
-
- return (
-
- );
-};
-
-export default UserCalendar;
\ No newline at end of file
diff --git a/src/redux/slices/usersSlice.tsx b/src/redux/slices/usersSlice.tsx
index a1b68ac..c8ffd1d 100644
--- a/src/redux/slices/usersSlice.tsx
+++ b/src/redux/slices/usersSlice.tsx
@@ -4,8 +4,8 @@ import { userLites, team } from "../../api-bodies/MockData";
import UserLite from "../../api-bodies/UserLite";
interface TeamState {
- user: string | null;
- manager: string | null;
+ user: string;
+ manager: string;
sameManager: string[];
directReports: string[];
}
@@ -17,7 +17,7 @@ interface UsersState {
const initialState: UsersState = {
users: {},
- team: { user: null, manager: null, sameManager: [], directReports: [] },
+ team: { user: "", manager: "", sameManager: [], directReports: [] },
};
export const usersSlice = createSlice({
@@ -61,9 +61,11 @@ export const selectUsers = (state: RootState, uuids: string[]): UserLite[] => {
};
export const selectTeam = (state: RootState) => {
const team: string[] = [];
- if (state.users.team.manager !== null) team.push(state.users.team.manager);
+ if (state.users.team.manager) team.push(state.users.team.manager);
state.users.team.sameManager.forEach((u) => team.push(u));
state.users.team.directReports.forEach((u) => team.push(u));
return team;
};
+export const selectMe = (state: RootState) => state.users.team.user;
+
export default usersSlice.reducer;
diff --git a/src/utils.tsx b/src/utils.tsx
index 6dbb3d5..3e2ad36 100644
--- a/src/utils.tsx
+++ b/src/utils.tsx
@@ -17,7 +17,8 @@ const getStatusColor = (ms: MeetingStatus): string => {
const formatTimeFromDate = (date: Date): string => {
let hour = date.getHours();
let ampm = "";
- let minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : "" + date.getMinutes();
+ const minutes =
+ date.getMinutes() < 10 ? "0" + date.getMinutes() : "" + date.getMinutes();
if (hour < 12) {
ampm = "am";
} else {