status update fixed and warning message added
This commit is contained in:
parent
4f306d2fea
commit
0ec7478728
7
package-lock.json
generated
7
package-lock.json
generated
@ -4815,6 +4815,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"anymatch": "~3.1.2",
|
"anymatch": "~3.1.2",
|
||||||
"braces": "~3.0.2",
|
"braces": "~3.0.2",
|
||||||
|
"fsevents": "~2.3.2",
|
||||||
"glob-parent": "~5.1.2",
|
"glob-parent": "~5.1.2",
|
||||||
"is-binary-path": "~2.1.0",
|
"is-binary-path": "~2.1.0",
|
||||||
"is-glob": "~4.0.1",
|
"is-glob": "~4.0.1",
|
||||||
@ -8032,6 +8033,12 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"imagemin": "^7.0.1",
|
"imagemin": "^7.0.1",
|
||||||
|
"imagemin-gifsicle": "^7.0.0",
|
||||||
|
"imagemin-mozjpeg": "^9.0.0",
|
||||||
|
"imagemin-optipng": "^8.0.0",
|
||||||
|
"imagemin-pngquant": "^9.0.2",
|
||||||
|
"imagemin-svgo": "^9.0.0",
|
||||||
|
"imagemin-webp": "^7.0.0",
|
||||||
"loader-utils": "^2.0.0",
|
"loader-utils": "^2.0.0",
|
||||||
"object-assign": "^4.1.1",
|
"object-assign": "^4.1.1",
|
||||||
"schema-utils": "^2.7.1"
|
"schema-utils": "^2.7.1"
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import CalendarPage from "./components/calendar/CalendarPage";
|
|||||||
import { ThemeProvider } from "@emotion/react";
|
import { ThemeProvider } from "@emotion/react";
|
||||||
import ProtectedRoute from "./ProtectedRoute";
|
import ProtectedRoute from "./ProtectedRoute";
|
||||||
import MeetingDetails from "./components/meeting-details/MeetingDetails";
|
import MeetingDetails from "./components/meeting-details/MeetingDetails";
|
||||||
|
import MeetingLink from "./components/meeting-link/MeetingLink";
|
||||||
|
|
||||||
import Theme from "./Theme";
|
import Theme from "./Theme";
|
||||||
|
|
||||||
@ -29,6 +30,7 @@ const App: React.FC = () => {
|
|||||||
</Routes>
|
</Routes>
|
||||||
</Router>
|
</Router>
|
||||||
<MeetingDetails />
|
<MeetingDetails />
|
||||||
|
<MeetingLink />
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,14 +1,5 @@
|
|||||||
import {
|
import { Box, Button, IconButton, Typography } from "@mui/material";
|
||||||
Box,
|
import React from "react";
|
||||||
Button,
|
|
||||||
Dialog,
|
|
||||||
DialogContent,
|
|
||||||
DialogContentText,
|
|
||||||
DialogTitle,
|
|
||||||
IconButton,
|
|
||||||
Typography,
|
|
||||||
} from "@mui/material";
|
|
||||||
import React, { useState } from "react";
|
|
||||||
import PhoneIcon from "@mui/icons-material/Phone";
|
import PhoneIcon from "@mui/icons-material/Phone";
|
||||||
import AddIcon from "@mui/icons-material/Add";
|
import AddIcon from "@mui/icons-material/Add";
|
||||||
import UserLite from "../../../../api-bodies/UserLite";
|
import UserLite from "../../../../api-bodies/UserLite";
|
||||||
@ -28,6 +19,7 @@ import { MeetingStatus } from "../../../../utils";
|
|||||||
import { selectManager, selectMe } from "../../../../redux/slices/usersSlice";
|
import { selectManager, selectMe } from "../../../../redux/slices/usersSlice";
|
||||||
import axios from "../../../../api/axios";
|
import axios from "../../../../api/axios";
|
||||||
import NewMeeting from "../../../../api-bodies/NewMeeting";
|
import NewMeeting from "../../../../api-bodies/NewMeeting";
|
||||||
|
import { open } from "../../../../redux/slices/meetingUrlSlice";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
contactInfo: UserLite;
|
contactInfo: UserLite;
|
||||||
@ -35,7 +27,6 @@ interface Props {
|
|||||||
|
|
||||||
const UpperBody: React.FC<Props> = ({ contactInfo }) => {
|
const UpperBody: React.FC<Props> = ({ contactInfo }) => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const [dialog, setDialog] = useState({ open: false, url: "" });
|
|
||||||
const userStatus: UserStatus = useAppSelector((state) =>
|
const userStatus: UserStatus = useAppSelector((state) =>
|
||||||
selectUserStatus(state, contactInfo.uuid)
|
selectUserStatus(state, contactInfo.uuid)
|
||||||
);
|
);
|
||||||
@ -53,18 +44,21 @@ const UpperBody: React.FC<Props> = ({ contactInfo }) => {
|
|||||||
: MeetingStatus.NOT_IN_MEETING;
|
: MeetingStatus.NOT_IN_MEETING;
|
||||||
|
|
||||||
const startCall = async () => {
|
const startCall = async () => {
|
||||||
|
const start = new Date().toISOString();
|
||||||
|
let newStart = start.split(".")[0];
|
||||||
|
newStart += start.includes("Z") ? "Z" : "";
|
||||||
const newMeeting: NewMeeting = {
|
const newMeeting: NewMeeting = {
|
||||||
startTime: "2022-03-30T23:40:00Z",
|
startTime: newStart,
|
||||||
duration: 30,
|
duration: 30,
|
||||||
topic: `Meeting with ${contactInfo.name}`,
|
topic: `Meeting with ${contactInfo.name}`,
|
||||||
registrantIds: [contactInfo.uuid],
|
registrantIds: [contactInfo.uuid, me],
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const response = await axios.post(
|
const response = await axios.post(
|
||||||
`/users/${me}/meetings`,
|
`/users/${me}/meetings`,
|
||||||
JSON.stringify(newMeeting)
|
JSON.stringify(newMeeting)
|
||||||
);
|
);
|
||||||
setDialog({ open: true, url: response.data.joinUrl });
|
dispatch(open(response.data.joinUrl));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
}
|
}
|
||||||
@ -92,7 +86,9 @@ const UpperBody: React.FC<Props> = ({ contactInfo }) => {
|
|||||||
mx: 4,
|
mx: 4,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography sx={{ mt: 2 }} variant="h3">{contactInfo.name}</Typography>
|
<Typography sx={{ mt: 2 }} variant="h3">
|
||||||
|
{contactInfo.name}
|
||||||
|
</Typography>
|
||||||
{!favoritesUuids.includes(contactInfo.uuid) ? (
|
{!favoritesUuids.includes(contactInfo.uuid) ? (
|
||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
@ -151,17 +147,6 @@ const UpperBody: React.FC<Props> = ({ contactInfo }) => {
|
|||||||
) : null}
|
) : null}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
<Dialog
|
|
||||||
open={dialog.open}
|
|
||||||
onClose={() => {
|
|
||||||
setDialog({ open: false, url: "" });
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<DialogTitle>Join</DialogTitle>
|
|
||||||
<DialogContent>
|
|
||||||
<DialogContentText>{dialog.url}</DialogContentText>
|
|
||||||
</DialogContent>
|
|
||||||
</Dialog>
|
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -4,7 +4,6 @@ import {
|
|||||||
Dialog,
|
Dialog,
|
||||||
DialogActions,
|
DialogActions,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogContentText,
|
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
FormControlLabel,
|
FormControlLabel,
|
||||||
FormGroup,
|
FormGroup,
|
||||||
@ -12,7 +11,7 @@ import {
|
|||||||
Typography,
|
Typography,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { useAppSelector } from "../../redux/hooks";
|
import { useAppSelector, useAppDispatch } from "../../redux/hooks";
|
||||||
import { selectFavorites } from "../../redux/slices/favoritesSlice";
|
import { selectFavorites } from "../../redux/slices/favoritesSlice";
|
||||||
import { selectTeam, selectUsers } from "../../redux/slices/usersSlice";
|
import { selectTeam, selectUsers } from "../../redux/slices/usersSlice";
|
||||||
import GroupSelect from "../sidebar/GroupSelect";
|
import GroupSelect from "../sidebar/GroupSelect";
|
||||||
@ -20,6 +19,7 @@ import axios from "../../api/axios";
|
|||||||
import useAuth from "../../hooks/useAuth";
|
import useAuth from "../../hooks/useAuth";
|
||||||
import DetailedMeeting from "../../api-bodies/DetailedMeeting";
|
import DetailedMeeting from "../../api-bodies/DetailedMeeting";
|
||||||
import NewMeeting from "../../api-bodies/NewMeeting";
|
import NewMeeting from "../../api-bodies/NewMeeting";
|
||||||
|
import { open as openMeetingUrl } from "../../redux/slices/meetingUrlSlice";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
@ -30,11 +30,9 @@ const CallFavouritesDialog: React.FC<Props> = ({
|
|||||||
open,
|
open,
|
||||||
handleClose,
|
handleClose,
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
|
|
||||||
const [group, setGroup] = useState<string>("Favorites");
|
const [group, setGroup] = useState<string>("Favorites");
|
||||||
const [inputText, setInputText] = useState<string>("");
|
const [inputText, setInputText] = useState<string>("");
|
||||||
const [checkedUuids, setCheckedUuids] = useState<string[]>([]);
|
const [checkedUuids, setCheckedUuids] = useState<string[]>([]);
|
||||||
const [urlDialog, seturlDialog] = useState({ open: false, url: "" });
|
|
||||||
|
|
||||||
const handleCheck = (uuid: string, checked: boolean) => {
|
const handleCheck = (uuid: string, checked: boolean) => {
|
||||||
if (checked) {
|
if (checked) {
|
||||||
@ -44,6 +42,7 @@ const CallFavouritesDialog: React.FC<Props> = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
const handleGroupChange = () => {
|
const handleGroupChange = () => {
|
||||||
setCheckedUuids([]);
|
setCheckedUuids([]);
|
||||||
};
|
};
|
||||||
@ -59,23 +58,25 @@ const CallFavouritesDialog: React.FC<Props> = ({
|
|||||||
|
|
||||||
const auth = useAuth();
|
const auth = useAuth();
|
||||||
|
|
||||||
const handleCall = async(e: React.SyntheticEvent) => {
|
const handleCall = async () => {
|
||||||
const start = new Date().toISOString();
|
const start = new Date().toISOString();
|
||||||
let newStart = start.split('.')[0];
|
let newStart = start.split(".")[0];
|
||||||
newStart += start.includes("Z") ? "Z" : "";
|
newStart += start.includes("Z") ? "Z" : "";
|
||||||
const newMeeting: NewMeeting ={
|
const newMeeting: NewMeeting = {
|
||||||
startTime: newStart,
|
startTime: newStart,
|
||||||
duration: 60,
|
duration: 60,
|
||||||
topic: "Quick Call to Group",
|
topic: "Quick Call to Group",
|
||||||
registrantIds: checkedUuids
|
registrantIds: checkedUuids,
|
||||||
};
|
};
|
||||||
const response = await axios.post(
|
const response = await axios.post(
|
||||||
`/users/${auth?.uuid}/meetings`,
|
`/users/${auth?.uuid}/meetings`,
|
||||||
JSON.stringify(newMeeting)
|
JSON.stringify(newMeeting)
|
||||||
);
|
);
|
||||||
const meeting: DetailedMeeting = response?.data;
|
const meeting: DetailedMeeting = response?.data;
|
||||||
console.log("create meeting response: " + meeting.startTime + ":" + meeting.duration);
|
console.log(
|
||||||
seturlDialog({ open: true, url: meeting.joinUrl });
|
"create meeting response: " + meeting.startTime + ":" + meeting.duration
|
||||||
|
);
|
||||||
|
dispatch(openMeetingUrl(response.data.joinUrl));
|
||||||
handleClose();
|
handleClose();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -134,17 +135,6 @@ const CallFavouritesDialog: React.FC<Props> = ({
|
|||||||
</Button>
|
</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
<Dialog
|
|
||||||
open={urlDialog.open}
|
|
||||||
onClose={() => {
|
|
||||||
seturlDialog({ open: false, url: "" });
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<DialogTitle>Join</DialogTitle>
|
|
||||||
<DialogContent>
|
|
||||||
<DialogContentText>{urlDialog.url}</DialogContentText>
|
|
||||||
</DialogContent>
|
|
||||||
</Dialog>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import { selectUsers } from "../../redux/slices/usersSlice";
|
|||||||
import { formatTimeFromDate } from "../../utils";
|
import { formatTimeFromDate } from "../../utils";
|
||||||
import UserLite from "../../api-bodies/UserLite";
|
import UserLite from "../../api-bodies/UserLite";
|
||||||
|
|
||||||
|
|
||||||
const EmptyMeetingsList: React.FC = () => {
|
const EmptyMeetingsList: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
@ -25,9 +24,7 @@ const EmptyMeetingsList: React.FC = () => {
|
|||||||
{/* <Box>
|
{/* <Box>
|
||||||
</Box> */}
|
</Box> */}
|
||||||
<Box>
|
<Box>
|
||||||
<Typography>
|
<Typography>No Meetings in Progress</Typography>
|
||||||
No Meetings in Progress
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
<Box>
|
||||||
<Typography>
|
<Typography>
|
||||||
@ -36,7 +33,7 @@ const EmptyMeetingsList: React.FC = () => {
|
|||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
const MeetingsList: React.FC = () => {
|
const MeetingsList: React.FC = () => {
|
||||||
const meetings = useAppSelector(selectMeetings);
|
const meetings = useAppSelector(selectMeetings);
|
||||||
@ -68,73 +65,55 @@ const MeetingsList: React.FC = () => {
|
|||||||
let i = 1;
|
let i = 1;
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<List style={{ maxHeight: "100%", overflow: "auto" }}>
|
<List style={{ maxHeight: "100%", overflow: "auto" }}>
|
||||||
{meetings.map((meeting) => {
|
{meetings.map((meeting) => {
|
||||||
const meetingMembers: UserLite[] = [];
|
const meetingMembers: UserLite[] = [];
|
||||||
participants.forEach((userLite) => {
|
participants.forEach((userLite) => {
|
||||||
|
if (
|
||||||
|
userLite != undefined &&
|
||||||
|
meeting.liveParticipantIds.includes(userLite.uuid)
|
||||||
|
) {
|
||||||
|
meetingMembers.push(userLite);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const startDate = new Date(meeting.startTime);
|
||||||
|
const startDatemil = startDate.getTime();
|
||||||
|
const endDatemil = startDatemil + meeting.duration * 60000;
|
||||||
|
const endDate = new Date(endDatemil);
|
||||||
|
|
||||||
|
const currentDatemil = currentDate.getTime();
|
||||||
|
|
||||||
|
// console.log(meetingMembersString);
|
||||||
if (
|
if (
|
||||||
userLite != undefined &&
|
(currentDatemil >= startDatemil && currentDatemil <= endDatemil) ||
|
||||||
meeting.liveParticipantIds.includes(userLite.uuid)
|
meeting.liveParticipantIds.length > 0
|
||||||
) {
|
) {
|
||||||
meetingMembers.push(userLite);
|
const lastMeetingClass = meetings.length == i ? " lastMeeting" : "";
|
||||||
}
|
i += 1;
|
||||||
});
|
|
||||||
const startDate = new Date(meeting.startTime);
|
|
||||||
const startDatemil = startDate.getTime();
|
|
||||||
const endDatemil = startDatemil + meeting.duration * 60000;
|
|
||||||
const endDate = new Date(endDatemil);
|
|
||||||
|
|
||||||
const currentDatemil = currentDate.getTime();
|
|
||||||
|
|
||||||
const meetingMembersString = () => {
|
|
||||||
if (meetingMembers.length > 3) {
|
|
||||||
return (
|
return (
|
||||||
"Participants: " +
|
<Meeting
|
||||||
meetingMembers[0].name +
|
meeting={meeting}
|
||||||
", " +
|
meetingClass={"meeting-" + (i - 1) + lastMeetingClass}
|
||||||
meetingMembers[1].name +
|
meetingName={meeting.topic}
|
||||||
", " +
|
meetingTime={
|
||||||
meetingMembers[2].name +
|
formatTimeFromDate(startDate) +
|
||||||
", and " +
|
" - " +
|
||||||
(meetingMembers.length - 3).toString() +
|
formatTimeFromDate(endDate)
|
||||||
" more..."
|
}
|
||||||
);
|
meetingMembers={meetingMembers
|
||||||
} else {
|
.map((userLite) => " " + userLite.name + " ")
|
||||||
return (
|
.toString()}
|
||||||
"Participants: " +
|
/>
|
||||||
meetingMembers.map((userLite) => " " + userLite.name).toString()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
})}
|
||||||
// console.log(meetingMembersString);
|
</List>
|
||||||
if ((currentDatemil >= startDatemil && currentDatemil <= endDatemil) || meeting.liveParticipantIds.length > 0) {
|
{i === 1 ? <EmptyMeetingsList /> : <></>}
|
||||||
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()}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
})}
|
|
||||||
</List>
|
|
||||||
{i === 1 ? <EmptyMeetingsList /> : <></>}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
const MeetingsPanel: React.FC = () => {
|
const MeetingsPanel: React.FC = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="meetings-panel">
|
<div className="meetings-panel">
|
||||||
<div className="row panel-label">
|
<div className="row panel-label">
|
||||||
|
|||||||
@ -1,197 +1,194 @@
|
|||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogActions,
|
DialogActions,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogContentText,
|
DialogTitle,
|
||||||
DialogTitle,
|
FormControlLabel,
|
||||||
FormControlLabel,
|
FormGroup,
|
||||||
FormGroup,
|
TextField,
|
||||||
TextField,
|
Typography,
|
||||||
Typography,
|
} from "@mui/material";
|
||||||
} from "@mui/material";
|
import LocalizationProvider from "@mui/lab/LocalizationProvider";
|
||||||
import LocalizationProvider from '@mui/lab/LocalizationProvider';
|
import AdapterDateFns from "@mui/lab/AdapterDateFns";
|
||||||
import AdapterDateFns from '@mui/lab/AdapterDateFns';
|
import DateTimePicker from "@mui/lab/DateTimePicker";
|
||||||
import DateTimePicker from '@mui/lab/DateTimePicker';
|
import React, { useState } from "react";
|
||||||
import React, { useState } from "react";
|
import { useAppSelector, useAppDispatch } from "../../redux/hooks";
|
||||||
import { useAppSelector } from "../../redux/hooks";
|
import { selectFavorites } from "../../redux/slices/favoritesSlice";
|
||||||
import { selectFavorites } from "../../redux/slices/favoritesSlice";
|
import { selectTeam, selectUsers } from "../../redux/slices/usersSlice";
|
||||||
import { selectTeam, selectUsers } from "../../redux/slices/usersSlice";
|
import GroupSelect from "../sidebar/GroupSelect";
|
||||||
import GroupSelect from "../sidebar/GroupSelect";
|
import axios from "../../api/axios";
|
||||||
import axios from "../../api/axios";
|
import useAuth from "../../hooks/useAuth";
|
||||||
import useAuth from "../../hooks/useAuth";
|
import DetailedMeeting from "../../api-bodies/DetailedMeeting";
|
||||||
import DetailedMeeting from "../../api-bodies/DetailedMeeting";
|
import NewMeeting from "../../api-bodies/NewMeeting";
|
||||||
import NewMeeting from "../../api-bodies/NewMeeting";
|
import { open as openMeetingUrl } from "../../redux/slices/meetingUrlSlice";
|
||||||
|
|
||||||
interface Props {
|
|
||||||
open: boolean;
|
|
||||||
handleClose: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const CallScheduledMeetingDialog: React.FC<Props> = ({
|
|
||||||
open,
|
|
||||||
handleClose,
|
|
||||||
}: Props) => {
|
|
||||||
|
|
||||||
const [meetingStartDate, setMeetingStartDate] = React.useState<Date | null>(new Date());
|
|
||||||
const [meetingTopic, setMeetingTopic] = useState<string>("");
|
|
||||||
const [meetingDuration, setMeetingDuration] = useState<number>(60);
|
|
||||||
const [group, setGroup] = useState<string>("Favorites");
|
|
||||||
const [inputText, setInputText] = useState<string>("");
|
|
||||||
const [checkedUuids, setCheckedUuids] = useState<string[]>([]);
|
|
||||||
const [urlDialog, seturlDialog] = useState({ open: false, url: "" });
|
|
||||||
|
|
||||||
const handleCheck = (uuid: string, checked: boolean) => {
|
|
||||||
if (checked) {
|
|
||||||
setCheckedUuids(checkedUuids.concat([uuid]));
|
|
||||||
} else {
|
|
||||||
setCheckedUuids(checkedUuids.filter((id) => id != uuid));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleGroupChange = () => {
|
|
||||||
setCheckedUuids([]);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDateChange = (startDate: Date | null, keyboardInputValue?: string | undefined) => {
|
interface Props {
|
||||||
setMeetingStartDate(startDate);
|
open: boolean;
|
||||||
};
|
handleClose: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
const favoritesUuids = useAppSelector(selectFavorites);
|
const CallScheduledMeetingDialog: React.FC<Props> = ({
|
||||||
const teamUuids = useAppSelector(selectTeam);
|
open,
|
||||||
|
handleClose,
|
||||||
const groupMembersUuids: string[] =
|
}: Props) => {
|
||||||
group === "Favorites" ? favoritesUuids : teamUuids;
|
const [meetingStartDate, setMeetingStartDate] = React.useState<Date | null>(
|
||||||
const groupMembers = useAppSelector((state) =>
|
new Date()
|
||||||
selectUsers(state, groupMembersUuids)
|
);
|
||||||
);
|
const [meetingTopic, setMeetingTopic] = useState<string>("");
|
||||||
|
const [meetingDuration, setMeetingDuration] = useState<number>(60);
|
||||||
const auth = useAuth();
|
const [group, setGroup] = useState<string>("Favorites");
|
||||||
|
const [inputText, setInputText] = useState<string>("");
|
||||||
const handleCall = async(e: React.SyntheticEvent) => {
|
const [checkedUuids, setCheckedUuids] = useState<string[]>([]);
|
||||||
const start = meetingStartDate ? meetingStartDate.toISOString() : new Date().toISOString();
|
const dispatch = useAppDispatch();
|
||||||
let newStart = start.split('.')[0];
|
|
||||||
newStart += start.includes("Z") ? "Z" : "";
|
const handleCheck = (uuid: string, checked: boolean) => {
|
||||||
const newMeeting: NewMeeting ={
|
if (checked) {
|
||||||
startTime: newStart,
|
setCheckedUuids(checkedUuids.concat([uuid]));
|
||||||
duration: meetingDuration,
|
} else {
|
||||||
topic: meetingTopic,
|
setCheckedUuids(checkedUuids.filter((id) => id != uuid));
|
||||||
registrantIds: checkedUuids
|
}
|
||||||
};
|
|
||||||
const response = await axios.post(
|
|
||||||
`/users/${auth?.uuid}/meetings`,
|
|
||||||
JSON.stringify(newMeeting)
|
|
||||||
);
|
|
||||||
const meeting: DetailedMeeting = response?.data;
|
|
||||||
console.log("create meeting response: " + meeting.startTime + ":" + meeting.duration);
|
|
||||||
seturlDialog({ open: true, url: meeting.joinUrl });
|
|
||||||
handleClose();
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Dialog onClose={handleClose} open={open} fullWidth maxWidth="sm">
|
|
||||||
<DialogTitle>Schedule A Meeting</DialogTitle>
|
|
||||||
<DialogContent dividers>
|
|
||||||
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
|
||||||
<DateTimePicker
|
|
||||||
label="Meeting Start Date&Time"
|
|
||||||
value={meetingStartDate}
|
|
||||||
onChange={handleDateChange}
|
|
||||||
renderInput={(params) => <TextField {...params} />}
|
|
||||||
/>
|
|
||||||
</LocalizationProvider>
|
|
||||||
<TextField
|
|
||||||
className="meetingDuration-input"
|
|
||||||
id="outlined-number"
|
|
||||||
label="Duration in Minutes"
|
|
||||||
variant="outlined"
|
|
||||||
value={meetingDuration}
|
|
||||||
type="number"
|
|
||||||
onChange={(event) => {
|
|
||||||
setMeetingDuration(parseInt(event.target.value));
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</DialogContent>
|
|
||||||
<DialogContent dividers>
|
|
||||||
<TextField
|
|
||||||
fullWidth
|
|
||||||
className="meetingTopic-input"
|
|
||||||
id="outlined-basic"
|
|
||||||
label="Meeting Topic"
|
|
||||||
variant="outlined"
|
|
||||||
value={meetingTopic}
|
|
||||||
onChange={(event) => {
|
|
||||||
setMeetingTopic(event.target.value);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</DialogContent>
|
|
||||||
<DialogContent>
|
|
||||||
<GroupSelect
|
|
||||||
group={group}
|
|
||||||
setGroup={setGroup}
|
|
||||||
onGroupChange={handleGroupChange}
|
|
||||||
/>
|
|
||||||
</DialogContent>
|
|
||||||
<DialogContent sx={{ height: "40vh" }} dividers>
|
|
||||||
<TextField
|
|
||||||
label="Search"
|
|
||||||
variant="outlined"
|
|
||||||
placeholder="Person"
|
|
||||||
fullWidth
|
|
||||||
sx={{ pb: 1 }}
|
|
||||||
onChange={(e) => {
|
|
||||||
setInputText(e.target.value);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<FormGroup>
|
|
||||||
{groupMembers
|
|
||||||
.filter((member) =>
|
|
||||||
member.name.toLowerCase().includes(inputText.toLowerCase())
|
|
||||||
)
|
|
||||||
.map((member) => (
|
|
||||||
<FormControlLabel
|
|
||||||
key={member.uuid}
|
|
||||||
label={member.name}
|
|
||||||
sx={{ pl: 1 }}
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
onChange={(e: any) => {
|
|
||||||
handleCheck(member.uuid, e.target.checked);
|
|
||||||
}}
|
|
||||||
control={
|
|
||||||
<Checkbox
|
|
||||||
color="success"
|
|
||||||
checked={checkedUuids.includes(member.uuid)}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</FormGroup>
|
|
||||||
</DialogContent>
|
|
||||||
|
|
||||||
<DialogActions>
|
|
||||||
<Button color="success" onClick={handleCall}>
|
|
||||||
<Typography variant="button" color="black">
|
|
||||||
Call
|
|
||||||
</Typography>
|
|
||||||
</Button>
|
|
||||||
</DialogActions>
|
|
||||||
</Dialog>
|
|
||||||
<Dialog
|
|
||||||
open={urlDialog.open}
|
|
||||||
onClose={() => {
|
|
||||||
seturlDialog({ open: false, url: "" });
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<DialogTitle>Join</DialogTitle>
|
|
||||||
<DialogContent>
|
|
||||||
<DialogContentText>{urlDialog.url}</DialogContentText>
|
|
||||||
</DialogContent>
|
|
||||||
</Dialog>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default CallScheduledMeetingDialog;
|
const handleGroupChange = () => {
|
||||||
|
setCheckedUuids([]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDateChange = (
|
||||||
|
startDate: Date | null,
|
||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||||
|
keyboardInputValue?: string | undefined
|
||||||
|
) => {
|
||||||
|
setMeetingStartDate(startDate);
|
||||||
|
};
|
||||||
|
|
||||||
|
const favoritesUuids = useAppSelector(selectFavorites);
|
||||||
|
const teamUuids = useAppSelector(selectTeam);
|
||||||
|
|
||||||
|
const groupMembersUuids: string[] =
|
||||||
|
group === "Favorites" ? favoritesUuids : teamUuids;
|
||||||
|
const groupMembers = useAppSelector((state) =>
|
||||||
|
selectUsers(state, groupMembersUuids)
|
||||||
|
);
|
||||||
|
|
||||||
|
const auth = useAuth();
|
||||||
|
|
||||||
|
const handleCall = async () => {
|
||||||
|
const start = meetingStartDate
|
||||||
|
? meetingStartDate.toISOString()
|
||||||
|
: new Date().toISOString();
|
||||||
|
let newStart = start.split(".")[0];
|
||||||
|
newStart += start.includes("Z") ? "Z" : "";
|
||||||
|
const newMeeting: NewMeeting = {
|
||||||
|
startTime: newStart,
|
||||||
|
duration: meetingDuration,
|
||||||
|
topic: meetingTopic,
|
||||||
|
registrantIds: checkedUuids,
|
||||||
|
};
|
||||||
|
const response = await axios.post(
|
||||||
|
`/users/${auth?.uuid}/meetings`,
|
||||||
|
JSON.stringify(newMeeting)
|
||||||
|
);
|
||||||
|
const meeting: DetailedMeeting = response?.data;
|
||||||
|
console.log(
|
||||||
|
"create meeting response: " + meeting.startTime + ":" + meeting.duration
|
||||||
|
);
|
||||||
|
dispatch(openMeetingUrl(response.data.joinUrl));
|
||||||
|
handleClose();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Dialog onClose={handleClose} open={open} fullWidth maxWidth="sm">
|
||||||
|
<DialogTitle>Schedule A Meeting</DialogTitle>
|
||||||
|
<DialogContent dividers>
|
||||||
|
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
||||||
|
<DateTimePicker
|
||||||
|
label="Meeting Start Date&Time"
|
||||||
|
value={meetingStartDate}
|
||||||
|
onChange={handleDateChange}
|
||||||
|
renderInput={(params) => <TextField {...params} />}
|
||||||
|
/>
|
||||||
|
</LocalizationProvider>
|
||||||
|
<TextField
|
||||||
|
className="meetingDuration-input"
|
||||||
|
id="outlined-number"
|
||||||
|
label="Duration in Minutes"
|
||||||
|
variant="outlined"
|
||||||
|
value={meetingDuration}
|
||||||
|
type="number"
|
||||||
|
onChange={(event) => {
|
||||||
|
setMeetingDuration(parseInt(event.target.value));
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogContent dividers>
|
||||||
|
<TextField
|
||||||
|
fullWidth
|
||||||
|
className="meetingTopic-input"
|
||||||
|
id="outlined-basic"
|
||||||
|
label="Meeting Topic"
|
||||||
|
variant="outlined"
|
||||||
|
value={meetingTopic}
|
||||||
|
onChange={(event) => {
|
||||||
|
setMeetingTopic(event.target.value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogContent>
|
||||||
|
<GroupSelect
|
||||||
|
group={group}
|
||||||
|
setGroup={setGroup}
|
||||||
|
onGroupChange={handleGroupChange}
|
||||||
|
/>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogContent sx={{ height: "40vh" }} dividers>
|
||||||
|
<TextField
|
||||||
|
label="Search"
|
||||||
|
variant="outlined"
|
||||||
|
placeholder="Person"
|
||||||
|
fullWidth
|
||||||
|
sx={{ pb: 1 }}
|
||||||
|
onChange={(e) => {
|
||||||
|
setInputText(e.target.value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<FormGroup>
|
||||||
|
{groupMembers
|
||||||
|
.filter((member) =>
|
||||||
|
member.name.toLowerCase().includes(inputText.toLowerCase())
|
||||||
|
)
|
||||||
|
.map((member) => (
|
||||||
|
<FormControlLabel
|
||||||
|
key={member.uuid}
|
||||||
|
label={member.name}
|
||||||
|
sx={{ pl: 1 }}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
onChange={(e: any) => {
|
||||||
|
handleCheck(member.uuid, e.target.checked);
|
||||||
|
}}
|
||||||
|
control={
|
||||||
|
<Checkbox
|
||||||
|
color="success"
|
||||||
|
checked={checkedUuids.includes(member.uuid)}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</FormGroup>
|
||||||
|
</DialogContent>
|
||||||
|
|
||||||
|
<DialogActions>
|
||||||
|
<Button color="success" onClick={handleCall}>
|
||||||
|
<Typography variant="button" color="black">
|
||||||
|
Call
|
||||||
|
</Typography>
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CallScheduledMeetingDialog;
|
||||||
|
|||||||
@ -1,19 +1,10 @@
|
|||||||
import {
|
import { AppBar, Button, IconButton, Toolbar, Typography } from "@mui/material";
|
||||||
AppBar,
|
import React from "react";
|
||||||
Button,
|
|
||||||
Dialog,
|
|
||||||
DialogContent,
|
|
||||||
DialogContentText,
|
|
||||||
DialogTitle,
|
|
||||||
IconButton,
|
|
||||||
Toolbar,
|
|
||||||
Typography,
|
|
||||||
} from "@mui/material";
|
|
||||||
import React, { useState } from "react";
|
|
||||||
import CloseIcon from "@mui/icons-material/Close";
|
import CloseIcon from "@mui/icons-material/Close";
|
||||||
import { useAppDispatch } from "../../../redux/hooks";
|
import { useAppDispatch } from "../../../redux/hooks";
|
||||||
import { close } from "../../../redux/slices/meetingDetailsOpenSlice";
|
import { close } from "../../../redux/slices/meetingDetailsOpenSlice";
|
||||||
import DetailedMeeting from "../../../api-bodies/DetailedMeeting";
|
import DetailedMeeting from "../../../api-bodies/DetailedMeeting";
|
||||||
|
import { open as openMeetingUrl } from "../../../redux/slices/meetingUrlSlice";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
meeting: DetailedMeeting;
|
meeting: DetailedMeeting;
|
||||||
@ -21,7 +12,6 @@ interface Props {
|
|||||||
|
|
||||||
const Header: React.FC<Props> = ({ meeting }) => {
|
const Header: React.FC<Props> = ({ meeting }) => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const [dialog, setDialog] = useState({ open: false, url: "" });
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppBar sx={{ position: "relative" }}>
|
<AppBar sx={{ position: "relative" }}>
|
||||||
@ -33,7 +23,7 @@ const Header: React.FC<Props> = ({ meeting }) => {
|
|||||||
variant="contained"
|
variant="contained"
|
||||||
color="secondary"
|
color="secondary"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setDialog({ open: true, url: meeting.joinUrl });
|
dispatch(openMeetingUrl(meeting.joinUrl));
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Join
|
Join
|
||||||
@ -48,17 +38,6 @@ const Header: React.FC<Props> = ({ meeting }) => {
|
|||||||
<CloseIcon />
|
<CloseIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Toolbar>
|
</Toolbar>
|
||||||
<Dialog
|
|
||||||
open={dialog.open}
|
|
||||||
onClose={() => {
|
|
||||||
setDialog({ open: false, url: "" });
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<DialogTitle>Join</DialogTitle>
|
|
||||||
<DialogContent>
|
|
||||||
<DialogContentText>{dialog.url}</DialogContentText>
|
|
||||||
</DialogContent>
|
|
||||||
</Dialog>
|
|
||||||
</AppBar>
|
</AppBar>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
30
src/components/meeting-link/MeetingLink.tsx
Normal file
30
src/components/meeting-link/MeetingLink.tsx
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogContentText,
|
||||||
|
DialogTitle,
|
||||||
|
} from "@mui/material";
|
||||||
|
import React from "react";
|
||||||
|
import { useAppSelector, useAppDispatch } from "../../redux/hooks";
|
||||||
|
import { close, selectMeetingUrl } from "../../redux/slices/meetingUrlSlice";
|
||||||
|
|
||||||
|
const warningText =
|
||||||
|
"For real-time user status updates to function correctly, please ensure you are logged into the Zoom desktop client with your Digital Walkaround Zoom account and that you are not logged into the Zoom.us website in this browser with a Zoom account different from your Digital Walkaround one";
|
||||||
|
|
||||||
|
const MeetingLink: React.FC = () => {
|
||||||
|
const meetingUrl = useAppSelector(selectMeetingUrl);
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
return (
|
||||||
|
<Dialog open={meetingUrl.open} onClose={() => dispatch(close())}>
|
||||||
|
<DialogTitle>Join</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
<DialogContentText sx={{ marginBottom: 2 }}>
|
||||||
|
{"Link: " + meetingUrl.url}
|
||||||
|
</DialogContentText>
|
||||||
|
<DialogContentText>{warningText}</DialogContentText>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MeetingLink;
|
||||||
@ -15,6 +15,7 @@ import { useNavigate } from "react-router-dom";
|
|||||||
import { selectMe } from "../../redux/slices/usersSlice";
|
import { selectMe } from "../../redux/slices/usersSlice";
|
||||||
import NewMeeting from "../../api-bodies/NewMeeting";
|
import NewMeeting from "../../api-bodies/NewMeeting";
|
||||||
import axios from "../../api/axios";
|
import axios from "../../api/axios";
|
||||||
|
import { open as openMeetingUrl } from "../../redux/slices/meetingUrlSlice";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
user: UserLite;
|
user: UserLite;
|
||||||
@ -38,7 +39,10 @@ const SettingsButton: React.FC<Props> = ({ user, status }: Props) => {
|
|||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
setAnchorEl(null);
|
setAnchorEl(null);
|
||||||
};
|
};
|
||||||
const handleSnackbarClose = (event?: React.SyntheticEvent | Event, reason?: string) => {
|
const handleSnackbarClose = (
|
||||||
|
event?: React.SyntheticEvent | Event,
|
||||||
|
reason?: string
|
||||||
|
) => {
|
||||||
if (reason === "clickaway") {
|
if (reason === "clickaway") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -46,18 +50,21 @@ const SettingsButton: React.FC<Props> = ({ user, status }: Props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const startCall = async () => {
|
const startCall = async () => {
|
||||||
|
const start = new Date().toISOString();
|
||||||
|
let newStart = start.split(".")[0];
|
||||||
|
newStart += start.includes("Z") ? "Z" : "";
|
||||||
const newMeeting: NewMeeting = {
|
const newMeeting: NewMeeting = {
|
||||||
startTime: "2022-03-30T23:40:00Z",
|
startTime: newStart,
|
||||||
duration: 30,
|
duration: 30,
|
||||||
topic: `Meeting with ${user.name}`,
|
topic: `Meeting with ${user.name}`,
|
||||||
registrantIds: [user.uuid],
|
registrantIds: [user.uuid, me],
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const response = await axios.post(
|
const response = await axios.post(
|
||||||
`/users/${me}/meetings`,
|
`/users/${me}/meetings`,
|
||||||
JSON.stringify(newMeeting)
|
JSON.stringify(newMeeting)
|
||||||
);
|
);
|
||||||
window.open(response.data.joinUrl, "_blank")?.focus();
|
dispatch(openMeetingUrl(response.data.joinUrl));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
}
|
}
|
||||||
@ -100,7 +107,6 @@ const SettingsButton: React.FC<Props> = ({ user, status }: Props) => {
|
|||||||
>
|
>
|
||||||
Add to Favorites
|
Add to Favorites
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|
||||||
)}
|
)}
|
||||||
{status.inMeeting ? (
|
{status.inMeeting ? (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
@ -129,10 +135,17 @@ const SettingsButton: React.FC<Props> = ({ user, status }: Props) => {
|
|||||||
Create meeting
|
Create meeting
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</Menu>
|
</Menu>
|
||||||
<Snackbar
|
<Snackbar
|
||||||
anchorOrigin={{ vertical: "bottom", horizontal: "right" }}
|
anchorOrigin={{ vertical: "bottom", horizontal: "right" }}
|
||||||
open={snackbarOpen} autoHideDuration={3000} onClose={handleSnackbarClose}>
|
open={snackbarOpen}
|
||||||
<Alert onClose={handleSnackbarClose} severity="success" sx={{ width: "100%" }}>
|
autoHideDuration={3000}
|
||||||
|
onClose={handleSnackbarClose}
|
||||||
|
>
|
||||||
|
<Alert
|
||||||
|
onClose={handleSnackbarClose}
|
||||||
|
severity="success"
|
||||||
|
sx={{ width: "100%" }}
|
||||||
|
>
|
||||||
User successfully added to favourites list!
|
User successfully added to favourites list!
|
||||||
</Alert>
|
</Alert>
|
||||||
</Snackbar>
|
</Snackbar>
|
||||||
|
|||||||
@ -19,7 +19,6 @@ export const meetingDetailsOpenSlice = createSlice({
|
|||||||
open: (state, action) => {
|
open: (state, action) => {
|
||||||
state.open = true;
|
state.open = true;
|
||||||
state.meeting = action.payload;
|
state.meeting = action.payload;
|
||||||
console.log(action.payload);
|
|
||||||
},
|
},
|
||||||
close: (state) => {
|
close: (state) => {
|
||||||
state.open = false;
|
state.open = false;
|
||||||
|
|||||||
31
src/redux/slices/meetingUrlSlice.tsx
Normal file
31
src/redux/slices/meetingUrlSlice.tsx
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { createSlice } from "@reduxjs/toolkit";
|
||||||
|
import { RootState } from "../store";
|
||||||
|
|
||||||
|
interface MeetingUrlState {
|
||||||
|
open: boolean;
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const initialState: MeetingUrlState = {
|
||||||
|
open: false,
|
||||||
|
url: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const meetingUrlSlice = createSlice({
|
||||||
|
name: "meetingUrl",
|
||||||
|
initialState,
|
||||||
|
reducers: {
|
||||||
|
open: (state, action) => {
|
||||||
|
state.open = true;
|
||||||
|
state.url = action.payload;
|
||||||
|
},
|
||||||
|
close: (state) => {
|
||||||
|
state.open = false;
|
||||||
|
state.url = "";
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const { open, close } = meetingUrlSlice.actions;
|
||||||
|
export const selectMeetingUrl = (state: RootState) => state.meetingUrl;
|
||||||
|
export default meetingUrlSlice.reducer;
|
||||||
@ -31,9 +31,28 @@ export const meetingsAndUserStatusSlice = createSlice({
|
|||||||
state.isConnected = true;
|
state.isConnected = true;
|
||||||
},
|
},
|
||||||
meetingCreated: (state, action) => {
|
meetingCreated: (state, action) => {
|
||||||
|
console.log(action.payload);
|
||||||
state.meetings.push(action.payload);
|
state.meetings.push(action.payload);
|
||||||
},
|
},
|
||||||
userStatusChanged: (state, action) => {
|
userStatusChanged: (state, action) => {
|
||||||
|
const meetingIndex = state.meetings.findIndex(
|
||||||
|
(meeting) => meeting.meetingId === action.payload.meetingId
|
||||||
|
);
|
||||||
|
const liveParticipantIndex = state.meetings[
|
||||||
|
meetingIndex
|
||||||
|
].liveParticipantIds.indexOf(action.payload.userId);
|
||||||
|
if (action.payload.inMeeting) {
|
||||||
|
if (liveParticipantIndex === -1)
|
||||||
|
state.meetings[meetingIndex].liveParticipantIds.push(
|
||||||
|
action.payload.userId
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
if (liveParticipantIndex !== -1)
|
||||||
|
state.meetings[meetingIndex].liveParticipantIds.splice(
|
||||||
|
liveParticipantIndex,
|
||||||
|
1
|
||||||
|
);
|
||||||
|
}
|
||||||
state.userStatuses[action.payload.userId] = action.payload;
|
state.userStatuses[action.payload.userId] = action.payload;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import meetingDetailsOpenReducer from "./slices/meetingDetailsOpenSlice";
|
|||||||
import favoritesReducer from "./slices/favoritesSlice";
|
import favoritesReducer from "./slices/favoritesSlice";
|
||||||
import meetingsAndUserStatusReducer from "./slices/meetingsAndUserStatusSlice";
|
import meetingsAndUserStatusReducer from "./slices/meetingsAndUserStatusSlice";
|
||||||
import usersReducer from "./slices/usersSlice";
|
import usersReducer from "./slices/usersSlice";
|
||||||
|
import meetingUrlReducer from "./slices/meetingUrlSlice";
|
||||||
import socketMiddleware from "./middleware/socketMiddleware";
|
import socketMiddleware from "./middleware/socketMiddleware";
|
||||||
|
|
||||||
export const store = configureStore({
|
export const store = configureStore({
|
||||||
@ -11,6 +12,7 @@ export const store = configureStore({
|
|||||||
favorites: favoritesReducer,
|
favorites: favoritesReducer,
|
||||||
meetingsAndUserStatuses: meetingsAndUserStatusReducer,
|
meetingsAndUserStatuses: meetingsAndUserStatusReducer,
|
||||||
users: usersReducer,
|
users: usersReducer,
|
||||||
|
meetingUrl: meetingUrlReducer,
|
||||||
},
|
},
|
||||||
middleware: (getDefaultMiddleware) => {
|
middleware: (getDefaultMiddleware) => {
|
||||||
return getDefaultMiddleware().concat([socketMiddleware]);
|
return getDefaultMiddleware().concat([socketMiddleware]);
|
||||||
|
|||||||
Reference in New Issue
Block a user