HW13.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. // create Store
  2. function createStore(reducer) {
  3. let state = reducer(undefined, {})
  4. let cbs = []
  5. const getState = () => state
  6. const subscribe = cb => (cbs.push(cb),
  7. () => cbs = cbs.filter(c => c !== cb))
  8. const dispatch = action => {
  9. const newState = reducer(state, action)
  10. if (newState !== state) {
  11. state = newState
  12. for (let cb of cbs) cb()
  13. }
  14. }
  15. return {
  16. getState,
  17. dispatch,
  18. subscribe
  19. }
  20. }
  21. // create Reduser
  22. function reducer(state, { type, ШО, СКОКА, БАБЛО, ШО_ДОБАВИТЬ, СКОКА_ДОБАВИТЬ, ЦЕНА_ДОБАВИТЬ }) {
  23. if (!state) {
  24. return {
  25. касса: 200,
  26. чай: 0,
  27. пиво: {
  28. amount: 110,
  29. price: 20
  30. },
  31. чипсы: {
  32. amount: 120,
  33. price: 30
  34. },
  35. сиги: {
  36. amount: 130,
  37. price: 50
  38. }
  39. }
  40. }
  41. if (type === 'КУПИТЬ' && СКОКА <= state[ШО].amount && БАБЛО === (СКОКА * state[ШО].price)) {
  42. return {
  43. ...state,
  44. [ШО]: {
  45. amount: state[ШО].amount - СКОКА,
  46. price: state[ШО].price
  47. },
  48. касса: state.касса + БАБЛО
  49. }
  50. }
  51. if (type === 'КУПИТЬ' && СКОКА <= state[ШО].amount && БАБЛО > (СКОКА * state[ШО].price)) {
  52. return {
  53. ...state,
  54. [ШО]: {
  55. amount: state[ШО].amount - СКОКА,
  56. price: state[ШО].price
  57. },
  58. касса: state.касса + (СКОКА * state[ШО].price),
  59. чай: state.чай + (БАБЛО - (СКОКА * state[ШО].price))
  60. }
  61. }
  62. if (type === 'ДОБАВИТЬ' && !(ШО_ДОБАВИТЬ in state) && state.касса >= (СКОКА_ДОБАВИТЬ * ЦЕНА_ДОБАВИТЬ)) {
  63. return {
  64. ...state,
  65. [ШО_ДОБАВИТЬ]: {
  66. amount: СКОКА_ДОБАВИТЬ,
  67. price: ЦЕНА_ДОБАВИТЬ
  68. },
  69. касса: state.касса - (СКОКА_ДОБАВИТЬ * ЦЕНА_ДОБАВИТЬ)
  70. }
  71. }
  72. if (type === 'ДОБАВИТЬ' && ШО_ДОБАВИТЬ in state && state.касса >= (СКОКА_ДОБАВИТЬ * ЦЕНА_ДОБАВИТЬ)) {
  73. return {
  74. ...state,
  75. [ШО_ДОБАВИТЬ]: {
  76. amount: state[ШО_ДОБАВИТЬ].amount + СКОКА_ДОБАВИТЬ,
  77. price: ЦЕНА_ДОБАВИТЬ
  78. },
  79. касса: state.касса - (СКОКА_ДОБАВИТЬ * ЦЕНА_ДОБАВИТЬ)
  80. }
  81. }
  82. return state
  83. }
  84. const store = createStore(reducer)
  85. // create divStore
  86. const divStore = document.createElement('div')
  87. divStore.style.cssText = `
  88. min-width: 700px;
  89. width: 50%;
  90. border: 1px solid #A9A9A9;
  91. border-radius: 8px;
  92. box-shadow: rgb(0 0 0 / 50%) 5px 5px 5px 0px;
  93. padding: 20px;`
  94. document.body.append(divStore)
  95. // create divStore title
  96. const divStoreitle = document.createElement('h1')
  97. divStoreitle.innerText = 'ЛАРЕК'
  98. divStoreitle.style.cssText = `
  99. text-align: center;`
  100. divStore.append(divStoreitle)
  101. // create Table of Store
  102. let table, col, row
  103. const createTable = () => {
  104. table = document.createElement('table')
  105. divStore.append(table)
  106. // create names of parametrs
  107. const params = []
  108. for (const child of Object.values(store.getState())) {
  109. for (const key of Object.keys(child)) {
  110. if (!params.includes(key)) {
  111. params.push(key);
  112. }
  113. }
  114. }
  115. // create Header of table
  116. row = document.createElement('tr')
  117. table.append(row)
  118. // create first cell in Header
  119. col = document.createElement('td')
  120. row.append(col)
  121. // create header names
  122. for (const key of params) {
  123. col = document.createElement('td')
  124. col.innerText = `${key}`
  125. col.style.cssText = `
  126. font-size: 1.5em;
  127. padding: 5px 10px;
  128. margin: 0 10px;
  129. text-align: center;
  130. background-color: #D9D9D9;`
  131. row.append(col)
  132. }
  133. // create table body
  134. for (const [key, values] of Object.entries(store.getState())) {
  135. if (key === 'касса') {
  136. row = document.createElement('tr')
  137. table.append(row)
  138. col = document.createElement('td')
  139. col.innerText = `${key.toUpperCase()}`
  140. col.style.cssText = `
  141. min-width: 150px;
  142. font-size: 2em;
  143. padding: 5px 10px;
  144. text-align: left`
  145. row.append(col)
  146. col = document.createElement('td')
  147. col.innerText = `${values}`
  148. col.style.cssText = `
  149. font-size: 2em;
  150. text-align: center;`
  151. row.append(col)
  152. } else if (key === 'чай') {
  153. row = document.createElement('tr')
  154. table.append(row)
  155. col = document.createElement('td')
  156. col.innerText = `На ${key.toUpperCase()} редюсеру-трудяге`
  157. col.style.cssText = `
  158. min-width: 150px;
  159. font-size: 1.5em;
  160. padding: 5px 10px;
  161. text-align: left`
  162. row.append(col)
  163. col = document.createElement('td')
  164. col.innerText = `${values}`
  165. col.style.cssText = `
  166. font-size: 1.5em;
  167. text-align: center;`
  168. row.append(col)
  169. } else {
  170. // рисуем строку заголовков
  171. row = document.createElement('tr')
  172. table.append(row)
  173. col = document.createElement('td')
  174. col.innerText = `${key.toUpperCase()}`
  175. col.style.cssText = `
  176. min-width: 150px;
  177. font-size: 2em;
  178. padding: 5px 10px;
  179. text-align: left`
  180. row.append(col)
  181. // рисуем строки значений для товаров
  182. for (const name of params) {
  183. col = document.createElement('td')
  184. col.innerText = `${(Object.keys(values)).includes(name) ? values[name] : ''}`
  185. col.style.cssText = `
  186. font-size: 1.5em;
  187. text-align: center`
  188. row.append(col)
  189. }
  190. }
  191. }
  192. return table
  193. }
  194. createTable()
  195. // start test in console.log
  196. store.subscribe(() => console.log(store.getState()))
  197. // create divWindow
  198. const divWindow = document.createElement('div')
  199. divWindow.style.cssText = `
  200. min-width: 700px;
  201. width: 50%;
  202. padding: 10px;
  203. margin-top: 30px;`
  204. document.body.append(divWindow)
  205. // create divWindow title
  206. const divWindowitle = document.createElement('h2')
  207. divWindowitle.innerText = 'Покупка в ларьке'
  208. divWindowitle.style.cssText = `
  209. text-align: center;`
  210. divWindow.append(divWindowitle)
  211. // create inputAmount
  212. const inputAmount = document.createElement('input')
  213. inputAmount.type = 'number'
  214. inputAmount.min = 0
  215. inputAmount.placeholder = 'Количество товара'
  216. divWindow.append(inputAmount)
  217. // ceate inputMoney
  218. const inputMoney = document.createElement('input')
  219. inputMoney.type = 'number'
  220. inputMoney.min = 0
  221. inputMoney.placeholder = 'Сумма, которую отдаете'
  222. divWindow.append(inputMoney)
  223. let selectProduct
  224. createListProduct = () => {
  225. // create selectProduct
  226. selectProduct = document.createElement('select')
  227. divWindow.insertBefore(selectProduct, inputMoney)
  228. for (let key of Object.keys(store.getState())) {
  229. if (key !== 'касса' && key !== 'чай') {
  230. let optionInput = document.createElement('option')
  231. optionInput.innerText = `${key}`
  232. selectProduct.append(optionInput)
  233. }
  234. }
  235. return selectProduct
  236. }
  237. createListProduct()
  238. // create buyButton
  239. const buyButton = document.createElement('button')
  240. buyButton.innerText = 'Купить'
  241. divWindow.append(buyButton)
  242. // create add div
  243. const divAdd = document.createElement('div')
  244. divAdd.style.cssText = `
  245. min-width: 700px;
  246. width: 50%;
  247. margin-top: 40px;`
  248. document.body.append(divAdd)
  249. // create add div title
  250. const divAddTitle = document.createElement('h2')
  251. divAddTitle.innerText = 'Пополнение ларька'
  252. divAddTitle.style.cssText = `
  253. text-align: center;`
  254. divAdd.append(divAddTitle)
  255. // create inputAddProduct
  256. const inputAddProduct = document.createElement('input')
  257. inputAddProduct.type = 'text'
  258. inputAddProduct.placeholder = 'Введите имя продукта'
  259. divAdd.append(inputAddProduct)
  260. // create inputAddAmount
  261. const inputAddAmount = document.createElement('input')
  262. inputAddAmount.type = 'number'
  263. inputAddAmount.min = 0
  264. inputAddAmount.placeholder = 'Введите количество продукта'
  265. divAdd.append(inputAddAmount)
  266. // create inputAddPrice
  267. const inputAddPrice = document.createElement('input')
  268. inputAddPrice.type = 'number'
  269. inputAddPrice.min = 0
  270. inputAddPrice.placeholder = 'Введите цену продукта'
  271. divAdd.append(inputAddPrice)
  272. // create addProductButton
  273. const addProductButton = document.createElement('button')
  274. addProductButton.innerText = 'Добавить продукт'
  275. divAdd.append(addProductButton)
  276. // mistake alert
  277. addProductButton.onclick = () => {
  278. if ((+inputAddAmount.value * +inputAddPrice.value) > store.getState().касса) {
  279. alert('В кассе нет столько денег! Давай торговаться?')
  280. }
  281. }
  282. // start addProductButton
  283. addProductButton.addEventListener('click', () => store.dispatch({ type: 'ДОБАВИТЬ', ШО_ДОБАВИТЬ: inputAddProduct.value, СКОКА_ДОБАВИТЬ: +inputAddAmount.value, ЦЕНА_ДОБАВИТЬ: +inputAddPrice.value }))
  284. // mistake alert
  285. buyButton.onclick = () => {
  286. if (+inputAmount.value > store.getState()[selectProduct.value].amount) {
  287. alert(`Количество товара, который вы хотите купить, больше, чем наличие на складе! На складе ${store.getState()[selectProduct.value].amount} единиц ${selectProduct.value}`)
  288. } else if (+inputMoney.value < (+inputAmount.value * store.getState()[selectProduct.value].price)) {
  289. alert(`Вы даете ${inputMoney.value}. А нужно ${+inputAmount.value * store.getState()[selectProduct.value].price}. Добавьте ${(+inputAmount.value * store.getState()[selectProduct.value].price) - +inputMoney.value}`)
  290. }
  291. }
  292. // start buyButton
  293. buyButton.addEventListener('click', () => store.dispatch({ type: 'КУПИТЬ', ШО: selectProduct.value, СКОКА: +inputAmount.value, БАБЛО: +inputMoney.value }))
  294. // Relaod table with new datas
  295. store.subscribe(() => {
  296. table.remove(),
  297. selectProduct.remove(),
  298. createTable(),
  299. createListProduct()
  300. })