recipeDetails.ejs 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. <div id="recipeDetails">
  2. <div class="sidebarIconButtons">
  3. <button class="iconButton" onclick="closeSidebar()">
  4. <svg width="30" height="30" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  5. <line x1="5" y1="12" x2="19" y2="12"></line>
  6. <polyline points="12 5 19 12 12 19"></polyline>
  7. </svg>
  8. </button>
  9. <% if(merchant.pos === "none"){ %>
  10. <button class="iconButton" onclick="recipeDetailsComp.edit()">
  11. <svg width="30" height="30" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  12. <path d="M12 20h9"></path>
  13. <path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"></path>
  14. </svg>
  15. </button>
  16. <button class="iconButton" onclick="recipeDetailsComp.remove()">
  17. <svg width="30" height="30" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  18. <polyline points="3 6 5 6 21 6"></polyline>
  19. <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path>
  20. </svg>
  21. </button>
  22. <% } %>
  23. </div>
  24. <h1 id="recipeName"></h1>
  25. <input id="recipeNameIn" type="text" style="display: none;">
  26. <div id="recipeIngredientList"></div>
  27. <button id="addRecIng" class="iconButton" onclick="recipeDetailsComp.displayAddIngredient()" style="display: none;">
  28. <svg width="30" height="30" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  29. <circle cx="12" cy="12" r="10"></circle>
  30. <line x1="12" y1="8" x2="12" y2="16"></line>
  31. <line x1="8" y1="12" x2="16" y2="12"></line>
  32. </svg>
  33. </button>
  34. <div class="lineBorder"></div>
  35. <div id="recipePrice">
  36. <h3>Price</h3>
  37. <p></p>
  38. <input type="number" min="0" step="0.01" style="display: none;">
  39. </div>
  40. <button id="recipeUpdate" onclick="recipeDetailsComp.update()" class="button" style="display: none;">Update</button>
  41. <template id="recipeIngredient">
  42. <div class="recipeIngredient">
  43. <p></p>
  44. <input type="number" min="0" step="0.01" style="display: none;">
  45. <p></p>
  46. <button class="iconButton" style="display: none;">
  47. <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  48. <polyline points="3 6 5 6 21 6"></polyline>
  49. <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path>
  50. </svg>
  51. </button>
  52. </div>
  53. </template>
  54. <template id="addRecIngredient">
  55. <div class="addRecIngredient">
  56. <select></select>
  57. <input type="number" min="0" step="0.01">
  58. </div>
  59. </template>
  60. <script>
  61. let recipeDetailsComp = {
  62. recipe: {},
  63. display: function(recipe){
  64. this.recipe = recipe;
  65. openSidebar(document.querySelector("#recipeDetails"));
  66. document.querySelector("#recipeName").style.display = "block";
  67. document.querySelector("#recipeNameIn").style.display = "none";
  68. document.querySelector("#recipeDetails h1").innerText = recipe.name;
  69. let ingredientList = document.querySelector("#recipeIngredientList");
  70. while(ingredientList.children.length > 0){
  71. ingredientList.removeChild(ingredientList.firstChild);
  72. }
  73. let template = document.querySelector("#recipeIngredient").content.children[0];
  74. for(let i = 0; i < recipe.ingredients.length; i++){
  75. ingredientDiv = template.cloneNode(true);
  76. ingredientDiv.children[0].innerText = recipe.ingredients[i].ingredient.name;
  77. ingredientDiv.children[2].innerText = `${recipe.ingredients[i].quantity} ${recipe.ingredients[i].ingredient.unit}`;
  78. ingredientDiv._id = recipe.ingredients[i].ingredient._id;
  79. ingredientDiv.name = recipe.ingredients[i].ingredient.name;
  80. ingredientList.appendChild(ingredientDiv);
  81. }
  82. document.querySelector("#addRecIng").style.display = "none";
  83. let price = document.querySelector("#recipePrice");
  84. price.children[1].style.display = "block";
  85. price.children[2].style.display = "none";
  86. price.children[1].innerText = `$${(recipe.price / 100).toFixed(2)}`;
  87. document.querySelector("#recipeUpdate").style.display = "none";
  88. },
  89. edit: function(){
  90. let ingredientDivs = document.querySelector("#recipeIngredientList");
  91. let name = document.querySelector("#recipeName");
  92. let nameIn = document.querySelector("#recipeNameIn");
  93. name.style.display = "none";
  94. nameIn.style.display = "block";
  95. nameIn.placeholder = name.innerText;
  96. for(let i = 0; i < ingredientDivs.children.length; i++){
  97. let div = ingredientDivs.children[i];
  98. div.children[2].innerText = this.recipe.ingredients[i].ingredient.unit;
  99. div.children[1].style.display = "block";
  100. div.children[1].placeholder = this.recipe.ingredients[i].quantity;
  101. div.children[3].style.display = "block";
  102. div.children[3].onclick = ()=>{div.parentElement.removeChild(div)};
  103. }
  104. document.querySelector("#addRecIng").style.display = "flex";
  105. let price = document.querySelector("#recipePrice");
  106. price.children[1].style.display = "none";
  107. price.children[2].style.display = "block";
  108. price.children[2].placeholder = price.children[1].innerText;
  109. document.querySelector("#recipeUpdate").style.display = "flex";
  110. },
  111. update: function(){
  112. let updatedRecipe = {
  113. _id: this.recipe._id,
  114. name: document.querySelector("#recipeNameIn").value || this.recipe.name,
  115. price: Math.round((document.querySelector("#recipePrice").children[2].value * 100)) || this.recipe.price,
  116. ingredients: []
  117. }
  118. let divs = document.querySelector("#recipeIngredientList").children;
  119. for(let i = 0; i < divs.length; i++){
  120. updatedRecipe.ingredients.push({
  121. ingredient: divs[i]._id,
  122. quantity: divs[i].children[1].value || divs[i].children[1].placeholder
  123. });
  124. }
  125. if(validator.recipe(updatedRecipe)){
  126. fetch("/recipe/update", {
  127. method: "PUT",
  128. headers: {
  129. "Content-Type": "application/json;charset=utf-8"
  130. },
  131. body: JSON.stringify(updatedRecipe)
  132. })
  133. .then((response) => response.json())
  134. .then((response)=>{
  135. if(typeof(response) === "string"){
  136. banner.createError(response);
  137. }else{
  138. updateRecipes(updatedRecipe);
  139. banner.createNotification("Recipe successfully updated");
  140. }
  141. })
  142. .catch((err)=>{
  143. banner.createError("Something went wrong. Please refresh the page");
  144. })
  145. }
  146. },
  147. remove: function(){
  148. fetch(`/merchant/recipes/remove/${this.recipe._id}`, {
  149. method: "DELETE"
  150. })
  151. .then((response) => response.json())
  152. .then((response)=>{
  153. if(typeof(response) === "string"){
  154. banner.createError(response);
  155. }else{
  156. updateRecipes(this.recipe, true);
  157. banner.createNotification("Recipe removed");
  158. }
  159. })
  160. .catch((err)=>{
  161. banner.createError("Something went wrong. Try refreshing the page");
  162. });
  163. },
  164. displayAddIngredient: function(){
  165. let template = document.querySelector("#addRecIngredient").content.children[0].cloneNode(true);
  166. document.querySelector("#recipeIngredientList").appendChild(template);
  167. let categories = categorizeIngredients(merchant.inventory);
  168. for(let i = 0; i < categories.length; i++){
  169. let optGroup = document.createElement("optgroup");
  170. optGroup.innerText = categories[i].name;
  171. template.children[0].appendChild(optGroup);
  172. for(let j = 0; j < categories[i].ingredients.length; j++){
  173. let option = document.createElement("option");
  174. option.innerText = `${categories[i].ingredients[j].name} (${categories[i].ingredients[j].unit})`;
  175. option.value = categories[i].ingredients[j].id;
  176. optGroup.appendChild(option);
  177. }
  178. }
  179. }
  180. }
  181. </script>
  182. </div>