index.html 7.5 KB

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