|
@@ -0,0 +1,140 @@
|
|
|
+
|
|
|
+function reducer(state, {type, productName, productQuantity, summ}){ //объект action деструктуризируется на три переменных
|
|
|
+ if (!state){ //начальная уборка в ларьке:
|
|
|
+ return {
|
|
|
+ пиво: {
|
|
|
+ quantity: 100,
|
|
|
+ price: 30,
|
|
|
+ },
|
|
|
+ чипсы: {
|
|
|
+ quantity: 100,
|
|
|
+ price: 52,
|
|
|
+ },
|
|
|
+ сиги: {
|
|
|
+ quantity: 100,
|
|
|
+ price: 89,
|
|
|
+ },
|
|
|
+ касса: 0
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (type === 'КУПИТЬ' && productQuantity <= state[productName].quantity && summ >= state[productName].price * productQuantity){ //если тип action - КУПИТЬ, то:
|
|
|
+ return {
|
|
|
+ ...state, //берем все что было из ассортимента
|
|
|
+ [productName]: {
|
|
|
+ quantity: state[productName].quantity - productQuantity,
|
|
|
+ price: state[productName].price
|
|
|
+ },
|
|
|
+ касса: state.касса + state[productName].price * productQuantity
|
|
|
+ //и уменьшаем то, что покупается на количество
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return state //если мы не поняли, что от нас просят в `action` - оставляем все как есть
|
|
|
+}
|
|
|
+
|
|
|
+function createStore(reducer){
|
|
|
+ let state = reducer(undefined, {}) //стартовая инициализация состояния, запуск редьюсера со state === undefined
|
|
|
+ let cbs = [] //массив подписчиков
|
|
|
+
|
|
|
+ const getState = () => state //функция, возвращающая переменную из замыкания
|
|
|
+ const subscribe = cb => (cbs.push(cb), //запоминаем подписчиков в массиве
|
|
|
+ () => cbs = cbs.filter(c => c !== cb)) //возвращаем функцию unsubscribe, которая удаляет подписчика из списка
|
|
|
+
|
|
|
+ const dispatch = action => {
|
|
|
+ const newState = reducer(state, action) //пробуем запустить редьюсер
|
|
|
+ if (newState !== state){ //проверяем, смог ли редьюсер обработать action
|
|
|
+ state = newState //если смог, то обновляем state
|
|
|
+ for (let cb of cbs) cb() //и запускаем подписчиков
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return {
|
|
|
+ getState, //добавление функции getState в результирующий объект
|
|
|
+ dispatch,
|
|
|
+ subscribe //добавление subscribe в объект
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function actionCreator (type, productName, productQuantity, summ){
|
|
|
+ return {
|
|
|
+ type,
|
|
|
+ productName,
|
|
|
+ productQuantity,
|
|
|
+ summ
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const store = createStore(reducer)
|
|
|
+myState = store.getState()
|
|
|
+
|
|
|
+const showcase = document.createElement('section')
|
|
|
+document.body.append(showcase)
|
|
|
+showcase.classList.add('showcase')
|
|
|
+
|
|
|
+const orderSection = document.createElement('section')
|
|
|
+document.body.append(orderSection)
|
|
|
+orderSection.classList.add('orderSection')
|
|
|
+
|
|
|
+const orderSelectProd = document.createElement('select')
|
|
|
+orderSection.append(orderSelectProd)
|
|
|
+
|
|
|
+const orderInputQuantity = document.createElement('input')
|
|
|
+orderInputQuantity.type = 'number'
|
|
|
+orderInputQuantity.min = '0'
|
|
|
+orderSection.append(orderInputQuantity)
|
|
|
+
|
|
|
+const orderInputQuantityName = document.createElement('div')
|
|
|
+orderInputQuantity.before(orderInputQuantityName)
|
|
|
+orderInputQuantityName.innerText = 'количество товара:'
|
|
|
+
|
|
|
+const orderSendMoney = document.createElement('input')
|
|
|
+orderSendMoney.type = 'number'
|
|
|
+orderSendMoney.min = '0'
|
|
|
+orderSection.append(orderSendMoney)
|
|
|
+
|
|
|
+const orderSendMoneyName = document.createElement('div')
|
|
|
+orderSendMoney.before(orderSendMoneyName)
|
|
|
+orderSendMoneyName.innerText = 'сумма:'
|
|
|
+
|
|
|
+const orderBuyButton = document.createElement('input')
|
|
|
+orderBuyButton.type = 'button'
|
|
|
+orderBuyButton.value = 'КУПИТЬ'
|
|
|
+orderSection.append(orderBuyButton)
|
|
|
+orderBuyButton.onclick = () => { store.dispatch( actionCreator(orderBuyButton.value, orderSelectProd.value, +orderInputQuantity.value, +orderSendMoney.value ) ) }
|
|
|
+
|
|
|
+
|
|
|
+for (const elemProduct in store.getState()){
|
|
|
+ if (elemProduct === 'касса') continue
|
|
|
+
|
|
|
+ const productCard = document.createElement('div')
|
|
|
+ const productName = document.createElement('h2')
|
|
|
+ const productPrice = document.createElement('div')
|
|
|
+ const productQuantity = document.createElement('div')
|
|
|
+
|
|
|
+ productCard.append(productName)
|
|
|
+ productCard.append(productQuantity)
|
|
|
+ productCard.append(productPrice)
|
|
|
+ showcase.append(productCard)
|
|
|
+
|
|
|
+ productCard.classList.add('productCard')
|
|
|
+ productName.classList.add('productName')
|
|
|
+ productPrice.classList.add('productPrice')
|
|
|
+ productQuantity.classList.add('productQuantity')
|
|
|
+
|
|
|
+ productName.innerText = elemProduct
|
|
|
+ productPrice.innerText = store.getState()[elemProduct].price + ' грн'
|
|
|
+ productQuantity.innerText = store.getState()[elemProduct].quantity + ' шт\nв наличии'
|
|
|
+
|
|
|
+ const selectProdOption = document.createElement('option')
|
|
|
+ selectProdOption.value = selectProdOption.innerText = elemProduct
|
|
|
+ orderSelectProd.append(selectProdOption)
|
|
|
+ const productPriceUnsubscribe = store.subscribe( () => {
|
|
|
+ productPrice.innerText = store.getState()[elemProduct].price + ' грн'
|
|
|
+ } )
|
|
|
+ const productQuantityUnsubscribe = store.subscribe( () => {
|
|
|
+ productQuantity.innerText = store.getState()[elemProduct].quantity + ' шт\nв наличии'
|
|
|
+ } )
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|