diff --git a/src/components/Home/Home.js b/src/components/Home/Home.js index 1cc202baa..ad17c0f8a 100644 --- a/src/components/Home/Home.js +++ b/src/components/Home/Home.js @@ -19,9 +19,14 @@ import { DashStatVerifiedCaptures, } from '../DashStat.container'; import GreenStandSvgLogo from '../images/GreenStandSvgLogo'; -import GrowerReportingCard from '../ReportingCards'; +import ReportingCard1 from '../reportingCards/ReportingCard1'; +import ReportingCard2 from '../reportingCards/ReportingCard2'; +import ReportingCard3 from '../reportingCards/ReportingCard3'; +import ReportingCard4 from '../reportingCards/ReportingCard4'; +import ReportingCard5 from '../reportingCards/ReportingCard5'; import MenuItem from '@material-ui/core/MenuItem'; import MenuMui from '@material-ui/core/Menu'; +import moment from 'moment'; /** * @function @@ -41,12 +46,32 @@ function Home(props) { document.title = `${documentTitle}`; }, []); + // the time range + const timeRange = [ + { range: 30, text: 'Last Month' }, + { range: 30 * 60, text: 'Last 6 Months' }, + { range: 356, text: 'Last Year' }, + { range: 356 * 50, text: 'All' }, + ]; + const [timeRangeIndex, setTimeRangeIndex] = React.useState(0); + const [startDate, setStartDate] = React.useState( + moment() + .add(-1 * timeRange[timeRangeIndex], 'day') + .format('YYYY-MM-DD'), + ); + const [endDate, setEndDate] = React.useState(moment().format('YYYY-MM-DD')); const handleTimeClick = (event) => { setAnchorEl(event.currentTarget); }; - const handleTimeClose = () => { + const handleTimeClose = (index) => { setAnchorEl(null); + setTimeRangeIndex(index); + setStartDate( + moment() + .add(-1 * timeRange[index].range, 'day') + .format('YYYY-MM-DD'), + ); }; return ( @@ -75,7 +100,9 @@ function Home(props) { className={classes.timeButton} > - Last month + + {timeRange[timeRangeIndex].text} + - Last month - Last two month - Last six month - Last year + {timeRange.map((item, index) => ( + handleTimeClose(index)}> + {timeRange[index].text} + + ))} @@ -114,16 +142,19 @@ function Home(props) { ]) && } - + + + + - + - + - + diff --git a/src/components/ReportingCards.js b/src/components/ReportingCards.js deleted file mode 100644 index f0cdfe2f6..000000000 --- a/src/components/ReportingCards.js +++ /dev/null @@ -1,203 +0,0 @@ -/* - * The reporting card components - */ -import { - Box, - Grid, - Card, - Modal, - Typography, - Avatar, - Button, -} from '@material-ui/core'; -import { withStyles } from '@material-ui/styles'; -import React from 'react'; -import ArrayIcon from '@material-ui/icons/ArrowForward'; -import theme from './common/theme'; -import PeopleOutlineIcon from '@material-ui/icons/PeopleOutline'; -import log from 'loglevel'; -import * as d3 from 'd3'; - -console.error('color:', theme.palette.stats.green); -console.error( - 'color2:', - d3.color(theme.palette.stats.green).brighter().toString(), -); -//use material ui withStyles to style the component -const style = (theme) => ({ - root: { - margin: theme.spacing(2.5), - borderRadius: 10, - backgroundColor: 'white', - padding: theme.spacing(4, 6), - }, - title: { - fontStyle: 'normal', - fontWeight: 'bold', - fontSize: '16px', - lineHeight: '24px', - }, - box2: { - marginTop: theme.spacing(4), - display: 'flex', - }, - avatar: { - width: theme.spacing(20), - height: theme.spacing(20), - }, - box3: { - display: 'flex', - flexDirection: 'column', - justifyContent: 'center', - marginLeft: theme.spacing(4), - }, - total: { - fontWeight: 'bold', - fontSize: '24px', - lineHeight: '24px', - }, - totalText: { - fontWeight: 'normal', - fontSize: '12px', - lineHeight: '16px', - color: '#585B5D', - }, - box4: { - display: 'flex', - justifyContent: 'space-between', - fontWeight: 'normal', - fontSize: '16px', - lineHeight: '24px', - marginTop: theme.spacing(2), - }, - box1: { - marginTop: theme.spacing(4), - display: 'flex', - justifyContent: 'flex-start', - alignItems: 'center', - color: '#c6c4c4', - }, - icon: { - width: theme.spacing(4), - height: theme.spacing(4), - }, - seeMore: { - marginLeft: theme.spacing(2), - }, - iconTotal: { - fontSize: '48px', - color: theme.palette.stats.green, - }, - iconTotalBox: { - width: theme.spacing(20), - height: theme.spacing(20), - backgroundColor: d3 - .color(theme.palette.stats.green) - .copy({ opacity: 0.15 }) - .toString(), - borderRadius: '50%', - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - }, - modal: { - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - }, - card: { - maxWidth: '80%', - minWidth: 400, - minHeight: 600, - maxHeight: 600, - overflow: 'auto', - }, -}); - -function GrowerReportingCard(props) { - const { classes } = props; - const [open, setOpen] = React.useState(false); - - function handleSeeMore() { - log.log('see more'); - setOpen(true); - } - - return ( - <> - - Grower - - - - - - 785 - total - - - - - CAN SL - 56 - - - CAN SL - 56 - - - CAN SL - 56 - - - - - - - setOpen(false)} - className={classes.modal} - > - - - Grower - - - - - - 785 - total - - - - - CAN SL - 56 - - - CAN SL - 56 - - - CAN SL - 56 - - {Array.from(new Array(20)).map((_, i) => ( - - CAN SL - 56 - - ))} - - - - - ); -} - -//export the component -export default withStyles(style)(GrowerReportingCard); diff --git a/src/components/reportingCards/ReportingCard.hook.js b/src/components/reportingCards/ReportingCard.hook.js new file mode 100644 index 000000000..a323f4b09 --- /dev/null +++ b/src/components/reportingCards/ReportingCard.hook.js @@ -0,0 +1,37 @@ +import React from 'react'; +import axios from 'axios'; +import log from 'loglevel'; + +export default function useLoadData( + startDate, + endDate, + field1, + field2, + getNum1 = (e) => e.total, +) { + const [data, setData] = React.useState(undefined); + + async function load(baseUrl, startDate, endDate) { + const res = await axios.get( + `${baseUrl}?${ + startDate ? 'capture_created_start_date=' + startDate : '' + }&${endDate ? 'capture_created_end_date=' + endDate : ''}`, + ); + const { data } = res; + log.warn('load data: ', data); + setData({ + num1: getNum1(data[field1]), + top: data[field1][field2].map((p) => ({ + name: p.name, + num: p.number, + })), + }); + } + + React.useEffect(() => { + setData(undefined); + load('http://47.91.14.192:3006/capture/statistics', startDate, endDate); + }, [startDate, endDate]); + + return data; +} diff --git a/src/components/reportingCards/ReportingCard.js b/src/components/reportingCards/ReportingCard.js new file mode 100644 index 000000000..ebe7ccb0d --- /dev/null +++ b/src/components/reportingCards/ReportingCard.js @@ -0,0 +1,227 @@ +/* + * The reporting card components + */ +import { + Box, + Grid, + Card, + Modal, + Typography, + Avatar, + Button, +} from '@material-ui/core'; +import { withStyles } from '@material-ui/styles'; +import React from 'react'; +import ArrayIcon from '@material-ui/icons/ArrowForward'; +import theme from '../common/theme'; +import log from 'loglevel'; +import * as d3 from 'd3'; +import Skeleton from '@material-ui/lab/Skeleton'; + +console.error('color:', theme.palette.stats.green); +console.error( + 'color2:', + d3.color(theme.palette.stats.green).brighter().toString(), +); +//use material ui withStyles to style the component +const style = (theme) => ({ + root: { + margin: theme.spacing(2.5), + borderRadius: 10, + backgroundColor: 'white', + padding: theme.spacing(4, 6), + minHeight: theme.spacing(74), + display: 'flex', + flexDirection: 'column', + justifyContent: 'space-between', + }, + title: { + fontStyle: 'normal', + fontWeight: 'bold', + fontSize: '16px', + lineHeight: '24px', + }, + box2: { + marginTop: theme.spacing(4), + display: 'flex', + }, + avatar: { + width: theme.spacing(20), + height: theme.spacing(20), + }, + box3: { + display: 'flex', + flexGrow: 1, + flexDirection: 'column', + justifyContent: 'center', + marginLeft: theme.spacing(4), + }, + total: { + fontWeight: 'bold', + fontSize: '24px', + lineHeight: '24px', + }, + totalText: { + fontWeight: 'normal', + fontSize: '12px', + lineHeight: '16px', + color: '#585B5D', + }, + box4: { + display: 'flex', + justifyContent: 'space-between', + fontWeight: 'normal', + fontSize: '16px', + lineHeight: '24px', + marginTop: theme.spacing(2), + }, + box1: { + width: '100%', + marginTop: theme.spacing(4), + display: 'flex', + justifyContent: 'flex-start', + alignItems: 'center', + color: '#c6c4c4', + }, + icon: { + width: theme.spacing(4), + height: theme.spacing(4), + }, + seeMore: { + marginLeft: theme.spacing(2), + }, + iconTotal: { + fontSize: '48px', + color: theme.palette.stats.green, + }, + iconTotalBox: { + width: theme.spacing(20), + height: theme.spacing(20), + backgroundColor: d3 + .color(theme.palette.stats.green) + .copy({ opacity: 0.15 }) + .toString(), + borderRadius: '50%', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + }, + modal: { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + }, + card: { + maxWidth: '80%', + minWidth: 400, + minHeight: 600, + maxHeight: 600, + overflow: 'auto', + }, +}); + +function GrowerReportingCard(props) { + const { classes, data, text, color, icon } = props; + const [open, setOpen] = React.useState(false); + + const Icon = icon; + + function handleSeeMore() { + log.log('see more'); + setOpen(true); + } + + log.warn('icon', icon); + + return ( + <> + + + {text.title} + + + + + + + {data ? data.num1 : } + + + {text.text1} + + + + + {data ? ( + data.top.slice(0, 3).map((item, i) => ( + + {item.name} + {item.num} + + )) + ) : ( + <> + + + + + )} + + + {data ? ( + <> + + + + ) : ( + + )} + + + {data && ( + setOpen(false)} + className={classes.modal} + > + + + {text.title} + + + + + + {data.num1} + + {text.text1} + + + + + {data.top.map((item, i) => ( + + {item.name} + {item.num} + + ))} + + + + )} + + ); +} + +//export the component +export default withStyles(style)(GrowerReportingCard); diff --git a/src/components/reportingCards/ReportingCard1.js b/src/components/reportingCards/ReportingCard1.js new file mode 100644 index 000000000..941a50fa6 --- /dev/null +++ b/src/components/reportingCards/ReportingCard1.js @@ -0,0 +1,23 @@ +import React from 'react'; +import ReportingCard from './ReportingCard'; +import log from 'loglevel'; +import useLoadData from './ReportingCard.hook'; +import PeopleOutlineIcon from '@material-ui/icons/PeopleOutline'; + +export default function ReportingCard1(props) { + const { startDate, endDate } = props; + + const data = useLoadData(startDate, endDate, 'planters', 'planters'); + + return ( + + ); +} diff --git a/src/components/reportingCards/ReportingCard2.js b/src/components/reportingCards/ReportingCard2.js new file mode 100644 index 000000000..5654d355c --- /dev/null +++ b/src/components/reportingCards/ReportingCard2.js @@ -0,0 +1,23 @@ +import React from 'react'; +import ReportingCard from './ReportingCard'; +import log from 'loglevel'; +import useLoadData from './ReportingCard.hook'; +import PhotoCameraIcon from '@material-ui/icons/PhotoCamera'; + +export default function ReportingCard2(props) { + const { startDate, endDate } = props; + + const data = useLoadData(startDate, endDate, 'captures', 'captures'); + + return ( + + ); +} diff --git a/src/components/reportingCards/ReportingCard3.js b/src/components/reportingCards/ReportingCard3.js new file mode 100644 index 000000000..ae8ed7163 --- /dev/null +++ b/src/components/reportingCards/ReportingCard3.js @@ -0,0 +1,28 @@ +import React from 'react'; +import ReportingCard from './ReportingCard'; +import log from 'loglevel'; +import useLoadData from './ReportingCard.hook'; +import Icon from '@material-ui/icons/LiveHelp'; + +export default function component(props) { + const { startDate, endDate } = props; + + const data = useLoadData( + startDate, + endDate, + 'unverified_captures', + 'unverified_captures', + ); + + return ( + + ); +} diff --git a/src/components/reportingCards/ReportingCard4.js b/src/components/reportingCards/ReportingCard4.js new file mode 100644 index 000000000..2a4c4a489 --- /dev/null +++ b/src/components/reportingCards/ReportingCard4.js @@ -0,0 +1,29 @@ +import React from 'react'; +import ReportingCard from './ReportingCard'; +import log from 'loglevel'; +import useLoadData from './ReportingCard.hook'; +import Icon from '@material-ui/icons/Flag'; + +export default function component(props) { + const { startDate, endDate } = props; + + const data = useLoadData( + startDate, + endDate, + 'top_planters', + 'top_planters', + (data) => data.average, + ); + + return ( + + ); +} diff --git a/src/components/reportingCards/ReportingCard5.js b/src/components/reportingCards/ReportingCard5.js new file mode 100644 index 000000000..25de222ba --- /dev/null +++ b/src/components/reportingCards/ReportingCard5.js @@ -0,0 +1,23 @@ +import React from 'react'; +import ReportingCard from './ReportingCard'; +import log from 'loglevel'; +import useLoadData from './ReportingCard.hook'; +import Icon from '@material-ui/icons/Eco'; + +export default function component(props) { + const { startDate, endDate } = props; + + const data = useLoadData(startDate, endDate, 'species', 'species'); + + return ( + + ); +}