123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- <header>KIOSK</header>
- <body>
- <script>
- const addCell = (row, value) => {
- let cell = document.createElement("td");
- cell.innerText = value;
- row.append(cell);
- return cell;
- }
- const createAssortTable = (store) => {
- let state = store.getState();
- let table = document.createElement("table");
- let row = document.createElement("tr");
- table.append(row);
- addCell(row, "NAME");
- addCell(row, "PRICE");
- addCell(row, "AMOUNT");
- for (const itemKey in state) {
- if (itemKey == "cashbox")
- continue;
- let item = state[itemKey];
- let row = document.createElement("tr");
- table.append(row);
- addCell(row, itemKey);
- addCell(row, item.price);
- let amountVal = addCell(row, item.amount);
- store.subscribe(() => {
- const state = store.getState();
- const item = state[itemKey];
- const amount = item.amount;
- amountVal.innerText = amount;
- });
- //store.getState()[itemKey].amount);
- }
- return table;
- }
- const addLabel = (element, value) => {
- let label = document.createElement("label");
- label.htmlFor = element.id;
- label.innerText = value + ": ";
- element.parentElement.insertBefore(label, element);
- }
- const addBr = (element) => element.append(document.createElement("br"));
- const createSale = (store) => {
- let state = store.getState();
- let resDiv = document.createElement("div")
- let select = document.createElement("select");
- resDiv.append(select);
- for (itemKey in state) {
- if (itemKey == "cashbox")
- continue;
- let option = document.createElement("option");
- option.value = itemKey;
- option.text = itemKey;
- select.append(option);
- }
- select.onchange = () => {
- priceDiv.innerText = state[select.value].price;
- }
- addLabel(select, "NAME");
- addBr(resDiv);
- let priceDiv = document.createElement("a");
- priceDiv.innerText = state[select.value].price;
- priceDiv.id = "priceId";
- resDiv.append(priceDiv);
- addLabel(priceDiv, "price");
- addBr(resDiv);
- let amountInp = document.createElement("input");
- amountInp.id = "amountId";
- amountInp.value = 0;
- resDiv.append(amountInp);
- addLabel(amountInp, "amount");
- addBr(resDiv);
- let cashInp = document.createElement("input");
- cashInp.id = "cashId";
- cashInp.value = 0;
- resDiv.append(cashInp);
- addLabel(cashInp, "cash");
- addBr(resDiv);
- let buyBtn = document.createElement("button");
- buyBtn.innerText = "BUY";
- buyBtn.onclick = () => {
- store.dispatch({ type: 'BUY', item: select.value, amount: +amountInp.value, cash: +cashInp.value });
- }
- resDiv.append(buyBtn);
- return resDiv;
- }
- function CreateStore(reducer) {
- let state = reducer(undefined, {}) //стартовая инициализация состояния, запуск редьюсера со state === undefined
- let cbs = [] //массив подписчиков
- this.getState = () => state //функция, возвращающая переменную из замыкания
- this.subscribe = cb => (cbs.push(cb), //запоминаем подписчиков в массиве
- () => cbs = cbs.filter(c => c !== cb)) //возвращаем функцию unsubscribe, которая удаляет подписчика из списка
- this.dispatch = action => {
- const newState = reducer(state, action) //пробуем запустить редьюсер
- if (newState !== state) { //проверяем, смог ли редьюсер обработать action
- state = newState //если смог, то обновляем state
- for (let cb of cbs) cb() //и запускаем подписчиков
- }
- }
- }
- const seller = (state, { type, item, amount, cash, price }) => {
- if (state === undefined) {
- state = {
- beer: { amount: 20, price: 10 },
- vodka: { amount: 10, price: 30 },
- cigars: { amount: 100, price: 20 },
- cashbox: 0,
- }
- }
- if (type === 'BUY' &&
- item in state &&
- typeof amount == "number" &&
- typeof cash == "number" &&
- state[item].amount >= amount &&
- amount > 0 &&
- cash > 0 &&
- state[item].price <= cash / amount) { //если тип action - КУПИТЬ, то:
- return {
- ...state, //берем все что было из ассортимента
- [item]: { amount: state[item].amount - amount, price: state[item].price }, //и уменьшаем то, что покупается на количество
- cashbox: state.cashbox + amount * state[item].price,
- }
- }
- return state;
- }
- let store = new CreateStore(seller);
- const unsubscribe = store.subscribe(() => console.log(store.getState()))
- document.body.append(createAssortTable(store));
- document.body.append(document.createElement("br"));
- document.body.append(createSale(store));
- </script>
- </body>
- <footer>
- </footer>
|