This commit is contained in:
= 2021-01-24 21:23:52 +01:00
parent 8191799760
commit d3b1fa03fc
10 changed files with 88 additions and 125 deletions

View File

@ -1,71 +0,0 @@
import React, { useState } from 'react';
import {Dialog, DialogTitle, Tooltip, DialogContent, Grid, Typography, TextField, DialogContentText, DialogActions, IconButton, Button} from "@material-ui/core";
import InputField from "components/InputField";
import {Edit as EditIcon, VerifiedUserTwoTone as VerifiedUserIcon, EcoTwoTone as EcoIcon} from "@material-ui/icons";
const ProductLabel = ({ label, eco, verified }) => {
return (
<DialogTitle>
<Grid container alignItems="center">
{label}
{verified && (
<Tooltip title="Verified product">
<VerifiedUserIcon fontSize="small" color="primary" />
</Tooltip>
)}
{eco && (
<Tooltip title="Eco product">
<EcoIcon color="primary" />
</Tooltip>
)}
</Grid>
</DialogTitle>
)
}
const EditProductDialog = () => {
const [isDialogOpen, setIsDialogOpen] = useState(false)
const handleOpenDialog = () => {
setIsDialogOpen(true)
}
const handleCloseDialog = () => {
setIsDialogOpen(false)
}
return (
<React.Fragment>
<IconButton variant="outlined" color="primary" onClick={handleOpenDialog}>
<EditIcon />
</IconButton>
<Dialog open={isDialogOpen} onClose={handleCloseDialog}>
<ProductLabel label={"eggs"} eco={true} verified={true}/>
<DialogContent>
<DialogContentText>
To subscribe to this website, please enter your email address here. We will send updates
occasionally.
</DialogContentText>
<TextField
autoFocus
margin="dense"
id="name"
label="Email Address"
type="email"
fullWidth
/>
</DialogContent>
<DialogActions>
<Button onClick={handleCloseDialog} color="secondary">
Discard
</Button>
<Button onClick={handleCloseDialog} variant="contained" color="primary">
Save
</Button>
</DialogActions>
</Dialog>
</React.Fragment>
);
}
export default EditProductDialog;

View File

@ -41,6 +41,7 @@ const MealCard = ({ id, label, products }) => {
<List>
{products.map(({ _id, product, quantity, unit }) => (
<ProductCard
mealId={id}
id={_id}
product={product}
quantity={quantity}

View File

@ -2,11 +2,13 @@ import {ListItem, ListItemText, ListItemSecondaryAction, IconButton} from "@mate
import PropTypes from 'prop-types'
import React from "react";
import MacronutrientsDetails from "components/MacronutrientsDetails";
import EditProductDialog from "components/EditProductDialog";
import {Delete as DeleteIcon} from "@material-ui/icons";
import ProductLabel from 'components/ProductLabel'
import {useDispatch } from 'react-redux'
import {removeProductFromMealAction} from 'pages/Home/actions'
const ProductCard = ({ id, product, quantity, unit }) => {
const ProductCard = ({ mealId, id, product, quantity, unit }) => {
const dispatch = useDispatch()
const { label, calories, eco, verified } = product
@ -20,6 +22,10 @@ const ProductCard = ({ id, product, quantity, unit }) => {
return (calories / 100) * quantity
}
const removeProductFormMeal = () => {
dispatch(removeProductFromMealAction({ mealId, id }))
}
return (
<ListItem>
<ListItemText
@ -28,8 +34,7 @@ const ProductCard = ({ id, product, quantity, unit }) => {
secondary={`calories: ${calculateCalories()}`}
/>
<ListItemSecondaryAction>
<EditProductDialog />
<IconButton onClick={() => alert('remove')}>
<IconButton onClick={removeProductFormMeal}>
<DeleteIcon />
</IconButton>
</ListItemSecondaryAction>

View File

@ -1,10 +1,10 @@
import React, {useEffect, useState} from 'react';
import {Paper, IconButton} from "@material-ui/core";
import { Close as CloseIcon } from '@material-ui/icons'
import PropTypes from 'prop-types'
import useStyles from "./styles";
const Barcode = ({ isScannerOpen, handleClose }) => {
const [decodecBarcode, setDecodedBarcode] = useState('');
const Scanner = ({ handleClose, setBarcode }) => {
const classes = useStyles()
const onClose = () => {
@ -268,7 +268,7 @@ const Barcode = ({ isScannerOpen, handleClose }) => {
// output
if(quality < config.quality) {
const barcode = checkDigit + result.join('')
setDecodedBarcode(barcode)
setBarcode(barcode)
onClose()
}
@ -319,4 +319,9 @@ const Barcode = ({ isScannerOpen, handleClose }) => {
);
}
export default Barcode;
Scanner.propTypes ={
handleClose: PropTypes.func.isRequired,
setBarcode: PropTypes.func.isRequired,
}
export default Scanner;

View File

@ -1,10 +1,14 @@
import React, {useState} from 'react';
import React, {useState, useEffect} from 'react';
import {IconButton} from "@material-ui/core";
import {CropFree as CropFreeIcon} from '@material-ui/icons'
import Barcode from './Barcode'
import Scanner from './Scanner'
import { useDispatch } from 'react-redux'
import {searchProductByBarcodeAction} from 'pages/Home/actions'
const BarcodeScanner = () => {
const [isScannerOpen, setIsScannerOpen] = useState(false)
const [barcode, setBarcode] = useState('')
const dispatch = useDispatch()
const handleOpen = () => {
setIsScannerOpen(true)
@ -13,13 +17,20 @@ const BarcodeScanner = () => {
const handleClose = () => {
setIsScannerOpen(false)
}
useEffect(() => {
if (barcode) {
dispatch(searchProductByBarcodeAction({ barcode }))
}
}, [barcode])
return (
<React.Fragment>
<IconButton onClick={handleOpen}>
<CropFreeIcon />
</IconButton>
{isScannerOpen ? (
<Barcode isScannerOpen={isScannerOpen} handleClose={handleClose} />
<Scanner handleClose={handleClose} setBarcode={setBarcode} />
) : null}
</React.Fragment>
);

View File

@ -1,7 +1,6 @@
import React from 'react';
import {Paper, InputBase, FormLabel, ListItemSecondaryAction, ListItem, ListItemText, List, FormControl, FormGroup, FormControlLabel, Divider, Checkbox, Grid, Typography, FilledInput , DialogContentText, DialogActions, IconButton, Button} from "@material-ui/core";
import { CropFree as CropFreeIcon, Search as SearchIcon } from '@material-ui/icons'
import EditProductDialog from 'components/EditProductDialog'
import useStyles from './styles'
function generate(element) {

View File

@ -17,6 +17,9 @@ import {
SEARCH_PRODUCT_BY_BARCODE_ERROR,
SEARCH_PRODUCT_BY_LABEL_SUCCESS,
SEARCH_PRODUCT_BY_LABEL_ERROR,
REMOVE_PRODUCT_FROM_MEAL_REQUEST,
REMOVE_PRODUCT_FROM_MEAL_SUCCESS,
REMOVE_PRODUCT_FROM_MEAL_ERROR,
SET_SELECTED_MEAL,
} from './constants';
@ -61,9 +64,10 @@ export const getMealsAction = ({ date }) => ({
date,
})
export const getMealsSuccessAction = ({ meals }) => ({
export const getMealsSuccessAction = ({ meals, dailyCalories }) => ({
type: GET_MEALS_SUCCESS,
meals
meals,
dailyCalories,
})
export const getMealsErrorAction = ({ error }) => ({
@ -92,12 +96,10 @@ export const createMealAction = ({ label, products, date }) => ({
date,
})
export const createMealSuccessAction = ({ id, label, products, date }) => ({
export const createMealSuccessAction = ({ meal, dailyCalories }) => ({
type: CREATE_MEAL_SUCCESS,
id,
label,
products,
date,
meal,
dailyCalories,
})
export const createMealErrorAction = ({error}) => ({
@ -120,3 +122,19 @@ export const addProductsToMealErrorAction = ({error}) => ({
type: ADD_PRODUCTS_TO_MEAL_ERROR,
error,
})
export const removeProductFromMealAction = ({ mealId, id }) => ({
type: REMOVE_PRODUCT_FROM_MEAL_REQUEST,
mealId,
id
})
export const removeProductFromMealSuccessAction = ({ meal }) => ({
type: REMOVE_PRODUCT_FROM_MEAL_SUCCESS,
meal,
})
export const removeProductFromMealErrorAction = ({error}) => ({
type: REMOVE_PRODUCT_FROM_MEAL_ERROR,
error,
})

View File

@ -14,6 +14,10 @@ export const ADD_PRODUCTS_TO_MEAL_REQUEST = 'app/HomePage/ADD_PRODUCTS_TO_MEAL_R
export const ADD_PRODUCTS_TO_MEAL_SUCCESS = 'app/HomePage/ADD_PRODUCTS_TO_MEAL_SUCCESS';
export const ADD_PRODUCTS_TO_MEAL_ERROR = 'app/HomePage/ADD_PRODUCTS_TO_MEAL_ERROR';
export const REMOVE_PRODUCT_FROM_MEAL_REQUEST = 'app/HomePage/REMOVE_PRODUCT_FROM_MEAL_REQUEST'
export const REMOVE_PRODUCT_FROM_MEAL_SUCCESS = 'app/HomePage/REMOVE_PRODUCT_FROM_MEAL_SUCCESS';
export const REMOVE_PRODUCT_FROM_MEAL_ERROR = 'app/HomePage/REMOVE_PRODUCT_FROM_MEAL_ERROR';
export const SEARCH_PRODUCT_BY_LABEL_REQUEST = 'app/HomePage/SEARCH_PRODUCT_BY_LABEL_REQUEST'
export const SEARCH_PRODUCT_BY_LABEL_SUCCESS = 'app/HomePage/SEARCH_PRODUCT_BY_LABEL_SUCCESS';
export const SEARCH_PRODUCT_BY_LABEL_ERROR = 'app/HomePage/SEARCH_PRODUCT_BY_LABEL_ERROR';

View File

@ -25,37 +25,22 @@ import {
const defaultMeals = [
{
id: null,
label: 'Breakfast',
label: 'breakfast',
products: [],
},
{
id: null,
label: 'Snack I',
label: 'lunch',
products: [],
},
{
id: null,
label: 'Lunch',
label: 'dinner',
products: [],
},
{
id: null,
label: 'Snack II',
products: [],
},
{
id: null,
label: 'Dinner',
products: [],
},
{
id: null,
label: 'Snack III',
products: [],
},
{
id: null,
label: 'Supper',
label: 'supper',
products: [],
},
]
@ -66,6 +51,7 @@ export const initialState = {
error: {},
label: '',
products: [],
dailyCalories: 0,
barcode: '',
product: {},
date: '',
@ -93,10 +79,12 @@ const homePageReducer = produce((draft, action) => {
break;
case GET_MEALS_SUCCESS:
draft.meals =
action.meals.length > 0
? action.meals
: defaultMeals;
const labels = action.meals.map(({ label }) => label)
draft.meals = defaultMeals
.filter((candidate) => !labels.includes(candidate.label))
.concat(action.meals)
.sort(({ label: aLabel}, { label: bLabel }) => aLabel.localeCompare(bLabel))
draft.dailyCalories = action.dailyCalories;
draft.isLoading = false;
break;
@ -132,18 +120,21 @@ const homePageReducer = produce((draft, action) => {
break;
case ADD_PRODUCTS_TO_MEAL_SUCCESS:
console.log(ADD_PRODUCTS_TO_MEAL_SUCCESS, 'ADD_PRODUCTS_TO_MEAL_SUCCESS')
const restMeals = draft.meals.filter(({ id }) => id === action.meal.id)
draft.meals = [...restMeals, action.meal]
draft.meals = defaultMeals
.filter((candidate) => !(candidate.label === action.meal.label))
.concat(action.meal)
.sort(
({ label: aLabel}, { label: bLabel }) => aLabel.localeCompare(bLabel))
draft.isLoading = false;
break;
case CREATE_MEAL_SUCCESS:
const { id, label, products, date } = action
draft.meals.push({ id, label, products, date });
draft.meals = defaultMeals
.filter((candidate) => !(candidate.label === action.meal.label))
.concat(action.meal)
.sort(
({ label: aLabel}, { label: bLabel }) => aLabel.localeCompare(bLabel))
draft.dailyCalories = action.dailyCalories;
draft.isLoading = false;
break;

View File

@ -20,8 +20,8 @@ export function* getMeals() {
};
try {
const meals = yield call(request, requestURL, requestParameters);
yield put(getMealsSuccessAction({ meals }));
const {meals, dailyCalories} = yield call(request, requestURL, requestParameters);
yield put(getMealsSuccessAction({ meals, dailyCalories }));
} catch (error) {
yield put(getMealsErrorAction({ error: error.message }));
}
@ -68,8 +68,8 @@ export function* createMeal() {
};
try {
const meal = yield call(request, requestURL, requestParameters);
yield put(createMealSuccessAction(meal));
const {meal, dailyCalories} = yield call(request, requestURL, requestParameters);
yield put(createMealSuccessAction({meal, dailyCalories}));
yield put(push(routes.dashboard.path));
} catch (error) {
yield put(createMealErrorAction({error: error.message}));