contacts page first draft done

This commit is contained in:
Taehee Choi 2022-03-05 01:30:48 -08:00
parent abeede8d82
commit d21dda7719
7 changed files with 208 additions and 42 deletions

View File

@ -0,0 +1,28 @@
import { Box, Toolbar } from "@mui/material";
import React from "react";
import UpperBody from "./UpperBody";
import LowerBody from "./LowerBody";
import ContactInfo from "./ContactInfo";
interface Props {
contactSelected: ContactInfo;
}
const Body: React.FC<Props> = (props) => {
return (
<Box
sx={{
display: "flex",
flexDirection: "column",
width: "100%",
height: "100%",
}}
>
<Toolbar />
<UpperBody contactInfo={props.contactSelected} />
<LowerBody contactInfo={props.contactSelected} />
</Box>
);
};
export default Body;

View File

@ -1,48 +1,31 @@
import { import { ListItemButton, ListItemIcon, ListItemText } from "@mui/material";
Box,
ListItemButton,
ListItemIcon,
ListItemText,
Typography,
} from "@mui/material";
import React from "react"; import React from "react";
import Status from "./Status";
import PersonOutlineIcon from "@mui/icons-material/PersonOutline"; import PersonOutlineIcon from "@mui/icons-material/PersonOutline";
import CircleIcon from "@mui/icons-material/Circle"; import CircleIcon from "@mui/icons-material/Circle";
import ContactInfo from "./ContactInfo"; import ContactInfo from "./ContactInfo";
import { returnStatusColor } from "./Utils";
const returnStatus = ( interface Props {
status: Status contactInfo: ContactInfo;
): "success" | "disabled" | "warning" | "error" => { setContactSelected: (contactInfo: ContactInfo) => void;
switch (status) {
case Status.Online:
return "success";
case Status.Offline:
return "disabled";
case Status.Away:
return "warning";
case Status.InMeeting:
return "error";
} }
};
const ContactItem: React.FC<ContactInfo> = (props) => { const ContactItem: React.FC<Props> = (props) => {
return ( return (
<ListItemButton> <ListItemButton
onClick={() => {
props.setContactSelected(props.contactInfo);
}}
>
<ListItemIcon> <ListItemIcon>
<PersonOutlineIcon /> <PersonOutlineIcon />
</ListItemIcon> </ListItemIcon>
<Box sx={{ display: "flex", flexDirection: "column", flexGrow: 1 }}>
<ListItemText primary={props.name} />
<ListItemText <ListItemText
primary={ primary={props.contactInfo.name}
<Typography variant="subtitle1" sx={{ fontSize: "0.7rem" }}> secondary={props.contactInfo.status}
{props.status} sx={{ flexGrow: 1 }}
</Typography>
}
/> />
</Box> <CircleIcon color={returnStatusColor(props.contactInfo.status)} />
<CircleIcon color={returnStatus(props.status)} />
</ListItemButton> </ListItemButton>
); );
}; };

View File

@ -1,12 +1,20 @@
import { Box } from "@mui/material"; import { Box } from "@mui/material";
import React from "react"; import React from "react";
import Body from "./Body";
import ContactInfo from "./ContactInfo";
import Sidebar from "./Sidebar"; import Sidebar from "./Sidebar";
const Contacts: React.FC = () => { const Contacts: React.FC = () => {
const [contactSelected, setContactSelected] =
React.useState<ContactInfo | null>(null);
return ( return (
<Box> <Box sx={{ display: "flex", height: "100%" }}>
<Sidebar></Sidebar> <Sidebar setContactSelected={setContactSelected} />
{contactSelected !== null ? (
<Body contactSelected={contactSelected} />
) : null}
</Box> </Box>
); );
}; };

View File

@ -0,0 +1,55 @@
import { Box, List, Typography } from "@mui/material";
import React from "react";
import ContactInfo from "./ContactInfo";
const meetings: { name: string; duration: string }[] = [
{ name: "Kanban Meeting", duration: "10:45 am - 11:45 am" },
{ name: "Design Meeting", duration: "10:45 am - 11:45 am" },
{ name: "Customer Meeting", duration: "10:45 am - 11:45 am" },
{ name: "Some kind of Meeting", duration: "10:45 am - 11:45 am" },
{ name: "Some kind of Meeting", duration: "10:45 am - 11:45 am" },
];
interface Props {
contactInfo: ContactInfo;
}
const LowerBody: React.FC<Props> = () => {
return (
<Box
sx={{
display: "flex",
flexDirection: "column",
border: 1,
borderRadius: 2,
width: "70%",
height: "70%",
alignSelf: "center",
}}
>
<Typography variant="h4" textAlign="center">
Upcoming meetings
</Typography>
<List sx={{ maxHeight: "100%", overflow: "auto" }}>
{meetings.map((meeting, i) => (
<Box
sx={{
display: "flex",
justifyContent: "space-between",
height: "50px",
px: "10px",
borderTop: 1,
borderBottom: i === meetings.length - 1 ? 1 : 0,
}}
key={i}
>
<Typography sx={{ pt: "12px" }}>{meeting.name}</Typography>
<Typography sx={{ pt: "12px" }}>{meeting.duration}</Typography>
</Box>
))}
</List>
</Box>
);
};
export default LowerBody;

View File

@ -20,9 +20,13 @@ const contacts: ContactInfo[] = [
{ name: "Esteban ...", status: Status.Away }, { name: "Esteban ...", status: Status.Away },
]; ];
interface Props {
setContactSelected: (contactInfo: ContactInfo) => void;
}
const sidebarWidth = 240; const sidebarWidth = 240;
const Sidebar: React.FC = () => { const Sidebar: React.FC<Props> = (props) => {
const [favoritesOpen, setFavoritesOpen] = React.useState<boolean>(true); const [favoritesOpen, setFavoritesOpen] = React.useState<boolean>(true);
const [teamOpen, setTeamOpen] = React.useState<boolean>(false); const [teamOpen, setTeamOpen] = React.useState<boolean>(false);
@ -51,9 +55,9 @@ const Sidebar: React.FC = () => {
<List disablePadding> <List disablePadding>
{contacts.map((contact, i) => ( {contacts.map((contact, i) => (
<ContactItem <ContactItem
name={contact.name} contactInfo={contact}
status={contact.status}
key={i} key={i}
setContactSelected={props.setContactSelected}
/> />
))} ))}
</List> </List>
@ -67,9 +71,9 @@ const Sidebar: React.FC = () => {
<List disablePadding> <List disablePadding>
{contacts.map((contact, i) => ( {contacts.map((contact, i) => (
<ContactItem <ContactItem
name={contact.name} contactInfo={contact}
status={contact.status}
key={i} key={i}
setContactSelected={props.setContactSelected}
/> />
))} ))}
</List> </List>

View File

@ -0,0 +1,70 @@
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 ContactInfo from "./ContactInfo";
interface Props {
contactInfo: ContactInfo;
}
const UpperBody: React.FC<Props> = (props) => {
return (
<Box
sx={{
display: "flex",
flexDirection: "column",
border: 1,
borderRadius: 2,
width: "70%",
alignSelf: "center",
mb: 2,
}}
>
<Box
sx={{
display: "flex",
flexDirection: "row",
justifyContent: "space-evenly",
alignItems: "center",
}}
>
<Typography variant="h3">{props.contactInfo.name}</Typography>
</Box>
<Box
sx={{
display: "flex",
flexDirection: "row",
alignItems: "center",
my: 2,
}}
>
<Box
sx={{
ml: "5%",
}}
>
<IconButton sx={{ border: 1, mr: 1 }} size="large">
<PhoneIcon fontSize="large" />
</IconButton>
<IconButton sx={{ border: 1, mr: 1 }} size="large">
<VideocamIcon fontSize="large" />
</IconButton>
<IconButton sx={{ border: 1, mr: 1 }} size="large">
<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>
<Typography>MeetingName-1372</Typography>
</Box>
</Box>
</Box>
);
};
export default UpperBody;

View File

@ -0,0 +1,18 @@
import Status from "./Status";
const returnStatusColor = (
status: Status
): "success" | "disabled" | "warning" | "error" => {
switch (status) {
case Status.Online:
return "success";
case Status.Offline:
return "disabled";
case Status.Away:
return "warning";
case Status.InMeeting:
return "error";
}
};
export { returnStatusColor };