Explorar o código

Merge branch 'development'

Lee Morgan %!s(int64=6) %!d(string=hai) anos
pai
achega
6f9065bc6d

+ 4 - 6
controllers/merchantData.js

@@ -230,9 +230,7 @@ module.exports = {
 
     //POST - Adds an ingredient to merchant's inventory
     //Inputs:
-    //  req.body: array of objects containing ingredient id and quantity
-    //Returns:
-    //  entire inventory of merchant
+    //  req.body: array of objects (each object is a full ingredient)
     addMerchantIngredient: function(req, res){
         if(!req.session.user){
             req.session.error = "Must be logged in to do that";
@@ -243,13 +241,13 @@ module.exports = {
             .then((merchant)=>{
                 for(let ingredient of req.body){
                     for(let item of merchant.inventory){
-                        if(item.ingredient.toString() === ingredient.id){
+                        if(item.ingredient.toString() === ingredient.ingredient._id){
                             return res.json("Error: Duplicate ingredient detected");
                         }
                     }
                     
                     merchant.inventory.push({
-                        ingredient: ingredient.id,
+                        ingredient: ingredient.ingredient._id,
                         quantity: ingredient.quantity
                     });
                 }
@@ -260,7 +258,7 @@ module.exports = {
                             if(err){
                                 return res.json("Warning: refresh page to view updates");
                             }else{
-                                return res.json(newMerchant.inventory);
+                                return res.json({});
                             }
                         });
                     })

+ 0 - 2
controllers/renderer.js

@@ -126,8 +126,6 @@ module.exports = {
                                 });
                         })
                         .catch((err)=>{
-                            console.log("Fucking bitch error");
-                            console.log(err);
                             let errorMessage = "There was an error and we could not retrieve your transactions from Clover";
 
                             merchant.password = undefined;

+ 2 - 2
routes.js

@@ -17,7 +17,7 @@ module.exports = function(app){
     app.post("/merchant/create/clover", merchantData.createMerchantClover);
     // app.get("/merchant/recipes/update", merchantData.updateRecipes);
     // app.post("/merchant/recipes/remove", merchantData.removeRecipe);
-    // app.post("/merchant/ingredients/add/:id", merchantData.addMerchantIngredient);
+    app.put("/merchant/ingredients/add", merchantData.addMerchantIngredient);
     // app.post("/merchant/ingredients/remove", merchantData.removeMerchantIngredient);
     app.put("/merchant/ingredients/update", merchantData.updateMerchantIngredient);
     // app.post("/merchant/recipes/ingredients/create", merchantData.addRecipeIngredient);
@@ -27,7 +27,7 @@ module.exports = function(app){
     // app.post("/merchant/password", merchantData.updatePassword);
 
     //Ingredients
-    // app.get("/ingredients", ingredientData.getIngredients);
+    app.get("/ingredients", ingredientData.getIngredients);
     // app.post("/ingredients/create", ingredientData.createIngredient);  //also adds to merchant
 
     //Recipes

+ 0 - 12
views/dashboardPage/components/addIngredient.ejs

@@ -1,12 +0,0 @@
-<div id="addIngredient">
-    <button class="sidebarIconButton" onclick="closeSidebar()">
-        <svg width="30" height="30" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
-            <line x1="5" y1="12" x2="19" y2="12"></line>
-            <polyline points="12 5 19 12 12 19"></polyline>
-        </svg>
-    </button>
-    
-    <h1>Add New Ingredients</h1>
-
-    <input type="text">
-</div>

+ 174 - 0
views/dashboardPage/components/addIngredients.ejs

@@ -0,0 +1,174 @@
+<div id="addIngredients">
+    <button class="sidebarIconButton" onclick="closeSidebar()">
+        <svg width="30" height="30" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
+            <line x1="5" y1="12" x2="19" y2="12"></line>
+            <polyline points="12 5 19 12 12 19"></polyline>
+        </svg>
+    </button>
+    
+    <h1>Add New Ingredients</h1>
+
+    <div id="addIngredientList"></div>
+
+    <button class="button addIngredientsBtn" onclick="addIngredientsComp.submitAddIngredients()">Add</button>
+
+    <template id="addIngredientsCategory">
+        <div class="addIngredientsCategory">
+            <div class="categoryHeader">
+                <h5></h5>
+                
+                <button>
+                    <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
+                        <polyline points="6 9 12 15 18 9"></polyline>
+                    </svg>
+
+                    <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
+                        <polyline points="18 15 12 9 6 15"></polyline>
+                    </svg>
+                </button>
+            </div>
+
+            <div class="addIngredientsIngredients"></div>
+        </div>
+    </template>
+
+    <template id="addIngredientsIngredient">
+        <div class="addIngredientsIngredient">
+            <input type="checkbox">
+            <p></p>
+            <input type="number" min="0" step="0.01">
+        </div>
+    </template>
+
+    <script>
+        let addIngredientsComp = {
+            isPopulated: false,
+
+            display: function(){
+                let sidebar = document.querySelector("#addIngredients");
+
+                if(!this.isPopulated){
+                    let addIngredientsDiv = document.getElementById("addIngredientList");
+                    let categoryTemplate = document.getElementById("addIngredientsCategory");
+                    let ingredientTemplate = document.getElementById("addIngredientsIngredient");
+
+                    fetch("/ingredients")
+                        .then((response) => response.json())
+                        .then((response)=>{
+                            if(typeof(response) === "string"){
+                                banner.createError(response);
+                            }else{
+                                for(let i = 0; i < merchant.inventory.length; i++){
+                                    for(let j = 0; j < response.length; j++){
+                                        if(merchant.inventory[i].ingredient._id === response[j]._id){
+                                            response.splice(j, 1);
+                                            break;
+                                        }
+                                    }
+                                }
+                                let categories = categorizeIngredientsFromDB(response);
+
+                                while(addIngredientsDiv.children.length > 0){
+                                    addIngredientsDiv.removeChild(addIngredientsDiv.firstChild);
+                                }
+                                this.addIngredientsDiv = [];
+                                for(let i = 0; i < categories.length; i++){
+                                    let categoryDiv = categoryTemplate.content.children[0].cloneNode(true);
+                                    categoryDiv.children[0].children[0].innerText = categories[i].name;
+                                    categoryDiv.children[0].children[1].onclick = ()=>{addIngredientsComp.toggleAddIngredient(categoryDiv)};
+                                    categoryDiv.children[1].style.display = "none";
+                                    categoryDiv.children[0].children[1].children[1].style.display = "none";
+
+                                    addIngredientsDiv.appendChild(categoryDiv);
+                                    
+                                    for(let j = 0; j < categories[i].ingredients.length; j++){
+                                        let ingredientDiv = ingredientTemplate.content.children[0].cloneNode(true);
+                                        ingredientDiv.children[1].innerText = categories[i].ingredients[j].name;
+                                        ingredientDiv._id = categories[i].ingredients[j].id;
+                                        ingredientDiv._name = categories[i].ingredients[j].name;
+                                        ingredientDiv._unit = categories[i].ingredients[j].unit;
+                                        ingredientDiv._category = categories[i].name;
+
+                                        categoryDiv.children[1].appendChild(ingredientDiv);
+
+                                        this.addIngredientsDiv.push(ingredientDiv);
+                                    }
+                                }
+                            }
+                        })
+                        .catch((err)=>{
+                            console.log(err);
+                            banner.createError("Unable to retrieve data");
+                        });
+
+                    this.isPopulated = true;
+                }
+
+                openSidebar(sidebar);
+            },
+
+            toggleAddIngredient: function(categoryElement){
+                let button = categoryElement.children[0].children[1];
+                let ingredientDisplay = categoryElement.children[1];
+
+                if(ingredientDisplay.style.display === "none"){
+                    ingredientDisplay.style.display = "flex";
+
+                    button.children[0].style.display = "none";
+                    button.children[1].style.display = "block";
+                }else{
+                    ingredientDisplay.style.display = "none";
+
+                    button.children[0].style.display = "block";
+                    button.children[1].style.display = "none";
+                }
+            },
+
+            submitAddIngredients: function(){
+                let addIngredients = [];
+
+                for(let i = 0; i < this.addIngredientsDiv.length; i++){
+                    let ingredient = this.addIngredientsDiv[i];
+
+                    if(ingredient.children[0].checked){
+                        if(!validator.ingredient.quantity(ingredient.children[2].value)){
+                            return;
+                        }
+
+                        addIngredients.push({
+                            ingredient: {
+                                _id: ingredient._id,
+                                name: ingredient._name,
+                                category: ingredient._category,
+                                unit: ingredient._unit
+                            },
+                            quantity: ingredient.children[2].value,
+                        });
+                    }
+                }
+
+                if(addIngredients > 0){
+                    fetch("/merchant/ingredients/add", {
+                        method: "PUT",
+                        headers: {
+                            "Content-Type": "application/json;charset=utf-8"
+                        },
+                        body: JSON.stringify(addIngredients)
+                    })
+                        .then((response)=>{
+                            if(typeof(response.data) === "string"){
+                                banner.createError(response.data);
+                            }else{
+                                banner.createNotification("Ingredients added");
+                                updateInventory(addIngredients);
+                            }
+                        })
+                        .catch((err)=>{
+                            console.log(err);
+                            banner.createError("Unable to update data.  Please refresh the page");
+                        });
+                }
+            }
+        }
+    </script>
+</div>

+ 70 - 3
views/dashboardPage/components/components.css

@@ -183,7 +183,7 @@
         visibility: hidden;
     }
 
-.sidebar button:first-of-type{
+.sidebarIconButton{
     background: none;
     border: none;
     cursor: pointer;
@@ -192,7 +192,7 @@
     margin-right: auto;
 }
 
-    .sidebar button:first-of-type:hover{
+    .sidebarIconButton:hover{
         background: rgb(0, 27, 45);
         color: white;
     }
@@ -203,11 +203,30 @@
     margin: 25px;
 }
 
-#addIngredient{
+/* Add Ingredients */
+#addIngredients{
     flex-direction: column;
     width: 100%;
 }
 
+    #addIngredientList{
+        overflow-y: auto;
+        margin-bottom: 15px;
+    }
+
+    .addIngredient{
+        display: flex;
+        justify-content: space-between;
+        padding: 10px;
+        background: rgb(240, 252, 255);
+        border: 1px solid black;
+        border-radius: 5px;
+    }
+
+    .addIngredientsBtn{
+        margin-left: auto;
+    }
+
 #ingredientDetails{
     flex-direction: column;
     align-items: center;
@@ -233,6 +252,54 @@
         padding: 10px;
     }
 
+    .addIngredientsCategory{
+        width: 90%;
+    }
+
+        .categoryHeader{
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+            width: 100%;
+            border: 1px solid black;
+            background: rgb(240, 252, 255);
+            border-radius: 5px;
+            padding: 5px;
+        }
+
+            .categoryHeader > button{
+                display: flex;
+                align-items: center;
+                background: none;
+                border: none;
+                padding: 5px;
+                border-radius: 5px;
+                cursor: pointer;
+            }
+
+            .categoryHeader > button:hover{
+                background: rgb(0, 27, 45);
+                color: white;
+            }
+
+        .addIngredientsIngredients{
+            flex-direction: column;
+            padding: 0 20px;
+        }
+
+        .addIngredientsIngredient{
+            display: flex;
+            justify-content: left;
+            align-items: center;
+            margin: 5px;
+        }
+
+        .addIngredientsIngredient input[type=number]{
+            width: 100px;
+            margin-left: auto;
+        }
+
+/* Recipe Details */
 #recipeDetails{
     flex-direction: column;
     align-items: center;

+ 47 - 12
views/dashboardPage/controller.js

@@ -58,6 +58,8 @@ let updateInventory = (ingredients, remove = false)=>{
 
     homeStrandObj.drawInventoryCheckCard();
     ingredientsStrandObj.populateIngredients();
+    addIngredientsComp.isPopulated = false;
+    closeSidebar();
 }
 
 //Close any open sidebar
@@ -241,18 +243,52 @@ Return:
             unit: Measurement unit
         name: Category name
 */
-let categorizeIngredients = ()=>{
+let categorizeIngredients = (ingredients)=>{
+    let ingredientsByCategory = [];
+
+    for(let i = 0; i < ingredients.length; i++){
+        let categoryExists = false;
+        for(let j = 0; j < ingredientsByCategory.length; j++){
+            if(ingredients[i].ingredient.category === ingredientsByCategory[j].name){
+                ingredientsByCategory[j].ingredients.push({
+                    id: ingredients[i].ingredient._id,
+                    name: ingredients[i].ingredient.name,
+                    quantity: ingredients[i].quantity,
+                    unit: ingredients[i].ingredient.unit
+                });
+
+                categoryExists = true;
+                break;
+            }
+        }
+
+        if(!categoryExists){
+            ingredientsByCategory.push({
+                name: ingredients[i].ingredient.category,
+                ingredients: [{
+                    id: ingredients[i].ingredient._id,
+                    name: ingredients[i].ingredient.name,
+                    quantity: ingredients[i].quantity,
+                    unit: ingredients[i].ingredient.unit
+                }]
+            });
+        }
+    }
+
+    return ingredientsByCategory;
+}
+
+let categorizeIngredientsFromDB = (ingredients)=>{
     let ingredientsByCategory = [];
 
-    for(let i = 0; i < merchant.inventory.length; i++){
+    for(let i = 0; i < ingredients.length; i++){
         let categoryExists = false;
         for(let j = 0; j < ingredientsByCategory.length; j++){
-            if(merchant.inventory[i].ingredient.category === ingredientsByCategory[j].name){
+            if(ingredients[i].category === ingredientsByCategory[j].name){
                 ingredientsByCategory[j].ingredients.push({
-                    id: merchant.inventory[i].ingredient._id,
-                    name: merchant.inventory[i].ingredient.name,
-                    quantity: merchant.inventory[i].quantity,
-                    unit: merchant.inventory[i].ingredient.unit
+                    id: ingredients[i]._id,
+                    name: ingredients[i].name,
+                    unit: ingredients[i].unit
                 });
 
                 categoryExists = true;
@@ -262,12 +298,11 @@ let categorizeIngredients = ()=>{
 
         if(!categoryExists){
             ingredientsByCategory.push({
-                name: merchant.inventory[i].ingredient.category,
+                name: ingredients[i].category,
                 ingredients: [{
-                    id: merchant.inventory[i].ingredient._id,
-                    name: merchant.inventory[i].ingredient.name,
-                    quantity: merchant.inventory[i].quantity,
-                    unit: merchant.inventory[i].ingredient.unit
+                    id: ingredients[i]._id,
+                    name: ingredients[i].name,
+                    unit: ingredients[i].unit
                 }]
             });
         }

+ 2 - 2
views/dashboardPage/dashboard.ejs

@@ -57,7 +57,7 @@
                 <div id="ingredientHead">
                     <h1 class="strandTitle">Ingredient Inventory</h1>
 
-                    <button class="button" onclick="ingredientsStrandObj.displayAddIngredient()">
+                    <button class="button" onclick="addIngredientsComp.display()">
                         <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line></svg>
                         add
                     </button>
@@ -87,7 +87,7 @@
         </div>
 
         <div id="sidebarDiv" class="sidebarHide">
-            <% include ./components/addIngredient %>
+            <% include ./components/addIngredients %>
 
             <% include ./components/ingredientDetails %>
 

+ 2 - 2
views/dashboardPage/home.js

@@ -230,10 +230,10 @@ window.homeStrandObj = {
                 body: JSON.stringify(changes)
             })
                 .then((response)=>{
-                    banner.createError("Ingredients updated");
                     if(typeof(response.data) === "string"){
-                        console.log(err);
+                        banner.createError(response.data);
                     }else{
+                        banner.createNotification("Ingredients updated");
                         updateInventory(changes);
                     }
                 })

+ 6 - 10
views/dashboardPage/ingredients.js

@@ -1,5 +1,6 @@
 window.ingredientsStrandObj = {
     isPopulated: false,
+    addIngredientsDiv: [],
 
     display: function(){
         if(!this.isPopulated){
@@ -10,7 +11,7 @@ window.ingredientsStrandObj = {
     },
 
     populateIngredients: function(){
-        let categories = categorizeIngredients();
+        let categories = categorizeIngredients(merchant.inventory);
 
         let ingredientStrand = document.querySelector("#categoryList");
         while(ingredientStrand.children.length > 0){
@@ -62,18 +63,15 @@ window.ingredientsStrandObj = {
     //Open or close the list of ingredients for a category
     toggleCategory: function(div, button){
         if(div.style.display === "none"){
-            button.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="18 15 12 9 6 15"></polyline></svg>';
+            button.innerHTML = '<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="18 15 12 9 6 15"></polyline></svg>';
             div.style.display = "flex";
         }else if(div.style.display === "flex"){
-            button.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>';
+            button.innerHTML = '<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>';
             div.style.display = "none";
         }
     },
 
-    displayAddIngredient: function(){
-        let sidebar = document.querySelector("#addIngredient");
-        openSidebar(sidebar);
-    },
+    
 
     displayIngredient: function(ingredient, category){
         sidebar = document.querySelector("#ingredientDetails");
@@ -97,7 +95,5 @@ window.ingredientsStrandObj = {
         }
 
         document.querySelector("#dailyUse").innerText = `${(sum/quantities.length).toFixed(2)} ${ingredient.unit}`;
-    },
-
-    
+    }
 }

+ 1 - 1
views/dashboardPage/recipeBook.js

@@ -59,7 +59,7 @@ window.recipeBookStrandObj = {
         openSidebar(document.querySelector("#addRecipe"));
 
         let ingredientsSelect = document.querySelector("#recipeInputIngredients select");
-        let categories = categorizeIngredients();
+        let categories = categorizeIngredients(merchant.inventory);
         for(let category of categories){
             let optgroup = document.createElement("optgroup");
             optgroup.label = category.name;