Add marco display

This commit is contained in:
= 2021-01-24 23:32:34 +01:00
parent d3b1fa03fc
commit 8f72bfdb23
7 changed files with 96 additions and 18 deletions

View File

@ -12,6 +12,8 @@ import {MACRONUTRIENTS, MEALS_LIST} from "utils/mock";
import MacronutrientsChart from "components/MacronutrientsChart"; import MacronutrientsChart from "components/MacronutrientsChart";
import ProductCard from "components/ProductCard"; import ProductCard from "components/ProductCard";
import AddProductToMealDialog from 'components/AddProductToMealDialog'; import AddProductToMealDialog from 'components/AddProductToMealDialog';
import {colors} from "utils/theme";
import RadialChart from "components/RadialChart";
// {/*{*/} // {/*{*/}
@ -20,7 +22,10 @@ import AddProductToMealDialog from 'components/AddProductToMealDialog';
// {/* ))*/} // {/* ))*/}
// {/*}*/} // {/*}*/}
const MealCard = ({ id, label, products }) => { const MealCard = ({ dailyCalories, id, label, products }) => {
const totalCalories = products.reduce((totalCalories, { product: { calories }}) => totalCalories += calories, 0)
const totalProteins = products.reduce((totalProteins, { product: { protein }}) => totalProteins += protein, 0)
const totalFats = products.reduce((totalFats, { product: { fat }}) => totalFats += fat, 0)
return ( return (
<Accordion> <Accordion>
@ -32,7 +37,25 @@ const MealCard = ({ id, label, products }) => {
</Typography> </Typography>
<AddProductToMealDialog mealId={id} mealLabel={label} /> <AddProductToMealDialog mealId={id} mealLabel={label} />
</Grid> </Grid>
<Grid container alignItems="center"> <Grid container alignItems="center" justifyContent="space-between">
<Grid container alignItems="center" justifyContent="center">
<RadialChart progress={(totalCalories/dailyCalories) * 100} width={25} height={25} color={colors.calories} />
<Typography gutterBottom>
{totalCalories} calories
</Typography>
</Grid>
<Grid container alignItems="center" justifyContent="center">
<RadialChart progress={(totalProteins/dailyCalories) * 100} width={25} height={25} color={colors.protein} />
<Typography gutterBottom>
{totalProteins} g
</Typography>
</Grid>
<Grid container alignItems="center" justifyContent="center">
<RadialChart progress={(totalFats/dailyCalories) * 100} width={25} height={25} color={colors.fat} />
<Typography gutterBottom>
{totalFats} g
</Typography>
</Grid>
</Grid> </Grid>
</Grid> </Grid>
</AccordionSummary> </AccordionSummary>
@ -58,6 +81,7 @@ const MealCard = ({ id, label, products }) => {
MealCard.propTypes = { MealCard.propTypes = {
id: PropTypes.string, id: PropTypes.string,
dailyCalories: PropTypes.number.isRequired,
label: PropTypes.string.isRequired, label: PropTypes.string.isRequired,
products: PropTypes.oneOfType([ products: PropTypes.oneOfType([
PropTypes.array, PropTypes.array,

View File

@ -89,6 +89,7 @@ const Scanner = ({ handleClose, setBarcode }) => {
const stop = () => { const stop = () => {
elements.video.pause(); elements.video.pause();
localMediaStream.getTracks()[0].stop(); localMediaStream.getTracks()[0].stop();
elements.video.removeEventListener('canplay', play)
} }
const init = () => { const init = () => {
@ -268,6 +269,7 @@ const Scanner = ({ handleClose, setBarcode }) => {
// output // output
if(quality < config.quality) { if(quality < config.quality) {
const barcode = checkDigit + result.join('') const barcode = checkDigit + result.join('')
console.log(barcode)
setBarcode(barcode) setBarcode(barcode)
onClose() onClose()
} }

View File

@ -64,10 +64,13 @@ export const getMealsAction = ({ date }) => ({
date, date,
}) })
export const getMealsSuccessAction = ({ meals, dailyCalories }) => ({ export const getMealsSuccessAction = ({ meals, dailyCalories, dailyFats, dailyProteins, dailyCarbs }) => ({
type: GET_MEALS_SUCCESS, type: GET_MEALS_SUCCESS,
meals, meals,
dailyCalories, dailyCalories,
dailyFats,
dailyProteins,
dailyCarbs,
}) })
export const getMealsErrorAction = ({ error }) => ({ export const getMealsErrorAction = ({ error }) => ({
@ -96,10 +99,9 @@ export const createMealAction = ({ label, products, date }) => ({
date, date,
}) })
export const createMealSuccessAction = ({ meal, dailyCalories }) => ({ export const createMealSuccessAction = ({ meal }) => ({
type: CREATE_MEAL_SUCCESS, type: CREATE_MEAL_SUCCESS,
meal, meal,
dailyCalories,
}) })
export const createMealErrorAction = ({error}) => ({ export const createMealErrorAction = ({error}) => ({

View File

@ -1,27 +1,32 @@
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import { Container } from '@material-ui/core'; import { Container, Grid, Card, Typography, CardContent } from '@material-ui/core';
import {useDispatch, useSelector} from "react-redux"; import {useDispatch, useSelector} from "react-redux";
import {useInjectSaga, useInjectReducer} from "redux-injectors"; import {useInjectSaga, useInjectReducer} from "redux-injectors";
import {format} from "date-fns"; import {format} from "date-fns";
import RadialChart from 'components/RadialChart'
import { colors } from 'utils/theme'
import saga from "./saga"; import saga from "./saga";
import reducer from "./reducer"; import reducer from "./reducer";
import {makeSelectMeals} from "./selectors"; import {makeSelectMeals, makeSelectDailyCalories, makeSelectCaloriesLeft, makeSelectDailyFats, makeSelectDailyCarbs, makeSelectDailyProteins} from "./selectors";
import { getMealsAction } from './actions' import { getMealsAction } from './actions'
import MealCard from "components/MealCard"; import MealCard from "components/MealCard";
import { createStructuredSelector } from 'reselect' import { createStructuredSelector } from 'reselect'
import BarcodeScanner from 'containers/BarcodeScanner'
const stateSelector = createStructuredSelector({ const stateSelector = createStructuredSelector({
meals: makeSelectMeals() meals: makeSelectMeals(),
dailyCalories: makeSelectDailyCalories(),
caloriesLeft: makeSelectCaloriesLeft(),
dailyFats: makeSelectDailyFats(),
dailyProteins: makeSelectDailyProteins(),
dailyCarbs: makeSelectDailyCarbs(),
}) })
const key = 'homePage' const key = 'homePage'
const HomePage = () => { const HomePage = () => {
useInjectSaga({ key, saga }); useInjectSaga({ key, saga });
useInjectReducer({key, reducer }); useInjectReducer({key, reducer });
const { meals } = useSelector(stateSelector); const { meals, dailyCalories, caloriesLeft } = useSelector(stateSelector);
const dispatch = useDispatch(); const dispatch = useDispatch();
@ -32,8 +37,18 @@ const HomePage = () => {
return ( return (
<Container> <Container>
<Card>
<CardContent>
<Grid container alignItems="center" justifyContent="center">
<RadialChart progress={(caloriesLeft/dailyCalories) * 100} width={50} height={50} color={colors.calories} />
<Typography gutterBottom>
{caloriesLeft} calories left
</Typography>
</Grid>
</CardContent>
</Card>
{meals.map(({ id, products, label }, index) => ( {meals.map(({ id, products, label }, index) => (
<MealCard id={id} label={label} products={products} key={index} /> <MealCard dailyCalories={dailyCalories} id={id} label={label} products={products} key={index} />
))} ))}
</Container> </Container>
); );

View File

@ -52,7 +52,11 @@ export const initialState = {
label: '', label: '',
products: [], products: [],
dailyCalories: 0, dailyCalories: 0,
dailyFats: 0,
dailyProteins: 0,
dailyCarbs: 0,
barcode: '', barcode: '',
caloriesLeft: 0,
product: {}, product: {},
date: '', date: '',
form: { form: {
@ -85,8 +89,17 @@ const homePageReducer = produce((draft, action) => {
.concat(action.meals) .concat(action.meals)
.sort(({ label: aLabel}, { label: bLabel }) => aLabel.localeCompare(bLabel)) .sort(({ label: aLabel}, { label: bLabel }) => aLabel.localeCompare(bLabel))
draft.dailyCalories = action.dailyCalories; draft.dailyCalories = action.dailyCalories;
draft.dailyFats = action.dailyFats;
draft.dailyProteins = action.dailyProteins;
draft.dailyCarbs = action.dailyCarbs;
const total = draft.meals.reduce(
(totalCalories, meal) => totalCalories += meal.products.reduce(
(mealCalories, { product: { calories }}) => mealCalories += calories, 0)
, 0)
draft.isLoading = false; draft.caloriesLeft = draft.dailyCalories - total;
draft.isLoading = false;
break; break;
case SEARCH_PRODUCT_BY_BARCODE_REQUEST: case SEARCH_PRODUCT_BY_BARCODE_REQUEST:
@ -134,7 +147,6 @@ const homePageReducer = produce((draft, action) => {
.concat(action.meal) .concat(action.meal)
.sort( .sort(
({ label: aLabel}, { label: bLabel }) => aLabel.localeCompare(bLabel)) ({ label: aLabel}, { label: bLabel }) => aLabel.localeCompare(bLabel))
draft.dailyCalories = action.dailyCalories;
draft.isLoading = false; draft.isLoading = false;
break; break;

View File

@ -20,8 +20,8 @@ export function* getMeals() {
}; };
try { try {
const {meals, dailyCalories} = yield call(request, requestURL, requestParameters); const {meals, dailyCalories, dailyFats, dailyProteins, dailyCarbs} = yield call(request, requestURL, requestParameters);
yield put(getMealsSuccessAction({ meals, dailyCalories })); yield put(getMealsSuccessAction({ meals, dailyCalories, dailyFats, dailyProteins, dailyCarbs }));
} catch (error) { } catch (error) {
yield put(getMealsErrorAction({ error: error.message })); yield put(getMealsErrorAction({ error: error.message }));
} }
@ -68,8 +68,8 @@ export function* createMeal() {
}; };
try { try {
const {meal, dailyCalories} = yield call(request, requestURL, requestParameters); const meal = yield call(request, requestURL, requestParameters);
yield put(createMealSuccessAction({meal, dailyCalories})); yield put(createMealSuccessAction({meal}));
yield put(push(routes.dashboard.path)); yield put(push(routes.dashboard.path));
} catch (error) { } catch (error) {
yield put(createMealErrorAction({error: error.message})); yield put(createMealErrorAction({error: error.message}));
@ -104,6 +104,8 @@ export function* searchProductByBarcode() {
const requestURL = `${api.products}?barcode=${barcode}`; const requestURL = `${api.products}?barcode=${barcode}`;
console.log(`${api.products}?barcode=${barcode}`)
const requestParameters = { const requestParameters = {
method: 'GET', method: 'GET',
headers: { headers: {

View File

@ -36,8 +36,29 @@ const makeSelectMealId = () =>
const makeSelectFormProducts = () => const makeSelectFormProducts = () =>
createSelector(selectHomePageDomain, (substate) => substate.form.products); createSelector(selectHomePageDomain, (substate) => substate.form.products);
const makeSelectDailyCalories = () =>
createSelector(selectHomePageDomain, (substate) => substate.dailyCalories);
const makeSelectDailyCarbs = () =>
createSelector(selectHomePageDomain, (substate) => substate.dailyCarbs);
const makeSelectDailyFats = () =>
createSelector(selectHomePageDomain, (substate) => substate.dailyFats);
const makeSelectDailyProteins = () =>
createSelector(selectHomePageDomain, (substate) => substate.dailyProteins);
const makeSelectCaloriesLeft = () =>
createSelector(selectHomePageDomain, (substate) => substate.caloriesLeft);
export { export {
selectHomePageDomain, selectHomePageDomain,
makeSelectDailyProteins,
makeSelectDailyCarbs,
makeSelectDailyFats,
makeSelectCaloriesLeft,
makeSelectDailyCalories,
makeSelectFormProducts, makeSelectFormProducts,
makeSelectMealLabel, makeSelectMealLabel,
makeSelectMealId, makeSelectMealId,