inventory.js 9.1 KB

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