Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save josecarneiro/f6576b4aadd62b0e1f394203daa1da6a to your computer and use it in GitHub Desktop.
Save josecarneiro/f6576b4aadd62b0e1f394203daa1da6a to your computer and use it in GitHub Desktop.
import React from 'react';
import meals from './foods.json';
class MealBox extends React.Component {
state = {
quantity: 1,
};
handleQuantityChange = (event) => {
const { value } = event.target;
// const value = event.target.value;
// const value = event.target.valueAsNumber;
this.setState({
quantity: Number(value),
});
};
handleFormSubmission = (event) => {
event.preventDefault();
const { quantity } = this.state;
const { meal } = this.props;
this.props.onAddToTodaysMeals(meal, quantity);
};
render() {
const meal = this.props.meal;
return (
<div className="media">
<img
src={meal.image}
className="img-thumbnail mr-3 mw-25 border-0"
style={{ maxWidth: '10em' }}
alt={meal.name}
/>
<div className="media-body align-self-center">
<h5 className="mt-0 mb-1">{meal.name}</h5>
<small>{meal.calories} cal</small>
</div>
<form
className="row align-self-center"
onSubmit={this.handleFormSubmission}
>
<input
className="form-control col-9"
type="number"
onChange={this.handleQuantityChange}
value={this.state.quantity}
/>
<button className="btn btn-primary col-3">+</button>
</form>
</div>
);
}
}
class AddNewMealForm extends React.Component {
state = {
name: '',
calories: 0,
image: '',
};
handleInputChange = (event) => {
// const { value, name } = event.target;
// this.setState({
// [name]: value,
// });
const value = event.target.value;
const placeholder = event.target.name;
this.setState({
[placeholder]: value,
});
};
handleFormSubmission = (event) => {
event.preventDefault();
// const { name, calories, image } = this.state;
// const meal = { name, calories, image };
const meal = {
name: this.state.name,
calories: this.state.calories,
image: this.state.image,
};
this.props.onAddNewMeal(meal);
};
render() {
return (
<form onSubmit={this.handleFormSubmission}>
<label htmlFor="name-input">Meal Name</label>
<input
id="name-input"
type="text"
placeholder="Name"
name="name"
required
onChange={this.handleInputChange}
value={this.state.name}
/>
<label htmlFor="calories-input">Number of Calories</label>
<input
id="calories-input"
type="number"
placeholder="Calories"
name="calories"
required
onChange={this.handleInputChange}
value={this.state.calories}
/>
<label htmlFor="image-input">Image</label>
<input
id="image-input"
type="text"
placeholder="Image"
name="image"
required
onChange={this.handleInputChange}
value={this.state.image}
/>
<button>Confirm Meal</button>
</form>
);
}
}
const Search = (props) => {
const handleInputChange = (event) => {
props.onQueryChange(event.target.value);
};
return (
<input
type="text"
placeholder="Search for any meal..."
value={props.query}
onChange={handleInputChange}
/>
);
};
const TodaysMealsList = ({ meals }) => {
const total = meals.reduce(
(sum, meal) => sum + meal.calories * meal.quantity,
0
);
return (
<div>
<ul>
{meals.map((meal) => (
<li>
{meal.quantity} - {meal.name} = {meal.calories * meal.quantity}{' '}
calories
</li>
))}
</ul>
<span>Total: {total} calories</span>
</div>
);
};
class App extends React.Component {
state = {
addNewMealActive: false,
meals: meals,
searchQuery: '',
todaysMeals: [],
};
handleMealAddition = (meal) => {
this.setState({
meals: [meal, ...this.state.meals],
addNewMealActive: false,
});
};
openAddNewMealForm = () => {
this.setState({
addNewMealActive: true,
});
};
handleQueryChange = (query) => {
this.setState({
searchQuery: query,
});
};
handleTodaysMealsAddition = (meal, quantity) => {
const { todaysMeals } = this.state;
const existingMealInList = todaysMeals.find(
(todaysMeal) => todaysMeal.name === meal.name
);
if (existingMealInList) {
const replacerMeal = {
...meal,
quantity: quantity + existingMealInList.quantity,
};
const cloneTodaysMeals = [...todaysMeals];
const indexOfExistentMeal = todaysMeals.indexOf(existingMealInList);
cloneTodaysMeals.splice(indexOfExistentMeal, 1, replacerMeal);
this.setState({
todaysMeals: cloneTodaysMeals,
});
} else {
this.setState({
todaysMeals: [...this.state.todaysMeals, { ...meal, quantity }],
});
}
};
render() {
const filteredMeals = this.state.meals.filter((meal) => {
if (!this.state.searchQuery) {
return true;
} else {
return meal.name
.toLowerCase()
.includes(this.state.searchQuery.toLowerCase());
}
});
return (
<div className="App">
<Search
query={this.state.searchQuery}
onQueryChange={this.handleQueryChange}
/>
{(this.state.addNewMealActive && (
<AddNewMealForm onAddNewMeal={this.handleMealAddition} />
)) || <button onClick={this.openAddNewMealForm}>Add new meal</button>}
{filteredMeals.map((meal) => (
<MealBox
key={meal.name}
meal={meal}
onAddToTodaysMeals={this.handleTodaysMealsAddition}
/>
))}
<TodaysMealsList meals={this.state.todaysMeals} />
</div>
);
}
}
export default App;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment