index.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. function reducer(state, {type, productName, productQuantity, summ}){ //объект action деструктуризируется на три переменных
  2. if (!state){ //начальная уборка в ларьке:
  3. return {
  4. пиво: {
  5. quantity: 100,
  6. price: 30,
  7. },
  8. чипсы: {
  9. quantity: 100,
  10. price: 52,
  11. },
  12. сиги: {
  13. quantity: 100,
  14. price: 89,
  15. },
  16. касса: 0
  17. }
  18. }
  19. if (type === 'КУПИТЬ' && productQuantity <= state[productName].quantity && summ >= state[productName].price * productQuantity){ //если тип action - КУПИТЬ, то:
  20. return {
  21. ...state, //берем все что было из ассортимента
  22. [productName]: {
  23. quantity: state[productName].quantity - productQuantity,
  24. price: state[productName].price
  25. },
  26. касса: state.касса + state[productName].price * productQuantity
  27. //и уменьшаем то, что покупается на количество
  28. }
  29. }
  30. return state //если мы не поняли, что от нас просят в `action` - оставляем все как есть
  31. }
  32. function createStore(reducer){
  33. let state = reducer(undefined, {}) //стартовая инициализация состояния, запуск редьюсера со state === undefined
  34. let cbs = [] //массив подписчиков
  35. const getState = () => state //функция, возвращающая переменную из замыкания
  36. const subscribe = cb => (cbs.push(cb), //запоминаем подписчиков в массиве
  37. () => cbs = cbs.filter(c => c !== cb)) //возвращаем функцию unsubscribe, которая удаляет подписчика из списка
  38. const dispatch = action => {
  39. const newState = reducer(state, action) //пробуем запустить редьюсер
  40. if (newState !== state){ //проверяем, смог ли редьюсер обработать action
  41. state = newState //если смог, то обновляем state
  42. for (let cb of cbs) cb() //и запускаем подписчиков
  43. }
  44. }
  45. return {
  46. getState, //добавление функции getState в результирующий объект
  47. dispatch,
  48. subscribe //добавление subscribe в объект
  49. }
  50. }
  51. function actionCreator (type, productName, productQuantity, summ){
  52. return {
  53. type,
  54. productName,
  55. productQuantity,
  56. summ
  57. }
  58. }
  59. const store = createStore(reducer)
  60. myState = store.getState()
  61. const showcase = document.createElement('section')
  62. document.body.append(showcase)
  63. showcase.classList.add('showcase')
  64. const orderSection = document.createElement('section')
  65. document.body.append(orderSection)
  66. orderSection.classList.add('orderSection')
  67. const orderSelectProd = document.createElement('select')
  68. orderSection.append(orderSelectProd)
  69. const orderInputQuantity = document.createElement('input')
  70. orderInputQuantity.type = 'number'
  71. orderInputQuantity.min = '0'
  72. orderSection.append(orderInputQuantity)
  73. const orderInputQuantityName = document.createElement('div')
  74. orderInputQuantity.before(orderInputQuantityName)
  75. orderInputQuantityName.innerText = 'количество товара:'
  76. const orderSendMoney = document.createElement('input')
  77. orderSendMoney.type = 'number'
  78. orderSendMoney.min = '0'
  79. orderSection.append(orderSendMoney)
  80. const orderSendMoneyName = document.createElement('div')
  81. orderSendMoney.before(orderSendMoneyName)
  82. orderSendMoneyName.innerText = 'сумма:'
  83. const orderBuyButton = document.createElement('input')
  84. orderBuyButton.type = 'button'
  85. orderBuyButton.value = 'КУПИТЬ'
  86. orderSection.append(orderBuyButton)
  87. orderBuyButton.onclick = () => { store.dispatch( actionCreator(orderBuyButton.value, orderSelectProd.value, +orderInputQuantity.value, +orderSendMoney.value ) ) }
  88. for (const elemProduct in store.getState()){
  89. if (elemProduct === 'касса') continue
  90. const productCard = document.createElement('div')
  91. const productName = document.createElement('h2')
  92. const productPrice = document.createElement('div')
  93. const productQuantity = document.createElement('div')
  94. productCard.append(productName)
  95. productCard.append(productQuantity)
  96. productCard.append(productPrice)
  97. showcase.append(productCard)
  98. productCard.classList.add('productCard')
  99. productName.classList.add('productName')
  100. productPrice.classList.add('productPrice')
  101. productQuantity.classList.add('productQuantity')
  102. productName.innerText = elemProduct
  103. productPrice.innerText = store.getState()[elemProduct].price + ' грн'
  104. productQuantity.innerText = store.getState()[elemProduct].quantity + ' шт\nв наличии'
  105. const selectProdOption = document.createElement('option')
  106. selectProdOption.value = selectProdOption.innerText = elemProduct
  107. orderSelectProd.append(selectProdOption)
  108. const productPriceUnsubscribe = store.subscribe( () => {
  109. productPrice.innerText = store.getState()[elemProduct].price + ' грн'
  110. } )
  111. const productQuantityUnsubscribe = store.subscribe( () => {
  112. productQuantity.innerText = store.getState()[elemProduct].quantity + ' шт\nв наличии'
  113. } )
  114. }