inventory.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. let inventoryPage = {
  2. items: [], //the ingredients to be displayed
  3. currentSort: "", //boolean used for sorting
  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/ingredients/update", {ingredientId: id, quantity: quantity})
  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 < merchant.inventory.length; i++){
  114. if(id === merchant.inventory[i]._id){
  115. merchant.inventory.splice(i, 1);
  116. break;
  117. }
  118. }
  119. row.parentNode.removeChild(row);
  120. banner.createNotification("The ingredient has been removed from your inventory");
  121. })
  122. .catch((err)=>{
  123. banner.createError("There was an error and the ingredient has not been removed from your inventory");
  124. console.log(err);
  125. });
  126. },
  127. //Display the modal to allow for adding a new ingredient
  128. displayAdd: function(){
  129. document.querySelector("#existingIngredient").style.display = "block";
  130. document.querySelector("#quantityInput").style.display = "none";
  131. document.querySelector("#newIngredient").style.display = "none";
  132. document.querySelector("#createNew").onclick = ()=>{this.displayNew();};
  133. let modal = document.querySelector(".add-ingredient");
  134. let removeModal = (modal)=>{modal.style.visibility = "hidden";}
  135. modal.onclick = ()=>{removeModal(modal);};
  136. modal.style.visibility = "visible";
  137. axios.get("/ingredients")
  138. .then((ingredients)=>{
  139. let tbody = document.querySelector("#existingIngredient table tbody");
  140. while(tbody.children.length > 0){
  141. tbody.removeChild(tbody.firstChild);
  142. }
  143. for(let ingredient of ingredients.data){
  144. let row = document.createElement("tr");
  145. tbody.appendChild(row);
  146. let name = document.createElement("td");
  147. name.innerText = ingredient.name;
  148. row.appendChild(name);
  149. let category = document.createElement("td");
  150. category.innerText = ingredient.category;
  151. row.appendChild(category);
  152. let unit = document.createElement("td");
  153. unit.innerText = ingredient.unit;
  154. row.appendChild(unit);
  155. let addButton = document.createElement("button");
  156. addButton.innerText = "Add";
  157. addButton.onclick = ()=>{this.configureAddIngredient(ingredient);};
  158. row.appendChild(addButton);
  159. }
  160. })
  161. .catch((err)=>{
  162. banner.createError("Failed to retrieve ingredients list");
  163. });
  164. },
  165. configureAddIngredient: function(ingredient){
  166. document.querySelector("#existingIngredient").style.display = "none";
  167. document.querySelector("#quantityInput").style.display = "block";
  168. document.querySelector("#newIngredient").style.display = "none";
  169. document.querySelector("#quantityInputTitle").innerText = `${ingredient.name} (${ingredient.unit})`;
  170. let button = document.querySelector("#addIngredient");
  171. let input = document.querySelector("#quantityInput input");
  172. button.onclick = ()=>{this.addIngredient({ingredient: ingredient, quantity: input.value});};
  173. },
  174. displayNew: function(){
  175. document.querySelector("#existingIngredient").style.display = "none";
  176. document.querySelector("#quantityInput").style.display = "none";
  177. document.querySelector("#newIngredient").style.display = "block";
  178. document.querySelector("#createIngredient").onclick = ()=>{this.createIngredient();};
  179. },
  180. createIngredient: function(){
  181. let newItem = {
  182. ingredient: {
  183. name: document.querySelector("#newName").value,
  184. category: document.querySelector("#newCategory").value,
  185. unit: document.querySelector("#newUnit").value
  186. },
  187. quantity: document.querySelector("#newQuantity").value
  188. }
  189. this.addIngredient(newItem);
  190. },
  191. //Update new ingredient on both the page and the database
  192. //Close the modal
  193. addIngredient: function(item){
  194. if(validator.ingredient.all(item.ingredient, item.quantity)){
  195. merchant.inventory.push(item);
  196. if(item.ingredient._id){
  197. axios.post("/merchant/ingredients/create", item)
  198. .then((newMerchant)=>{
  199. this.filter();
  200. banner.createNotification("The new ingredient has been successfully added to your inventory");
  201. })
  202. .catch((err)=>{
  203. banner.createError("There was an error and the ingredient could not be added to your inventory");
  204. console.log(err);
  205. });
  206. }else{
  207. axios.post("/ingredients/createone", item)
  208. .then((newMerchant)=>{
  209. this.filter();
  210. banner.createNotification("The new ingredient has been successfully added to your inventory");
  211. })
  212. .catch((err)=>{
  213. console.log(err);
  214. banner.createError("There was an error and the ingredient could not be added to your inventory");
  215. });
  216. }
  217. }
  218. let modal = document.querySelector(".add-ingredient");
  219. modal.style.visibility = "hidden";
  220. }
  221. }
  222. inventoryPage.filter();