Olga_Brekhuntsova пре 2 година
родитељ
комит
91cd5e2901

+ 104 - 0
hw-js-11-redux-cart/.gitignore

@@ -0,0 +1,104 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+lerna-debug.log*
+
+# Diagnostic reports (https://nodejs.org/api/report.html)
+report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
+
+# Runtime data
+pids
+*.pid
+*.seed
+*.pid.lock
+
+# Directory for instrumented libs generated by jscoverage/JSCover
+lib-cov
+
+# Coverage directory used by tools like istanbul
+coverage
+*.lcov
+
+# nyc test coverage
+.nyc_output
+
+# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
+.grunt
+
+# Bower dependency directory (https://bower.io/)
+bower_components
+
+# node-waf configuration
+.lock-wscript
+
+# Compiled binary addons (https://nodejs.org/api/addons.html)
+build/Release
+
+# Dependency directories
+node_modules/
+jspm_packages/
+
+# TypeScript v1 declaration files
+typings/
+
+# TypeScript cache
+*.tsbuildinfo
+
+# Optional npm cache directory
+.npm
+
+# Optional eslint cache
+.eslintcache
+
+# Microbundle cache
+.rpt2_cache/
+.rts2_cache_cjs/
+.rts2_cache_es/
+.rts2_cache_umd/
+
+# Optional REPL history
+.node_repl_history
+
+# Output of 'npm pack'
+*.tgz
+
+# Yarn Integrity file
+.yarn-integrity
+
+# dotenv environment variables file
+.env
+.env.test
+
+# parcel-bundler cache (https://parceljs.org/)
+.cache
+
+# Next.js build output
+.next
+
+# Nuxt.js build / generate output
+.nuxt
+dist
+
+# Gatsby files
+.cache/
+# Comment in the public line in if your project uses Gatsby and *not* Next.js
+# https://nextjs.org/blog/next-9-1#public-directory-support
+# public
+
+# vuepress build output
+.vuepress/dist
+
+# Serverless directories
+.serverless/
+
+# FuseBox cache
+.fusebox/
+
+# DynamoDB Local files
+.dynamodb/
+
+# TernJS port file
+.tern-port

+ 12 - 0
hw-js-11-redux-cart/.prettierrc.json

@@ -0,0 +1,12 @@
+{
+    "printWidth": 80,
+    "tabWidth": 2,
+    "useTabs": false,
+    "semi": true,
+    "singleQuote": true,
+    "trailingComma": "all",
+    "bracketSpacing": true,
+    "jsxBracketSameLine": false,
+    "arrowParens": "avoid",
+    "proseWrap": "always"
+  }

+ 3 - 0
hw-js-11-redux-cart/.vscode/settings.json

@@ -0,0 +1,3 @@
+{
+  "liveServer.settings.port": 5503
+}

+ 2 - 0
hw-js-11-redux-cart/README.md

@@ -0,0 +1,2 @@
+# JS-1
+Hometask-1

+ 16 - 0
hw-js-11-redux-cart/index.css

@@ -0,0 +1,16 @@
+.wrapper {
+  width: 60%;
+  align-content: center;
+  margin: auto;
+  border: 1px green solid;
+  border-radius: 5px;
+  padding: 30px;
+}
+.inputWrapper {
+  text-align: center;
+}
+.tableWrapper {
+  display: flex;
+  justify-content: center;
+  margin-top: 20px;
+}

+ 30 - 0
hw-js-11-redux-cart/index.html

@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html lang="ru">
+<head>
+<meta charset="UTF-8" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+  <link rel="stylesheet" href="index.css">
+ <title>hw-js-11-redux-cart</title>
+</head>
+<body>
+<div class="wrapper">
+  <div class="inputWrapper">
+<label for="laryok"><b>Корзина</b></label><br/>
+<select name="laryok" id="laryok">
+  <option value="">--Выбери товар--</option>
+ </select>
+<input type="number" id="amount" placeholder="Сколько штук?">
+<input type="number" id="bablo" placeholder="Сколько даешь бабла?">
+<button id='buyButton'>Buy</button>
+</div>
+
+<div class='tableWrapper'>
+<table id="goodsTable" border="1">
+  
+</table>
+</div>
+</div>
+<script src="/js/cart.js" type="module"></script>
+</body>
+</html>
+

+ 81 - 0
hw-js-11-redux-cart/js/cart.js

@@ -0,0 +1,81 @@
+// +сделать отображение всего того, что есть в ларьке (можете хоть витрину нарисовать, если интересно) с количествами;
+//+ сделать select для выбора товара и input type = 'number' для выбора количества и кнопку "купить",
+// которая посылает action в store используя actionCreator для создания action
+// +добавить в reducer проверку на уход в минус, что бы нельзя было продать то, чего нет в должном количестве.
+// +добавить в state цену каждого товара и поле касса.Для этого вместо структуры вида пиво: 100 используйте
+// пиво: КАКОЙ - ТО ОБЪЕКТ С КОЛИЧЕСТВОМ И СТОИМОСТЬЮ ОДНОЙ ЕДИНИЦЫ.
+// +В action добавьте поле "бабло".Всё это пишется в reducer, не забудьте проверки что бабла хватает.
+// +добавьте в интерфейс поле для денег.
+
+
+
+
+function reducer(state, { type, ШО, СКОКА, бабло }) { //объект action деструктуризируется на три переменных
+    if (!state) { //начальная уборка в ларьке:
+        return {
+            пиво: { amount: 100, price: 20 },
+            чипсы: { amount: 100, price: 15 },
+            сиги: { amount: 100, price: 45 },
+            касса:0
+        }
+    }
+    if (type === 'КУПИТЬ') {
+                 //если тип action - КУПИТЬ, то:
+        if ((typeof state[ШО] !== "undefined") && ((СКОКА <= state[ШО]['amount']) && СКОКА > 0) && (бабло >= state[ШО]['price'] * СКОКА)) {
+ 
+            return {
+                ...state, //берем все что было из ассортимента
+                [ШО]: { 'amount': state[ШО]['amount'] - СКОКА, 'price': state[ШО]['price'] },
+                'касса': state['касса']+state[ШО]['price']*СКОКА
+                //и уменьшаем то, что покупается на количество
+            }
+                  
+        }
+        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()));
+
+for ( const item of Object.keys(store.getState())) { laryok.insertAdjacentHTML('beforeend', `<option >${item}</option>`)}
+
+buyButton.onclick = () => {
+    store.dispatch({ type: "КУПИТЬ", ШО: laryok.value, СКОКА: amount.value, бабло:bablo.value });
+drawTable()}
+
+function drawTable() {
+    goodsTable.innerHTML = "";
+     goodsTable.insertAdjacentHTML('beforeend', '<caption><b>Данные о товарах</b></caption><tr><th>Товар</th><th>Кол-во на складе</th><th>Цена</th></tr>');
+   
+    for (const item of Object.entries(store.getState())) {
+        if (item[0] !== 'касса') {
+            const good = document.createElement('tr');
+            good.innerHTML = `<td>${item[0]}</td><td>${item[1]['amount']}</td><td>${item[1]['price']}</td>`
+            goodsTable.appendChild(good);
+        }
+        }
+}
+drawTable();