linter fix

This commit is contained in:
Taehee Choi 2022-03-30 04:02:48 -07:00
parent 749732a6cf
commit 29a47707d7
23 changed files with 326 additions and 171 deletions

View File

@ -3,21 +3,18 @@ import useAuth from "./hooks/useAuth";
import Navbar from "./components/navbar/Navbar";
import Sidebar from "./components/sidebar/Sidebar";
import { Box } from "@mui/material";
import { store } from "./redux/store";
import { fetchFavorites } from "./redux/slices/favoritesSlice";
import { fetchMeetings } from "./redux/slices/meetingsAndUserStatusSlice";
import { fetchUsers } from "./redux/slices/usersSlice";
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));
}
// 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());
// }
return auth?.isLoggedIn ? (
<>
<Navbar />

View File

@ -2,7 +2,7 @@ interface DetailedMeeting {
meetingId: string; // primary key
liveParticipantIds: string[];
registrantIds: string[];
start: string;
startTime: string;
duration: number;
timezone: string;
joinUrl: string;

View File

@ -48,7 +48,7 @@ const meetings = [
meetingId: "",
liveParticipantIds: [],
registrantIds: ["", "1", "2", "3", "4", "5", "6"],
start: "2022-03-13T17:00:00",
startTime: "2022-03-13T17:00:00",
duration: 15,
timezone: "",
joinUrl: "",
@ -58,7 +58,7 @@ const meetings = [
meetingId: "1",
liveParticipantIds: [],
registrantIds: ["", "2", "4"],
start: "2022-03-16T17:30:00",
startTime: "2022-03-16T17:30:00",
duration: 30,
timezone: "",
joinUrl: "",
@ -68,7 +68,7 @@ const meetings = [
meetingId: "2",
liveParticipantIds: ["3", "5"],
registrantIds: ["3", "5", "6"],
start: "2022-03-13T17:30:00",
startTime: "2022-03-13T17:30:00",
duration: 30,
timezone: "",
joinUrl: "",
@ -78,7 +78,7 @@ const meetings = [
meetingId: "3",
liveParticipantIds: [],
registrantIds: ["", "1"],
start: "2022-03-10T07:27:27",
startTime: "2022-03-10T07:27:27",
duration: 727,
timezone: "",
joinUrl: "",
@ -88,7 +88,7 @@ const meetings = [
meetingId: "4",
liveParticipantIds: [],
registrantIds: ["", "2", "3"],
start: "2022-03-10T12:30:00",
startTime: "2022-03-10T12:30:00",
duration: 120,
timezone: "",
joinUrl: "",
@ -98,7 +98,7 @@ const meetings = [
meetingId: "5",
liveParticipantIds: [""],
registrantIds: [""],
start: "2022-03-24T23:11:11",
startTime: "2022-03-24T23:11:11",
duration: 11,
timezone: "",
joinUrl: "",
@ -108,7 +108,7 @@ const meetings = [
meetingId: "6",
liveParticipantIds: ["", "1"],
registrantIds: ["", "1", "2", "3", "4", "5"],
start: "2022-03-25T09:00:00",
startTime: "2022-03-25T09:00:00",
duration: 360,
timezone: "",
joinUrl: "",
@ -118,7 +118,7 @@ const meetings = [
meetingId: "7",
liveParticipantIds: [],
registrantIds: ["", "5"],
start: "2022-03-25T15:00:00",
startTime: "2022-03-25T15:00:00",
duration: 150,
timezone: "",
joinUrl: "",
@ -128,7 +128,7 @@ const meetings = [
meetingId: "8",
liveParticipantIds: ["2"],
registrantIds: ["", "5", "2", "3"],
start: "2022-03-25T17:45:00",
startTime: "2022-03-25T17:45:00",
duration: 60,
timezone: "",
joinUrl: "",
@ -138,7 +138,7 @@ const meetings = [
meetingId: "9",
liveParticipantIds: ["2", "5"],
registrantIds: ["", "4"],
start: "2022-03-25T18:15:30",
startTime: "2022-03-25T18:15:30",
duration: 75,
timezone: "",
joinUrl: "",
@ -148,7 +148,7 @@ const meetings = [
meetingId: "10",
liveParticipantIds: [],
registrantIds: ["", "1", "2", "3", "4", "5", "6"],
start: "2022-04-04T18:30:00",
startTime: "2022-04-04T18:30:00",
duration: 90,
timezone: "",
joinUrl: "",

View File

@ -1,10 +1,8 @@
interface NewMeeting {
uuid: string;
startTime: string;
duration: number;
timezone: string;
topic: string;
registrantsIds: string[];
registrantIds: string[];
}
export default NewMeeting;

View File

@ -2,7 +2,7 @@ import UserLite from "./UserLite";
interface UserFull {
userInfo: UserLite;
manager: UserLite;
manager?: UserLite;
managerDirectReports: UserLite[];
userDirectReports: UserLite[];
}

View File

@ -64,15 +64,15 @@ const CalendarPage: React.FC = () => {
meetingId: m.meetingId,
liveParticipantIds: m.liveParticipantIds,
registrantIds: m.registrantIds,
startIso: m.start,
startIso: m.startTime,
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
start: new Date(Date.parse(m.startTime)), // Turns the ISO String into a date object
end: new Date(Date.parse(m.startTime) + m.duration * 60000), // result of Date.parse() is milliseconds, and m.duration is given in minutes
}));
const [selectedUserUuid, setSelectedUserUuid] = useState(currentUserUuid);
@ -83,7 +83,7 @@ const CalendarPage: React.FC = () => {
meetingId: event.meetingId,
liveParticipantIds: event.liveParticipantIds,
registrantIds: event.registrantIds,
start: event.startIso,
startTime: event.startIso,
duration: event.duration,
timezone: event.timezone,
joinUrl: event.joinUrl,
@ -108,14 +108,16 @@ const CalendarPage: React.FC = () => {
};
return (
<Box sx={{
<Box
sx={{
display: "flex",
flexDirection: "column",
width: "98.5%",
height: "99.5%",
ml: 1,
mt: 1}}>
mt: 1,
}}
>
<Toolbar />
<FormControl fullWidth>
@ -162,7 +164,6 @@ const CalendarPage: React.FC = () => {
return { style: { backgroundColor, borderColor } };
}}
/>
</Box>
);
};

View File

@ -7,6 +7,7 @@ import UserLite from "../../api-bodies/UserLite";
import { useParams } from "react-router-dom";
import { selectUser } from "../../redux/slices/usersSlice";
import { useAppSelector } from "../../redux/hooks";
import EmptyBody from "./contacts-components/EmptyBody";
const Contacts: React.FC = () => {
const { uuid } = useParams();
@ -15,9 +16,14 @@ const Contacts: React.FC = () => {
);
return (
<Box sx={{ display: "flex", height: "100%" }}>
<Box
sx={{
display: "flex",
height: "100%",
}}
>
<Sidebar />
{uriContact ? <Body contactSelected={uriContact} /> : null}
{uriContact ? <Body contactSelected={uriContact} /> : <EmptyBody />}
</Box>
);
};

View File

@ -1,7 +1,7 @@
import DetailedMeeting from "../../api-bodies/DetailedMeeting";
const getUpcomingMeetingTime = (meeting: DetailedMeeting) => {
const startDate = new Date(meeting.start);
const startDate = new Date(meeting.startTime);
const endDate = new Date(startDate.getTime() + meeting.duration * 60000);
const startTime = startDate
.toTimeString()

View File

@ -0,0 +1,29 @@
import { Box, Typography } from "@mui/material";
import React from "react";
import PermContactCalendarIcon from "@mui/icons-material/PermContactCalendar";
const EmptyBody: React.FC = () => {
return (
<Box
sx={{
display: "flex",
flexDirection: "column",
width: "100%",
height: "100%",
justifyContent: "center",
alignItems: "center",
}}
>
<Box>
<PermContactCalendarIcon color="secondary" sx={{ fontSize: 100 }} />
</Box>
<Box>
<Typography>
View contact info by clicking a contact in the left panel
</Typography>
</Box>
</Box>
);
};
export default EmptyBody;

View File

@ -32,6 +32,15 @@ const LowerBody: React.FC<Props> = (props) => {
<Typography variant="h4" textAlign="center">
Upcoming meetings
</Typography>
{meetings.length === 0 ? (
<Typography
variant="h5"
textAlign="center"
sx={{ position: "relative", top: "30%" }}
>
No upcoming meetings today
</Typography>
) : (
<List sx={{ maxHeight: "100%", overflow: "auto" }}>
{meetings.map((meeting, i) => (
<Box
@ -58,6 +67,7 @@ const LowerBody: React.FC<Props> = (props) => {
</Box>
))}
</List>
)}
</Box>
);
};

View File

@ -1,8 +1,6 @@
import { Box, Button, IconButton, Typography } from "@mui/material";
import React from "react";
import PhoneIcon from "@mui/icons-material/Phone";
import VideocamIcon from "@mui/icons-material/Videocam";
import GroupsIcon from "@mui/icons-material/Groups";
import AddIcon from "@mui/icons-material/Add";
import UserLite from "../../../../api-bodies/UserLite";
import UserStatus from "../../../../api-bodies/UserStatus";
@ -18,26 +16,50 @@ import {
} from "../../../../redux/slices/favoritesSlice";
import RemoveIcon from "@mui/icons-material/Remove";
import { MeetingStatus } from "../../../../utils";
import { selectMe } from "../../../../redux/slices/usersSlice";
import { selectManager, selectMe } from "../../../../redux/slices/usersSlice";
import axios from "../../../../api/axios";
import NewMeeting from "../../../../api-bodies/NewMeeting";
interface Props {
contactInfo: UserLite;
}
const UpperBody: React.FC<Props> = (props) => {
const UpperBody: React.FC<Props> = ({ contactInfo }) => {
const dispatch = useAppDispatch();
const userStatus: UserStatus = useAppSelector((state) =>
selectUserStatus(state, props.contactInfo.uuid)
selectUserStatus(state, contactInfo.uuid)
);
const me = useAppSelector(selectMe);
const favoritesUuids = useAppSelector(selectFavorites);
const detailedMeeting = useAppSelector((state) =>
selectMeeting(state, userStatus.meetingId)
selectMeeting(state, userStatus.inMeeting ? userStatus.meetingId : null)
);
const managerId = useAppSelector(selectManager);
const meetingStatus: MeetingStatus =
userStatus && userStatus.inMeeting
managerId === contactInfo.uuid
? MeetingStatus.NOT_AVAILABLE
: userStatus && userStatus.inMeeting
? MeetingStatus.IN_MEETING
: MeetingStatus.NOT_IN_MEETING;
const startCall = async () => {
const newMeeting: NewMeeting = {
startTime: "2022-03-30T23:40:00Z",
duration: 30,
topic: `Meeting with ${contactInfo.name}`,
registrantIds: [contactInfo.uuid],
};
try {
const response = await axios.post(
`/users/${me}/meetings`,
JSON.stringify(newMeeting)
);
window.open(response.data.joinUrl, "_blank")?.focus();
} catch (e) {
console.log(e);
}
};
return (
<Box
sx={{
@ -59,16 +81,14 @@ const UpperBody: React.FC<Props> = (props) => {
mx: 4,
}}
>
<Typography variant="h3">{props.contactInfo.name}</Typography>
{!favoritesUuids.includes(props.contactInfo.uuid) ? (
<Typography variant="h3">{contactInfo.name}</Typography>
{!favoritesUuids.includes(contactInfo.uuid) ? (
<Button
variant="outlined"
color="success"
startIcon={<AddIcon />}
onClick={() =>
dispatch(
addFavorite({ userId: me, toBeAdded: props.contactInfo.uuid })
)
dispatch(addFavorite({ userId: me, toBeAdded: contactInfo.uuid }))
}
>
favorites
@ -82,7 +102,7 @@ const UpperBody: React.FC<Props> = (props) => {
dispatch(
removeFavorite({
userId: me,
toBeRemoved: props.contactInfo.uuid,
toBeRemoved: contactInfo.uuid,
})
)
}
@ -106,15 +126,10 @@ const UpperBody: React.FC<Props> = (props) => {
sx={{ border: 1, mr: 1, backgroundColor: "secondary" }}
size="large"
color="secondary"
onClick={startCall}
>
<PhoneIcon fontSize="large" />
</IconButton>
<IconButton sx={{ border: 1, mr: 1 }} size="large" color="secondary">
<VideocamIcon fontSize="large" />
</IconButton>
<IconButton sx={{ border: 1, mr: 1 }} size="large" color="secondary">
<GroupsIcon fontSize="large" />
</IconButton>
</Box>
<Box sx={{ display: "flex", flexDirection: "column" }}>
<Typography sx={{ textAlign: "right" }}>{meetingStatus}</Typography>

View File

@ -8,31 +8,35 @@ import { useAppSelector } from "../../../../redux/hooks";
import { selectUserStatus } from "../../../../redux/slices/meetingsAndUserStatusSlice";
import UserStatus from "../../../../api-bodies/UserStatus";
import { useNavigate } from "react-router-dom";
import { selectManager } from "../../../../redux/slices/usersSlice";
interface Props {
contactInfo: UserLite;
}
const ContactItem: React.FC<Props> = (props) => {
const ContactItem: React.FC<Props> = ({ contactInfo }) => {
const navigate = useNavigate();
const userStatus: UserStatus | null = useAppSelector((state) =>
selectUserStatus(state, props.contactInfo.uuid)
selectUserStatus(state, contactInfo.uuid)
);
const managerId = useAppSelector(selectManager);
const status: MeetingStatus =
userStatus && userStatus.inMeeting
managerId === contactInfo.uuid
? MeetingStatus.NOT_AVAILABLE
: userStatus && userStatus.inMeeting
? MeetingStatus.IN_MEETING
: MeetingStatus.NOT_IN_MEETING;
return (
<ListItemButton
onClick={() => {
navigate(`/contacts/${props.contactInfo.uuid}`);
navigate(`/contacts/${contactInfo.uuid}`);
}}
>
<ListItemIcon>
<PersonOutlineIcon />
</ListItemIcon>
<ListItemText
primary={props.contactInfo.name}
primary={contactInfo.name}
secondary={status}
sx={{ flexGrow: 1 }}
/>

View File

@ -19,9 +19,7 @@ const MeetingsPanel: React.FC = () => {
});
});
const participants = useAppSelector((state) =>
selectUsers(state,uuids)
);
const participants = useAppSelector((state) => selectUsers(state, uuids));
// const participants: (UserLite | undefined)[] = [];
// uuids.forEach((uuid) => {
@ -46,15 +44,18 @@ const MeetingsPanel: React.FC = () => {
</Typography>
</div>
<List style={{maxHeight: '100%', overflow: 'auto'}} >
<List style={{ maxHeight: "100%", overflow: "auto" }}>
{meetings.map((meeting) => {
const meetingMembers: UserLite[] = [];
participants.forEach((userLite) => {
if (userLite != undefined && meeting.liveParticipantIds.includes(userLite.uuid)) {
if (
userLite != undefined &&
meeting.liveParticipantIds.includes(userLite.uuid)
) {
meetingMembers.push(userLite);
}
});
const startDate = new Date(meeting.start);
const startDate = new Date(meeting.startTime);
const startDatemil = startDate.getTime();
const endDatemil = startDatemil + meeting.duration * 60000;
const endDate = new Date(endDatemil);
@ -62,15 +63,21 @@ const MeetingsPanel: React.FC = () => {
const currentDatemil = currentDate.getTime();
if (currentDatemil >= startDatemil && currentDatemil <= endDatemil) {
let lastMeetingClass = meetings.length == i ? " lastMeeting" : "";
const lastMeetingClass = meetings.length == i ? " lastMeeting" : "";
i += 1;
return (
<Meeting
meeting={meeting}
meetingClass={"meeting-" + (i - 1) + lastMeetingClass}
meetingName={meeting.topic}
meetingTime={formatTimeFromDate(startDate) + " - " + formatTimeFromDate(endDate)}
meetingMembers={meetingMembers.map((userLite) => (" " + userLite.name + " ")).toString()}
meetingTime={
formatTimeFromDate(startDate) +
" - " +
formatTimeFromDate(endDate)
}
meetingMembers={meetingMembers
.map((userLite) => " " + userLite.name + " ")
.toString()}
/>
);
}

View File

@ -1,7 +1,5 @@
import PeopleIcon from "@mui/icons-material/People";
import AddIcon from "@mui/icons-material/Add";
import PhoneEnabledIcon from "@mui/icons-material/PhoneEnabled";
import CircleIcon from "@mui/icons-material/Circle";
import Button from "@mui/material/Button";
import Grid from "@mui/material/Grid";
import Typography from "@mui/material/Typography";

View File

@ -9,6 +9,13 @@ import zoomLogo from "../../assets/zoom.png";
import LoginIcon from "@mui/icons-material/Login";
import useAuth from "../../hooks/useAuth";
import axios from "../../api/axios";
import { store } from "../../redux/store";
import { fetchFavorites } from "../../redux/slices/favoritesSlice";
import {
fetchMeetings,
socketActions,
} from "../../redux/slices/meetingsAndUserStatusSlice";
import { fetchUsers } from "../../redux/slices/usersSlice";
interface LocationState {
from: { pathname: string };
@ -43,6 +50,10 @@ const Login: React.FC = () => {
if (email === "" && password === "") {
setAuth["uuid"] = "";
setAuth["isLoggedIn"] = true;
store.dispatch(fetchMeetings(""));
store.dispatch(fetchUsers(""));
store.dispatch(fetchFavorites(""));
store.dispatch(socketActions.startConnecting());
navigate(from, { replace: true });
}
@ -62,6 +73,10 @@ const Login: React.FC = () => {
if (logedInUserId != undefined) {
setAuth["uuid"] = logedInUserId;
setAuth["isLoggedIn"] = true;
store.dispatch(fetchMeetings(logedInUserId));
store.dispatch(fetchUsers(logedInUserId));
store.dispatch(fetchFavorites(logedInUserId));
store.dispatch(socketActions.startConnecting());
navigate(from, { replace: true });
}
} catch (error) {

View File

@ -1,16 +1,7 @@
import DetailedMeeting from "../../api-bodies/DetailedMeeting";
const getMeetingStatus = (meeting: DetailedMeeting) => {
const startDate = new Date(meeting.start);
const endDate = new Date(startDate.getTime() + meeting.duration * 60000);
const currentDate = new Date();
if (currentDate > startDate && currentDate < endDate) return "Live";
else if (currentDate < startDate) return "Scheduled";
else return "Finished";
};
const getUpcomingMeetingTime = (meeting: DetailedMeeting) => {
const startDate = new Date(meeting.start);
const startDate = new Date(meeting.startTime);
const endDate = new Date(startDate.getTime() + meeting.duration * 60000);
const startTime = startDate
.toTimeString()
@ -27,4 +18,22 @@ const getUpcomingMeetingTime = (meeting: DetailedMeeting) => {
return `${startTime} - ${endTime}`;
};
export { getMeetingStatus, getUpcomingMeetingTime };
const getMeetingDuration = (meeting: DetailedMeeting) => {
const startDate = new Date(meeting.startTime);
const endDate = new Date(startDate.getTime() + meeting.duration * 60000);
const startDateString = startDate.toDateString();
const startTimeString = startDate
.toTimeString()
.split(" ")[0]
.split(":")
.splice(0, 2)
.join(":");
const endTimeString = endDate
.toTimeString()
.split(" ")[0]
.split(":")
.slice(0, 2)
.join(":");
return `${startDateString} ${startTimeString} - ${endTimeString}`;
};
export { getUpcomingMeetingTime, getMeetingDuration };

View File

@ -11,18 +11,40 @@ import PersonOutlineIcon from "@mui/icons-material/PersonOutline";
import DetailedMeeting from "../../../api-bodies/DetailedMeeting";
import { useAppSelector } from "../../../redux/hooks";
import { selectUsers } from "../../../redux/slices/usersSlice";
import { getMeetingStatus } from "../Utils";
import UserLite from "../../../api-bodies/UserLite";
import { getMeetingDuration } from "../Utils";
enum MeetingStatus {
Live = "Live",
Scheduled = "Scheduled",
Finished = "Finished",
}
interface Props {
meeting: DetailedMeeting;
}
const Body: React.FC<Props> = (props) => {
const getMeetingStatus = (meeting: DetailedMeeting) => {
const startDate = new Date(meeting.startTime);
const endDate = new Date(startDate.getTime() + meeting.duration * 60000);
const currentDate = new Date();
if (meeting.liveParticipantIds.length === 0) {
if (startDate.getTime() - currentDate.getTime() > 0)
return MeetingStatus.Scheduled;
else if (endDate.getTime() - currentDate.getTime() > 0)
return MeetingStatus.Live;
else return MeetingStatus.Finished;
} else {
return MeetingStatus.Live;
}
};
const Body: React.FC<Props> = ({ meeting }) => {
const registrants: UserLite[] = useAppSelector((state) =>
selectUsers(state, props.meeting.registrantIds)
selectUsers(state, meeting.registrantIds)
);
const meetingStatus = getMeetingStatus(meeting);
return (
<Box
sx={{
@ -41,8 +63,8 @@ const Body: React.FC<Props> = (props) => {
height: "100%",
}}
>
<Typography>Feb 10, 2022 10:45 am - 11:00 am</Typography>
<Typography>Status: {getMeetingStatus(props.meeting)}</Typography>
<Typography>{getMeetingDuration(meeting)}</Typography>
<Typography>Status: {meetingStatus}</Typography>
<Typography>
Topic: Lorem Ipsum is simply dummy text of the printing and
typesetting industry. Lorem Ipsum has been the industrys standard

View File

@ -6,24 +6,27 @@ import { close } from "../../../redux/slices/meetingDetailsOpenSlice";
import DetailedMeeting from "../../../api-bodies/DetailedMeeting";
interface Props {
meeting: DetailedMeeting | null;
meeting: DetailedMeeting;
}
const Header: React.FC<Props> = (props) => {
const Header: React.FC<Props> = ({ meeting }) => {
const dispatch = useAppDispatch();
return (
<AppBar sx={{ position: "relative" }}>
<Toolbar>
<Typography variant="h6" sx={{ flexGrow: 1 }}>
{props.meeting !== null ? props.meeting.topic : null}
{meeting !== null ? meeting.topic : null}
</Typography>
<Button variant="contained" color="secondary">
<Button
variant="contained"
color="secondary"
onClick={() => {
window.open(meeting.joinUrl, "_blank")?.focus();
}}
>
Join
</Button>
<Button variant="contained" color="secondary" sx={{ ml: 1 }}>
Recording
</Button>
<IconButton
edge="start"
color="inherit"

View File

@ -13,6 +13,8 @@ import { open as openMeetingDetails } from "../../redux/slices/meetingDetailsOpe
import { selectMeeting } from "../../redux/slices/meetingsAndUserStatusSlice";
import { useNavigate } from "react-router-dom";
import { selectMe } from "../../redux/slices/usersSlice";
import NewMeeting from "../../api-bodies/NewMeeting";
import axios from "../../api/axios";
interface Props {
user: UserLite;
@ -36,6 +38,24 @@ const SettingsButton: React.FC<Props> = ({ user, status }: Props) => {
setAnchorEl(null);
};
const startCall = async () => {
const newMeeting: NewMeeting = {
startTime: "2022-03-30T23:40:00Z",
duration: 30,
topic: `Meeting with ${user.name}`,
registrantIds: [user.uuid],
};
try {
const response = await axios.post(
`/users/${me}/meetings`,
JSON.stringify(newMeeting)
);
window.open(response.data.joinUrl, "_blank")?.focus();
} catch (e) {
console.log(e);
}
};
return (
<div>
<IconButton
@ -91,7 +111,14 @@ const SettingsButton: React.FC<Props> = ({ user, status }: Props) => {
>
View upcoming meetings
</MenuItem>
<MenuItem onClick={handleClose}>Create meeting</MenuItem>
<MenuItem
onClick={() => {
handleClose();
startCall();
}}
>
Create meeting
</MenuItem>
</Menu>
</div>
);

View File

@ -1,10 +1,8 @@
import { Middleware } from "redux";
import { io, Socket } from "socket.io-client";
import DetailedMeeting from "../../api-bodies/DetailedMeeting";
import { socketActions } from "../slices/meetingsAndUserStatusSlice";
const socketMiddleware: Middleware = (store) => {
let socket: Socket;
let socket: WebSocket;
return (next) => (action) => {
const isConnectionEstablished =
@ -14,28 +12,23 @@ const socketMiddleware: Middleware = (store) => {
socketActions.startConnecting.match(action) &&
!isConnectionEstablished
) {
console.log("startConnecting called");
socket = io("wss://uo5wdcbn6l.execute-api.us-west-2.amazonaws.com/Prod/");
socket.on("Connect", () => {
console.log("connected!!!");
store.dispatch(socketActions.connectionEstablished());
});
socket.on("MeetingCreated", (meeting: DetailedMeeting) => {
store.dispatch(socketActions.meetingCreated(meeting));
});
socket.on(
"UserStatusChange",
(statusChange: {
userId: string;
inMeeting: boolean;
meetingId: string;
}) => {
store.dispatch(socketActions.userStatusChanged(statusChange));
}
console.log("start connecting");
socket = new WebSocket(
"wss://uo5wdcbn6l.execute-api.us-west-2.amazonaws.com/Prod/"
);
socket.onopen = () => {
console.log("connected");
store.dispatch(socketActions.connectionEstablished());
};
socket.addEventListener("message", (event: MessageEvent) => {
const json = JSON.parse(event.data);
console.log(json);
if ("inMeeting" in json) {
store.dispatch(socketActions.userStatusChanged(json));
} else {
store.dispatch(socketActions.meetingCreated(json));
}
});
}
next(action);
};

View File

@ -31,10 +31,10 @@ export const meetingsAndUserStatusSlice = createSlice({
state.isConnected = true;
},
meetingCreated: (state, action) => {
state.meetings.push(action.payload.meeting);
state.meetings.push(action.payload);
},
userStatusChanged: (state, action) => {
state.userStatuses[action.payload.uuid] = action.payload;
state.userStatuses[action.payload.userId] = action.payload;
},
},
extraReducers(builder) {
@ -90,8 +90,24 @@ export const selectMeeting = (state: RootState, meetingID: string | null) => {
: null;
};
export const selectUserUpcomingMeetings = (state: RootState, uuid: string) => {
return state.meetingsAndUserStatuses.meetings.filter((meeting) =>
meeting.registrantIds.includes(uuid)
const isToday = (date: Date) => {
const today = new Date();
return (
date.getDate() == today.getDate() &&
date.getMonth() == today.getMonth() &&
date.getFullYear() == today.getFullYear()
);
};
return state.meetingsAndUserStatuses.meetings
.filter(
(meeting) =>
meeting.registrantIds.includes(uuid) &&
meeting.startTime &&
isToday(new Date(meeting.startTime))
)
.sort(
(a, b) =>
new Date(a.startTime).getTime() - new Date(b.startTime).getTime()
);
};
export const selectUserStatus = (

View File

@ -47,14 +47,14 @@ export const fetchUsers = createAsyncThunk(
};
// fetch userfull
const userResp = await axios.get(`/users/${uuid}`);
const user: UserFull = userResp.data.user;
const user: UserFull = userResp.data["user"];
console.log("1");
users[user.userInfo.uuid] = user.userInfo;
users[user.manager.uuid] = user.manager;
console.log("2");
if (user.manager) users[user.manager.uuid] = user.manager;
team.user = user.userInfo.uuid;
team.manager = user.manager.uuid;
if (user.manager) team.manager = user.manager.uuid;
user.userDirectReports.forEach((userLite) => {
users[userLite.uuid] = userLite;
team.directReports.push(userLite.uuid);
@ -76,6 +76,7 @@ export const fetchUsers = createAsyncThunk(
);
export const selectMe = (state: RootState) => state.users.team.user;
export const selectManager = (state: RootState) => state.users.team.manager;
export const selectUser = (
state: RootState,
uuid: string | undefined

View File

@ -1,6 +1,7 @@
const enum MeetingStatus {
NOT_IN_MEETING = "Not in meeting",
IN_MEETING = "In meeting",
NOT_AVAILABLE = "Not available",
}
const getStatusColor = (ms: MeetingStatus): string => {
@ -11,6 +12,9 @@ const getStatusColor = (ms: MeetingStatus): string => {
case MeetingStatus.IN_MEETING: {
return "#ff7070";
}
case MeetingStatus.NOT_AVAILABLE: {
return "#808080";
}
}
};