// create Store function createStore(reducer) { let state = reducer(undefined, {}) let cbs = [] const getState = () => state const subscribe = cb => (cbs.push(cb), () => cbs = cbs.filter(c => c !== cb)) const dispatch = action => { const newState = reducer(state, action) if (newState !== state) { state = newState for (let cb of cbs) cb() } } return { getState, dispatch, subscribe } } // create Reduser function reducer(state, { type, ШО, СКОКА, БАБЛО, ШО_ДОБАВИТЬ, СКОКА_ДОБАВИТЬ, ЦЕНА_ДОБАВИТЬ }) { if (!state) { return { касса: 200, чай: 0, пиво: { amount: 110, price: 20 }, чипсы: { amount: 120, price: 30 }, сиги: { amount: 130, price: 50 } } } if (type === 'КУПИТЬ' && СКОКА <= state[ШО].amount && БАБЛО === (СКОКА * state[ШО].price)) { return { ...state, [ШО]: { amount: state[ШО].amount - СКОКА, price: state[ШО].price }, касса: state.касса + БАБЛО } } if (type === 'КУПИТЬ' && СКОКА <= state[ШО].amount && БАБЛО > (СКОКА * state[ШО].price)) { return { ...state, [ШО]: { amount: state[ШО].amount - СКОКА, price: state[ШО].price }, касса: state.касса + (СКОКА * state[ШО].price), чай: state.чай + (БАБЛО - (СКОКА * state[ШО].price)) } } if (type === 'ДОБАВИТЬ' && !(ШО_ДОБАВИТЬ in state) && state.касса >= (СКОКА_ДОБАВИТЬ * ЦЕНА_ДОБАВИТЬ)) { return { ...state, [ШО_ДОБАВИТЬ]: { amount: СКОКА_ДОБАВИТЬ, price: ЦЕНА_ДОБАВИТЬ }, касса: state.касса - (СКОКА_ДОБАВИТЬ * ЦЕНА_ДОБАВИТЬ) } } if (type === 'ДОБАВИТЬ' && ШО_ДОБАВИТЬ in state && state.касса >= (СКОКА_ДОБАВИТЬ * ЦЕНА_ДОБАВИТЬ)) { return { ...state, [ШО_ДОБАВИТЬ]: { amount: state[ШО_ДОБАВИТЬ].amount + СКОКА_ДОБАВИТЬ, price: ЦЕНА_ДОБАВИТЬ }, касса: state.касса - (СКОКА_ДОБАВИТЬ * ЦЕНА_ДОБАВИТЬ) } } return state } const store = createStore(reducer) // create divStore const divStore = document.createElement('div') divStore.style.cssText = ` min-width: 700px; width: 50%; border: 1px solid #A9A9A9; border-radius: 8px; box-shadow: rgb(0 0 0 / 50%) 5px 5px 5px 0px; padding: 20px;` document.body.append(divStore) // create divStore title const divStoreitle = document.createElement('h1') divStoreitle.innerText = 'ЛАРЕК' divStoreitle.style.cssText = ` text-align: center;` divStore.append(divStoreitle) // create Table of Store let table, col, row const createTable = () => { table = document.createElement('table') divStore.append(table) // create names of parametrs const params = [] for (const child of Object.values(store.getState())) { for (const key of Object.keys(child)) { if (!params.includes(key)) { params.push(key); } } } // create Header of table row = document.createElement('tr') table.append(row) // create first cell in Header col = document.createElement('td') row.append(col) // create header names for (const key of params) { col = document.createElement('td') col.innerText = `${key}` col.style.cssText = ` font-size: 1.5em; padding: 5px 10px; margin: 0 10px; text-align: center; background-color: #D9D9D9;` row.append(col) } // create table body for (const [key, values] of Object.entries(store.getState())) { if (key === 'касса') { row = document.createElement('tr') table.append(row) col = document.createElement('td') col.innerText = `${key.toUpperCase()}` col.style.cssText = ` min-width: 150px; font-size: 2em; padding: 5px 10px; text-align: left` row.append(col) col = document.createElement('td') col.innerText = `${values}` col.style.cssText = ` font-size: 2em; text-align: center;` row.append(col) } else if (key === 'чай') { row = document.createElement('tr') table.append(row) col = document.createElement('td') col.innerText = `На ${key.toUpperCase()} редюсеру-трудяге` col.style.cssText = ` min-width: 150px; font-size: 1.5em; padding: 5px 10px; text-align: left` row.append(col) col = document.createElement('td') col.innerText = `${values}` col.style.cssText = ` font-size: 1.5em; text-align: center;` row.append(col) } else { // рисуем строку заголовков row = document.createElement('tr') table.append(row) col = document.createElement('td') col.innerText = `${key.toUpperCase()}` col.style.cssText = ` min-width: 150px; font-size: 2em; padding: 5px 10px; text-align: left` row.append(col) // рисуем строки значений для товаров for (const name of params) { col = document.createElement('td') col.innerText = `${(Object.keys(values)).includes(name) ? values[name] : ''}` col.style.cssText = ` font-size: 1.5em; text-align: center` row.append(col) } } } return table } createTable() // start test in console.log store.subscribe(() => console.log(store.getState())) // create divWindow const divWindow = document.createElement('div') divWindow.style.cssText = ` min-width: 700px; width: 50%; padding: 10px; margin-top: 30px;` document.body.append(divWindow) // create divWindow title const divWindowitle = document.createElement('h2') divWindowitle.innerText = 'Покупка в ларьке' divWindowitle.style.cssText = ` text-align: center;` divWindow.append(divWindowitle) // create inputAmount const inputAmount = document.createElement('input') inputAmount.type = 'number' inputAmount.min = 0 inputAmount.placeholder = 'Количество товара' divWindow.append(inputAmount) // ceate inputMoney const inputMoney = document.createElement('input') inputMoney.type = 'number' inputMoney.min = 0 inputMoney.placeholder = 'Сумма, которую отдаете' divWindow.append(inputMoney) let selectProduct createListProduct = () => { // create selectProduct selectProduct = document.createElement('select') divWindow.insertBefore(selectProduct, inputMoney) for (let key of Object.keys(store.getState())) { if (key !== 'касса' && key !== 'чай') { let optionInput = document.createElement('option') optionInput.innerText = `${key}` selectProduct.append(optionInput) } } return selectProduct } createListProduct() // create buyButton const buyButton = document.createElement('button') buyButton.innerText = 'Купить' divWindow.append(buyButton) // create add div const divAdd = document.createElement('div') divAdd.style.cssText = ` min-width: 700px; width: 50%; margin-top: 40px;` document.body.append(divAdd) // create add div title const divAddTitle = document.createElement('h2') divAddTitle.innerText = 'Пополнение ларька' divAddTitle.style.cssText = ` text-align: center;` divAdd.append(divAddTitle) // create inputAddProduct const inputAddProduct = document.createElement('input') inputAddProduct.type = 'text' inputAddProduct.placeholder = 'Введите имя продукта' divAdd.append(inputAddProduct) // create inputAddAmount const inputAddAmount = document.createElement('input') inputAddAmount.type = 'number' inputAddAmount.min = 0 inputAddAmount.placeholder = 'Введите количество продукта' divAdd.append(inputAddAmount) // create inputAddPrice const inputAddPrice = document.createElement('input') inputAddPrice.type = 'number' inputAddPrice.min = 0 inputAddPrice.placeholder = 'Введите цену продукта' divAdd.append(inputAddPrice) // create addProductButton const addProductButton = document.createElement('button') addProductButton.innerText = 'Добавить продукт' divAdd.append(addProductButton) // mistake alert addProductButton.onclick = () => { if ((+inputAddAmount.value * +inputAddPrice.value) > store.getState().касса) { alert('В кассе нет столько денег! Давай торговаться?') } } // start addProductButton addProductButton.addEventListener('click', () => store.dispatch({ type: 'ДОБАВИТЬ', ШО_ДОБАВИТЬ: inputAddProduct.value, СКОКА_ДОБАВИТЬ: +inputAddAmount.value, ЦЕНА_ДОБАВИТЬ: +inputAddPrice.value })) // mistake alert buyButton.onclick = () => { if (+inputAmount.value > store.getState()[selectProduct.value].amount) { alert(`Количество товара, который вы хотите купить, больше, чем наличие на складе! На складе ${store.getState()[selectProduct.value].amount} единиц ${selectProduct.value}`) } else if (+inputMoney.value < (+inputAmount.value * store.getState()[selectProduct.value].price)) { alert(`Вы даете ${inputMoney.value}. А нужно ${+inputAmount.value * store.getState()[selectProduct.value].price}. Добавьте ${(+inputAmount.value * store.getState()[selectProduct.value].price) - +inputMoney.value}`) } } // start buyButton buyButton.addEventListener('click', () => store.dispatch({ type: 'КУПИТЬ', ШО: selectProduct.value, СКОКА: +inputAmount.value, БАБЛО: +inputMoney.value })) // Relaod table with new datas store.subscribe(() => { table.remove(), selectProduct.remove(), createTable(), createListProduct() })