Recipe Box

Developer
Size
7,954 Kb
Views
12,144

How do I make an recipe box?

A simple recipe box that stores your recipes on the browser local storage. Uses React js and Materialize. If it doesn't load, clear your local storage using localStorage.removeItem("recipeBook"). What is a recipe box? How do you make a recipe box? This script and codes were developed by Zac Clemans on 14 January 2023, Saturday.

Recipe Box Previews

Recipe Box - Script Codes HTML Codes

<!DOCTYPE html>
<html >
<head> <meta charset="UTF-8"> <title>Recipe Box</title> <meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css"> <link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/css/materialize.min.css'> <link rel="stylesheet" href="css/style.css">
</head>
<body> <div id="app-container"></div> <script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script src='https://fb.me/react-15.0.2.js'></script>
<script src='https://fb.me/react-dom-15.0.2.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/redux/3.5.2/redux.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/react-redux/4.0.6/react-redux.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/js/materialize.min.js'></script> <script src="js/index.js"></script>
</body>
</html>

Recipe Box - Script Codes CSS Codes

h1 { margin: 0; line-height: 122px;
}
@media screen and (max-width: 900px) { h1 { font-size: 40px; text-align: center; }
}
.top-nav { height: 122px; box-shadow: none;
}
.container { padding-left: 80px;
}
@media screen and (max-width: 900px) { .container { padding-left: 0; }
}
.recipeList { max-width: 220px;
}
.recipeList h5 { padding: 15px 0 0 15px;
}
.recipeList .search-wrapper { height: 45px; margin: 22px 0 20px 0;
}
.recipeList .search-wrapper .card { margin: 0;
}
.recipeList .search-wrapper .search-icon { position: absolute; top: 10px; right: 0;
}
.recipeList .search-wrapper input { position: absolute; margin: 0; padding: 0 15px; height: 45px; width: 170px; border: none;
}
.recipeList .search-wrapper input:focus { border: none; outline: none; box-shadow: none;
}
.recipeList .add-button { position: absolute; bottom: 70px; right: 10px;
}
.recipeList .add-button i { width: 25.5px;
}
.recipeList .recipeRow a { height: 50px; line-height: 50px;
}
.recipeList li { padding: 0;
}
.recipeView, .newRecipeForm { margin-top: 30px;
}
.recipeView .card, .newRecipeForm .card { height: 600px;
}
@media screen and (max-height: 780px) { .recipeView .card, .newRecipeForm .card { height: auto; }
}
.button-collapse { position: absolute; top: -90px; left: 20px;
}

Recipe Box - Script Codes JS Codes

"use strict";
//window.onload = function() {
//localStorage.removeItem('recipeBook');
//}
var RecipeApp = React.createClass({ displayName: "RecipeApp", getInitialState: function getInitialState() { if (localStorage.recipeBook) { console.log("Loading local"); console.log(localStorage.recipeBook); return { recipes: JSON.parse(localStorage.recipeBook), currentRecipeId: 0, addingNewRecipe: false }; } else { console.log("Loading default"); return { recipes: [{ id: 0, name: "Pie", ingredients: ["fruit filling", "pie crust", "butter"], directions: ["Preheat the over to 350 degrees F.", "Put the crust in a pan.", "Fill the crust with the fruit filling.", "Bake for 30 mintues.", "Sit to let cool."] }, { id: 1, name: "Cake", ingredients: ["flour", "sugar", "eggs"], directions: ["Mix all of it up.", "Bake...", "Enjoy!"] }], currentRecipeId: 0, addingNewRecipe: false }; } }, handleRecipeSelect: function handleRecipeSelect(recipeId) { this.setState({ currentRecipeId: recipeId }); }, handleNewRecipeForm: function handleNewRecipeForm() { this.setState({ addingNewRecipe: true }); }, handleNewRecipeCancel: function handleNewRecipeCancel() { this.setState({ addingNewRecipe: false }); }, handleNewRecipeAdd: function handleNewRecipeAdd(recipe) { var newRecipes = this.state.recipes; newRecipes.push(recipe); this.setState({ recipes: newRecipes, currentRecipeId: newRecipes.length - 1, addingNewRecipe: false }); localStorage.setItem("recipeBook", JSON.stringify(newRecipes)); }, handleRecipeEdit: function handleRecipeEdit(newRecipe) { var newRecipes = this.state.recipes; newRecipes[this.state.currentRecipeId] = newRecipe; this.setState({ recipes: newRecipes }); localStorage.setItem("recipeBook", JSON.stringify(newRecipes)); }, handleRecipeDelete: function handleRecipeDelete() { var newRecipes = this.state.recipes; newRecipes.splice(this.state.currentRecipeId, 1); this.setState({ recipes: newRecipes }); if (this.state.recipes.length === 0) { this.setState({ currentRecipeId: null }); } else { this.setState({ currentRecipeId: 0 }); } localStorage.setItem("recipeBook", JSON.stringify(newRecipes)); }, render: function render() { var recipe; var viewType; if (this.state.currentRecipeId == null) { recipe = { id: null, name: "No recipes stored", ingredients: [], directions: [] }; } else { recipe = this.state.recipes[this.state.currentRecipeId]; } if (this.state.addingNewRecipe != true) { viewType = React.createElement(RecipeView, { currentRecipe: recipe, onEdit: this.handleRecipeEdit, onDelete: this.handleRecipeDelete }); } else { viewType = React.createElement(NewRecipeForm, { onAdd: this.handleNewRecipeAdd, onCancel: this.handleNewRecipeCancel }); } console.log(RecipeView); return React.createElement( "div", { className: "recipeApp" }, React.createElement(RecipeList, { recipes: this.state.recipes, onSelect: this.handleRecipeSelect, onAdd: this.handleNewRecipeForm }), viewType ); }
});
var RecipeList = React.createClass({ displayName: "RecipeList", getInitialState: function getInitialState() { return { filter: '' }; }, componentDidMount: function componentDidMount() { $(".button-collapse").sideNav(); }, handleChange: function handleChange(recipeId) { this.props.onSelect(recipeId); }, handleSearch: function handleSearch() { var newFilter = $(".search-wrapper input").val(); console.log("new filter term: " + newFilter); this.setState({ filter: newFilter }); }, handleAdd: function handleAdd() { if ($(window).width() <= 990) { $(".button-collapse").click(); } this.props.onAdd(); }, render: function render() { var recipeNodes = this.props.recipes.map(function (recipe, index) { if (recipe.name.toLowerCase().indexOf(this.state.filter.toLowerCase()) != -1) { return React.createElement(RecipeRow, { recipeId: index, name: recipe.name, onSelect: this.handleChange }); } }.bind(this)); return React.createElement( "div", null, React.createElement( "nav", { className: "top-nav" }, React.createElement( "div", { className: "container" }, React.createElement( "h1", null, "Recipe Box" ) ), React.createElement( "a", { href: "#", "data-activates": "slide-out", className: "button-collapse full hide-on-large-only" }, React.createElement("i", { className: "mdi-navigation-menu" }) ) ), React.createElement( "ul", { id: "slide-out", className: "recipeList side-nav fixed" }, React.createElement( "li", { className: "black-text " }, React.createElement( "h5", null, "Recipe List" ) ), React.createElement( "li", null, React.createElement( "div", { className: "search-wrapper card" }, React.createElement("input", { className: "grey-text", type: "text", onChange: this.handleSearch }), React.createElement( "i", { className: "material-icons grey-text search-icon" }, "search" ) ) ), recipeNodes, React.createElement( "a", { className: "btn-floating btn-large waves-effect waves-light red add-button", onClick: this.handleAdd }, React.createElement( "i", { className: "material-icons" }, "add" ) ) ) ); }
});
var RecipeRow = React.createClass({ displayName: "RecipeRow", handleClick: function handleClick() { if ($(window).width() <= 990) { $(".button-collapse").click(); } this.props.onSelect(this.props.recipeId); }, render: function render() { return React.createElement( "li", { className: "recipeRow" }, React.createElement( "a", { href: "#!", onClick: this.handleClick }, this.props.name ) ); }
});
var RecipeView = React.createClass({ displayName: "RecipeView", getInitialState: function getInitialState() { return { newIngredients: this.props.currentRecipe.ingredients, newDirections: this.props.currentRecipe.directions }; }, componentWillReceiveProps: function componentWillReceiveProps(newProps) { this.setState({ newIngredients: newProps.currentRecipe.ingredients, newDirections: newProps.currentRecipe.directions }); }, handleNewIngredients: function handleNewIngredients() { this.setState({ newIngredients: $("#ingredients-input").val().split(",") }); }, handleNewDirections: function handleNewDirections() { this.setState({ newDirections: $("#directions-input").val().split(",") }); }, handleEdit: function handleEdit() { var newRecipe = this.props.currentRecipe; newRecipe.ingredients = this.state.newIngredients; newRecipe.directions = this.state.newDirections; $("#card-reveal-close").click(); this.props.onEdit(newRecipe); }, handleDelete: function handleDelete() { $("#card-reveal-close").click(); this.props.onDelete(); }, render: function render() { var ingredients = this.props.currentRecipe.ingredients.map(function (ingredient) { return React.createElement( "li", null, ingredient ); }); var directions = this.props.currentRecipe.directions.map(function (step) { return React.createElement( "li", null, step ); }); return React.createElement( "div", { className: "recipeView container" }, React.createElement( "div", { className: "card" }, React.createElement( "div", { className: "card-content" }, React.createElement( "span", { className: "card-title activator" }, React.createElement( "h3", null, this.props.currentRecipe.name, React.createElement( "i", { className: "material-icons right" }, "edit" ) ) ), React.createElement( "h5", null, "Ingredient List" ), React.createElement( "ul", null, ingredients ), React.createElement("br", null), React.createElement( "h5", null, "Directions" ), React.createElement( "ul", null, directions ) ), React.createElement( "div", { className: "card-reveal" }, React.createElement( "span", { className: "card-title" }, "Edit ", this.props.currentRecipe.name, " Recipe", React.createElement( "i", { id: "card-reveal-close", className: "material-icons right" }, "close" ) ), React.createElement( "p", null, "Edit recipe here. Seperate ingredients and directions by commas." ), React.createElement("br", null), React.createElement( "form", null, React.createElement( "div", { className: "input-field" }, React.createElement( "label", { "for": "ingredients-input" }, "Ingredients" ), React.createElement("textarea", { id: "ingredients-input", className: "materialize-textarea", value: this.state.newIngredients.join(","), onChange: this.handleNewIngredients }) ), React.createElement( "div", { className: "input-field" }, React.createElement( "label", { "for": "directions-input" }, "Directions" ), React.createElement("textarea", { id: "directions-input", className: "materialize-textarea", value: this.state.newDirections.join(","), onChange: this.handleNewDirections }) ) ), React.createElement( "div", { className: "card-action" }, React.createElement( "div", { className: "row" }, React.createElement( "a", { className: "col s3 waves-effect waves-light btn red", onClick: this.handleDelete }, React.createElement( "i", { className: "material-icons left" }, "delete" ), "Delete" ), React.createElement( "a", { className: "col s3 offset-s6 waves-effect waves-light btn green", onClick: this.handleEdit }, React.createElement( "i", { className: "material-icons left" }, "done" ), "Save" ) ) ) ) ) ); }
});
var NewRecipeForm = React.createClass({ displayName: "NewRecipeForm", handleCancel: function handleCancel() { console.log("Cancel Clicked"); this.props.onCancel(); }, handleDone: function handleDone() { var name = $("#new-name-input").val(); var ingredients = $("#new-ingredients-input").val().split(","); var directions = $("#new-directions-input").val().split(","); var newRecipe = { name: name, ingredients: ingredients, directions: directions }; this.props.onAdd(newRecipe); }, render: function render() { return React.createElement( "div", { className: "newRecipeForm container" }, React.createElement( "div", { className: "card" }, React.createElement( "div", { className: "card-content" }, React.createElement( "span", { className: "card-title" }, "Create New Recipe" ), React.createElement( "p", null, "Edit recipe here. Seperate ingredients and directions by commas." ), React.createElement("br", null), React.createElement( "form", null, React.createElement( "div", { className: "input-field" }, React.createElement( "label", { "for": "new-title-input" }, "Name" ), React.createElement("input", { id: "new-name-input", type: "text" }) ), React.createElement( "div", { className: "input-field" }, React.createElement( "label", { "for": "new-ingredients-input" }, "Ingredients" ), React.createElement("textarea", { id: "new-ingredients-input", className: "materialize-textarea" }) ), React.createElement( "div", { className: "input-field" }, React.createElement( "label", { "for": "new-directions-input" }, "Directions" ), React.createElement("textarea", { id: "new-directions-input", className: "materialize-textarea" }) ) ), React.createElement( "div", { className: "card-action" }, React.createElement( "div", { className: "row" }, React.createElement( "a", { className: "col s3 waves-effect waves-light btn red", onClick: this.handleCancel }, React.createElement( "i", { className: "material-icons left" }, "cancel" ), "Cancel" ), React.createElement( "a", { className: "col s3 offset-s6 waves-effect waves-light btn green", onClick: this.handleDone }, React.createElement( "i", { className: "material-icons left" }, "done" ), "Done" ) ) ) ) ) ); }
});
ReactDOM.render(React.createElement(RecipeApp, null), document.getElementById("app-container"));
Recipe Box - Script Codes
Recipe Box - Script Codes
Home Page Home
Developer Zac Clemans
Username thalpha
Uploaded January 14, 2023
Rating 3
Size 7,954 Kb
Views 12,144
Do you need developer help for Recipe Box?

Find the perfect freelance services for your business! Fiverr's mission is to change how the world works together. Fiverr connects businesses with freelancers offering digital services in 500+ categories. Find Developer!

Zac Clemans (thalpha) Script Codes
Create amazing Facebook ads with AI!

Jasper is the AI Content Generator that helps you and your team break through creative blocks to create amazing, original content 10X faster. Discover all the ways the Jasper AI Content Platform can help streamline your creative workflows. Start For Free!