contacts page first draft done
This commit is contained in:
parent
abeede8d82
commit
d21dda7719
28
src/components/contacts/Body.tsx
Normal file
28
src/components/contacts/Body.tsx
Normal 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;
|
||||||
@ -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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
55
src/components/contacts/LowerBody.tsx
Normal file
55
src/components/contacts/LowerBody.tsx
Normal 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;
|
||||||
@ -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>
|
||||||
|
|||||||
70
src/components/contacts/UpperBody.tsx
Normal file
70
src/components/contacts/UpperBody.tsx
Normal 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;
|
||||||
18
src/components/contacts/Utils.tsx
Normal file
18
src/components/contacts/Utils.tsx
Normal 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 };
|
||||||
Reference in New Issue
Block a user