ReactReduxNodeJSMongoDBExpressJSCreateReactWebkit Speech APIBabelWebpackHTMLCSSEdemam Recipe API
-
This README documents the steps necessary to get the application up and running.
-
Welcome to Smart Kitchen. Smart Kitchen is a recipe app that suggests what to cook based on what you have.
-
git clone the repo with the url: https://github.com/parisDreyer/SmartKitchen
-
npm install-install backend dependencies -
npm run frontend-install-install frontend dependencies -
npm run dev-start the project running on local host 3000 and 5000- the project UI runs on port 3000
- the server runs on port 5000
The project should then be available at the address localhost:3000 in your browser
-
NodeJS,ExpressJS, andCreateReactinstalled on your machine -
The frontend is compiled with
webpackthrough FacebooksCreateReactthat generates adist/bundle.jsfile which is the compiled version of the project -
Frontend UI is handled with
React
- Splash page welcomes users to the site.
-
Users can
Searchforrecipesbyingredients. Users can search byvoiceusing webkit's speech-to-text api or by text on the search page. -
Search results are rendered in the recipe index page where the user can select a recipe that they want to view.
-
Search results persist between page reloads.
-
Recipe Results either have a link to an external site that discusses the recipe, or a link to a recipe show page on the Smart Kitchen site that displays the recipe.
- Backup recipes filtered to match the user's search criteria are always available to supplement those provided by the external API.
const filteredBackup = (url) => {
let params = url.match(/\?ingredient=(.*)/)[1];
params = params ? params.split(',').map(w => w.replace(/%|-|_|$|#|@|~|<|>|\ |\+|`|/gi, "").toLowerCase()) : params;
let recipes = [];
if (params){
for(let i = 0; i < BackupRecipes.length; ++i) {
let obj = BackupRecipes[i];
let canUse = !!obj;
// let categories = obj.categories ? obj.categories.join(', ') : ''; // use maybe
for (let j = 0; j < params.length; ++j){
if (obj)
if (obj.title) canUse = obj.title.toLowerCase().includes(params[j]);
else if (obj.ingredients) canUse = obj.ingredients.join(' ').toLowerCase().includes(params[j]);
// else if (obj.categories) canUse = categories.includes(params[j]) // use maybe
if(!canUse) break;
}
if(canUse) recipes.push({
title: obj.title,
ingredients: obj.ingredients,
directions: obj.directions,
url: `/recipes/${recipes.length - 1}`,
label: obj.title || params.join(', '),
image: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQmr2voMEJRAC2K9CmZ9c9B4TLfogkg3iN0pa3o7DNwL_qnV99K'
});
if(recipes.length > 50) break;
}
}
return recipes;
};
module.exports = { filteredBackup };- Recipes are filtered to match the ingredients input by the user.
- Ingredient percent match criteria is decreased if a user inputs fewer than three ingredients, ensuring that some recipes will still be returned if the user input size is small.
matchedRecipes = this.state.recipes.filter(recipe => {
let matchCount = 0;
const recipeIngredients = recipe.recipe ? recipe.recipe.ingredients : recipe.ingredients ? recipe.ingredients : [];
this.state.ingredients.forEach(ingredient => {
recipeIngredients.forEach(recipeIngredient => {
if (recipeIngredient.text ? recipeIngredient.text.includes(ingredient) : recipeIngredient.includes(ingredient)) {
matchCount += 1;
}
});
});
if (this.state.ingredients.length > 2) {
// if user input is 3 ingredients or more, recipes will be filtered to show
// only those for which the user has input at least 60% of the listed ingredients
return matchCount / (recipeIngredients.length) >= 0.6;
} else {
// if user input is 1 to 2 ingredients, recipes will be filtered to show
// only those for which the user has input at least 30% of the listed ingredients
return matchCount / (recipeIngredients.length) >= 0.3;
}
});- The splash page component shown below is one of many React Components that are conditionally rendered based on the front end route.
export default () => (
<div className="home-container">
<div className="home-main">
<h2 className="tagline">A Cooking App for Smart People</h2>
<div className="slide">What's in your kitchen?</div>
<p className="noneed">
Let Smart Kitchen know what you've got on hand,
<br />
and we'll show delicious recipes you can make.
</p>
<br />
<br />
<Link to="/search" className="start">
Get started now!
</Link>
</div>
</div>
);

