main.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. function createStore(reducer) {
  2. let state = reducer(undefined, {}) //стартовая инициализация состояния, запуск редьюсера со state === undefined
  3. let cbs = [] //массив подписчиков
  4. const getState = () => state //функция, возвращающая переменную из замыкания
  5. const subscribe = cb => (cbs.push(cb), //запоминаем подписчиков в массиве
  6. () => cbs = cbs.filter(c => c !== cb)) //возвращаем функцию unsubscribe, которая удаляет подписчика из списка
  7. const dispatch = action => {
  8. const newState = reducer(state, action) //пробуем запустить редьюсер
  9. if (newState !== state) { //проверяем, смог ли редьюсер обработать action
  10. state = newState //если смог, то обновляем state
  11. for (let cb of cbs) cb() //и запускаем подписчиков
  12. }
  13. }
  14. return {
  15. getState, //добавление функции getState в результирующий объект
  16. dispatch,
  17. subscribe //добавление subscribe в объект
  18. }
  19. }
  20. function reducer(state, { type, ГДЕ, ШО, СКОКА, БАБЛО }) { //объект action деструктуризируется на три переменных
  21. if (!state) { //начальная уборка в ларьке:
  22. return {
  23. бухло: {
  24. пиво: { count: 100, price: 25 },
  25. святая: { count: 100, price: 35 },
  26. ректификат: { count: 30, price: 50 },
  27. },
  28. загрызнуть: {
  29. камса: { count: 80, price: 15 },
  30. чипсы: { count: 100, price: 20 },
  31. огурчик: { count: 35, price: 5 },
  32. раки: { count: 15, price: 100 },
  33. },
  34. остальное: {
  35. сиги: { count: 100, price: 35 },
  36. 'Даме шоколад': { count: 100, price: 35 },
  37. },
  38. касса: 0,
  39. 'Моя заначка': 1500//при покупках увеличивается
  40. }
  41. }
  42. if (type === 'КУПИТЬ') {
  43. if ((state[ГДЕ][ШО].count - СКОКА) < 0 || (state['Моя заначка'] - БАБЛО) < 0) {
  44. return state
  45. } else {
  46. return {
  47. ...state, //берем все что было из ассортимента
  48. [ГДЕ]: {
  49. ...state[ГДЕ],
  50. [ШО]: {
  51. ...state[ГДЕ][ШО],
  52. count: state[ГДЕ][ШО].count - СКОКА
  53. }
  54. },
  55. касса: state.касса + БАБЛО,
  56. 'Моя заначка': state['Моя заначка'] - БАБЛО
  57. //и уменьшаем то, что покупается на количество
  58. }
  59. }
  60. } else if (type === 'ЗАТАРИТЬ') {
  61. if ((state[ГДЕ][ШО].count + СКОКА) <= 100 || (state.касса - БАБЛО) < 0) {
  62. return state
  63. } else {
  64. return {
  65. ...state, //берем все что было из ассортимента
  66. [ГДЕ]: {
  67. ...state[ГДЕ],
  68. [ШО]: {
  69. ...state[ГДЕ][ШО],
  70. count: state[ГДЕ][ШО].count + +СКОКА
  71. }
  72. },
  73. касса: state.касса - БАБЛО,
  74. //и уменьшаем то, что покупается на количество
  75. }
  76. }
  77. }
  78. return state //если мы не поняли, что от нас просят в `action` - оставляем все как есть
  79. }
  80. const store = createStore(reducer)
  81. const table = document.createElement('table')
  82. let flag = true
  83. for (const key in store.getState()) {
  84. let optgroup = document.createElement('optgroup')
  85. optgroup.label = key
  86. for (const deepkey in store.getState()[key]) {
  87. let option = document.createElement('option')
  88. option.setAttribute('name', key)
  89. option.innerText = deepkey
  90. optgroup.append(option)
  91. createTable(key, deepkey, flag)
  92. flag = false
  93. }
  94. if (key === 'касса') createCasaCash(kassa, key)
  95. else if (key === 'Моя заначка') createCasaCash(myCash, key)
  96. else {
  97. goods.append(optgroup)
  98. flag = true
  99. }
  100. }
  101. function createTable(key, deepkey, flag) {
  102. table.setAttribute('border', '1')
  103. const tr = document.createElement('tr')
  104. const th = document.createElement('th')
  105. const tdName = document.createElement('td')
  106. const tdCount = document.createElement('td')
  107. const tdPrice = document.createElement('td')
  108. flag ? th.innerText = key : th.innerText = ''
  109. tdName.innerText = deepkey
  110. tdPrice.innerText = `Цена ${store.getState()[key][deepkey].price} грн`
  111. tdCount.innerText = ` ${store.getState()[key][deepkey].count} шт`
  112. store.subscribe(() => tdCount.innerText = store.getState()[key][deepkey].count)
  113. tr.append(th)
  114. tr.append(tdName)
  115. tr.append(tdPrice)
  116. tr.append(tdCount)
  117. table.append(tr)
  118. products.append(table)
  119. }
  120. function createCasaCash(el, key) {
  121. const tableCasa = document.createElement('table')
  122. tableCasa.setAttribute('border', '1')
  123. const tr = document.createElement('tr')
  124. const th = document.createElement('th')
  125. const td = document.createElement('td')
  126. th.innerText = key
  127. td.innerText = store.getState()[key]
  128. store.subscribe(() => td.innerText = store.getState()[key])
  129. tr.append(th)
  130. tr.append(td)
  131. tableCasa.append(tr)
  132. el.append(tableCasa)
  133. }
  134. const findSelectedOption = (el) => el.options[el.selectedIndex].getAttribute('name')
  135. const купи = (ГДЕ, ШО, СКОКА, БАБЛО) => ({ type: 'КУПИТЬ', ГДЕ, ШО, СКОКА, БАБЛО })
  136. const затарить = (ГДЕ, ШО, СКОКА, БАБЛО) => ({ type: 'ЗАТАРИТЬ', ГДЕ, ШО, СКОКА, БАБЛО })
  137. buy.onclick = () => {
  138. store.dispatch(купи(findSelectedOption(goods), goods.value, quantity.value, store.getState()[findSelectedOption(goods)][goods.value].price * quantity.value))
  139. }
  140. buyShop.onclick = () => {
  141. store.dispatch(затарить(findSelectedOption(goods), goods.value, quantity.value, store.getState()[findSelectedOption(goods)][goods.value].price * quantity.value))
  142. }
  143. const unsubscribe = store.subscribe(() => console.log(store.getState()))