LenDoc 2 years ago
parent
commit
3159bc8049
3 changed files with 220 additions and 0 deletions
  1. 19 0
      js/12/index.html
  2. 152 0
      js/12/main.js
  3. 49 0
      js/12/style.css

+ 19 - 0
js/12/index.html

@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="UTF-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title> Redux </title>
+    <link rel="stylesheet" href="style.css">
+</head>
+
+<body>
+    <h2> WELCOME TO THE LENDOC SHOP ! </h2>
+    <button name="button" id="btn">КУПИТЬ</button>
+
+    <script src="main.js"></script>
+</body>
+
+</html>

+ 152 - 0
js/12/main.js

@@ -0,0 +1,152 @@
+const КУПИТЬ = 'КУПИТЬ'
+
+function reducer(state, { type, ШО, СКОКА, БАБЛО }) { //объект action деструктуризируется на три переменных
+    if (!state) { //начальная уборка в ларьке:
+        return {
+            пиво: {
+                quantity: 100,
+                price: 20
+            },
+            чипсы: {
+                quantity: 100,
+                price: 25
+            },
+            сиги: {
+                quantity: 100,
+                price: 60
+            },
+            сникерс: {
+                quantity: 100,
+                price: 15
+            },
+            вода: {
+                quantity: 100,
+                price: 10
+            },
+            касса: 0,
+        }
+    }
+
+    if (type === КУПИТЬ) { //если тип action - КУПИТЬ, то:
+        if ((state[ШО].quantity - СКОКА) < 0) {
+            alert('упс, вы ушли в минус, введите корректное количество')
+            return {
+                ...state, //берем все что было из ассортимента
+            }
+        }
+        if (БАБЛО < state[ШО].price * СКОКА) {
+            alert('упс, НЕ ХВАТАЕТ БАБЛА')
+            return {
+                ...state, //берем все что было из ассортимента
+            }
+        } else if ((БАБЛО > 0) && (СКОКА > 0)) {
+            {
+                return {
+                    ...state, //берем все что было из ассортимента
+                    [ШО]: {
+                        ...state[ШО],
+                        quantity: state[ШО].quantity - СКОКА
+                    },
+                    касса: state.касса + state[ШО].price * СКОКА,
+                    БАБЛО: БАБЛО - state[ШО].price * СКОКА
+                }
+            }
+
+        } else alert('вы внесли некорректные данные... попробуйте еще раз ...')
+    }
+
+
+    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 в объект
+    }
+}
+
+const store = createStore(reducer)
+store.subscribe(() => console.log(store.getState()))
+
+let selectProduct = document.createElement('select')
+selectProduct.id = "select"
+let input = document.createElement('input')
+input.placeholder = "quantity"
+input.type = "number"
+input.min = 0
+document.body.appendChild(input)
+let inputMoney = document.createElement('input')
+inputMoney.placeholder = "money"
+inputMoney.type = "number"
+inputMoney.min = 0
+document.body.appendChild(inputMoney)
+
+for (let key in (store.getState())) {
+    let option = document.createElement('option')
+    option.innerHTML = key
+    selectProduct.appendChild(option)
+}
+document.body.appendChild(selectProduct)
+let br = document.createElement("br")
+let table = document.createElement("table")
+document.body.append(table)
+
+function createTable() {
+    table.innerHTML = ""
+    for (let [keyName, storeValue] of Object.entries(store.getState())) {
+        let tr = document.createElement('tr')
+
+        if (typeof storeValue === "object") {
+            let thProduct = document.createElement('th')
+            thProduct.innerHTML = `${keyName}`
+            tr.appendChild(thProduct)
+
+            for (let [key, value] of Object.entries(storeValue)) {
+                let thKey = document.createElement('th')
+                let thValue = document.createElement('td')
+                thKey.innerHTML = ` ${key}`;
+                thValue.innerHTML = `${value}`
+                tr.appendChild(thKey)
+                tr.appendChild(thValue)
+            }
+
+        } else {
+            let thKey2 = document.createElement('th')
+            let thValue2 = document.createElement('td')
+            thKey2.innerHTML = `${keyName}`;
+            thValue2.innerHTML = ` ${storeValue}`
+            tr.appendChild(thKey2)
+            tr.appendChild(thValue2)
+        }
+        table.append(tr)
+    }
+
+
+}
+createTable()
+store.subscribe(() => createTable())
+let labelProduct = document.createElement('label')
+document.body.appendChild(br)
+document.body.appendChild(labelProduct)
+
+let btn = document.getElementById("btn")
+btn.onclick = (e) => {
+    store.dispatch({ type: КУПИТЬ, ШО: selectProduct.value, СКОКА: input.value, БАБЛО: inputMoney.value })
+}

+ 49 - 0
js/12/style.css

@@ -0,0 +1,49 @@
+h2 {
+    text-align: center;
+}
+
+body {
+    text-align: center;
+    font-size: medium;
+    font-family: Verdana
+}
+
+table {
+    margin-top: 30px;
+    text-align: center;
+    background-color: rgb(239, 248, 223);
+    color: rgb(6, 58, 55);
+}
+
+input {
+    font-size: medium;
+    font-family: Verdana
+}
+
+button {
+    font-size: medium;
+    font-family: Verdana
+}
+
+option {
+    font-size: medium;
+    font-family: Verdana
+}
+
+th {
+    border-style: solid;
+    padding: 10px;
+    text-align: center;
+}
+
+tr {
+    border-style: double;
+    padding: 5px;
+    text-align: center;
+}
+
+td {
+    border-style: double;
+    padding: 5px;
+    text-align: center;
+}