Add marco display
This commit is contained in:
parent
d3b1fa03fc
commit
8f72bfdb23
@ -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,
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
@ -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}) => ({
|
||||||
|
@ -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>
|
||||||
);
|
);
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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: {
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user