inventory.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. let inventoryPage = {
  2. items: [], //the ingredients to be displayed
  3. currentSort: "",
  4. //Remove any existing ingredients in table
  5. //loop through this.items and create rows for the table
  6. renderIngredients: function(){
  7. let tbody = document.querySelector(".container table tbody");
  8. while(tbody.hasChildNodes()){
  9. tbody.removeChild(tbody.firstChild);
  10. }
  11. for(let item of this.items){
  12. let row = document.createElement("tr");
  13. tbody.appendChild(row);
  14. let name = document.createElement("td");
  15. name.innerText = item.name;
  16. row.appendChild(name);
  17. let category = document.createElement("td");
  18. category.innerText = item.category;
  19. row.appendChild(category);
  20. let quantity = document.createElement("td");
  21. quantity.innerText = item.quantity;
  22. row.appendChild(quantity);
  23. let unit = document.createElement("td");
  24. unit.innerText = item.unit;
  25. row.appendChild(unit);
  26. let action = document.createElement("td");
  27. row.appendChild(action);
  28. let editBtn = document.createElement("button");
  29. editBtn.onclick = ()=>{this.editIngredient(item.id, row)};
  30. editBtn.innerText = "Edit";
  31. editBtn.className = "edit-button"
  32. action.appendChild(editBtn);
  33. let removeBtn = document.createElement("button");
  34. removeBtn.onclick = ()=>{this.removeIngredient(item.id, row)};
  35. removeBtn.innerText = "Remove";
  36. removeBtn.className = "edit-button";
  37. action.appendChild(removeBtn);
  38. }
  39. },
  40. //sorts this.items by specified property
  41. sortIngredients: function(property){
  42. if(this.currentSort === property){
  43. this.items.sort((a, b) => (a[property] > b[property]) ? -1 : 1);
  44. this.currentSort = "";
  45. }else{
  46. this.items.sort((a, b) => (a[property] > b[property]) ? 1 : -1);
  47. this.currentSort = property;
  48. }
  49. this.renderIngredients();
  50. },
  51. //Empty this.items list
  52. //Add ingredients back to this.items list based on this.filter input
  53. filter: function(){
  54. this.items = [];
  55. let searchString = document.querySelector("#filter").value.toLowerCase();
  56. for(let item of merchant.inventory){
  57. if(item.ingredient.name.toLowerCase().includes(searchString)){
  58. this.items.push({
  59. id: item._id,
  60. name: item.ingredient.name,
  61. category: item.ingredient.category,
  62. quantity: item.quantity,
  63. unit: item.ingredient.unit
  64. });
  65. }
  66. }
  67. this.sortIngredients("name");
  68. this.renderIngredients(this.items);
  69. },
  70. //Create input allowing for user edit of ingredient
  71. editIngredient: function(id, row){
  72. let quantity = row.children[2];
  73. let button = row.children[4].children[0];
  74. let originalQuantity = quantity.innerText;
  75. let quantityInput = document.createElement("input");
  76. quantityInput.type = "number";
  77. quantityInput.step = "0.01";
  78. quantityInput.value = quantity.innerText;
  79. quantity.innerText = "";
  80. quantity.appendChild(quantityInput);
  81. button.innerText = "Save";
  82. button.onclick = ()=>{this.updateOne(id, row, originalQuantity)};
  83. },
  84. //Save user input of ingredient
  85. //Update both page and database
  86. updateOne: function(id, row, originalQuantity){
  87. let quantityField = row.children[2];
  88. let quantity = quantityField.children[0].value;
  89. let button = row.children[4].children[0];
  90. quantityField.removeChild(quantityField.firstChild);
  91. if(validator.ingredient.quantity(quantity)){
  92. let updateIngredient = merchant.inventory.find(i => i._id === id);
  93. updateIngredient.quantity = quantity;
  94. axios.post("merchant/update", merchant)
  95. .then((merchant)=>{
  96. banner.createNotification("The ingredient has been successfully updated");
  97. })
  98. .catch((err)=>{
  99. banner.createError("There was an error and the ingredient was not updated");
  100. console.log(err);
  101. });
  102. quantityField.innerText = quantity;
  103. }else{
  104. quantityField.innerText = originalQuantity;
  105. }
  106. button.innerText = "Edit";
  107. button.onclick = ()=>{this.editIngredient(id, row)};
  108. },
  109. //Delete an ingredient from both the page and the database
  110. removeIngredient: function(id, row){
  111. axios.post("/merchant/ingredients/remove", {ingredientId: id})
  112. .then(()=>{
  113. for(let i = 0; i < this.items.length; i++){
  114. if(id === this.items[i].id){
  115. this.items.splice(i, 1);
  116. }
  117. }
  118. row.parentNode.removeChild(row);
  119. banner.createNotification("The ingredient has been removed from your inventory");
  120. })
  121. .catch((err)=>{
  122. banner.createError("There was an error and the ingredient has not been removed from your inventory");
  123. console.log(err);
  124. });
  125. },
  126. //Display the modal to allow for adding a new ingredient
  127. displayAdd: function(){
  128. document.querySelector("#existingIngredient").style.display = "block";
  129. document.querySelector("#quantityInput").style.display = "none";
  130. document.querySelector("#newIngredient").style.display = "none";
  131. document.querySelector("#createNew").onclick = ()=>{this.displayNew();};
  132. let modal = document.querySelector(".add-ingredient");
  133. let removeModal = (modal)=>{modal.style.visibility = "hidden";}
  134. modal.onclick = ()=>{removeModal(modal);};
  135. modal.style.visibility = "visible";
  136. axios.get("/ingredients")
  137. .then((ingredients)=>{
  138. let tbody = document.querySelector("#existingIngredient table tbody");
  139. while(tbody.children.length > 0){
  140. tbody.removeChild(tbody.firstChild);
  141. }
  142. for(let ingredient of ingredients.data){
  143. let row = document.createElement("tr");
  144. tbody.appendChild(row);
  145. let name = document.createElement("td");
  146. name.innerText = ingredient.name;
  147. row.appendChild(name);
  148. let category = document.createElement("td");
  149. category.innerText = ingredient.category;
  150. row.appendChild(category);
  151. let unit = document.createElement("td");
  152. unit.innerText = ingredient.unit;
  153. row.appendChild(unit);
  154. let addButton = document.createElement("button");
  155. addButton.innerText = "Add";
  156. addButton.onclick = ()=>{this.configureAddIngredient(ingredient);};
  157. row.appendChild(addButton);
  158. }
  159. })
  160. .catch((err)=>{
  161. banner.createError("Failed to retrieve ingredients list");
  162. });
  163. },
  164. configureAddIngredient: function(ingredient){
  165. document.querySelector("#existingIngredient").style.display = "none";
  166. document.querySelector("#quantityInput").style.display = "block";
  167. document.querySelector("#newIngredient").style.display = "none";
  168. document.querySelector("#quantityInputTitle").innerText = `${ingredient.name} (${ingredient.unit})`;
  169. let button = document.querySelector("#addIngredient");
  170. let input = document.querySelector("#quantityInput input");
  171. button.onclick = ()=>{this.addIngredient({ingredient: ingredient, quantity: input.value});};
  172. },
  173. displayNew: function(){
  174. document.querySelector("#existingIngredient").style.display = "none";
  175. document.querySelector("#quantityInput").style.display = "none";
  176. document.querySelector("#newIngredient").style.display = "block";
  177. document.querySelector("#createIngredient").onclick = ()=>{this.createIngredient();};
  178. },
  179. createIngredient: function(){
  180. let newItem = {
  181. ingredient: {
  182. name: document.querySelector("#newName").value,
  183. category: document.querySelector("#newCategory").value,
  184. unit: document.querySelector("#newUnit").value
  185. },
  186. quantity: document.querySelector("#newQuantity").value
  187. }
  188. this.addIngredient(newItem);
  189. },
  190. //Update new ingredient on both the page and the database
  191. //Close the modal
  192. addIngredient: function(item){
  193. if(validator.ingredient.all(item.ingredient, item.quantity)){
  194. merchant.inventory.push(item);
  195. if(item.ingredient._id){
  196. axios.post("/merchant/ingredients/create", item)
  197. .then((newMerchant)=>{
  198. this.filter();
  199. banner.createNotification("The new ingredient has been successfully added to your inventory");
  200. })
  201. .catch((err)=>{
  202. banner.createError("There was an error and the ingredient could not be added to your inventory");
  203. console.log(err);
  204. });
  205. }else{
  206. axios.post("/ingredients/createone", item)
  207. .then((newMerchant)=>{
  208. this.filter();
  209. banner.createNotification("The new ingredient has been successfully added to your inventory");
  210. })
  211. .catch((err)=>{
  212. console.log(err);
  213. banner.createError("There was an error and the ingredient could not be added to your inventory");
  214. });
  215. }
  216. }
  217. let modal = document.querySelector(".add-ingredient");
  218. modal.style.visibility = "hidden";
  219. }
  220. }
  221. inventoryPage.filter();