From 69cc42a7e624969b021fbcdc5dc70c929703d73e Mon Sep 17 00:00:00 2001 From: MattDWalsh Date: Mon, 23 May 2022 16:37:25 -0700 Subject: [PATCH 1/4] implemented ingredient list API call, list search, saving user ingredients to list, recipe list lookup, and local storage --- .../javascript/minicapstone/css/style.css | 0 code/matt/javascript/minicapstone/index.html | 38 ++++ .../matt/javascript/minicapstone/js/script.js | 176 ++++++++++++++++++ 3 files changed, 214 insertions(+) create mode 100644 code/matt/javascript/minicapstone/css/style.css create mode 100644 code/matt/javascript/minicapstone/index.html create mode 100644 code/matt/javascript/minicapstone/js/script.js diff --git a/code/matt/javascript/minicapstone/css/style.css b/code/matt/javascript/minicapstone/css/style.css new file mode 100644 index 00000000..e69de29b diff --git a/code/matt/javascript/minicapstone/index.html b/code/matt/javascript/minicapstone/index.html new file mode 100644 index 00000000..954cff55 --- /dev/null +++ b/code/matt/javascript/minicapstone/index.html @@ -0,0 +1,38 @@ + + + + + + + This is a JS mini-capstone, allegedly + + + + + + + + +
+
+ + +
+
+

mine:

+ {{ myIngredients }} +
+ +
+ +
+ +
+ + \ No newline at end of file diff --git a/code/matt/javascript/minicapstone/js/script.js b/code/matt/javascript/minicapstone/js/script.js new file mode 100644 index 00000000..59f291c2 --- /dev/null +++ b/code/matt/javascript/minicapstone/js/script.js @@ -0,0 +1,176 @@ +// generate app +const { createApp } = Vue +createApp({ + data () { + return { + // main API endpoint and modifiers + baseURL: `https://www.thecocktaildb.com/api/json/v2/${API_KEY}/`, + listURL: 'list.php', + searchURL: 'search.php', + filterURL: 'filter.php', + // object to hold full ingredient list + ingredientsObj: {}, + // user ingredient search input + ingredientSearchInput: '', + // current search results + filteredIngredients: [], + // user's selected ingredients + myIngredients: [], + // recipes containing at least one of user's ingredients + myRecipes: {}, + } + }, + created () { + this.loadFromLocal() + this.getIngredients() + // console.log(this.ingredientsObj) + }, + methods: { + // gets full list of ingredients from API + getIngredients () { + axios({ + url: this.baseURL + this.listURL, + method: 'get', + headers: { + Accept: 'application/json', + }, + params: { + i: 'list', + } + }).then(res => { + // iterate through response and add each ingredient to array as an object + res.data.drinks.forEach(item => { + // loosely correct capitalization errors on API + let itemName = item.strIngredient1[0].toUpperCase() + item.strIngredient1.substring(1) + // add name key with string value and recipes key with empty array to each ingredient + this.ingredientsObj[itemName] = { + name: itemName, + recipes: [], + } + }) + console.log(this.ingredientsObj) + }) + }, + // searches full list of ingredients against user input + ingredientSearch () { + // reset search results + this.filteredIngredients = [] + // iterate through ingredients Object + Object.keys(this.ingredientsObj).forEach(item => { + // add to filtered/results array if input is not blank AND the current string is found in ingredients Object keys + if (!(this.ingredientSearchInput == '') && (item.toLowerCase().includes(this.ingredientSearchInput.toLowerCase()))) { + this.filteredIngredients.push(item) + this.filteredIngredients.sort() + } + }) + }, + // adds a given ingredient to an array storing the user's ingredients + addToMyIngredients (ingredient) { + // only run if the ingredient isn't already added + if (!(this.myIngredients.includes(ingredient))) { + // add to array and sort + this.myIngredients.push(ingredient) + this.myIngredients.sort() + // save to local storage + this.saveToLocal() + // get list of recipes for this ingredient + this.ingredientRecipes(ingredient) + } + }, + // gets all cocktails that a given ingredient is used in + ingredientRecipes (ingredient) { + axios({ + url: this.baseURL + this.filterURL, + method: 'get', + headers: { + Accept: 'application/json', + }, + params: { + i: ingredient, + } + }).then(res => { + // iterate through response and add recipe names to ingredient object + res.data.drinks.forEach(item => { + this.ingredientsObj[ingredient].recipes.push(item.strDrink) + }) + // console.log(this.ingredientsObj) + }) + //////////////////////////THIS IS WHERE I'M AT - STARTED recipeDetails AND I NEED TO FINISH THAT AND CALL IT AFTER I ADD RECIPE NAMES + }, + // gets details of recipes + recipeDetails (recipeName) { + axios({ + url: this.baseURL + this.searchURL, + method: 'get', + headers: { + Accept: 'application/json', + }, + params: { + s: recipeName, + } + }) + }, + // saves myIngredients array to local storage + saveToLocal () { + const parsedMyIngredients = JSON.stringify(this.myIngredients) + localStorage.setItem('myIngredients', parsedMyIngredients) + }, + // loads myIngredients array from local storage + loadFromLocal () { + if (localStorage.getItem('myIngredients')) { + this.myIngredients = JSON.parse(localStorage.getItem('myIngredients')) + } + }, + // resets local storage + clearLocal () { + this.myIngredients = [] + localStorage.clear() + }, + } +}).mount('#app') + + +/* +***API call to get all ingredients +?Save ingredients to local storage +***List all possible ingredients +***User selects ingredients they have +***Save user's ingredients to local storage +***API call per ingredient -> save drink name/ID +API call per saved drink +?? save drinks to local storage ?? +per drink, check if all ingredients are on user ingredient list (increment counter if not) + +*/ + +/* +filter = { + "drinks": [ + { + "strDrink": "155 Belmont", + "strDrinkThumb": "https://www.thecocktaildb.com/images/media/drink/yqvvqs1475667388.jpg", + "idDrink": "15346" + }, + ] +} + +*/ + + +/* + +myRecipes Object of Objects { + ==strDrink==: { + name: string, // strDrink + glass: string, // strGlass + instructions: string, // strInstructions + image: string, // strDrinkThumb + ingredients: { + ==strIngredient[1-15]==: ==strMeasure[1-15]== + } + + } +} + + +*/ \ No newline at end of file From 94e4ca2561e22824e643ca8cf8a23bad37602692 Mon Sep 17 00:00:00 2001 From: MattDWalsh Date: Tue, 24 May 2022 15:27:56 -0700 Subject: [PATCH 2/4] added recipe details and sorting by missing ingredients, improved recipe search, improved localstorage handling --- code/matt/javascript/minicapstone/index.html | 3 + .../matt/javascript/minicapstone/js/script.js | 132 ++++++++++-------- 2 files changed, 75 insertions(+), 60 deletions(-) diff --git a/code/matt/javascript/minicapstone/index.html b/code/matt/javascript/minicapstone/index.html index 954cff55..ffa5a9c0 100644 --- a/code/matt/javascript/minicapstone/index.html +++ b/code/matt/javascript/minicapstone/index.html @@ -25,8 +25,11 @@
+ let's gooooo

mine:

{{ myIngredients }} +

also mine:

+ {{ Object.keys(myRecipes) }}
diff --git a/code/matt/javascript/minicapstone/js/script.js b/code/matt/javascript/minicapstone/js/script.js index 59f291c2..601b3503 100644 --- a/code/matt/javascript/minicapstone/js/script.js +++ b/code/matt/javascript/minicapstone/js/script.js @@ -6,6 +6,7 @@ createApp({ // main API endpoint and modifiers baseURL: `https://www.thecocktaildb.com/api/json/v2/${API_KEY}/`, listURL: 'list.php', + lookupURL: 'lookup.php', searchURL: 'search.php', filterURL: 'filter.php', // object to hold full ingredient list @@ -18,6 +19,8 @@ createApp({ myIngredients: [], // recipes containing at least one of user's ingredients myRecipes: {}, + // array of arrays of recipes indexed according to number of missing ingredients + possibleRecipes: [], } }, created () { @@ -45,7 +48,7 @@ createApp({ // add name key with string value and recipes key with empty array to each ingredient this.ingredientsObj[itemName] = { name: itemName, - recipes: [], + recipes: {}, } }) console.log(this.ingredientsObj) @@ -71,10 +74,10 @@ createApp({ // add to array and sort this.myIngredients.push(ingredient) this.myIngredients.sort() - // save to local storage - this.saveToLocal() // get list of recipes for this ingredient this.ingredientRecipes(ingredient) + // save to local storage + this.saveToLocal() } }, // gets all cocktails that a given ingredient is used in @@ -89,88 +92,97 @@ createApp({ i: ingredient, } }).then(res => { - // iterate through response and add recipe names to ingredient object - res.data.drinks.forEach(item => { - this.ingredientsObj[ingredient].recipes.push(item.strDrink) + // iterate through response and add recipes to ingredient object as objects + if (!(res.data.drinks == "None Found")) { + res.data.drinks.forEach(item => { + // format each object as drinkNameString: drinkID + this.ingredientsObj[ingredient].recipes[item.strDrink] = item.idDrink + // request full recipe for each drink returned + this.recipeDetails(item.idDrink) }) - // console.log(this.ingredientsObj) + } + // console.log(this.ingredientsObj) }) - //////////////////////////THIS IS WHERE I'M AT - STARTED recipeDetails AND I NEED TO FINISH THAT AND CALL IT AFTER I ADD RECIPE NAMES }, // gets details of recipes - recipeDetails (recipeName) { + recipeDetails (recipeID) { axios({ - url: this.baseURL + this.searchURL, + url: this.baseURL + this.lookupURL, method: 'get', headers: { Accept: 'application/json', }, params: { - s: recipeName, + i: recipeID,//change to int id + } + }).then(res => { + // assign drink response to variable for easier access + let recipeResponse = res.data.drinks[0] + // construct recipe object + this.myRecipes[recipeResponse.strDrink] = { + name: recipeResponse.strDrink, + id: recipeID, + glass: recipeResponse.strGlass, + instructions: recipeResponse.strInstructions, + image: recipeResponse.strDrinkThumb, + ingredients: {} + } + // get arrays of keys for ingredients and measures + let recipeIngredients = Object.keys(recipeResponse).filter(eachString => {return eachString.includes('Ingredient')}) + let recipeMeasures = Object.keys(recipeResponse).filter(eachString => {return eachString.includes('Measure')}) + // iterate over non-null ingredients and add them and their measures to object + recipeIngredients.forEach((item, index) => { + if (recipeResponse[item]) { + this.myRecipes[recipeResponse.strDrink].ingredients[recipeResponse[item]] = recipeResponse[recipeMeasures[index]] + } + }) + this.saveToLocal() + // console.log(this.myRecipes) + }) + }, + // finds number of missing ingredients per recipe + missingIngredientCount () { + // iterate through each recipe + Object.keys(this.myRecipes).forEach(thisRecipe => { + // reset counter for missing ingredients + let numMissing = 0 + // iterate through each ingredient in the recipe + Object.keys(this.myRecipes[thisRecipe].ingredients).forEach(thisIngredient => { + // increment counter if a missing ingredient is found + if (!(this.myIngredients.includes(thisIngredient))) { + numMissing++ + } + }) + // add an empty array at the index matching the number of missing ingredients if an array is not already present + if (!(this.possibleRecipes[numMissing])) { + this.possibleRecipes[numMissing] = [] } + // add recipe to possibleRecipes array at the index position matching the number of missing ingredients + this.possibleRecipes[numMissing].push(thisRecipe) }) + // console.log(this.possibleRecipes) }, - // saves myIngredients array to local storage + // saves myIngredients and myRecipes arrays to local storage saveToLocal () { const parsedMyIngredients = JSON.stringify(this.myIngredients) localStorage.setItem('myIngredients', parsedMyIngredients) + const parsedMyRecipes = JSON.stringify(this.myRecipes) + localStorage.setItem('myRecipes', parsedMyRecipes) }, - // loads myIngredients array from local storage + // loads myIngredients and myRecipes arrays from local storage loadFromLocal () { if (localStorage.getItem('myIngredients')) { this.myIngredients = JSON.parse(localStorage.getItem('myIngredients')) } + if (localStorage.getItem('myRecipes')) { + this.myRecipes = JSON.parse(localStorage.getItem('myRecipes')) + } }, // resets local storage clearLocal () { this.myIngredients = [] + this.myRecipes = {} localStorage.clear() }, } -}).mount('#app') - - -/* -***API call to get all ingredients -?Save ingredients to local storage -***List all possible ingredients -***User selects ingredients they have -***Save user's ingredients to local storage -***API call per ingredient -> save drink name/ID -API call per saved drink -?? save drinks to local storage ?? -per drink, check if all ingredients are on user ingredient list (increment counter if not) - -*/ - -/* -filter = { - "drinks": [ - { - "strDrink": "155 Belmont", - "strDrinkThumb": "https://www.thecocktaildb.com/images/media/drink/yqvvqs1475667388.jpg", - "idDrink": "15346" - }, - ] -} - -*/ - - -/* - -myRecipes Object of Objects { - ==strDrink==: { - name: string, // strDrink - glass: string, // strGlass - instructions: string, // strInstructions - image: string, // strDrinkThumb - ingredients: { - ==strIngredient[1-15]==: ==strMeasure[1-15]== - } - - } -} - - -*/ \ No newline at end of file +}).mount('#app') \ No newline at end of file From 962ca2852d58d1910dd4311daeefc80288e2b722 Mon Sep 17 00:00:00 2001 From: MattDWalsh Date: Wed, 25 May 2022 16:36:23 -0700 Subject: [PATCH 3/4] fixed timing of method calling, added possible recipes to localstorage, began styling --- .../javascript/minicapstone/css/style.css | 31 +++++++ code/matt/javascript/minicapstone/index.html | 86 ++++++++++++++----- .../matt/javascript/minicapstone/js/script.js | 40 ++++++++- 3 files changed, 133 insertions(+), 24 deletions(-) diff --git a/code/matt/javascript/minicapstone/css/style.css b/code/matt/javascript/minicapstone/css/style.css index e69de29b..7d234856 100644 --- a/code/matt/javascript/minicapstone/css/style.css +++ b/code/matt/javascript/minicapstone/css/style.css @@ -0,0 +1,31 @@ +#ing-select { + height: 100vh; + background-color: #faa; + overflow: auto; +} +#ing-search-results { + background-color: white; + position: absolute; + overflow: auto; + min-height: 0vh; + max-height: 80vh; +} +#recipe-select { + height: 100vh; + background-color: #afa; + overflow: auto; +} +#recipe-view { + height: 100vh; + background-color: #aaf; + overflow: auto; +} +.active { + width: 70vw +} +.inactive { + width: 15vw; +} +.transition { + transition: .5s; +} \ No newline at end of file diff --git a/code/matt/javascript/minicapstone/index.html b/code/matt/javascript/minicapstone/index.html index ffa5a9c0..c8ad71d4 100644 --- a/code/matt/javascript/minicapstone/index.html +++ b/code/matt/javascript/minicapstone/index.html @@ -14,28 +14,74 @@
- -
- let's gooooo -

mine:

- {{ myIngredients }} -

also mine:

- {{ Object.keys(myRecipes) }} -
+
+
+ + + + + + + +

my ingredients:

+ {{ myIngredients }} + + + +
+
+ + + -
- -
+
+ +
+ + +
+
+ + + + + +
+

{{ currentRecipe.name }}

+ currentrecipe.name +
    +
  • + {{ ingredient }} - {{ measure }} +
  • +
+

+ {{ currentRecipe.glass }} +

+

+ {{ currentRecipe.instructions }} +

+ +
+ + +
+
\ No newline at end of file diff --git a/code/matt/javascript/minicapstone/js/script.js b/code/matt/javascript/minicapstone/js/script.js index 601b3503..04bb467e 100644 --- a/code/matt/javascript/minicapstone/js/script.js +++ b/code/matt/javascript/minicapstone/js/script.js @@ -1,6 +1,5 @@ // generate app -const { createApp } = Vue -createApp({ +Vue.createApp({ data () { return { // main API endpoint and modifiers @@ -21,6 +20,9 @@ createApp({ myRecipes: {}, // array of arrays of recipes indexed according to number of missing ingredients possibleRecipes: [], + currentRecipe: null, + // array holding active states for each panel + isActive: [true,false,false], } }, created () { @@ -29,6 +31,16 @@ createApp({ // console.log(this.ingredientsObj) }, methods: { + // handles activating/deactivating panels by flipping their boolean + makeActive (element) { + this.isActive.forEach((item, index) => { + if (index == element) { + this.isActive[index] = true + } else { + this.isActive[index] = false + } + }) + }, // gets full list of ingredients from API getIngredients () { axios({ @@ -51,7 +63,7 @@ createApp({ recipes: {}, } }) - console.log(this.ingredientsObj) + // console.log(this.ingredientsObj) }) }, // searches full list of ingredients against user input @@ -137,11 +149,14 @@ createApp({ } }) this.saveToLocal() + this.missingIngredientCount() // console.log(this.myRecipes) }) }, // finds number of missing ingredients per recipe missingIngredientCount () { + // reset array + this.possibleRecipes = [] // iterate through each recipe Object.keys(this.myRecipes).forEach(thisRecipe => { // reset counter for missing ingredients @@ -159,15 +174,28 @@ createApp({ } // add recipe to possibleRecipes array at the index position matching the number of missing ingredients this.possibleRecipes[numMissing].push(thisRecipe) + this.possibleRecipes[numMissing].sort() }) + // save to local storage + this.saveToLocal() // console.log(this.possibleRecipes) }, + // assigns a specific recipe to currentRecipe for display + showCurrentRecipe (recipeName) { + this.currentRecipe = this.myRecipes[recipeName] + }, + // clears currentRecipe to hide display + hideCurrentRecipe () { + this.currentRecipe = null + }, // saves myIngredients and myRecipes arrays to local storage saveToLocal () { const parsedMyIngredients = JSON.stringify(this.myIngredients) localStorage.setItem('myIngredients', parsedMyIngredients) const parsedMyRecipes = JSON.stringify(this.myRecipes) localStorage.setItem('myRecipes', parsedMyRecipes) + const parsedPossibleRecipes = JSON.stringify(this.possibleRecipes) + localStorage.setItem('possibleRecipes', parsedPossibleRecipes) }, // loads myIngredients and myRecipes arrays from local storage loadFromLocal () { @@ -177,11 +205,15 @@ createApp({ if (localStorage.getItem('myRecipes')) { this.myRecipes = JSON.parse(localStorage.getItem('myRecipes')) } + if (localStorage.getItem('possibleRecipes')) { + this.possibleRecipes = JSON.parse(localStorage.getItem('possibleRecipes')) + } }, - // resets local storage + // resets local storage and clears associated variables clearLocal () { this.myIngredients = [] this.myRecipes = {} + this.possibleRecipes = [] localStorage.clear() }, } From 29e951857f562893826d6336011f26180ce71a30 Mon Sep 17 00:00:00 2001 From: MattDWalsh Date: Thu, 26 May 2022 17:08:19 -0700 Subject: [PATCH 4/4] added styling, made search case-insensitive, yelled at CSS --- .../javascript/minicapstone/css/style.css | 160 ++++++++++++++++-- code/matt/javascript/minicapstone/index.html | 85 ++++++---- .../matt/javascript/minicapstone/js/script.js | 37 ++-- 3 files changed, 223 insertions(+), 59 deletions(-) diff --git a/code/matt/javascript/minicapstone/css/style.css b/code/matt/javascript/minicapstone/css/style.css index 7d234856..59791f95 100644 --- a/code/matt/javascript/minicapstone/css/style.css +++ b/code/matt/javascript/minicapstone/css/style.css @@ -1,31 +1,161 @@ +@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@400;700&display=swap'); +body { + font-family: 'Nunito', sans-serif; +} +#app { + height: 100vh; +} +h1, h2, h3, h4, h5 { + margin-top: 5px; + margin-bottom: 5px; +} +main { + display: flex; +} #ing-select { height: 100vh; - background-color: #faa; - overflow: auto; + background-color: #A1EF8B; + overflow-y: auto; + overflow-x: hidden; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + text-align: center; +} +#ing-search { + flex-direction: column; + align-items: center; } #ing-search-results { background-color: white; position: absolute; - overflow: auto; - min-height: 0vh; - max-height: 80vh; + overflow-y: auto; + overflow-x: hidden; + max-height: 20vh; + border-radius: 10px; + padding: 10px; + box-sizing: border-box; +} +.active #ing-search-results, .active #my-ingredients { + width: 40vw; +} +.inactive #ing-search-results, .inactive #my-ingredients { + width: 18vw; +} +#ing-select a { + color: #7F80B8; +} +#ing-select a:hover { + color: #62BFED; +} +#my-ingredients { + background-color: rgba(255,255,255,.2); + border-radius: 10px; + padding: 10px; + box-sizing: border-box; + margin-top: 20px; + margin-bottom: 20px; } #recipe-select { height: 100vh; - background-color: #afa; - overflow: auto; + background-color: #62BFED; + overflow-y: auto; + overflow-x: hidden; + display: flex; + flex-flow: wrap; + align-items: center; + justify-content: center; } #recipe-view { height: 100vh; - background-color: #aaf; - overflow: auto; + background-color: #7F80B8; + overflow-y: auto; + overflow-x: hidden; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} +@media screen and ( max-height: 1000px ) { + #recipe-view.has-recipe { + justify-content: flex-start; + } +} +#recipe-view div { + max-width: 700px; + display: flex; + flex-direction: column; + align-items: center; +} +div.active { + width: 60vw +} +div.inactive { + width: 20vw; +} +.transition, .transition * { + transition: .25s; +} +#drink-image { + max-width: 100%; +} +.active h1 { + font-size: xx-large; +} +.inactive h1 { + font-size: small; +} +#recipe-view p, #recipe-view li { + text-align: center; +} +.active p, .active li { + font-size: medium; +} +.inactive p, .inactive li { + font-size: small; +} +ul { + list-style-type: none; + margin: 0; + padding: 0; +} +#recipe-select ul { + margin: 10px; + width: 25vw; + text-align: center; +} +.open-button { + position: absolute; + bottom: 0px; +} +.num-missing { + background-color: rgba(255,255,255,.2); + border-radius: 10px; + padding: 10px; +} +.num-missing a { + color: #7F80B8; +} +.num-missing a:hover { + color: #A1EF8B; +} +input { + text-align: center; + font-size: large; + height: 40px; + border-radius: 10px; + border: 0px; + box-sizing: border-box; + margin-top: 20px; } -.active { - width: 70vw +input:focus { + border: 0px; + outline: none; } -.inactive { - width: 15vw; +.active input { + width: 40vw; } -.transition { - transition: .5s; +.inactive input { + width: 18vw; } \ No newline at end of file diff --git a/code/matt/javascript/minicapstone/index.html b/code/matt/javascript/minicapstone/index.html index c8ad71d4..1f6ea037 100644 --- a/code/matt/javascript/minicapstone/index.html +++ b/code/matt/javascript/minicapstone/index.html @@ -4,7 +4,7 @@ - This is a JS mini-capstone, allegedly + Drink Decider 2000 @@ -14,73 +14,92 @@
-
+
- + +

+ Drink Decider 2000 +

- -
-
- + +

+ add ingredients to continue +

-
- +
+
+ +
-
+
- + - -
-

{{ currentRecipe.name }}

- currentrecipe.name +

+ select a recipe to continue +

+ +
+

{{ currentRecipe.name }}

+ currentrecipe.name
  • - {{ ingredient }} - {{ measure }} + {{ measure }} {{ ingredient }}

- {{ currentRecipe.glass }} + Serve in a {{ currentRecipe.glass }}

{{ currentRecipe.instructions }}

-
-
+
diff --git a/code/matt/javascript/minicapstone/js/script.js b/code/matt/javascript/minicapstone/js/script.js index 04bb467e..62498590 100644 --- a/code/matt/javascript/minicapstone/js/script.js +++ b/code/matt/javascript/minicapstone/js/script.js @@ -83,13 +83,31 @@ Vue.createApp({ addToMyIngredients (ingredient) { // only run if the ingredient isn't already added if (!(this.myIngredients.includes(ingredient))) { - // add to array and sort - this.myIngredients.push(ingredient) - this.myIngredients.sort() - // get list of recipes for this ingredient - this.ingredientRecipes(ingredient) - // save to local storage - this.saveToLocal() + // case-insensitive search + const found = this.filteredIngredients.find(element => { + return element.toLowerCase() === ingredient.toLowerCase() + }) + // return ingredient with matching capitalization if case-insensitive search was successful + if (!(this.filteredIngredients.includes(ingredient)) && (found !== undefined)) { + this.filteredIngredients.forEach(element => { + if (element.toLowerCase() == ingredient.toLowerCase()) { + ingredient = element + } + }) + } + // only run if current input is a valid ingredient + if (this.filteredIngredients.includes(ingredient)) { + // add to array and sort + this.myIngredients.push(ingredient) + this.myIngredients.sort() + // get list of recipes for this ingredient + this.ingredientRecipes(ingredient) + // save to local storage + this.saveToLocal() + // clear search after adding + this.filteredIngredients = [] + this.ingredientSearchInput = null + } } }, // gets all cocktails that a given ingredient is used in @@ -184,10 +202,6 @@ Vue.createApp({ showCurrentRecipe (recipeName) { this.currentRecipe = this.myRecipes[recipeName] }, - // clears currentRecipe to hide display - hideCurrentRecipe () { - this.currentRecipe = null - }, // saves myIngredients and myRecipes arrays to local storage saveToLocal () { const parsedMyIngredients = JSON.stringify(this.myIngredients) @@ -214,6 +228,7 @@ Vue.createApp({ this.myIngredients = [] this.myRecipes = {} this.possibleRecipes = [] + this.currentRecipe = null localStorage.clear() }, }