Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,19 @@ export function addUser(newUserFromForm) {
return {type: 'ADD_USER', payload: newUserFromApi}

}


export function updateMenu(menu) {
const request = fetch(`http://localhost:5000/api/v1/menus/${menu.id}`, {
method: 'PUT',
headers: new Headers({
'Content-Type': 'application/json'
}),
body: JSON.stringify({menu: menu})
}).then(responseMenu => {
return responseMenu.json()
}).then(updateMenuPayload => {
return updateMenuPayload
})
return {type: 'UPDATE_CAT',request}
}
69 changes: 69 additions & 0 deletions src/components/menus/MenuEdit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React from 'react'
import * as actions from '../../actions'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'

class MenuEdit extends React.Component {

constructor(props){
super(props)
this.newMenuHandler = this.newMenuHandler.bind(this)
}

newMenuHandler(event){
event.preventDefault()
let recipes = this.props.recipes
let checkedRecipes = recipes.filter((recipe) => this.refs[recipe.id].checked )
let idRecipes = checkedRecipes.map((recipe) => (recipe.id))

const newMenu = {
name: this.refs.name.value,
occasion: this.refs.occasion.value,
description: this.refs.description.value,
recipe_ids: idRecipes
}
this.props.actions.addMenu(newMenu)
}

makeRecipes() {
let recipes = this.props.recipes
return recipes.map((recipe) => <div ref={`div${recipe.id}`}> <label>{recipe.name}</label><input type='checkbox' ref={`${recipe.id}`}/> </div>)
}

render(){
return (
<div>
<form onSubmit={this.newMenuHandler}>
<label>name:</label>
<input ref='name' /><br/>
<label>occasion:</label>
<input ref='occasion' /><br/>
<label>description:</label>
<input ref='description' /><br/>
{this.makeRecipes()}
<input type='submit' disabled={this.props.saving}
value={this.props.saving ? 'Saving...' : 'Save'}
className="btn btn-primary"
onClick={this.props.onSave}/>
</form>
</div>
)
}
}


function mapDispatchToProps(dispatch){
return {actions: bindActionCreators(actions, dispatch)}
}

function mapStateToProps(state, ownProps) {
if (state.recipes.length > 0) {
return {recipes: state.recipes}
}
else {
return {recipes: [{name: ''}]}
}
}

const componentCreator = connect(mapStateToProps, mapDispatchToProps)
export default componentCreator(MenuEdit)
173 changes: 134 additions & 39 deletions src/components/menus/MenuShow.js
Original file line number Diff line number Diff line change
@@ -1,76 +1,171 @@
import React from 'react';
import {connect} from 'react-redux';
import MenuCreate from './MenuCreate'
import MenuEdit from './MenuEdit'
import ReduxPromise from 'redux-promise';
import ReduxThunk from 'redux-thunk'
import * as actions from '../../actions'
import { bindActionCreators } from 'redux'


class MenuShow extends React.Component {
constructor(){
super();
constructor(props,context){
super(props,context);
this.state ={
isEditing: false,
menu: this.props.cat,
menuRecipes: this.props.menuRecipes,
checkBoxRecipes: this.props.checkBoxRecipes
};
this.appetizers = this.appetizers.bind(this)
this.mains = this.mains.bind(this)
this.dessert = this.dessert.bind(this)
this.toggleEdit = this.toggleEdit.bind(this)
this.updateMenuState = this.updateMenuState.bind(this)
this.updateMenuRecipes = this.updateMenuRecipes.bind(this);
this.saveMenu = this.saveMenu.bind(this)
}

updateMenuState(event) {
const field = event.target.name;
const menu = this.state.cat;
menu[field] = event.target.value;
return this.setState({menu:menu})
}

updateMenuRecipes(event) {
const menu = this.state.menu;
const recipeId = event.target.value;
const recipe = this.state.checkBoxHobbies.filter(recipe => recipe.id == recipeId)[0];
const checked = !recipe.checked;
recipe['checked'] = !recipe.checked;
if (checked) {
menu.recipe_ids.push(recipe.id);
} else {
menu.recipe_ids.splice(menu.recipe_ids.indexOf(recipe.id));
}
this.setState({menu: menu});

appetizers(){
}
componentWillReceiveProps(nextProps) {
if (this.props.menu.id != nextProps.menu.id) {
this.setState({menu: nextProps.menu});
}
if (this.props.checkBoxRecipes.length < nextProps.checkBoxRecipes.length) {
this.setState({menuRecipes: nextProps.menuRecipes, checkBoxRecipes: nextProps.checkBoxRecipes});
}
}

return this.props.menu.recipes.filter(recipe => recipe.course == 'appetizer').map(recipe => <li>{recipe.name}</li>)
toggleEdit(){
this.setState({
isEditing: !this.state.isEditing
})
}
saveMenu(event) {
event.preventDefault();
this.props.actions.updateMenu(this.state.menu);
}

appetizers(){
return this.props.menu.recipes.filter(recipe => recipe.course == 'appetizer').map(recipe => <li>{recipe.name}</li>)
}
mains(){
mains(){
return this.props.menu.recipes.filter(recipe => recipe.course == 'main').map(recipe => <li>{recipe.name}</li>)
}
dessert(){
return this.props.menu.recipes.filter(recipe => recipe.course == 'dessert').map(recipe => <li>{recipe.name}</li>)
dessert(){
return this.props.menu.recipes.filter(recipe => recipe.course == 'dessert').map(recipe => <li>{recipe.name}</li>)
}

render(){
if (this.state.isEditing) {
return(
<div>
<h1>Edit Menu</h1>
<MenuEdit
menu={this.state.menu}
recipes={this.state.checkBoxRecipes}
onSave={this.saveMenu}
onChange={this.updateMenuState}
onRecipeChange={this.updateMenuRecipes}/>
</div>
)
}
render(){
return(
<div className='center text-center'>
<div className='left-padding'>
<h2>{this.props.menu.name}</h2>
<h5 className='uppercase'> {this.props.menu.occasion} </h5>
<h6 className='uppercase'> {this.props.menu.description}</h6>
<h4>Appetizers</h4>
<ul>
<li>Deviled Eggs</li>
{this.appetizers()}
</ul>
<h4>Mains</h4>
<ul>
<li>Jambalaya</li>
{this.mains()}
return(



<div className='center text-center'>
<div className='left-padding'>
<h2>{this.props.menu.name}</h2>
<h5 className='uppercase'> {this.props.menu.occasion} </h5>
<h6 className='uppercase'> {this.props.menu.description}</h6>
<h4>Appetizers</h4>
<ul>
{this.appetizers()}
</ul>
<h4>Mains</h4>
<ul>
{this.mains()}
</ul>
<h4>Desserts</h4>
<ul>
{this.dessert()}
</ul>
<h4>Desserts</h4>
<ul>
<li>Beignets</li>
{this.dessert()}
</ul>
</div>
<button className='btn' onClick={this.toggleEdit.bind(this)}>Edit this Menu</button>
</div>
</div>
)
)
}
}
function recipesForMenus(recipes,menu=null) {
return recipes.map( recipe => {
if (menu && menu.recipes.filter(recipeId => recipeId.id == recipe.id).length > 0) {
recipe['checked'] = true;
} else {
recipe['checked'] = false;
}
return recipe;
});

}
function collectMenuRecipes(recipes, menu) {
let selected = recipes.map(recipe => {
if (menu.recipes.filter(recipeId => recipeId.id == recipe.id).length > 0) {
return recipe;
}
})
return selected.filter(r => r != undefined)
}

function mapDispatchToProps(dispatch){
return {actions: bindActionCreators(actions, dispatch)}
}
function mapStateToProps(state, ownProps){
console.log('mapStateToProps',state, ownProps);
if (state.menus.length > 0){
const menu = state.menus.find((menu) => {
console.log(state);
const stateRecipes = Object.assign([],state.recipes)
let checkBoxRecipes =[];
let menuRecipes = [];
let menu = {menu: [{name: '', occasion: '', description: '', recipes: [{name: ''}]}]}
if (ownProps.params.id && state.menus.length > 0 && state.recipes.length > 0){
menu = state.menus.find((menu) => {
return menu.id == ownProps.params.id
})
return {menu: menu}
} else {
return {menu: [{name: '', occasion: '', description: '', recipes: [{name: ''}]}]}
}
});
if (menu.recipes.length > 0) {
checkBoxRecipes = recipesForMenus(stateRecipes,menu);
menuRecipes = collectMenuRecipes(stateRecipes,menu);
} else {
checkBoxRecipes = recipesForMenus(stateRecipes)
}
}
return {
menu: menu,
checkBoxRecipes: checkBoxRecipes,
menuRecipes:menuRecipes
};
}





const componentCreator = connect(mapStateToProps,mapDispatchToProps)
export default componentCreator(MenuShow);
3 changes: 3 additions & 0 deletions src/reducers/menus_reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ export default function menusReducer(state=[], action) {
return action.payload;
case 'ADD_MENU':
return [...state, action.payload]
case 'UPDATE_MENU':
return [...state.filter(cat => cat.id !== action.cat.id),
Object.assign({}),action.cat]
default:
return state;
}
Expand Down
3 changes: 3 additions & 0 deletions src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import App from './components/App'
import MenusIndex from './components/menus/MenusIndex'
import MenuCreate from './components/menus/MenuCreate'
import MenuShow from './components/menus/MenuShow'
import MenuEdit from './components/menus/MenuEdit'


import RecipeIndex from './components/recipes/RecipeIndex'
import RecipeCreate from './components/recipes/RecipeCreate'
Expand Down Expand Up @@ -34,6 +36,7 @@ export default(
<Route path='/menus' component={MenusIndex}/>
<Route path='/menus/new' component={MenuCreate} />
<Route path='/menus/:id' component={MenuShow} />
<Route path='/menus/edit' component={MenuEdit} />

<Route path='/ingredients' component={IngredientsIndex}/>
<Route path='/ingredients/new' component={IngredientCreate} />
Expand Down