script.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803
  1. function createStore(reducer) {
  2. let state = reducer(undefined, {}); //стартовая инициализация состояния, запуск редьюсера со state === undefined
  3. let cbs = []; //массив подписчиков
  4. const getState = () => state; //функция, возвращающая переменную из замыкания
  5. const subscribe = (cb) => (
  6. cbs.push(cb), //запоминаем подписчиков в массиве
  7. () => (cbs = cbs.filter((c) => c !== cb))
  8. ); //возвращаем функцию unsubscribe, которая удаляет подписчика из списка
  9. const dispatch = (action) => {
  10. if (typeof action === "function") {
  11. //если action - не объект, а функция
  12. return action(dispatch, getState); //запускаем эту функцию и даем ей dispatch и getState для работы
  13. }
  14. const newState = reducer(state, action); //пробуем запустить редьюсер
  15. if (newState !== state) {
  16. //проверяем, смог ли редьюсер обработать action
  17. state = newState; //если смог, то обновляем state
  18. for (let cb of cbs) cb(); //и запускаем подписчиков
  19. }
  20. };
  21. return {
  22. getState, //добавление функции getState в результирующий объект
  23. dispatch,
  24. subscribe, //добавление subscribe в объект
  25. };
  26. }
  27. function jwtDecode(token) {
  28. try {
  29. return JSON.parse(atob(token.split(".")[1]));
  30. } catch (e) {}
  31. }
  32. function authReducer(state, { type, token }) {
  33. if (state === undefined) {
  34. if (localStorage.authToken) {
  35. type = "AUTH_LOGIN";
  36. token = localStorage.authToken;
  37. }
  38. }
  39. if (type === "AUTH_LOGIN") {
  40. let payload = jwtDecode(token);
  41. if (payload) {
  42. localStorage.authToken = token;
  43. return { token, payload };
  44. }
  45. }
  46. if (type === "AUTH_LOGOUT") {
  47. localStorage.removeItem("authToken");
  48. return {};
  49. }
  50. return state || {};
  51. }
  52. const actionAuthLogin = (token) => ({ type: "AUTH_LOGIN", token });
  53. const actionAuthLogout = () => (dispatch) => {
  54. dispatch({ type: "AUTH_LOGOUT" });
  55. localStorage.removeItem("authToken");
  56. };
  57. function promiseReducer(state = {}, { type, name, status, payload, error }) {
  58. if (type === "PROMISE") {
  59. return {
  60. ...state,
  61. [name]: { status, payload, error },
  62. };
  63. }
  64. return state;
  65. }
  66. const actionPending = (name) => ({
  67. type: "PROMISE",
  68. status: "PENDING",
  69. name,
  70. });
  71. const actionFulfilled = (name, payload) => ({
  72. type: "PROMISE",
  73. status: "FULFILLED",
  74. name,
  75. payload,
  76. });
  77. const actionRejected = (name, error) => ({
  78. type: "PROMISE",
  79. status: "REJECTED",
  80. name,
  81. error,
  82. });
  83. const actionPromise = (name, promise) => async (dispatch) => {
  84. try {
  85. dispatch(actionPending(name));
  86. let payload = await promise;
  87. dispatch(actionFulfilled(name, payload));
  88. return payload;
  89. } catch (e) {
  90. dispatch(actionRejected(name, e));
  91. }
  92. };
  93. function cartReducer(state = {}, { type, count = 1, good }) {
  94. // type CART_ADD CART_REMOVE CART_CLEAR CART_DEL
  95. // {
  96. // id1: {count: 1, good: {name, price, images, id}}
  97. // }
  98. if (type === "CART_ADD") {
  99. return {
  100. ...state,
  101. [good._id]: { count: count + (state[good._id]?.count || 0), good },
  102. };
  103. }
  104. if (type === "CART_DELETE") {
  105. if (state[good._id].count > 1) {
  106. return {
  107. ...state,
  108. [good._id]: {
  109. count: -count + (state[good._id]?.count || 0),
  110. good,
  111. },
  112. };
  113. }
  114. if (state[good._id].count === 1) {
  115. let { [good._id]: id1, ...newState } = state; //o4en strashnoe koldunstvo
  116. //delete newState[good._id]
  117. return newState;
  118. }
  119. }
  120. if (type === "CART_CLEAR") {
  121. return {};
  122. }
  123. if (type === "CART_REMOVE") {
  124. // let newState = {...state}
  125. let { [good._id]: id1, ...newState } = state; //o4en strashnoe koldunstvo
  126. //delete newState[good._id]
  127. return newState;
  128. }
  129. return state;
  130. }
  131. const actionCartAdd = (good, count = 1) => ({ type: "CART_ADD", good, count });
  132. const actionCartDelete = (good) => ({ type: "CART_DELETE", good });
  133. const actionCartClear = () => ({ type: "CART_CLEAR" });
  134. const actionCartRemove = (good) => ({ type: "CART_REMOVE", good });
  135. function localStoreReducer(reducer, localStorageKey) {
  136. function localStoredReducer(state, action) {
  137. // Если state === undefined, то достать старый state из local storage
  138. if (state === undefined) {
  139. try {
  140. return JSON.parse(localStorage[localStorageKey]);
  141. } catch (e) {}
  142. }
  143. const newState = reducer(state, action);
  144. // Сохранить newState в local storage
  145. localStorage[localStorageKey] = JSON.stringify(newState);
  146. return newState;
  147. }
  148. return localStoredReducer;
  149. }
  150. const delay = (ms) => new Promise((ok) => setTimeout(() => ok(ms), ms));
  151. function combineReducers(reducers) {
  152. //пачку редьюсеров как объект {auth: authReducer, promise: promiseReducer}
  153. function combinedReducer(combinedState = {}, action) {
  154. //combinedState - типа {auth: {...}, promise: {....}}
  155. const newCombinedState = {};
  156. for (const [reducerName, reducer] of Object.entries(reducers)) {
  157. const newSubState = reducer(combinedState[reducerName], action);
  158. if (newSubState !== combinedState[reducerName]) {
  159. newCombinedState[reducerName] = newSubState;
  160. }
  161. }
  162. if (Object.keys(newCombinedState).length === 0) {
  163. return combinedState;
  164. }
  165. return { ...combinedState, ...newCombinedState };
  166. }
  167. return combinedReducer; //нам возвращают один редьюсер, который имеет стейт вида {auth: {...стейт authReducer-а}, promise: {...стейт promiseReducer-а}}
  168. }
  169. const getGQL = (url) => (query, variables) =>
  170. fetch(url, {
  171. method: "POST",
  172. headers: {
  173. "Content-Type": "application/json",
  174. // 'Accept' : 'application/json',
  175. ...(localStorage.authToken
  176. ? { Authorization: "Bearer " + localStorage.authToken }
  177. : {}),
  178. },
  179. body: JSON.stringify({ query, variables }),
  180. })
  181. .then((res) => res.json())
  182. .then((data) => {
  183. if (data.data) {
  184. return Object.values(data.data)[0];
  185. } else throw new Error(JSON.stringify(data.errors));
  186. });
  187. const backendURL = "http://shop-roles.node.ed.asmer.org.ua";
  188. const gql = getGQL(backendURL + "/graphql");
  189. const store = createStore(
  190. combineReducers({
  191. auth: authReducer,
  192. promise: promiseReducer,
  193. cart: localStoreReducer(cartReducer, "cart"),
  194. })
  195. ); //не забудьте combineReducers если он у вас уже есть
  196. if (localStorage.authToken) {
  197. store.dispatch(actionAuthLogin(localStorage.authToken));
  198. }
  199. //const store = createStore(combineReducers({promise: promiseReducer, auth: authReducer, cart: cartReducer}))
  200. store.subscribe(() => console.log(store.getState()));
  201. // const backendURL = "http://shop-roles.node.ed.asmer.org.ua/graphql";
  202. // const backendURLNotGraphQL = "http://shop-roles.node.ed.asmer.org.ua";
  203. // const gql = (url, query, variables) =>
  204. // fetch(url, {
  205. // method: "POST",
  206. // headers: {
  207. // "Content-Type": "application/json",
  208. // Accept: "application/json",
  209. // },
  210. // body: JSON.stringify({ query, variables }),
  211. // }).then((res) => res.json());
  212. const actionRootCats = () =>
  213. actionPromise(
  214. "rootCats",
  215. gql(
  216. `query {
  217. CategoryFind(query: "[{\\"parent\\":null}]"){
  218. _id name
  219. }
  220. }`
  221. )
  222. );
  223. const actionCatById = (_id) =>
  224. actionPromise(
  225. "catById",
  226. gql(
  227. `query catById($q: String){
  228. CategoryFindOne(query: $q){
  229. _id name subCategories {
  230. name _id
  231. }
  232. goods {
  233. _id name price images {
  234. url
  235. }
  236. }
  237. }
  238. }`,
  239. { q: JSON.stringify([{ _id }]) }
  240. )
  241. );
  242. const actionLogin = (login, password) =>
  243. actionPromise(
  244. "actionLogin",
  245. gql(
  246. `query log($login:String, $password:String){
  247. login(login:$login, password:$password)
  248. }`,
  249. { login, password }
  250. )
  251. );
  252. const actionGoodById = (_id) =>
  253. actionPromise(
  254. "GoodFineOne",
  255. gql(
  256. `query goodByid($goodId: String) {
  257. GoodFindOne(query: $goodId) {
  258. _id
  259. name
  260. price
  261. description
  262. images {
  263. url
  264. }
  265. }
  266. }`,
  267. { goodId: JSON.stringify([{ _id }]) }
  268. )
  269. );
  270. store.dispatch(actionRootCats());
  271. const actionFullLogin = (log, pass) => async (dispatch) => {
  272. let token = await dispatch(
  273. actionPromise(
  274. "login",
  275. gql(
  276. `query login($login: String, $password: String) {
  277. login(login: $login, password: $password)
  278. }`,
  279. { login: log, password: pass }
  280. )
  281. )
  282. );
  283. if (token) {
  284. dispatch(actionAuthLogin(token));
  285. }
  286. };
  287. const actionFullRegister = (login, password) => async (dispatch) => {
  288. let user = await dispatch(
  289. actionPromise(
  290. "register",
  291. gql(
  292. `mutation register($login: String, $password: String) {
  293. UserUpsert(user: {login: $login, password: $password}) {
  294. _id
  295. login
  296. }
  297. }`,
  298. { login: login, password: password }
  299. )
  300. )
  301. );
  302. if (user) {
  303. dispatch(actionFullLogin(login, password));
  304. }
  305. };
  306. const actionOrder = () => async (dispatch, getState) => {
  307. let { cart } = getState();
  308. const orderGoods = Object.entries(cart).map(([_id, { count }]) => ({
  309. good: { _id },
  310. count,
  311. }));
  312. let result = await dispatch(
  313. actionPromise(
  314. "order",
  315. gql(
  316. `
  317. mutation newOrder($order:OrderInput){
  318. OrderUpsert(order:$order)
  319. { _id total }
  320. }
  321. `,
  322. { order: { orderGoods } }
  323. )
  324. )
  325. );
  326. if (result?._id) {
  327. dispatch(actionCartClear());
  328. document.location.hash = "#/cart/";
  329. alert("Поздравляем, вы оформили заказ!");
  330. }
  331. };
  332. const orderHistory = () =>
  333. actionPromise(
  334. "history",
  335. gql(` query OrderFind{
  336. OrderFind(query:"[{}]"){
  337. _id total createdAt orderGoods{
  338. count good{
  339. _id name price images{
  340. url
  341. }
  342. }
  343. owner{
  344. _id login
  345. }
  346. }
  347. }
  348. }
  349. `)
  350. );
  351. store.subscribe(() => {
  352. const { rootCats } = store.getState().promise;
  353. if (rootCats?.payload) {
  354. aside.innerHTML = "";
  355. for (let { _id, name } of rootCats?.payload) {
  356. const a = document.createElement("a");
  357. a.href = `#/category/${_id}`;
  358. a.innerHTML = name;
  359. aside.append(a);
  360. }
  361. }
  362. });
  363. store.subscribe(() => {
  364. const { catById } = store.getState().promise;
  365. const [, route] = location.hash.split("/");
  366. if (catById?.payload && route === "category") {
  367. const { name, goods, subCategories } = catById?.payload;
  368. categoryName.innerHTML = `<h1>${name}</h1>`;
  369. var element = document.getElementById("productBlock");
  370. while (element.firstChild) {
  371. element.removeChild(element.firstChild);
  372. }
  373. if (subCategories) {
  374. for (let { name, _id } of subCategories) {
  375. const link = document.createElement("a");
  376. link.id = "subCategories";
  377. link.href = `#/category/${_id}`;
  378. link.innerText = name;
  379. productBlock.append(link);
  380. }
  381. }
  382. for (let { _id, name, price, images } of goods) {
  383. const description = document.createElement("div");
  384. const textBlock = document.createElement("div");
  385. const imgProduct = document.createElement("img");
  386. const a = document.createElement("p");
  387. const productPrice = document.createElement("p");
  388. const linkCard = document.createElement("a");
  389. productBlock.append(linkCard);
  390. linkCard.href = `#/good/${_id}`;
  391. linkCard.append(description);
  392. description.setAttribute("class", "card");
  393. description.id = "card";
  394. description.append(imgProduct);
  395. imgProduct.src = `${backendURL}/${images[0].url}`;
  396. description.append(textBlock);
  397. a.innerHTML = name;
  398. textBlock.append(a);
  399. productPrice.innerHTML = "price: " + price;
  400. textBlock.append(productPrice);
  401. const addToCartButton = document.createElement("p");
  402. addToCartButton.innerText = "click to buy";
  403. addToCartButton.className = "addToCartButton";
  404. textBlock.append(addToCartButton);
  405. }
  406. }
  407. });
  408. const flexBlockForGFO = document.createElement("div");
  409. flexBlockForGFO.id = "flexBlockForGFO";
  410. const goodFineOneImgBlock = document.createElement("div");
  411. const goodFineOneTextBlock = document.createElement("div");
  412. const goodFineOneName = document.createElement("h2");
  413. const goodFineOneImg = document.createElement("img");
  414. const goodFineOnePrice = document.createElement("p");
  415. const goodFineOneDescription = document.createElement("p");
  416. const goodFineOneAddToCartButton = document.createElement("button");
  417. const buttonPlus = document.createElement("button");
  418. const buttonMinus = document.createElement("button");
  419. buttonPlus.innerHTML = "+";
  420. buttonMinus.innerHTML = "-";
  421. store.subscribe(() => {
  422. const { GoodFineOne } = store.getState().promise;
  423. const [, route, _id] = location.hash.split("/");
  424. if (GoodFineOne?.payload && route === "good") {
  425. productBlock.innerHTML = "";
  426. const { name, images, price, description } = GoodFineOne?.payload;
  427. productBlock.append(flexBlockForGFO);
  428. flexBlockForGFO.append(goodFineOneImgBlock);
  429. goodFineOneImg.src = `${backendURL}/${images[0].url}`;
  430. goodFineOneImg.id = "goodOneImg";
  431. goodFineOneImgBlock.append(goodFineOneImg);
  432. flexBlockForGFO.append(goodFineOneTextBlock);
  433. goodFineOneName.innerHTML = name;
  434. goodFineOneTextBlock.append(goodFineOneName);
  435. goodFineOnePrice.innerHTML = "price: " + price;
  436. goodFineOneTextBlock.append(goodFineOnePrice);
  437. goodFineOneDescription.innerHTML = description;
  438. goodFineOneTextBlock.append(goodFineOneDescription);
  439. goodFineOneAddToCartButton.innerHTML = "add to cart";
  440. goodFineOneTextBlock.append(goodFineOneAddToCartButton);
  441. goodFineOneAddToCartButton.onclick = () => {
  442. store.dispatch(actionCartAdd(GoodFineOne.payload));
  443. };
  444. }
  445. });
  446. const bPoputDeleteBlock = document.createElement("div");
  447. const bPoput = document.createElement("div");
  448. bPoput.className = "b-popup";
  449. bPoput.id = "b-popup";
  450. const bPoputContainer = document.createElement("div");
  451. bPoputContainer.className = "b-popup-content";
  452. bPoputContainer.id = "b-popup-content";
  453. const buttonGoodDeleteBlock = document.createElement("div");
  454. buttonGoodDeleteBlock.id = "buttonGoodDeleteBlock";
  455. const buttonCloseCart = document.createElement("button");
  456. buttonCloseCart.innerText = `×`;
  457. buttonCloseCart.id = "buttonCloseCartId";
  458. const buttonGoodDelete = document.createElement("button");
  459. buttonGoodDelete.innerText = "delete";
  460. buttonGoodDelete.id = "buttonDelete";
  461. shoppingCart.onclick = () => {
  462. header.append(bPoput);
  463. bPoput.append(bPoputContainer);
  464. };
  465. bPoputContainer.append(buttonGoodDeleteBlock);
  466. buttonGoodDeleteBlock.append(buttonGoodDelete);
  467. bPoputContainer.append(buttonCloseCart);
  468. const divToCardBlock = document.createElement("div");
  469. const goodByIdPrice = document.createElement("h2");
  470. const buyBlock = document.createElement("div");
  471. buyBlock.className = "buyBlock";
  472. const buttonBuy = document.createElement("button");
  473. buttonBuy.className = "buttonBuy";
  474. buttonBuy.id = "buttonBuy";
  475. store.subscribe(() => {
  476. divToCardBlock.innerHTML = "";
  477. goodByIdPrice.innerHTML = "";
  478. const toCartById = store.getState().cart;
  479. let countSum = 0;
  480. let priceSum = 0;
  481. for (let value of Object.values(toCartById)) {
  482. const { count, good, price } = value;
  483. countSum += count;
  484. priceSum += good.price * count;
  485. divToCardBlock.id = "divToCartBlock";
  486. const divToCart = document.createElement("div");
  487. const goodByIdImage = document.createElement("img");
  488. const goodByIdName = document.createElement("h2");
  489. const goodByIdCount = document.createElement("h2");
  490. const buttonPlus = document.createElement("button");
  491. const buttonMinus = document.createElement("button");
  492. buttonBuy.style.display = "block";
  493. buttonBuy.innerHTML = "Buy";
  494. goodByIdPrice.innerHTML = "Total: " + priceSum;
  495. buttonPlus.innerHTML = "+";
  496. buttonMinus.innerHTML = "-";
  497. buttonPlus.id = "buttonPlus";
  498. buttonMinus.id = "buttonMinus";
  499. divToCart.id = "divToCart";
  500. bPoputContainer.append(divToCardBlock);
  501. divToCardBlock.append(divToCart);
  502. divToCart.append(goodByIdImage);
  503. divToCart.append(goodByIdName);
  504. divToCart.append(goodByIdCount);
  505. divToCart.append(buttonPlus);
  506. divToCart.append(buttonMinus);
  507. bPoputContainer.append(buyBlock);
  508. buyBlock.append(goodByIdPrice);
  509. buyBlock.append(buttonBuy);
  510. goodByIdImage.src = `${backendURL}/${value.good.images[0].url}`;
  511. goodByIdName.innerText = good.name;
  512. goodByIdCount.innerText = count;
  513. buttonBuy.onclick = () => {
  514. store.dispatch(actionOrder());
  515. store.dispatch(orderHistory());
  516. };
  517. buttonPlus.onclick = () => store.dispatch(actionCartAdd(value.good));
  518. buttonMinus.onclick = () => {
  519. store.dispatch(actionCartDelete(value.good));
  520. console.log(value.good, "this");
  521. // if(value.good.count === 0)
  522. };
  523. }
  524. shoppingCart.innerHTML = "Cart: " + countSum;
  525. buttonCloseCart.onclick = () => {
  526. var parent = document.getElementById("header");
  527. var child = document.getElementById("b-popup");
  528. parent.removeChild(child);
  529. };
  530. const payload = store.getState().auth.token;
  531. if (payload) {
  532. shoppingCart.style.display = "block";
  533. } else {
  534. shoppingCart.style.display = "none";
  535. }
  536. });
  537. buttonGoodDelete.onclick = () => {
  538. store.dispatch(actionCartClear());
  539. let a = document.getElementById("divToCartBlock");
  540. a.innerHTML = "";
  541. let b = document.getElementById("shoppingCart");
  542. b.innerHTML = "Cart";
  543. let c = document.getElementById("buttonBuy");
  544. c.style.display = "none";
  545. };
  546. const goodByIdName = document.createElement("div");
  547. const h2text = document.createElement("h2");
  548. h2text.id = "h2text";
  549. qwer.append(h2text);
  550. const logoutButton = document.createElement("button");
  551. logoutButton.id = "logoutButton";
  552. qwer.append(logoutButton);
  553. store.subscribe(() => {
  554. const payload = store.getState().auth.token;
  555. if (payload) {
  556. logoutButton.style.display = "block";
  557. logoutButton.innerHTML = "Logout";
  558. login.style.display = "none";
  559. reg.style.display = "none";
  560. h2text.style.display = "block";
  561. h2text.innerText = jwtDecode(payload).sub.login;
  562. } else {
  563. h2text.style.display = "none";
  564. logoutButton.style.display = "none";
  565. }
  566. });
  567. // store.subscribe(() => {
  568. // const orders = store.dispatch()
  569. // })
  570. const buttonLogin = document.createElement("button");
  571. buttonLogin.id = "loginInputt";
  572. buttonLogin.innerText = "Login";
  573. const buttonReg = document.createElement("button");
  574. buttonReg.id = "regInput";
  575. buttonReg.innerText = "Registration";
  576. function bPopupCreate(text) {
  577. const bPopup = document.createElement("div");
  578. const bPopupContent = document.createElement("div");
  579. bPopup.id = "b-popup";
  580. bPopup.className = "b-popup";
  581. bPopupContent.className = "b-popup-content b-poput-container-flex";
  582. header.append(bPopup);
  583. bPopup.append(bPopupContent);
  584. const buttonCloseCart = document.createElement("button");
  585. buttonCloseCart.innerText = `×`;
  586. buttonCloseCart.id = "buttonCloseCartId";
  587. bPopupContent.append(buttonCloseCart);
  588. const loginText = document.createElement("h2");
  589. const passwordText = document.createElement("h2");
  590. loginText.innerText = "Enter Login:";
  591. bPopupContent.append(loginText);
  592. const loginInput = document.createElement("input");
  593. loginInput.type = "text";
  594. bPopupContent.append(loginInput);
  595. loginInput.id = "loginInput";
  596. loginInput.value = "illiaKozyr";
  597. passwordText.innerText = "Enter Password:";
  598. bPopupContent.append(passwordText);
  599. const loginInputPassword = document.createElement("input");
  600. loginInputPassword.type = "password";
  601. bPopupContent.append(loginInputPassword);
  602. loginInputPassword.id = "passwordInput";
  603. loginInputPassword.value = "qwerty123456";
  604. bPopupContent.append(text);
  605. buttonCloseCart.onclick = () => {
  606. var parent = document.getElementById("header");
  607. var child = document.getElementById("b-popup");
  608. parent.removeChild(child);
  609. };
  610. }
  611. window.onhashchange = () => {
  612. const [, route, _id] = location.hash.split("/");
  613. const routes = {
  614. category() {
  615. store.dispatch(actionCatById(_id));
  616. },
  617. good() {
  618. store.dispatch(actionGoodById(_id));
  619. },
  620. dashboard() {
  621. store.dispatch(orderHistory());
  622. },
  623. };
  624. if (route in routes) {
  625. routes[route]();
  626. }
  627. };
  628. window.onhashchange();
  629. store.dispatch(orderHistory());
  630. const h2 = document.createElement("h2");
  631. store.subscribe(() => {
  632. const { history } = store.getState().promise;
  633. const [, route] = location.hash.split("/");
  634. purchaseHistory.onclick = () => {
  635. const bPopup = document.createElement("div");
  636. const bPopupContent = document.createElement("div");
  637. bPopup.id = "b-popup";
  638. bPopup.className = "b-popup";
  639. bPopupContent.className = "b-popup-content b-poput-container-flex";
  640. header.append(bPopup);
  641. bPopup.append(bPopupContent);
  642. const buttonCloseCart = document.createElement("button");
  643. buttonCloseCart.innerText = `×`;
  644. buttonCloseCart.id = "buttonCloseCartId";
  645. bPopupContent.append(buttonCloseCart);
  646. for (let [key, value] of Object.entries(history.payload)) {
  647. const { _id, createdAt, total, orderGoods } = value;
  648. console.log(total, "this");
  649. const h2 = document.createElement("h2");
  650. h2.className = "h2History"
  651. const dateOfOrder = new Date(+createdAt);
  652. h2.innerHTML = `${dateOfOrder.toLocaleDateString()} ${dateOfOrder.toLocaleTimeString()}
  653. Order ID: ${_id} от , c ${orderGoods.length} goods worth: ${total}`;
  654. bPopupContent.append(h2);
  655. }
  656. if (Object.keys(history.payload).length == 0) {
  657. const p = document.createElement("p");
  658. p.innerHTML = "<p>No purchases made yet</p>";
  659. card.append(p);
  660. }
  661. buttonCloseCart.onclick = () => {
  662. var parent = document.getElementById("header");
  663. var child = document.getElementById("b-popup");
  664. parent.removeChild(child);
  665. };
  666. };
  667. });
  668. login.onclick = () => {
  669. bPopupCreate(buttonLogin);
  670. buttonLogin.onclick = () => {
  671. store.dispatch(actionFullLogin(loginInput.value, passwordInput.value));
  672. logoutButton.style.display = "block";
  673. var parent = document.getElementById("header");
  674. var child = document.getElementById("b-popup");
  675. parent.removeChild(child);
  676. purchaseHistory.style.display = "block";
  677. };
  678. };
  679. reg.onclick = () => {
  680. bPopupCreate(buttonReg);
  681. buttonReg.onclick = () => {
  682. store.dispatch(
  683. actionFullRegister(loginInput.value, passwordInput.value),
  684. store.dispatch(actionCartClear())
  685. );
  686. var parent = document.getElementById("header");
  687. var child = document.getElementById("b-popup");
  688. parent.removeChild(child);
  689. };
  690. };
  691. logoutButton.onclick = () => {
  692. store.dispatch(actionAuthLogout());
  693. login.style.display = "block";
  694. reg.style.display = "block";
  695. purchaseHistory.style.display = "none";
  696. };
  697. // purchaseHistory.onclick = () => {
  698. // }