index.html 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. <header>KIOSK</header>
  2. <body>
  3. <script>
  4. const addCell = (row, value) => {
  5. let cell = document.createElement("td");
  6. cell.innerText = value;
  7. row.append(cell);
  8. return cell;
  9. }
  10. const createAssortTable = (store) => {
  11. let state = store.getState();
  12. let table = document.createElement("table");
  13. let row = document.createElement("tr");
  14. table.append(row);
  15. addCell(row, "NAME");
  16. addCell(row, "PRICE");
  17. addCell(row, "AMOUNT");
  18. for (const itemKey in state) {
  19. if (itemKey == "cashbox")
  20. continue;
  21. let item = state[itemKey];
  22. let row = document.createElement("tr");
  23. table.append(row);
  24. addCell(row, itemKey);
  25. addCell(row, item.price);
  26. let amountVal = addCell(row, item.amount);
  27. store.subscribe(() => {
  28. const state = store.getState();
  29. const item = state[itemKey];
  30. const amount = item.amount;
  31. amountVal.innerText = amount;
  32. });
  33. //store.getState()[itemKey].amount);
  34. }
  35. return table;
  36. }
  37. const addLabel = (element, value) => {
  38. let label = document.createElement("label");
  39. label.htmlFor = element.id;
  40. label.innerText = value + ": ";
  41. element.parentElement.insertBefore(label, element);
  42. }
  43. const addBr = (element) => element.append(document.createElement("br"));
  44. const createSale = (store) => {
  45. let state = store.getState();
  46. let resDiv = document.createElement("div")
  47. let select = document.createElement("select");
  48. resDiv.append(select);
  49. for (itemKey in state) {
  50. if (itemKey == "cashbox")
  51. continue;
  52. let option = document.createElement("option");
  53. option.value = itemKey;
  54. option.text = itemKey;
  55. select.append(option);
  56. }
  57. select.onchange = () => {
  58. priceDiv.innerText = state[select.value].price;
  59. }
  60. addLabel(select, "NAME");
  61. addBr(resDiv);
  62. let priceDiv = document.createElement("a");
  63. priceDiv.innerText = state[select.value].price;
  64. priceDiv.id = "priceId";
  65. resDiv.append(priceDiv);
  66. addLabel(priceDiv, "price");
  67. addBr(resDiv);
  68. let amountInp = document.createElement("input");
  69. amountInp.id = "amountId";
  70. amountInp.value = 0;
  71. resDiv.append(amountInp);
  72. addLabel(amountInp, "amount");
  73. addBr(resDiv);
  74. let cashInp = document.createElement("input");
  75. cashInp.id = "cashId";
  76. cashInp.value = 0;
  77. resDiv.append(cashInp);
  78. addLabel(cashInp, "cash");
  79. addBr(resDiv);
  80. let buyBtn = document.createElement("button");
  81. buyBtn.innerText = "BUY";
  82. buyBtn.onclick = () => {
  83. store.dispatch({ type: 'BUY', item: select.value, amount: +amountInp.value, cash: +cashInp.value });
  84. }
  85. resDiv.append(buyBtn);
  86. return resDiv;
  87. }
  88. function createStore(reducer) {
  89. let state = reducer(undefined, {}) //стартовая инициализация состояния, запуск редьюсера со state === undefined
  90. let cbs = [] //массив подписчиков
  91. const getState = () => state //функция, возвращающая переменную из замыкания
  92. const subscribe = cb => (cbs.push(cb), //запоминаем подписчиков в массиве
  93. () => cbs = cbs.filter(c => c !== cb)) //возвращаем функцию unsubscribe, которая удаляет подписчика из списка
  94. const dispatch = action => {
  95. const newState = reducer(state, action) //пробуем запустить редьюсер
  96. if (newState !== state) { //проверяем, смог ли редьюсер обработать action
  97. state = newState //если смог, то обновляем state
  98. for (let cb of cbs) cb() //и запускаем подписчиков
  99. }
  100. }
  101. return {
  102. getState, //добавление функции getState в результирующий объект
  103. dispatch,
  104. subscribe //добавление subscribe в объект
  105. }
  106. }
  107. const seller = (state, { type, item, amount, cash, price }) => {
  108. if (state === undefined) {
  109. state = {
  110. beer: { amount: 20, price: 10 },
  111. vodka: { amount: 10, price: 30 },
  112. cigars: { amount: 100, price: 20 },
  113. cashbox: 0,
  114. }
  115. }
  116. if (type === 'BUY' &&
  117. item in state &&
  118. typeof amount == "number" &&
  119. typeof cash == "number" &&
  120. state[item].amount >= amount &&
  121. amount > 0 &&
  122. cash > 0 &&
  123. state[item].price <= cash / amount) { //если тип action - КУПИТЬ, то:
  124. return {
  125. ...state, //берем все что было из ассортимента
  126. [item]: { amount: state[item].amount - amount, price: state[item].price }, //и уменьшаем то, что покупается на количество
  127. cashbox: state.cashbox + amount * state[item].price,
  128. }
  129. }
  130. /* if (type === 'SUPPLY' &&
  131. typeof amount == "number" && amount > 0) {
  132. let newState = { ...state };
  133. let currItem = newState[item];
  134. if (!currItem) {
  135. if (typeof price != "number" || price <= 0)
  136. return state;
  137. newState[item] = { amount: 0, price: price };
  138. }
  139. else if (!(price === undefined))
  140. return state;
  141. newState[item] = { amount: newState[item].amount + amount, price: newState[item].price }; //и уменьшаем то, что покупается на количество
  142. return newState;
  143. }*/
  144. return state;
  145. }
  146. let store = createStore(seller);
  147. const unsubscribe = store.subscribe(() => console.log(store.getState()))
  148. /*store.dispatch({ type: 'BUY', item: 'cigars', amount: 3, cash: 58 })
  149. store.dispatch({ type: 'BUY', item: 'vodka', amount: 3, cash: 92 })
  150. store.dispatch({ type: 'SUPPLY', item: 'vodka', amount: 5 })
  151. store.dispatch({ type: 'SUPPLY', item: 'cukerky', amount: 5, price: 3 })*/
  152. document.body.append(createAssortTable(store));
  153. document.body.append(document.createElement("br"));
  154. document.body.append(createSale(store));
  155. </script>
  156. </body>
  157. <footer>
  158. </footer>