Recipe Box Redux Refactor

Developer
Size
11,597 Kb
Views
8,096

How do I make an recipe box redux refactor?

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 redux refactor? How do you make a recipe box redux refactor? This script and codes were developed by Zac Clemans on 14 January 2023, Saturday.

Recipe Box Redux Refactor Previews

Recipe Box Redux Refactor - Script Codes HTML Codes

<!DOCTYPE html>
<html >
<head> <meta charset="UTF-8"> <title>Recipe Box Redux Refactor</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="root"></div> <script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/js/materialize.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="js/index.js"></script>
</body>
</html>

Recipe Box Redux Refactor - 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 { margin-bottom: 0;
}
.recipeList .recipeRow .recipeThumbnail { position: relative; top: 7.5px; height: 30px; width: 30px; border: 1px solid #A8A8A8; border-radius: 2px;
}
.recipeList .recipeRow a { height: 45px; line-height: 45px;
}
.recipeList .recipeRow i { line-height: 45px; font-size: 20px;
}
.recipeList .recipeRow i:hover { cursor: pointer;
}
.recipeList .recipeRow .red-icon { color: #f44336;
}
.recipeList li { padding: 0; line-height: 40px;
}
.recipeView { margin-top: 30px;
}
.recipeView .recipeImage { border: 2px solid #A8A8A8; border-radius: 10px;
}
.recipeView .ingredientList, .recipeView .directionsList, .recipeView .notesList { padding: 5px; border: 1px solid #A8A8A8; border-radius: 5px;
}
.button-collapse { position: absolute; top: -90px; left: 20px;
}

Recipe Box Redux Refactor - Script Codes JS Codes

'use strict';
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
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 _Redux = Redux;
var combineReducers = _Redux.combineReducers;
var createStore = _Redux.createStore;
var applyMiddleware = _Redux.applyMiddleware;
var _React = React;
var Component = _React.Component;
var _ReactRedux = ReactRedux;
var connect = _ReactRedux.connect;
var Provider = _ReactRedux.Provider;
// Reducers
var recipe = function recipe() { var state = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; var action = arguments[1]; switch (action.type) { case 'ADD_RECIPE': return { id: action.id, name: action.name, ingredients: action.ingredients, directions: action.directions, notes: action.notes, image: action.image }; case 'EDIT_RECIPE': return { id: action.id, name: action.name, ingredients: action.ingredients, directions: action.directions, notes: action.notes, image: action.image }; default: return state; }
};
var recipes = function recipes() { var state = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0]; var action = arguments[1]; switch (action.type) { case 'ADD_RECIPE': return [].concat(state, [recipe(undefined, action)]); case 'DELETE_RECIPE': var newList = state.slice(0, action.id).concat(state.slice(action.id + 1)); console.log(newList); return newList.map(function (recipe, index) { return _extends({}, recipe, { id: index }); }); case 'EDIT_RECIPE': return state.slice(0, action.id).concat(recipe(undefined, action)).concat(state.slice(action.id + 1)); default: return state; }
};
var currentRecipe = function currentRecipe() { var state = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0]; var action = arguments[1]; switch (action.type) { case 'SET_CURRENT_RECIPE': return action.id; default: return state; }
};
var recipeFilter = function recipeFilter() { var state = arguments.length <= 0 || arguments[0] === undefined ? '' : arguments[0]; var action = arguments[1]; switch (action.type) { case 'SET_RECIPE_FILTER': return action.filter; default: return state; }
};
var isModalOpen = function isModalOpen() { var state = arguments.length <= 0 || arguments[0] === undefined ? false : arguments[0]; var action = arguments[1]; switch (action.type) { case 'TOGGLE_MODAL_OPEN': return !state; default: return state; }
};
var isAddingNew = function isAddingNew() { var state = arguments.length <= 0 || arguments[0] === undefined ? false : arguments[0]; var action = arguments[1]; switch (action.type) { case 'TOGGLE_ADDING_NEW': return !state; default: return state; }
};
// Action Creators
var nextRecipeId = localStorage.recipeBook ? JSON.parse(localStorage.recipeBook).length : 2;
var addRecipe = function addRecipe(recipe) { return { type: 'ADD_RECIPE', id: nextRecipeId++, name: recipe.name, ingredients: recipe.ingredients, directions: recipe.directions, notes: recipe.notes, image: recipe.image };
};
var deleteRecipe = function deleteRecipe(id) { nextRecipeId--; return { type: 'DELETE_RECIPE', id: id };
};
var editRecipe = function editRecipe(recipe) { return { type: 'EDIT_RECIPE', id: recipe.id, name: recipe.name, ingredients: recipe.ingredients, directions: recipe.directions, notes: recipe.notes, image: recipe.image };
};
var setCurrentRecipe = function setCurrentRecipe(id) { return { type: 'SET_CURRENT_RECIPE', id: id };
};
var setRecipeFilter = function setRecipeFilter(filter) { return { type: 'SET_RECIPE_FILTER', filter: filter };
};
var toggleModalOpen = function toggleModalOpen() { return { type: 'TOGGLE_MODAL_OPEN' };
};
var toggleAddingNew = function toggleAddingNew() { return { type: 'TOGGLE_ADDING_NEW' };
};
// Store Creation and Persistant State
// in local storage
var defaultRecipes = [{ 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."], notes: ["Your grandma makes it better", "Gluten free isn't an option"], image: "http://www.skylineucc.org/WordPress/wp-content/uploads/2013/11/201010-w-pies-aroma.jpg"
}, { id: 1, name: "Cake", ingredients: ["flour", "sugar", "eggs"], directions: ["Mix all of it up.", "Bake...", "Enjoy!"], notes: ["Don't eat all in one sitting", "Share with others"], image: "http://cakehutpowai.com/wp-content/uploads/2014/01/chocolate-birth-day-cake.jpg"
}];
var getInitialState = function getInitialState() { if (localStorage.recipeBook) { return { recipes: JSON.parse(localStorage.recipeBook) }; } else { return { recipes: defaultRecipes }; }
};
var reducer = combineReducers({ recipes: recipes, currentRecipe: currentRecipe, recipeFilter: recipeFilter, isModalOpen: isModalOpen, isAddingNew: isAddingNew
});
var store = createStore(reducer, getInitialState());
store.subscribe(function () { return localStorage.setItem("recipeBook", JSON.stringify(store.getState().recipes));
});
store.subscribe(function () { return console.log(store.getState());
});
// Helper Functions
var getVisibleRecipes = function getVisibleRecipes(recipes, filter) { return recipes.filter(function (recipe) { return recipe.name.toLowerCase().indexOf(filter.toLowerCase()) != -1; });
};
// React Presentational Components
var RecipeSearch = function RecipeSearch(_ref) { var recipeFilter = _ref.recipeFilter; var dispatch = _ref.dispatch; return React.createElement( 'li', null, React.createElement( 'div', { className: 'search-wrapper card' }, React.createElement('input', { className: 'grey-text', type: 'text', value: recipeFilter, placeholder: 'search recipes', onChange: function onChange(e) { return dispatch(setRecipeFilter(e.target.value)); } }), React.createElement( 'i', { className: 'material-icons grey-text search-icon' }, 'search' ) ) );
};
var mapSearchState = function mapSearchState(state) { return { recipeFilter: state.recipeFilter };
};
RecipeSearch = connect(mapSearchState)(RecipeSearch);
var AddRecipe = function AddRecipe(_ref2) { var dispatch = _ref2.dispatch; return React.createElement( 'a', { className: 'btn-floating btn-large waves-effect waves-light red add-button', onClick: function onClick() { dispatch(toggleAddingNew()); dispatch(toggleModalOpen()); $(window).width() < 993 ? $(".button-collapse").click() : null; } }, React.createElement( 'i', { className: 'material-icons' }, 'add' ) );
};
AddRecipe = connect()(AddRecipe);
var EditRecipe = function EditRecipe(_ref3) { var dispatch = _ref3.dispatch; var id = _ref3.id; return React.createElement( 'i', { className: 'material-icons right waves-effect waves-light col s2', onClick: function onClick() { dispatch(setCurrentRecipe(id)); dispatch(toggleModalOpen()); $(window).width() < 993 ? $(".button-collapse").click() : null; } }, 'edit' );
};
EditRecipe = connect()(EditRecipe);
var DeleteRecipe = function DeleteRecipe(_ref4) { var id = _ref4.id; var dispatch = _ref4.dispatch; return React.createElement( 'i', { className: 'material-icons right waves-effect waves-light col s2 red-icon', onClick: function onClick() { dispatch(deleteRecipe(id)); dispatch(setCurrentRecipe(0)); $(window).width() < 993 ? $(".button-collapse").click() : null; } }, 'delete' );
};
DeleteRecipe = connect()(DeleteRecipe);
var Recipe = function Recipe(_ref5) { var id = _ref5.id; var name = _ref5.name; var image = _ref5.image; var onClick = _ref5.onClick; return React.createElement( 'li', { className: 'recipeRow row' }, React.createElement( 'div', { className: 'col s2' }, React.createElement('img', { className: 'recipeThumbnail', src: image }) ), React.createElement( 'a', { className: 'col s6', href: '#!', onClick: onClick }, name ), React.createElement(DeleteRecipe, { id: id }), React.createElement(EditRecipe, { id: id }) );
};
var RecipeList = function (_Component) { _inherits(RecipeList, _Component); function RecipeList() { _classCallCheck(this, RecipeList); return _possibleConstructorReturn(this, _Component.apply(this, arguments)); } RecipeList.prototype.componentDidMount = function componentDidMount() { $(".button-collapse").sideNav(); }; RecipeList.prototype.render = function render() { var _props = this.props; var recipes = _props.recipes; var recipeFilter = _props.recipeFilter; var onRecipeClick = _props.onRecipeClick; 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(RecipeSearch, null), recipes.map(function (recipe) { return React.createElement(Recipe, _extends({ key: recipe.id }, recipe, { onClick: function onClick() { onRecipeClick(recipe.id); $(window).width() < 933 ? $(".button-collapse").click() : null; } })); }), React.createElement(AddRecipe, null) ) ); }; return RecipeList;
}(Component);
var mapRecipeListState = function mapRecipeListState(state) { return { recipes: getVisibleRecipes(state.recipes, state.recipeFilter), recipeFilter: state.recipeFilter };
};
var mapRecipeListDispatch = function mapRecipeListDispatch(dispatch) { return { onRecipeClick: function onRecipeClick(id) { return dispatch(setCurrentRecipe(id)); } };
};
var VisibleRecipeList = connect(mapRecipeListState, mapRecipeListDispatch)(RecipeList);
var RecipeView = function RecipeView(_ref6) { var name = _ref6.name; var ingredients = _ref6.ingredients; var directions = _ref6.directions; var notes = _ref6.notes; var image = _ref6.image; return React.createElement( 'div', { className: 'recipeView container' }, React.createElement( 'div', { className: 'card' }, React.createElement( 'div', { className: 'card-content' }, React.createElement( 'div', { className: 'row' }, React.createElement( 'div', { className: 'col m6 s12' }, React.createElement( 'h3', null, name ), React.createElement('img', { className: 'responsive-img recipeImage', src: image }) ), React.createElement( 'div', { className: 'col m6 s12' }, React.createElement( 'h5', null, 'Ingredient List' ), React.createElement( 'ul', { className: 'ingredientList' }, ingredients.map(function (ingredient) { return React.createElement( 'li', null, ingredient ); }) ), React.createElement( 'h5', null, 'Directions' ), React.createElement( 'ul', { className: 'directionsList' }, directions.map(function (direction) { return React.createElement( 'li', null, direction ); }) ), React.createElement( 'h5', null, 'Notes' ), React.createElement( 'ul', { className: 'notesList' }, notes.map(function (note) { return React.createElement( 'li', null, note ); }) ) ) ) ) ) );
};
var mapRecipeViewState = function mapRecipeViewState(state) { return _extends({}, state.recipes[state.currentRecipe]);
};
RecipeView = connect(mapRecipeViewState)(RecipeView);
var Modal = function (_Component2) { _inherits(Modal, _Component2); function Modal(props) { _classCallCheck(this, Modal); var _this2 = _possibleConstructorReturn(this, _Component2.call(this, props)); var _this2$props = _this2.props; var recipe = _this2$props.recipe; var isAddingNew = _this2$props.isAddingNew; _this2.state = { id: isAddingNew ? null : recipe.id, name: isAddingNew ? "" : recipe.name, ingredients: isAddingNew ? [] : recipe.ingredients, directions: isAddingNew ? [] : recipe.directions, notes: isAddingNew ? [] : recipe.notes, image: isAddingNew ? "" : recipe.image }; return _this2; } Modal.prototype.componentDidMount = function componentDidMount() { var _props2 = this.props; var isAddingNew = _props2.isAddingNew; var dispatch = _props2.dispatch; $('#editAddModal').openModal({ dismissible: false, complete: function complete() { dispatch(toggleModalOpen()); isAddingNew ? dispatch(toggleAddingNew()) : null; } }); // Prevents the labels from overlapping the input areas // by activating them on mount $(this.refs.imageRef).select(); $(this.refs.notesRef).select(); $(this.refs.directionsRef).select(); $(this.refs.ingredientsRef).select(); $(this.refs.nameRef).focus(); }; Modal.prototype.close = function close() { $('#editAddModal').closeModal(); }; Modal.prototype.handleNameChange = function handleNameChange(name) { this.setState({ name: name }); }; Modal.prototype.handleIngredientsChange = function handleIngredientsChange(ingredients) { var parsedIngredients = ingredients.split(','); this.setState({ ingredients: parsedIngredients }); }; Modal.prototype.handleDirectionsChange = function handleDirectionsChange(directions) { var parsedDirections = directions.split(','); this.setState({ directions: parsedDirections }); }; Modal.prototype.handleNotesChange = function handleNotesChange(notes) { var parsedNotes = notes.split(','); this.setState({ notes: parsedNotes }); }; Modal.prototype.handleImageChange = function handleImageChange(image) { this.setState({ image: image }); }; Modal.prototype.render = function render() { var _this3 = this; var _props3 = this.props; var isAddingNew = _props3.isAddingNew; var dispatch = _props3.dispatch; var _state = this.state; var id = _state.id; var name = _state.name; var ingredients = _state.ingredients; var directions = _state.directions; var notes = _state.notes; var image = _state.image; return React.createElement( 'div', { id: 'editAddModal', className: 'modal' }, React.createElement( 'div', { className: 'modal-content' }, React.createElement( 'h4', null, isAddingNew ? 'New Recipe' : 'Edit Recipe' ), React.createElement( 'p', null, isAddingNew ? 'Add new ' : 'Edit ', 'recipe, separating ingredients and directions by commas' ), React.createElement( 'div', { className: 'input-field' }, React.createElement( 'label', { 'for': 'new-title-input' }, 'Name' ), React.createElement('input', { id: 'new-name-input', type: 'text', value: name, onChange: function onChange(e) { _this3.handleNameChange(e.target.value); }, ref: 'nameRef' }) ), React.createElement( 'div', { className: 'input-field' }, React.createElement( 'label', { 'for': 'new-ingredients-input' }, 'Ingredients' ), React.createElement('textarea', { id: 'new-ingredients-input', className: 'materialize-textarea', value: ingredients.join(','), onChange: function onChange(e) { _this3.handleIngredientsChange(e.target.value); }, ref: 'ingredientsRef' }) ), React.createElement( 'div', { className: 'input-field' }, React.createElement( 'label', { 'for': 'new-directions-input' }, 'Directions' ), React.createElement('textarea', { id: 'new-directions-input', className: 'materialize-textarea', value: directions.join(','), onChange: function onChange(e) { _this3.handleDirectionsChange(e.target.value); }, ref: 'directionsRef' }) ), React.createElement( 'div', { className: 'input-field' }, React.createElement( 'label', { 'for': 'new-notes-input' }, 'Notes' ), React.createElement('textarea', { id: 'new-notes-input', className: 'materialize-textarea', value: notes.join(','), onChange: function onChange(e) { _this3.handleNotesChange(e.target.value); }, ref: 'notesRef' }) ), React.createElement( 'div', { className: 'input-field' }, React.createElement( 'label', { 'for': 'new-image-input' }, 'Image URL' ), React.createElement('input', { id: 'new-image-input', type: 'text', value: image, onChange: function onChange(e) { _this3.handleImageChange(e.target.value); }, ref: 'imageRef' }) ) ), React.createElement( 'div', { className: 'modal-footer' }, React.createElement( 'a', { href: '#!', className: 'modal-action modal-close waves-effect waves-green btn-flat', onClick: id ? function () { return dispatch(editRecipe(_this3.state)); } : function () { return dispatch(addRecipe(_this3.state)); } }, 'Save' ), React.createElement( 'a', { href: '#!', className: 'modal-action modal-close waves-effect waves-red btn-flat', onClick: this.close }, 'Cancel' ) ) ); }; return Modal;
}(Component);
;
var mapModalState = function mapModalState(state) { return { isAddingNew: state.isAddingNew, recipe: state.recipes[state.currentRecipe] };
};
Modal = connect(mapModalState)(Modal);
var App = function App(_ref7) { var isModalOpen = _ref7.isModalOpen; return React.createElement( 'div', null, React.createElement(VisibleRecipeList, null), isModalOpen ? React.createElement(Modal, null) : null, React.createElement(RecipeView, null) );
};
var mapAppState = function mapAppState(state) { return { isModalOpen: state.isModalOpen };
};
App = connect(mapAppState)(App);
ReactDOM.render(React.createElement( Provider, { store: store }, React.createElement(App, null)
), document.getElementById('root'));
Recipe Box Redux Refactor - Script Codes
Recipe Box Redux Refactor - Script Codes
Home Page Home
Developer Zac Clemans
Username thalpha
Uploaded January 14, 2023
Rating 3
Size 11,597 Kb
Views 8,096
Do you need developer help for Recipe Box Redux Refactor?

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!