ReactJS Recipe Box

In this example below you will see how to do a ReactJS Recipe Box with some HTML / CSS and Javascript

Thumbnail
This awesome code was written by captnstarburst, you can see more from this user in the personal repository.
You can find the original code on Codepen.io
Copyright captnstarburst ©

Technologies

  • HTML
  • CSS
  • JavaScript
<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  <title>ReactJS Recipe Box</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">

<link href="https://fonts.googleapis.com/css?family=Spirax" rel="stylesheet">
  
  <link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css'>
<link rel='stylesheet prefetch' href='http://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css'>

      <link rel="stylesheet" href="css/style.css">

  
</head>

<body>

   
  <div id="root"></div>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-dom.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/js/bootstrap.min.js'></script>

  

    <script  src="js/index.js"></script>




</body>

</html>

/*Downloaded from https://www.codeseek.co/captnstarburst/reactjs-recipe-box-NdYjBY */
body {
  background: #914b22;
  padding-top: 5%;
}

.header {
  font-family: 'Spirax', cursive;
  padding-bottom: 2%;
}

.recipe-thumbnail {
  width: 100%;
  background: black;
  height: 100%;
  cursor: pointer;
}

.btn-row {
  padding: 2%;
}

.btn {
  margin: 1%;
  cursor: pointer;
}

.close-x {
  margin: -40px 0 0;
  border-radius: 25%;
  cursor: pointer;
}

.directions {
  height: 200px;
  width: 100%;
  overflow: auto;
  background-color: black;
  color: white;
  scrollbar-base-color: gold;
  font-family: sans-serif;
  padding: 50px;
}

.view-recipe {
  border: 5px solid black;
  border-radius: 5%;
}

.img-recipe {
  width: 100%;
}

.delete-x {
  position: absolute;
}

textArea {
  width: 75%;
  height: 75%;
}

.warning-message {
  color: red;
}

/* Modal Header */
.modal-header {
  padding: 2px 16px;
  background-color: #5cb85c;
  color: white;
}

/* Modal Body */
.modal-body {
  padding: 2px 16px;
}

/* Modal Footer */
.modal-footer {
  padding: 2px 16px;
  background-color: #5cb85c;
  color: white;
}

/* Modal Content */
.modal-content {
  position: absolute;
  background-color: #fefefe;
  margin: auto;
  z-index: 1;
  padding: 0;
  border: 1px solid #888;
  width: 80%;
  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
  -webkit-animation-name: animatetop;
  -webkit-animation-duration: 0.9s;
  animation-name: animatetop;
  animation-duration: 0.9s;
}

/* Add Animation */
@-webkit-keyframes animatetop {
  from {
    top: -300px;
    opacity: 0;
  }
  to {
    top: 0;
    opacity: 1;
  }
}
@keyframes animatetop {
  from {
    top: -300px;
    opacity: 0;
  }
  to {
    top: 0;
    opacity: 1;
  }
}


/*Downloaded from https://www.codeseek.co/captnstarburst/reactjs-recipe-box-NdYjBY */
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var recipes = {
	titles: ["Green Chile Chicken Enchiladas", "Green Chile Chicken Stew", "Sopapillas"],
	images: ["https://s-media-cache-ak0.pinimg.com/originals/dc/3d/12/dc3d12b9162baaa1b03d2b751eca26d3.jpg", "https://cookdiary.net/wp-content/uploads/images/Green-Chile-Stew.jpg", "https://www.moms-mexican-recipes.com/wp-content/uploads/2017/05/New-Mexican-Sopaipillas-Recipe.jpg"],
	ingredients: [["Chicken", "Green Chile", "Cheese", "Green Enchilada Sauce", "Corn Tortillas", "Potatoes", "Seasoning"], ["Chicken", "Green Chile", "Chicken Broth", "Corn", "Navy Beans", "Potatoes"], ["Flour", "Lard", "Milk", "Vegetable Oil"]],
	directions: ["Season the raw chicken breast and bake in the oven at 350 degerees for 40 minutes. Clean and dice the potatoes and fry in a pan til golden brown, after cooked; drain, season with salt, pepper, and garlic. Very lightly fry the corn tortillas and place on a paper towel and pat dry. In a square baking pan pour a small amount of the enchilada sauce in the bottom. Place the frozen or canned green chile in small sauce pan on low heat until thawed and excess moisture has evaportated. In a large bowl mix together the potatoes, green chile, and shredded chicken. Roll the corn tortillas with the contents of the large bowl and place the rolled tortillas in the square baking pan, repeat until either pan is full or the bowl is empty. Empty the remainder of the enchilada sauce atop of the rolled corn torillas and cover with cheese. Bake at 425 for 30 minutes or until cheese is golden brown", "In a large pot combine the chicken broth, raw chicken, and green chile. Set on medium-high range, cover and boil for 30 minutes. Remove the cooked chicken shred and place back into the pot. Clean and chop the potatoes and add to the stew, boil for another 30 minutes. Clean the beans and corn and place into the stew, allow to boil for 10 minutes and enjoy.", "Mix the flour, lard, and small amount of water into a dough. Allow the dough to rest and rise for one hour. Heat at least one inch of vegetable oil in a large pot to 350 degrees. Roll the dough and cut into small one inch or greater triangles. Cook the dough in the hot oil, flipping when neccessary. The dough will expand outwards quickly, puffing out. Fry until golden brown. Place on paper towel to cool and dry. Fill the fryed sopapillas with honey or taco meat"]
};

if (window.localStorage) {
	if (window.localStorage.FCCRecipes) {
		recipes = JSON.parse(window.localStorage.getItem('FCCRecipes'));
	}
}

function setStorage(titleArr, imgArr, ingredientArr, directionsArr) {

	recipes.titles = titleArr;
	recipes.images = imgArr;
	recipes.ingredients = ingredientArr;
	recipes.directions = directionsArr;

	window.localStorage.setItem('FCCRecipes', JSON.stringify(recipes));
}

var Header = function Header() {
	return React.createElement(
		"div",
		{ className: "row" },
		React.createElement(
			"div",
			{ className: "col" },
			React.createElement(
				"h1",
				{ className: "header text-center" },
				"Recipe App",
				React.createElement(
					"small",
					null,
					" built with Reactjs"
				)
			)
		)
	);
};

var Footer = function Footer() {
	return React.createElement(
		"div",
		{ className: "row" },
		React.createElement(
			"div",
			{ className: "col text-center" },
			React.createElement(
				"p",
				null,
				"Coded By",
				" ",
				React.createElement(
					"a",
					{ href: "https://www.conorhinchee.com", target: "_blank" },
					" Conor Hinchee "
				)
			)
		)
	);
};

var Confirm = function (_React$Component) {
	_inherits(Confirm, _React$Component);

	function Confirm() {
		_classCallCheck(this, Confirm);

		return _possibleConstructorReturn(this, (Confirm.__proto__ || Object.getPrototypeOf(Confirm)).apply(this, arguments));
	}

	_createClass(Confirm, [{
		key: "render",
		value: function render() {
			return React.createElement(
				"div",
				{ className: "modal-content" },
				React.createElement(
					"div",
					{ className: "modal-header" },
					React.createElement(
						"span",
						{ className: "close", onClick: this.props.keep },
						"\xD7"
					),
					React.createElement(
						"h2",
						null,
						"Permanently Delete?"
					)
				),
				React.createElement(
					"div",
					{ className: "modal-body" },
					React.createElement(
						"p",
						null,
						"Are you sure you want to delete this recipe?"
					),
					React.createElement(
						"p",
						null,
						"Proceeding will permanently delete the recipe..."
					)
				),
				React.createElement(
					"div",
					{ className: "modal-footer" },
					React.createElement(
						"button",
						{ className: "btn btn-danger", onClick: this.props.remove },
						"Delete it"
					),
					React.createElement(
						"button",
						{ className: "btn btn-secondary", onClick: this.props.keep },
						"Keep it"
					)
				)
			);
		}
	}]);

	return Confirm;
}(React.Component);

var ViewAll = function (_React$Component2) {
	_inherits(ViewAll, _React$Component2);

	function ViewAll() {
		_classCallCheck(this, ViewAll);

		var _this2 = _possibleConstructorReturn(this, (ViewAll.__proto__ || Object.getPrototypeOf(ViewAll)).call(this));

		_this2.state = {
			deleteAllMount: false,
			deleteConfirmMount: false,
			markedForDeletion: ""
		};
		return _this2;
	}

	_createClass(ViewAll, [{
		key: "onDeleteARecipe",
		value: function onDeleteARecipe() {
			this.setState({
				deleteAllMount: !this.state.deleteAllMount
			});
		}
	}, {
		key: "onDeleteModal",
		value: function onDeleteModal(selection) {
			this.setState({
				markedForDeletion: selection.target.id,
				deleteConfirmMount: !this.state.deleteConfirmMount
			});
		}
	}, {
		key: "onKeepIt",
		value: function onKeepIt() {
			this.setState({
				deleteConfirmMount: !this.state.deleteConfirmMount,
				deleteAllMount: !this.state.deleteAllMount
			});
		}
	}, {
		key: "removeARecipe",
		value: function removeARecipe() {
			this.props.delete(this.state.markedForDeletion);
			this.setState({
				deleteConfirmMount: !this.state.deleteConfirmMount,
				deleteAllMount: !this.state.deleteAllMount
			});
		}
	}, {
		key: "render",
		value: function render() {
			var _this3 = this;

			var thumbnails = "";

			var headers = this.props.titles.map(function (key) {
				return React.createElement(
					"div",
					{ className: "col-4 text-center" },
					React.createElement(
						"h4",
						null,
						key
					)
				);
			});

			if (this.state.deleteAllMount) {
				thumbnails = this.props.images.map(function (key) {
					return React.createElement(
						"div",
						{ className: "col-4" },
						React.createElement(
							"button",
							{
								role: "close",
								className: "delete-x",
								id: key,
								onClick: _this3.onDeleteModal.bind(_this3)
							},
							"\u2716"
						),
						React.createElement("img", { src: key, className: "img img-fluid img-thumbnail recipe-thumbnail" })
					);
				});
			} else {
				thumbnails = this.props.images.map(function (key) {
					return React.createElement(
						"div",
						{ className: "col-4" },
						React.createElement("img", {
							src: key,
							className: "img img-fluid img-thumbnail recipe-thumbnail",
							onClick: _this3.props.view.bind(_this3)
						})
					);
				});
			}

			var p = 0,
			    n = 3;

			var body = [];

			do {
				body.push(React.createElement(
					"div",
					null,
					React.createElement(
						"div",
						{ className: "row" },
						headers.slice(p, n)
					),
					React.createElement(
						"div",
						{ className: "row" },
						thumbnails.slice(p, n)
					)
				));

				p = n;
				n += 3;
			} while (p < headers.length);

			return React.createElement(
				"div",
				null,
				this.state.deleteConfirmMount ? React.createElement(Confirm, {
					keep: this.onKeepIt.bind(this),
					remove: this.removeARecipe.bind(this)
				}) : null,
				body,
				React.createElement(
					"div",
					{ className: "row btn-row" },
					React.createElement(
						"div",
						{ className: "col text-center" },
						React.createElement(
							"button",
							{ className: "btn btn-primary", onClick: this.props.add },
							"Add A Recipe"
						),
						React.createElement(
							"button",
							{
								className: "btn btn-danger",
								onClick: this.onDeleteARecipe.bind(this)
							},
							"Delete A Recipe"
						)
					)
				)
			);
		}
	}]);

	return ViewAll;
}(React.Component);

var ViewRecipe = function (_React$Component3) {
	_inherits(ViewRecipe, _React$Component3);

	function ViewRecipe() {
		_classCallCheck(this, ViewRecipe);

		var _this4 = _possibleConstructorReturn(this, (ViewRecipe.__proto__ || Object.getPrototypeOf(ViewRecipe)).call(this));

		_this4.state = {
			confirmDeleteMount: false,
			editRecipeMount: false,
			markedForDeletion: ""
		};
		return _this4;
	}

	_createClass(ViewRecipe, [{
		key: "confirmDelete",
		value: function confirmDelete() {
			this.setState({
				confirmDeleteMount: !this.state.confirmDeleteMount,
				markedForDeletion: this.props.imgSrc
			});
		}
	}, {
		key: "onKeepIt",
		value: function onKeepIt() {
			this.setState({
				confirmDeleteMount: !this.state.confirmDeleteMount
			});
		}
	}, {
		key: "removeRecipe",
		value: function removeRecipe() {
			this.props.delete(this.state.markedForDeletion);
			this.setState({
				deleteConfirmMount: !this.state.deleteConfirmMount
			});
		}
	}, {
		key: "onEditRecipe",
		value: function onEditRecipe() {
			this.setState({
				editRecipeMount: !this.state.editRecipeMount
			});
		}
	}, {
		key: "onCancelChange",
		value: function onCancelChange() {
			this.setState({
				editRecipeMount: !this.state.editRecipeMount
			});
		}
	}, {
		key: "onSaveChange",
		value: function onSaveChange(indexImg, newTitle, newImg, newIngredients, newDirections) {

			this.props.update(indexImg, newTitle, newImg, newIngredients, newDirections);
			this.setState({
				editRecipeMount: !this.state.editRecipeMount
			});
		}
	}, {
		key: "render",
		value: function render() {
			var list = this.props.ingredients.map(function (key) {
				return React.createElement(
					"li",
					null,
					key
				);
			});
			var body = "";

			if (!this.state.editRecipeMount) {
				body = React.createElement(
					"div",
					null,
					React.createElement(
						"div",
						{ className: "row pull-right" },
						React.createElement(
							"h3",
							{ className: "close-x", onClick: this.props.goBack },
							"\u2716"
						)
					),
					React.createElement(
						"div",
						{ className: "row" },
						React.createElement(
							"div",
							{ className: "col" },
							React.createElement(
								"h2",
								{ className: "text-center" },
								this.props.name
							)
						)
					),
					this.state.confirmDeleteMount ? React.createElement(Confirm, {
						keep: this.onKeepIt.bind(this),
						remove: this.removeRecipe.bind(this)
					}) : null,
					React.createElement("hr", null),
					React.createElement(
						"div",
						{ className: "row" },
						React.createElement(
							"div",
							{ className: "col-4" },
							React.createElement("img", { src: this.props.imgSrc, className: "img img-fluid img-thumbnail" })
						),
						React.createElement(
							"div",
							{ className: "col-8" },
							React.createElement(
								"h4",
								{ className: "text-center" },
								"Ingredients"
							),
							React.createElement(
								"ol",
								null,
								list
							)
						)
					),
					React.createElement("hr", null),
					React.createElement(
						"div",
						{ className: "row" },
						React.createElement(
							"div",
							{ className: "col" },
							React.createElement(
								"h4",
								{ className: "text-center" },
								"Directions"
							),
							React.createElement(
								"div",
								{ className: "directions" },
								this.props.directions
							)
						)
					),
					React.createElement(
						"div",
						{ className: "row" },
						React.createElement(
							"div",
							{ className: "col text-center" },
							React.createElement(
								"div",
								{ className: "btn-grp" },
								React.createElement(
									"button",
									{
										className: "btn btn-secondary",
										onClick: this.onEditRecipe.bind(this)
									},
									"Edit This Recipe"
								),
								React.createElement(
									"button",
									{
										className: "btn btn-danger",
										onClick: this.confirmDelete.bind(this)
									},
									"Delete this Recipe"
								)
							)
						)
					)
				);
			} else {
				body = React.createElement(
					"div",
					null,
					React.createElement(EditRecipe, {
						title: this.props.name,
						image: this.props.imgSrc,
						ingredients: this.props.ingredients,
						directions: this.props.directions,
						cancel: this.onCancelChange.bind(this),
						update: this.onSaveChange.bind(this)
					})
				);
			}

			return React.createElement(
				"div",
				null,
				body
			);
		}
	}]);

	return ViewRecipe;
}(React.Component);

var AddRecipe = function (_React$Component4) {
	_inherits(AddRecipe, _React$Component4);

	function AddRecipe() {
		_classCallCheck(this, AddRecipe);

		var _this5 = _possibleConstructorReturn(this, (AddRecipe.__proto__ || Object.getPrototypeOf(AddRecipe)).call(this));

		_this5.state = {
			title: "TITLE",
			imgSrc: "https://tchxlease.co.uk/wp-content/uploads/2015/05/no-image-image.png",
			enterImg: "Image Source",
			ingredients: ["1st", "2nd", "3rd"],
			directions: "Lorem empsum, bla bla bla",
			validUrl: false
		};
		return _this5;
	}

	_createClass(AddRecipe, [{
		key: "onTitleChange",
		value: function onTitleChange(event) {
			this.setState({
				title: event.target.value
			});
		}
	}, {
		key: "onSourceChange",
		value: function onSourceChange(event) {
			var expression = /[-a-zA-Z0-9@:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?/gi;
			var regex = new RegExp(expression);

			this.setState({
				enterImg: event.target.value
			});

			if (event.target.value.match(regex)) {
				this.setState({
					imgSrc: event.target.value,
					validUrl: true
				});
			}
		}
	}, {
		key: "onAddIngredientList",
		value: function onAddIngredientList() {
			var currentLength = this.state.ingredients.length;

			var nextLength = currentLength + 1;

			var nth = nextLength.toString() + "th";

			this.setState({
				ingredients: this.state.ingredients.concat(nth)
			});
		}
	}, {
		key: "onRemoveIngredientList",
		value: function onRemoveIngredientList(event) {
			var arr = this.state.ingredients;

			arr.pop();
			this.setState({
				ingredients: arr
			});
		}
	}, {
		key: "onIngredientChange",
		value: function onIngredientChange(event) {
			var id = event.target.id;

			var arr = this.state.ingredients;

			arr[id] = event.target.value;

			this.setState({
				ingredient: arr
			});
		}
	}, {
		key: "onDirectionsChange",
		value: function onDirectionsChange(event) {
			this.setState({
				directions: event.target.value
			});
		}
	}, {
		key: "render",
		value: function render() {
			var _this6 = this;

			var list = this.state.ingredients.map(function (key, idx) {
				return React.createElement(
					"li",
					null,
					key,
					React.createElement("input", { value: key, id: idx, onChange: _this6.onIngredientChange.bind(_this6) })
				);
			});
			return React.createElement(
				"div",
				null,
				React.createElement(
					"div",
					{ className: "row pull-right" },
					React.createElement(
						"h3",
						{ className: "close-x", onClick: this.props.cancel },
						"\u2716"
					)
				),
				React.createElement(
					"div",
					{ className: "row" },
					React.createElement(
						"div",
						{ className: "col text-center" },
						React.createElement(
							"h2",
							null,
							this.state.title
						),
						React.createElement("input", {
							type: "text",
							value: this.state.title,
							onChange: function onChange() {
								return _this6.onTitleChange(event);
							}
						})
					)
				),
				React.createElement("hr", null),
				React.createElement(
					"div",
					{ className: "row" },
					React.createElement(
						"div",
						{ className: "col-4" },
						React.createElement("img", { src: this.state.imgSrc, className: "img img-fluid img-thumbnail" })
					),
					React.createElement(
						"div",
						{ className: "col-8" },
						!this.state.validUrl ? React.createElement(
							"p",
							{ className: "warning-message" },
							"Not a valid url"
						) : null,
						React.createElement("input", {
							type: "text",
							value: this.state.enterImg,
							onChange: function onChange() {
								return _this6.onSourceChange(event);
							}
						}),
						React.createElement(
							"h4",
							{ className: "text-center" },
							"Ingredients"
						),
						React.createElement(
							"ol",
							null,
							list
						),
						React.createElement(
							"button",
							{
								className: "btn btn-primary",
								onClick: this.onAddIngredientList.bind(this)
							},
							"Add Ingredient"
						),
						React.createElement(
							"button",
							{
								className: "btn btn-warning",
								onClick: this.onRemoveIngredientList.bind(this)
							},
							"Remove Ingredient"
						)
					)
				),
				React.createElement("hr", null),
				React.createElement(
					"div",
					{ className: "row" },
					React.createElement(
						"div",
						{ className: "col text-center" },
						React.createElement(
							"h4",
							{ className: "" },
							"Directions"
						),
						React.createElement("textarea", {
							type: "text",
							value: this.state.directions,
							onChange: this.onDirectionsChange.bind(this)
						})
					)
				),
				React.createElement(
					"div",
					{ className: "row" },
					React.createElement(
						"div",
						{ className: "col text-center" },
						React.createElement(
							"div",
							{ className: "btn-grp" },
							React.createElement(
								"button",
								{ className: "btn btn-secondary", onClick: this.props.cancel },
								"Cancel",
								" "
							),
							React.createElement(
								"button",
								{
									className: "btn btn-primary",
									onClick: function onClick() {
										return _this6.props.save(_this6.state.title, _this6.state.imgSrc, _this6.state.ingredients, _this6.state.directions);
									}
								},
								"Save"
							)
						)
					)
				)
			);
		}
	}]);

	return AddRecipe;
}(React.Component);

var EditRecipe = function (_React$Component5) {
	_inherits(EditRecipe, _React$Component5);

	function EditRecipe(props) {
		_classCallCheck(this, EditRecipe);

		var _this7 = _possibleConstructorReturn(this, (EditRecipe.__proto__ || Object.getPrototypeOf(EditRecipe)).call(this));

		_this7.state = {
			title: props.title,
			imgSrc: props.image,
			enteredImage: props.image,
			imgIndex: props.image,
			invalidImage: "https://tchxlease.co.uk/wp-content/uploads/2015/05/no-image-image.png",
			ingredients: props.ingredients,
			directions: props.directions,
			validUrl: true
		};
		return _this7;
	}

	_createClass(EditRecipe, [{
		key: "onTitleChange",
		value: function onTitleChange(event) {
			this.setState({
				title: event.target.value
			});
		}
	}, {
		key: "onSourceChange",
		value: function onSourceChange(event) {
			var expression = /[-a-zA-Z0-9@:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?/gi;
			var regex = new RegExp(expression);

			this.setState({
				enteredImage: event.target.value
			});

			if (event.target.value.match(regex)) {
				this.setState({
					imgSrc: event.target.value,
					validUrl: true
				});
			} else {
				this.setState({
					imgSrc: this.state.invalidImage,
					validUrl: false
				});
			}
		}
	}, {
		key: "onIngredientChange",
		value: function onIngredientChange(event) {
			var id = event.target.id;

			var arr = this.state.ingredients;

			arr[id] = event.target.value;

			this.setState({
				ingredient: arr
			});
		}
	}, {
		key: "onAddIngredientList",
		value: function onAddIngredientList() {
			var currentLength = this.state.ingredients.length;

			var nextLength = currentLength + 1;

			var nth = nextLength.toString() + "th";

			this.setState({
				ingredients: this.state.ingredients.concat(nth)
			});
		}
	}, {
		key: "onRemoveIngredientList",
		value: function onRemoveIngredientList(event) {
			var arr = this.state.ingredients;

			arr.pop();
			this.setState({
				ingredients: arr
			});
		}
	}, {
		key: "onDirectionsChange",
		value: function onDirectionsChange(event) {
			this.setState({
				directions: event.target.value
			});
		}
	}, {
		key: "render",
		value: function render() {
			var _this8 = this;

			var list = this.state.ingredients.map(function (key, idx) {
				return React.createElement(
					"li",
					null,
					key,
					React.createElement("input", { value: key, id: idx, onChange: _this8.onIngredientChange.bind(_this8) })
				);
			});

			return React.createElement(
				"div",
				null,
				React.createElement(
					"div",
					{ className: "row pull-right" },
					React.createElement(
						"h3",
						{ className: "close-x", onClick: this.props.cancel },
						"\u2716"
					)
				),
				React.createElement(
					"div",
					{ className: "row" },
					React.createElement(
						"div",
						{ className: "col text-center" },
						React.createElement(
							"h2",
							null,
							this.state.title
						),
						React.createElement("input", {
							type: "text",
							value: this.state.title,
							onChange: function onChange() {
								return _this8.onTitleChange(event);
							}
						})
					)
				),
				React.createElement("hr", null),
				React.createElement(
					"div",
					{ className: "row" },
					React.createElement(
						"div",
						{ className: "col-4" },
						React.createElement("img", { src: this.state.imgSrc, className: "img img-fluid img-thumbnail" })
					),
					React.createElement(
						"div",
						{ className: "col-8" },
						!this.state.validUrl ? React.createElement(
							"p",
							{ className: "warning-message" },
							"Not a valid url"
						) : null,
						React.createElement("input", {
							type: "text",
							value: this.state.enteredImage,
							onChange: function onChange() {
								return _this8.onSourceChange(event);
							}
						}),
						React.createElement(
							"h4",
							{ className: "text-center" },
							"Ingredients"
						),
						React.createElement(
							"ol",
							null,
							list
						),
						React.createElement(
							"button",
							{
								className: "btn btn-primary",
								onClick: this.onAddIngredientList.bind(this)
							},
							"Add Ingredient"
						),
						React.createElement(
							"button",
							{
								className: "btn btn-warning",
								onClick: this.onRemoveIngredientList.bind(this)
							},
							"Remove Ingredient"
						)
					)
				),
				React.createElement("hr", null),
				React.createElement(
					"div",
					{ className: "row" },
					React.createElement(
						"div",
						{ className: "col text-center" },
						React.createElement(
							"h4",
							{ className: "" },
							"Directions"
						),
						React.createElement("textarea", {
							type: "text",
							value: this.state.directions,
							onChange: this.onDirectionsChange.bind(this)
						})
					)
				),
				React.createElement(
					"div",
					{ className: "row" },
					React.createElement(
						"div",
						{ className: "col text-center" },
						React.createElement(
							"div",
							{ className: "btn-grp" },
							React.createElement(
								"button",
								{ className: "btn btn-secondary", onClick: this.props.cancel },
								"Cancel"
							),
							React.createElement(
								"button",
								{
									className: "btn btn-primary",
									onClick: function onClick() {
										return _this8.props.update(_this8.state.imgSrc, _this8.state.title, _this8.state.imgSrc, _this8.state.ingredients, _this8.state.directions);
									}
								},
								"Save"
							)
						)
					)
				)
			);
		}
	}]);

	return EditRecipe;
}(React.Component);

var App = function (_React$Component6) {
	_inherits(App, _React$Component6);

	function App() {
		_classCallCheck(this, App);

		var _this9 = _possibleConstructorReturn(this, (App.__proto__ || Object.getPrototypeOf(App)).call(this));

		_this9.state = {
			viewAllMount: true,
			recipeViewMount: false,
			deleteAllMount: false,
			addRecipeMount: false,
			titles: recipes.titles,
			images: recipes.images,
			ingredients: recipes.ingredients,
			directions: recipes.directions
		};
		return _this9;
	}

	_createClass(App, [{
		key: "onViewRecipe",
		value: function onViewRecipe(selection) {
			var x = selection.target.src;
			var num = void 0;

			for (var i = 0; i < this.state.images.length; i++) {
				if (x === this.state.images[i]) {
					num = i;
				}
			}

			this.setState({
				viewAllMount: !this.state.viewAllMount,
				recipeViewMount: !this.state.recipeViewMount,
				recipeIndex: num
			});
		}
	}, {
		key: "onGoBack",
		value: function onGoBack() {
			this.setState({
				viewAllMount: !this.state.viewAllMount,
				recipeViewMount: !this.state.recipeViewMount
			});
		}
	}, {
		key: "onAddRecipe",
		value: function onAddRecipe() {
			this.setState({
				viewAllMount: !this.state.viewAllMount,
				addRecipeMount: !this.state.addRecipeMount
			});
		}
	}, {
		key: "onCancelAdd",
		value: function onCancelAdd() {
			this.setState({
				addRecipeMount: !this.state.addRecipeMount,
				viewAllMount: !this.state.viewAllMount
			});
		}
	}, {
		key: "onRecipeAdded",
		value: function onRecipeAdded(newTitle, newImg, newIngredients, newDirections) {
			var titleArr = this.state.titles.concat(newTitle),
			    imgArr = this.state.images.concat(newImg),
			    ingredientArr = this.state.ingredients.concat([newIngredients]),
			    directionsArr = this.state.directions.concat(newDirections);

			this.setState({
				titles: titleArr,
				images: imgArr,
				ingredients: ingredientArr,
				directions: directionsArr,
				addRecipeMount: !this.state.addRecipeMount,
				viewAllMount: !this.state.viewAllMount
			});
			setStorage(titleArr, imgArr, ingredientArr, directionsArr);
		}
	}, {
		key: "onRemoveRecipe",
		value: function onRemoveRecipe(selection) {
			var index = void 0,
			    titleArr = this.state.titles,
			    imgArr = this.state.images,
			    ingredientArr = [],
			    directionsArr = this.state.directions;

			for (var i = 0; i < imgArr.length; i++) {
				if (selection === imgArr[i]) {
					index = i;
				}
			}

			titleArr = titleArr.filter(function (item) {
				return item !== titleArr[index];
			});
			imgArr = imgArr.filter(function (item) {
				return item !== imgArr[index];
			});
			directionsArr = directionsArr.filter(function (item) {
				return item !== directionsArr[index];
			});

			for (var _i = 0; _i < this.state.ingredients.length; _i++) {
				// console.log(this.state.ingredients[i]);
				if (_i !== index) {
					ingredientArr.push(this.state.ingredients[_i]);
				}
			}

			this.setState({
				titles: titleArr,
				images: imgArr,
				ingredients: ingredientArr,
				directions: directionsArr,
				viewAllMount: true,
				recipeViewMount: false
			});
			setStorage(titleArr, imgArr, ingredientArr, directionsArr);
		}
	}, {
		key: "onUpdateRecipe",
		value: function onUpdateRecipe(indexImg, newTitle, newImg, newIngredients, newDirections) {
			var index = void 0;

			for (var i = 0; i < this.state.images.length; i++) {
				if (indexImg === this.state.images[i]) {
					index = i;
				}
			}

			var titleArr = this.state.titles;
			titleArr[index] = newTitle;

			var imgArr = this.state.images;
			imgArr[index] = newImg;

			var ingredientArr = this.state.ingredients;
			ingredientArr[index] = newIngredients;

			var directionArr = this.state.directions;
			directionArr[index] = newDirections;

			this.setState({
				titles: titleArr,
				images: imgArr,
				ingredients: ingredientArr,
				directions: directionArr
			});
			setStorage(titleArr, imgArr, ingredientArr, directionsArr);
		}
	}, {
		key: "render",
		value: function render() {
			var index = "";

			if (this.state.viewAllMount) {
				index = React.createElement(
					"div",
					null,
					React.createElement(Header, null),
					React.createElement(ViewAll, {
						titles: this.state.titles,
						images: this.state.images,
						view: this.onViewRecipe.bind(this),
						add: this.onAddRecipe.bind(this),
						"delete": this.onRemoveRecipe.bind(this)
					}),
					React.createElement(Footer, null)
				);
			} else if (this.state.recipeViewMount) {
				index = React.createElement(
					"div",
					{ className: "jumbotron view-recipe" },
					React.createElement(ViewRecipe, {
						name: this.state.titles[this.state.recipeIndex],
						imgSrc: this.state.images[this.state.recipeIndex],
						ingredients: this.state.ingredients[this.state.recipeIndex],
						directions: this.state.directions[this.state.recipeIndex],
						goBack: this.onGoBack.bind(this),
						"delete": this.onRemoveRecipe.bind(this),
						update: this.onUpdateRecipe.bind(this)
					})
				);
			} else if (this.state.addRecipeMount) {
				index = React.createElement(
					"div",
					{ className: "jumbotron" },
					React.createElement(AddRecipe, {
						cancel: this.onCancelAdd.bind(this),
						save: this.onRecipeAdded.bind(this)
					})
				);
			}

			return React.createElement(
				"div",
				{ className: "container" },
				index
			);
		}
	}]);

	return App;
}(React.Component);

ReactDOM.render(React.createElement(App, null), document.querySelector("#root"));

Comments