Merge branch 'main' into cochrane

This commit is contained in:
Jincheng Lu 2022-03-11 01:29:56 -08:00 committed by GitHub
commit e0013d15f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 398 additions and 178 deletions

View File

@ -14,9 +14,15 @@ import Theme from "./Theme";
import "./style/App.css";
import Sidebar from "./components/sidebar/Sidebar";
import { MeetingStatus, SidebarUserObj } from "./components/sidebar/SidebarUser";
import {
MeetingStatus,
SidebarUserObj,
} from "./components/sidebar/SidebarUser";
import MeetingDetails from "./components/meeting-details/MeetingDetails";
import { Box } from "@mui/material";
const App: React.FC = () => {
const [meetingInfoOpen, setMeetingInfoOpen] = useState(false);
/* Temporary data */
const [sidebarUsers] = useState<SidebarUserObj[]>([
@ -45,17 +51,27 @@ const App: React.FC = () => {
return (
<ThemeProvider theme={Theme}>
<Sidebar users={sidebarUsers} />
<Router>
<Navbar />
<Box id="drawer-container" sx={{ display: "flex", height: "100%" }}>
<Box sx={{ flexGrow: 1 }}>
<Routes>
<Route path="/login" element={<Login />} />
<Route element={<ProtectedRoute />}>
<Route path="/" element={<Home />} />
<Route path="/contacts" element={<Contacts />} />
<Route
path="/contacts"
element={<Contacts setMeetingInfoOpen={setMeetingInfoOpen} />}
/>
<Route path="/calendar" element={<Calendar />} />
</Route>
</Routes>
</Box>
<Box>
<Sidebar users={sidebarUsers} />
</Box>
</Box>
<MeetingDetails open={meetingInfoOpen} setOpen={setMeetingInfoOpen} />
</Router>
</ThemeProvider>
);

View File

@ -0,0 +1,12 @@
interface DetailedMeeting {
meetingId: string; // primary key
liveParticipantIds: string[];
registrantIds: string[];
start: string;
duration: number;
timezone: string;
joinUrl: string;
topic: string;
}
export default DetailedMeeting;

View File

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

View File

@ -0,0 +1,9 @@
import UserLite from "./UserLite";
interface UserFull {
userInfo: UserLite;
manager: UserLite;
directReports: UserLite[];
}
export default UserFull;

View File

@ -0,0 +1,8 @@
interface UserLite {
uuid: string;
emailAddress: string;
name: string;
role: string;
}
export default UserLite;

View File

@ -1,11 +1,15 @@
import { Box } from "@mui/material";
import React from "react";
import Body from "./Body";
import Body from "./contacts-components/Body";
import ContactInfo from "./ContactInfo";
import Sidebar from "./Sidebar";
import Sidebar from "./contacts-components/Sidebar";
const Contacts: React.FC = () => {
interface Props {
setMeetingInfoOpen: (open: boolean) => void;
}
const Contacts: React.FC<Props> = (props) => {
const [contactSelected, setContactSelected] =
React.useState<ContactInfo | null>(null);
@ -13,7 +17,10 @@ const Contacts: React.FC = () => {
<Box sx={{ display: "flex", height: "100%" }}>
<Sidebar setContactSelected={setContactSelected} />
{contactSelected !== null ? (
<Body contactSelected={contactSelected} />
<Body
contactSelected={contactSelected}
setMeetingInfoOpen={props.setMeetingInfoOpen}
/>
) : null}
</Box>
);

View File

@ -1,11 +1,12 @@
import { Box, Toolbar } from "@mui/material";
import React from "react";
import UpperBody from "./UpperBody";
import LowerBody from "./LowerBody";
import ContactInfo from "./ContactInfo";
import UpperBody from "./body-components/UpperBody";
import LowerBody from "./body-components/LowerBody";
import ContactInfo from "../ContactInfo";
interface Props {
contactSelected: ContactInfo;
setMeetingInfoOpen: (open: boolean) => void;
}
const Body: React.FC<Props> = (props) => {
@ -20,7 +21,10 @@ const Body: React.FC<Props> = (props) => {
>
<Toolbar />
<UpperBody contactInfo={props.contactSelected} />
<LowerBody contactInfo={props.contactSelected} />
<LowerBody
contactInfo={props.contactSelected}
setMeetingInfoOpen={props.setMeetingInfoOpen}
/>
</Box>
);
};

View File

@ -9,9 +9,9 @@ import {
} from "@mui/material";
import React from "react";
import { ExpandLess, ExpandMore } from "@mui/icons-material";
import ContactInfo from "./ContactInfo";
import Status from "./Status";
import ContactItem from "./ContactItem";
import ContactInfo from "../ContactInfo";
import Status from "../Status";
import ContactItem from "./sidebar-components/ContactItem";
const contacts: ContactInfo[] = [
{ name: "Taehee ...", status: Status.Online },

View File

@ -1,6 +1,6 @@
import { Box, List, Typography } from "@mui/material";
import { Box, Button, List, Typography } from "@mui/material";
import React from "react";
import ContactInfo from "./ContactInfo";
import ContactInfo from "../../ContactInfo";
const meetings: { name: string; duration: string }[] = [
{ name: "Kanban Meeting", duration: "10:45 am - 11:45 am" },
@ -12,9 +12,10 @@ const meetings: { name: string; duration: string }[] = [
interface Props {
contactInfo: ContactInfo;
setMeetingInfoOpen: (open: boolean) => void;
}
const LowerBody: React.FC<Props> = () => {
const LowerBody: React.FC<Props> = (props) => {
return (
<Box
sx={{
@ -23,7 +24,7 @@ const LowerBody: React.FC<Props> = () => {
border: 1,
borderRadius: 2,
width: "70%",
height: "70%",
height: "60%",
alignSelf: "center",
}}
>
@ -43,8 +44,14 @@ const LowerBody: React.FC<Props> = () => {
}}
key={i}
>
<Typography sx={{ pt: "12px" }}>{meeting.name}</Typography>
<Typography sx={{ pt: "12px" }}>{meeting.duration}</Typography>
<Button
variant="text"
color="info"
onClick={() => props.setMeetingInfoOpen(true)}
>
{meeting.name}
</Button>
<Typography sx={{ pt: 1.5 }}>{meeting.duration}</Typography>
</Box>
))}
</List>

View File

@ -3,7 +3,8 @@ 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 ContactInfo from "./ContactInfo";
import ContactInfo from "../../ContactInfo";
import AddIcon from "@mui/icons-material/Add";
interface Props {
contactInfo: ContactInfo;
@ -26,40 +27,45 @@ const UpperBody: React.FC<Props> = (props) => {
sx={{
display: "flex",
flexDirection: "row",
justifyContent: "space-evenly",
justifyContent: "space-between",
alignItems: "center",
mx: 4,
}}
>
<Typography variant="h3">{props.contactInfo.name}</Typography>
<Button variant="outlined" color="success" startIcon={<AddIcon />}>
favorites
</Button>
</Box>
<Box
sx={{
display: "flex",
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
my: 2,
mx: 4,
}}
>
<Box
sx={{
ml: "5%",
}}
<Box>
<IconButton
sx={{ border: 1, mr: 1, backgroundColor: "secondary" }}
size="large"
color="secondary"
>
<IconButton sx={{ border: 1, mr: 1 }} size="large">
<PhoneIcon fontSize="large" />
</IconButton>
<IconButton sx={{ border: 1, mr: 1 }} size="large">
<IconButton sx={{ border: 1, mr: 1 }} size="large" color="secondary">
<VideocamIcon fontSize="large" />
</IconButton>
<IconButton sx={{ border: 1, mr: 1 }} size="large">
<IconButton sx={{ border: 1, mr: 1 }} size="large" color="secondary">
<GroupsIcon fontSize="large" />
</IconButton>
<Button variant="outlined" color="success">
Add to favorites
</Button>
</Box>
<Box sx={{ display: "flex", flexDirection: "column", ml: "10%" }}>
<Typography>{props.contactInfo.status}</Typography>
<Box sx={{ display: "flex", flexDirection: "column" }}>
<Typography sx={{ textAlign: "right" }}>
{props.contactInfo.status}
</Typography>
<Typography>MeetingName-1372</Typography>
</Box>
</Box>

View File

@ -2,8 +2,8 @@ import { ListItemButton, ListItemIcon, ListItemText } from "@mui/material";
import React from "react";
import PersonOutlineIcon from "@mui/icons-material/PersonOutline";
import CircleIcon from "@mui/icons-material/Circle";
import ContactInfo from "./ContactInfo";
import { returnStatusColor } from "./Utils";
import ContactInfo from "../../ContactInfo";
import { returnStatusColor } from "../../Utils";
interface Props {
contactInfo: ContactInfo;

View File

@ -1,6 +1,11 @@
function Meeting(props: any) {
return (
interface Props {
meetingName: string;
meetingTime: string;
meetingMembers: string
}
function Meeting(props: Props) {
return (
<div className="row meeting">
<div className="col-12">
<div className="row">
@ -15,6 +20,6 @@ function Meeting(props: any) {
</div>
</div>
);
};
}
export default Meeting;

View File

@ -1,7 +1,7 @@
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 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";

View File

@ -1,4 +1,4 @@
import { useRef, useState, useEffect, useContext } from 'react';
import { useRef, useState, useEffect, useContext } from "react";
import { useLocation, Link, useNavigate } from "react-router-dom";
import { Stack } from "@mui/material";
import Container from "@mui/material/Container";
@ -6,7 +6,7 @@ import TextField from "@mui/material/TextField";
import Button from "@mui/material/Button";
import hsbcLogo from "../../assets/logo-png.png";
import zoomLogo from "../../assets/zoom.png";
import LoginIcon from '@mui/icons-material/Login';
import LoginIcon from "@mui/icons-material/Login";
import useAuth from "../../hooks/useAuth";
const Login: React.FC = () => {
@ -17,8 +17,8 @@ const Login: React.FC = () => {
const location: any = useLocation();
const from = location.state?.from?.pathname || "/";
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
// const [errMsg, setErrMsg] = useState('');
// const userRef = useRef();

View File

@ -0,0 +1,20 @@
import { Dialog } from "@mui/material";
import React from "react";
import Body from "./meeting-details-components/Body";
import Header from "./meeting-details-components/Header";
interface Props {
open: boolean;
setOpen: (open: boolean) => void;
}
const MeetingDetails: React.FC<Props> = (props) => {
return (
<Dialog fullScreen open={props.open} onClose={() => props.setOpen(false)}>
<Header setOpen={props.setOpen} />
<Body />
</Dialog>
);
};
export default MeetingDetails;

View File

@ -0,0 +1,74 @@
import {
Box,
List,
ListItem,
ListItemIcon,
ListItemText,
Typography,
} from "@mui/material";
import React from "react";
import PersonOutlineIcon from "@mui/icons-material/PersonOutline";
const Body: React.FC = () => {
return (
<Box
sx={{
display: "flex",
flexDirection: "row",
width: "80%",
alignSelf: "center",
mt: 2,
}}
>
<Box
sx={{
display: "flex",
flexDirection: "column",
width: "70%",
height: "100%",
}}
>
<Typography>Feb 10, 2022 10:45 am - 11:00 am</Typography>
<Typography>Status: Live</Typography>
<Typography>
Topic: Lorem Ipsum is simply dummy text of the printing and
typesetting industry. Lorem Ipsum has been the industrys standard
dummy text ever since the 1500s. Topic: Lorem Ipsum is simply dummy
text of the printing and typesetting industry. Lorem Ipsum has been
the industrys standard dummy text ever since the 1500s.
</Typography>
</Box>
<Box
sx={{
display: "flex",
flexDirection: "column",
flexGrow: 1,
borderLeft: 1,
ml: 4,
}}
>
<List>
<ListItem sx={{ borderBottom: 1 }}>
<ListItemText primary="Invited" />
</ListItem>
<ListItem>
<ListItemIcon>
<PersonOutlineIcon />
</ListItemIcon>
<ListItemText primary="Taehee Choi" />
</ListItem>
</List>
<List>
<ListItem>
<ListItemIcon>
<PersonOutlineIcon />
</ListItemIcon>
<ListItemText primary="Taehee Choi" />
</ListItem>
</List>
</Box>
</Box>
);
};
export default Body;

View File

@ -0,0 +1,36 @@
import { AppBar, Button, IconButton, Toolbar, Typography } from "@mui/material";
import React from "react";
import CloseIcon from "@mui/icons-material/Close";
interface Props {
setOpen: (open: boolean) => void;
}
const Header: React.FC<Props> = (props) => {
return (
<AppBar sx={{ position: "relative" }}>
<Toolbar>
<Typography variant="h6" sx={{ flexGrow: 1 }}>
Kanban Meeting
</Typography>
<Button variant="contained" color="secondary">
Join
</Button>
<Button variant="contained" color="secondary" sx={{ ml: 1 }}>
Recording
</Button>
<IconButton
edge="start"
color="inherit"
aria-label="close"
onClick={() => props.setOpen(false)}
sx={{ ml: 1 }}
>
<CloseIcon />
</IconButton>
</Toolbar>
</AppBar>
);
};
export default Header;

View File

@ -1,13 +1,20 @@
import { Divider, Drawer, List, ListItem, ListSubheader } from "@mui/material";
import {
Divider,
Drawer,
List,
ListItem,
ListSubheader,
Toolbar,
} from "@mui/material";
import GroupSelect from "./GroupSelect";
import SidebarUser, { SidebarUserObj } from "./SidebarUser";
// TODO: toolbar on top of sidebar since it goes under the navbar
const drawerWidth = 240;
const drawerWidth = 200;
interface Props {
users: SidebarUserObj[],
users: SidebarUserObj[];
}
const Sidebar: React.FC<Props> = ({ users }: Props) => {
@ -15,15 +22,14 @@ const Sidebar: React.FC<Props> = ({ users }: Props) => {
<Drawer
sx={{
width: drawerWidth,
flexShrink: 0,
"& .MuiDrawer-paper": {
width: drawerWidth,
boxSizing: "border-box",
},
}}
variant="permanent"
anchor="right"
>
<Toolbar />
<List disablePadding sx={{ height: "80%", overflow: "auto" }}>
<ListSubheader disableGutters>
<GroupSelect />