From 18cb89e9f79ff2814b0abac57ad0fa4e7b758064 Mon Sep 17 00:00:00 2001 From: Skander Hatira <skander.hatira@inrae.fr> Date: Wed, 24 Feb 2021 21:10:52 +0100 Subject: [PATCH] Added DashLayout and working on different views for reports and runs --- src/components/Tableau/Chart.js | 66 +++++++++ src/components/Tableau/DashLayout.js | 210 +++++++++++++++++++++++++++ src/components/Tableau/Default.js | 40 +++++ src/components/Tableau/Deposits.js | 35 +++++ src/components/Tableau/Orders.js | 103 +++++++++++++ src/components/Tableau/Title.js | 15 ++ src/components/Tableau/listItems.js | 70 +++++++++ 7 files changed, 539 insertions(+) create mode 100644 src/components/Tableau/Chart.js create mode 100644 src/components/Tableau/DashLayout.js create mode 100644 src/components/Tableau/Default.js create mode 100644 src/components/Tableau/Deposits.js create mode 100644 src/components/Tableau/Orders.js create mode 100644 src/components/Tableau/Title.js create mode 100644 src/components/Tableau/listItems.js diff --git a/src/components/Tableau/Chart.js b/src/components/Tableau/Chart.js new file mode 100644 index 0000000..6117863 --- /dev/null +++ b/src/components/Tableau/Chart.js @@ -0,0 +1,66 @@ +import React from "react"; +import { useTheme } from "@material-ui/core/styles"; +import { + LineChart, + Line, + XAxis, + YAxis, + Label, + ResponsiveContainer, +} from "recharts"; +import Title from "./Title"; + +// Generate Sales Data +function createData(time, amount) { + return { time, amount }; +} + +const data = [ + createData("00:00", 0), + createData("03:00", 300), + createData("06:00", 600), + createData("09:00", 800), + createData("12:00", 1500), + createData("15:00", 2000), + createData("18:00", 2400), + createData("21:00", 2400), + createData("24:00", undefined), +]; + +export default function Chart() { + const theme = useTheme(); + + return ( + <React.Fragment> + <Title>Today</Title> + <ResponsiveContainer> + <LineChart + data={data} + margin={{ + top: 16, + right: 16, + bottom: 0, + left: 24, + }} + > + <XAxis dataKey="time" stroke={theme.palette.text.secondary} /> + <YAxis stroke={theme.palette.text.secondary}> + <Label + angle={270} + position="left" + style={{ textAnchor: "middle", fill: theme.palette.text.primary }} + > + Sales ($) + </Label> + </YAxis> + <Line + type="monotone" + dataKey="amount" + stroke={theme.palette.primary.main} + dot={false} + /> + </LineChart> + </ResponsiveContainer> + </React.Fragment> + ); +} diff --git a/src/components/Tableau/DashLayout.js b/src/components/Tableau/DashLayout.js new file mode 100644 index 0000000..bbebc26 --- /dev/null +++ b/src/components/Tableau/DashLayout.js @@ -0,0 +1,210 @@ +import React from "react"; +import CssBaseline from "@material-ui/core/CssBaseline"; +import Drawer from "@material-ui/core/Drawer"; +import AppBar from "@material-ui/core/AppBar"; +import Toolbar from "@material-ui/core/Toolbar"; +import List from "@material-ui/core/List"; +import Typography from "@material-ui/core/Typography"; +import Divider from "@material-ui/core/Divider"; +import IconButton from "@material-ui/core/IconButton"; +import Badge from "@material-ui/core/Badge"; +import MenuIcon from "@material-ui/icons/Menu"; +import ChevronLeftIcon from "@material-ui/icons/ChevronLeft"; +import NotificationsIcon from "@material-ui/icons/Notifications"; +import ExitToAppIcon from "@material-ui/icons/ExitToApp"; +import { mainListItems, secondaryListItems } from "./listItems"; +import { useAuth } from "../../hooks/useAuth"; +import { makeStyles } from "@material-ui/core/styles"; +import clsx from "clsx"; +import Link from "@material-ui/core/Link"; + +const drawerWidth = 240; + +const useStyles = makeStyles((theme) => ({ + root: { + display: "flex", + }, + toolbar: { + paddingRight: 24, // keep right padding when drawer closed + }, + toolbarIcon: { + display: "flex", + alignItems: "center", + justifyContent: "flex-end", + padding: "0 8px", + ...theme.mixins.toolbar, + }, + appBar: { + zIndex: theme.zIndex.drawer + 1, + transition: theme.transitions.create(["width", "margin"], { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.leavingScreen, + }), + }, + appBarShift: { + marginLeft: drawerWidth, + width: `calc(100% - ${drawerWidth}px)`, + transition: theme.transitions.create(["width", "margin"], { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.enteringScreen, + }), + }, + menuButton: { + marginRight: 36, + }, + menuButtonHidden: { + display: "none", + }, + title: { + flexGrow: 1, + }, + drawerPaper: { + position: "relative", + whiteSpace: "nowrap", + width: drawerWidth, + transition: theme.transitions.create("width", { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.enteringScreen, + }), + }, + drawerPaperClose: { + overflowX: "hidden", + transition: theme.transitions.create("width", { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.leavingScreen, + }), + width: theme.spacing(7), + [theme.breakpoints.up("sm")]: { + width: theme.spacing(9), + }, + }, + appBarSpacer: theme.mixins.toolbar, + content: { + flexGrow: 1, + height: "100vh", + overflow: "auto", + }, + container: { + paddingTop: theme.spacing(4), + paddingBottom: theme.spacing(4), + }, + paper: { + padding: theme.spacing(2), + display: "flex", + overflow: "auto", + flexDirection: "column", + }, + fixedHeight: { + height: 240, + }, +})); +function Copyright() { + return ( + <Typography variant="body2" color="textSecondary" align="center"> + {"Copyright ┬й "} + <Link color="inherit" href="https://material-ui.com/"> + Your Website + </Link>{" "} + {new Date().getFullYear()} + {"."} + </Typography> + ); +} +const DashLayout = ({ Filling }) => { + const classes = useStyles(); + + const fixedHeightPaper = clsx(classes.paper, classes.fixedHeight); + const auth = useAuth(); + const [open, setOpen] = React.useState(true); + const handleDrawerOpen = () => { + setOpen(true); + }; + const handleDrawerClose = () => { + setOpen(false); + }; + + return ( + <div className={classes.root}> + <CssBaseline /> + <AppBar + position="fixed" + className={clsx(classes.appBar, open && classes.appBarShift)} + > + <Toolbar className={classes.toolbar}> + <IconButton + edge="start" + color="inherit" + aria-label="open drawer" + onClick={handleDrawerOpen} + className={clsx( + classes.menuButton, + open && classes.menuButtonHidden + )} + > + <MenuIcon /> + </IconButton> + <Typography + component="h1" + variant="h6" + color="inherit" + noWrap + className={classes.title} + > + Dashboard + </Typography> + + {auth.user.isAuthenticated ? ( + <> + <IconButton color="inherit"> + <Badge badgeContent={4} color="secondary"> + <NotificationsIcon /> + </Badge> + </IconButton> + <IconButton color="inherit"> + <Typography + component="h1" + variant="h6" + color="inherit" + onClick={auth.signout} + noWrap + className={classes.title} + > + Logout + </Typography> + <ExitToAppIcon onClick={auth.signout} /> + </IconButton> + </> + ) : ( + "" + )} + </Toolbar> + </AppBar> + <Drawer + variant="permanent" + classes={{ + paper: clsx(classes.drawerPaper, !open && classes.drawerPaperClose), + }} + open={open} + > + <div className={classes.toolbarIcon}> + <IconButton onClick={handleDrawerClose}> + <ChevronLeftIcon /> + </IconButton> + </div> + <Divider /> + <List>{mainListItems}</List> + <Divider /> + <List>{secondaryListItems}</List> + </Drawer> + <main className={classes.content}> + <div className={classes.appBarSpacer} /> + <Filling + Copyright={Copyright} + classes={classes} + fixedHeightPaper={fixedHeightPaper} + /> + </main> + </div> + ); +}; +export default DashLayout; diff --git a/src/components/Tableau/Default.js b/src/components/Tableau/Default.js new file mode 100644 index 0000000..9b66fa6 --- /dev/null +++ b/src/components/Tableau/Default.js @@ -0,0 +1,40 @@ +import React from "react"; +import Chart from "./Chart"; +import Deposits from "./Deposits"; +import Orders from "./Orders"; +import Container from "@material-ui/core/Container"; +import Grid from "@material-ui/core/Grid"; +import Paper from "@material-ui/core/Paper"; +import Box from "@material-ui/core/Box"; + +const Default = ({ Copyright, classes, fixedHeightPaper }) => { + return ( + <Container maxWidth="lg" className={classes.container}> + <Grid container spacing={3}> + {/* Chart */} + <Grid item xs={12} md={8} lg={9}> + <Paper className={fixedHeightPaper}> + <Chart /> + </Paper> + </Grid> + {/* Recent Deposits */} + <Grid item xs={12} md={4} lg={3}> + <Paper className={fixedHeightPaper}> + <Deposits /> + </Paper> + </Grid> + {/* Recent Orders */} + <Grid item xs={12}> + <Paper className={classes.paper}> + <Orders /> + </Paper> + </Grid> + </Grid> + <Box pt={4}> + <Copyright /> + </Box> + </Container> + ); +}; + +export default Default; diff --git a/src/components/Tableau/Deposits.js b/src/components/Tableau/Deposits.js new file mode 100644 index 0000000..18bf978 --- /dev/null +++ b/src/components/Tableau/Deposits.js @@ -0,0 +1,35 @@ +import React from "react"; +import Link from "@material-ui/core/Link"; +import { makeStyles } from "@material-ui/core/styles"; +import Typography from "@material-ui/core/Typography"; +import Title from "./Title"; + +function preventDefault(event) { + event.preventDefault(); +} + +const useStyles = makeStyles({ + depositContext: { + flex: 1, + }, +}); + +export default function Deposits() { + const classes = useStyles(); + return ( + <React.Fragment> + <Title>Recent Deposits</Title> + <Typography component="p" variant="h4"> + $3,024.00 + </Typography> + <Typography color="textSecondary" className={classes.depositContext}> + on 15 March, 2019 + </Typography> + <div> + <Link color="primary" href="#" onClick={preventDefault}> + View balance + </Link> + </div> + </React.Fragment> + ); +} diff --git a/src/components/Tableau/Orders.js b/src/components/Tableau/Orders.js new file mode 100644 index 0000000..eb546a3 --- /dev/null +++ b/src/components/Tableau/Orders.js @@ -0,0 +1,103 @@ +import React from "react"; +import Link from "@material-ui/core/Link"; +import { makeStyles } from "@material-ui/core/styles"; +import Table from "@material-ui/core/Table"; +import TableBody from "@material-ui/core/TableBody"; +import TableCell from "@material-ui/core/TableCell"; +import TableHead from "@material-ui/core/TableHead"; +import TableRow from "@material-ui/core/TableRow"; +import Title from "./Title"; + +// Generate Order Data +function createData(id, date, name, shipTo, paymentMethod, amount) { + return { id, date, name, shipTo, paymentMethod, amount }; +} + +const rows = [ + createData( + 0, + "16 Mar, 2019", + "Elvis Presley", + "Tupelo, MS", + "VISA таАтАвтАвтАвтАв 3719", + 312.44 + ), + createData( + 1, + "16 Mar, 2019", + "Paul McCartney", + "London, UK", + "VISA таАтАвтАвтАвтАв 2574", + 866.99 + ), + createData( + 2, + "16 Mar, 2019", + "Tom Scholz", + "Boston, MA", + "MC таАтАвтАвтАвтАв 1253", + 100.81 + ), + createData( + 3, + "16 Mar, 2019", + "Michael Jackson", + "Gary, IN", + "AMEX таАтАвтАвтАвтАв 2000", + 654.39 + ), + createData( + 4, + "15 Mar, 2019", + "Bruce Springsteen", + "Long Branch, NJ", + "VISA таАтАвтАвтАвтАв 5919", + 212.79 + ), +]; + +function preventDefault(event) { + event.preventDefault(); +} + +const useStyles = makeStyles((theme) => ({ + seeMore: { + marginTop: theme.spacing(3), + }, +})); + +export default function Orders() { + const classes = useStyles(); + return ( + <React.Fragment> + <Title>Recent Orders</Title> + <Table size="small"> + <TableHead> + <TableRow> + <TableCell>Date</TableCell> + <TableCell>Name</TableCell> + <TableCell>Ship To</TableCell> + <TableCell>Payment Method</TableCell> + <TableCell align="right">Sale Amount</TableCell> + </TableRow> + </TableHead> + <TableBody> + {rows.map((row) => ( + <TableRow key={row.id}> + <TableCell>{row.date}</TableCell> + <TableCell>{row.name}</TableCell> + <TableCell>{row.shipTo}</TableCell> + <TableCell>{row.paymentMethod}</TableCell> + <TableCell align="right">{row.amount}</TableCell> + </TableRow> + ))} + </TableBody> + </Table> + <div className={classes.seeMore}> + <Link color="primary" href="#" onClick={preventDefault}> + See more orders + </Link> + </div> + </React.Fragment> + ); +} diff --git a/src/components/Tableau/Title.js b/src/components/Tableau/Title.js new file mode 100644 index 0000000..ea3c222 --- /dev/null +++ b/src/components/Tableau/Title.js @@ -0,0 +1,15 @@ +import React from "react"; +import PropTypes from "prop-types"; +import Typography from "@material-ui/core/Typography"; + +export default function Title(props) { + return ( + <Typography component="h2" variant="h6" color="primary" gutterBottom> + {props.children} + </Typography> + ); +} + +Title.propTypes = { + children: PropTypes.node, +}; diff --git a/src/components/Tableau/listItems.js b/src/components/Tableau/listItems.js new file mode 100644 index 0000000..acc5675 --- /dev/null +++ b/src/components/Tableau/listItems.js @@ -0,0 +1,70 @@ +import React from "react"; +import ListItem from "@material-ui/core/ListItem"; +import ListItemIcon from "@material-ui/core/ListItemIcon"; +import ListItemText from "@material-ui/core/ListItemText"; +import ListSubheader from "@material-ui/core/ListSubheader"; +import DashboardIcon from "@material-ui/icons/Dashboard"; +import ShoppingCartIcon from "@material-ui/icons/ShoppingCart"; +import PeopleIcon from "@material-ui/icons/People"; +import BarChartIcon from "@material-ui/icons/BarChart"; +import LayersIcon from "@material-ui/icons/Layers"; +import AssignmentIcon from "@material-ui/icons/Assignment"; + +export const mainListItems = ( + <div> + <ListItem button> + <ListItemIcon> + <DashboardIcon /> + </ListItemIcon> + <ListItemText primary="Dashboard" /> + </ListItem> + <ListItem button> + <ListItemIcon> + <ShoppingCartIcon /> + </ListItemIcon> + <ListItemText primary="Orders" /> + </ListItem> + <ListItem button> + <ListItemIcon> + <PeopleIcon /> + </ListItemIcon> + <ListItemText primary="Customers" /> + </ListItem> + <ListItem button> + <ListItemIcon> + <BarChartIcon /> + </ListItemIcon> + <ListItemText primary="Reports" /> + </ListItem> + <ListItem button> + <ListItemIcon> + <LayersIcon /> + </ListItemIcon> + <ListItemText primary="Integrations" /> + </ListItem> + </div> +); + +export const secondaryListItems = ( + <div> + <ListSubheader inset>Saved reports</ListSubheader> + <ListItem button> + <ListItemIcon> + <AssignmentIcon /> + </ListItemIcon> + <ListItemText primary="Current month" /> + </ListItem> + <ListItem button> + <ListItemIcon> + <AssignmentIcon /> + </ListItemIcon> + <ListItemText primary="Last quarter" /> + </ListItem> + <ListItem button> + <ListItemIcon> + <AssignmentIcon /> + </ListItemIcon> + <ListItemText primary="Year-end sale" /> + </ListItem> + </div> +); -- GitLab