diff --git a/src/ProtectedRoute.tsx b/src/ProtectedRoute.tsx
index 0288f33..3f30da5 100644
--- a/src/ProtectedRoute.tsx
+++ b/src/ProtectedRoute.tsx
@@ -2,21 +2,72 @@ import { useLocation, Outlet, Navigate } from "react-router-dom";
import useAuth from "./hooks/useAuth";
import Navbar from "./components/navbar/Navbar";
import Sidebar from "./components/sidebar/Sidebar";
+import { Alert, AlertTitle, Box, Snackbar, Typography } from "@mui/material";
+import { store } from "./redux/store";
+import { fetchFavorites } from "./redux/slices/favoritesSlice";
+import { fetchMeetings, selectMeetings } from "./redux/slices/meetingsAndUserStatusSlice";
+import { fetchUsers, selectMe } from "./redux/slices/usersSlice";
+import { useAppDispatch, useAppSelector, useInterval } from "./redux/hooks";
+import DetailedMeeting from "./api-bodies/DetailedMeeting";
+import React, { useState } from "react";
import { Box } from "@mui/material";
const ProtectedRoute = () => {
const auth = useAuth();
const location = useLocation();
- /* Temporary data */
- // if (auth?.isLoggedIn != undefined && auth?.isLoggedIn == true) {
- // store.dispatch(fetchMeetings(auth?.uuid));
- // store.dispatch(fetchUsers(auth?.uuid));
- // store.dispatch(fetchFavorites(auth?.uuid));
- // store.dispatch(socketActions.startConnecting());
- // }
+ useAppDispatch();
+ const currentUserUuid: string = useAppSelector(selectMe);
+ const meetings: DetailedMeeting[] = useAppSelector(selectMeetings);
+ const currentUserMeetings = meetings.filter((m) => m.registrantIds.includes(currentUserUuid));
+
+ const [open, setOpen] = useState(false);
+ const [notifMeetings, setNotifMeetings] = useState([""]);
+
+ const sixtySec = 60000;
+ // polls the current time against meeting times
+ useInterval(
+ () => {
+ console.log("polling");
+ const currentTime = Math.floor(Date.now() / sixtySec); // in minutes
+ const upcomingMeetings = currentUserMeetings.filter((meeting) =>
+ (currentTime == Math.floor(Date.parse(meeting.start) / sixtySec) - 15) || // 15 mins before meeting time
+ (currentTime == Math.floor(Date.parse(meeting.start) / sixtySec) - 30) // or 30 mins before meeting time
+ );
+ if (upcomingMeetings.length != 0) {
+ setOpen(true);
+ const newNotifMeetings: string[] = upcomingMeetings.map((m) => {
+ if (currentTime == Math.floor(Date.parse(m.start) / sixtySec) - 15) {
+ return m.topic + " in 15 minutes";
+ } else {
+ return m.topic + " in 30 minutes";
+ }
+ });
+ setNotifMeetings(newNotifMeetings);
+ }
+ },
+ sixtySec // poll time
+ );
+
+ const handleClose = (event?: React.SyntheticEvent | Event, reason?: string) => {
+ if (reason == "clickaway") {
+ return;
+ }
+ setOpen(false);
+ };
+
return auth?.isLoggedIn ? (
<>
+ {/* ----- */}
+
+
+ Upcoming Meetings
+ {notifMeetings.map((m, i) =>
+ {m}
+ )}
+
+
+ {/* ----- */}
diff --git a/src/redux/hooks.tsx b/src/redux/hooks.tsx
index 36b5ea2..797f6a6 100644
--- a/src/redux/hooks.tsx
+++ b/src/redux/hooks.tsx
@@ -1,6 +1,30 @@
+import { useLayoutEffect, useEffect, useRef } from "react";
import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux";
import type { RootState, AppDispatch } from "./store";
// Use throughout your app instead of plain `useDispatch` and `useSelector`
export const useAppDispatch = () => useDispatch();
export const useAppSelector: TypedUseSelectorHook = useSelector;
+
+const useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
+export function useInterval(callback: () => void, delay: number | null) {
+ const savedCallback = useRef(callback);
+
+ // Remember the latest callback if it changes.
+ useIsomorphicLayoutEffect(() => {
+ savedCallback.current = callback;
+ }, [callback]);
+
+ // Set up the interval.
+ useEffect(() => {
+ // Don't schedule if no delay is specified.
+ // Note: 0 is a valid value for delay.
+ if (!delay && delay !== 0) {
+ return;
+ }
+
+ const id = setInterval(() => savedCallback.current(), delay);
+
+ return () => clearInterval(id);
+ }, [delay]);
+}
\ No newline at end of file