script.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826
  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. store.subscribe(() => console.log(store.getState()));
  200. const actionRootCats = () =>
  201. actionPromise(
  202. "rootCats",
  203. gql(
  204. `query {
  205. CategoryFind(query: "[{\\"parent\\":null}]"){
  206. _id name
  207. }
  208. }`
  209. )
  210. );
  211. const actionCatById = (_id) =>
  212. actionPromise(
  213. "catById",
  214. gql(
  215. `query catById($q: String){
  216. CategoryFindOne(query: $q){
  217. _id name subCategories {
  218. name _id
  219. }
  220. goods {
  221. _id name price images {
  222. url
  223. }
  224. }
  225. }
  226. }`,
  227. { q: JSON.stringify([{ _id }]) }
  228. )
  229. );
  230. const actionLogin = (login, password) =>
  231. actionPromise(
  232. "actionLogin",
  233. gql(
  234. `query log($login:String, $password:String){
  235. login(login:$login, password:$password)
  236. }`,
  237. { login, password }
  238. )
  239. );
  240. const actionGoodById = (_id) =>
  241. actionPromise(
  242. "GoodFineOne",
  243. gql(
  244. `query goodByid($goodId: String) {
  245. GoodFindOne(query: $goodId) {
  246. _id
  247. name
  248. price
  249. description
  250. images {
  251. url
  252. }
  253. }
  254. }`,
  255. { goodId: JSON.stringify([{ _id }]) }
  256. )
  257. );
  258. store.dispatch(actionRootCats());
  259. const actionFullLogin = (log, pass) => async (dispatch) => {
  260. let token = await dispatch(
  261. actionPromise(
  262. "login",
  263. gql(
  264. `query login($login: String, $password: String) {
  265. login(login: $login, password: $password)
  266. }`,
  267. { login: log, password: pass }
  268. )
  269. )
  270. );
  271. if (token) {
  272. dispatch(actionAuthLogin(token));
  273. }
  274. };
  275. const actionFullRegister = (login, password) => async (dispatch) => {
  276. let user = await dispatch(
  277. actionPromise(
  278. "register",
  279. gql(
  280. `mutation register($login: String, $password: String) {
  281. UserUpsert(user: {login: $login, password: $password}) {
  282. _id
  283. login
  284. }
  285. }`,
  286. { login: login, password: password }
  287. )
  288. )
  289. );
  290. if (user) {
  291. dispatch(actionFullLogin(login, password));
  292. }
  293. };
  294. const actionOrder = () => async (dispatch, getState) => {
  295. let { cart } = getState();
  296. const orderGoods = Object.entries(cart).map(([_id, { count }]) => ({
  297. good: { _id },
  298. count,
  299. }));
  300. let result = await dispatch(
  301. actionPromise(
  302. "order",
  303. gql(
  304. `
  305. mutation newOrder($order:OrderInput){
  306. OrderUpsert(order:$order)
  307. { _id total }
  308. }
  309. `,
  310. { order: { orderGoods } }
  311. )
  312. )
  313. );
  314. if (result?._id) {
  315. dispatch(actionCartClear());
  316. document.location.hash = "#/cart/";
  317. alert("Purchase completed")
  318. }
  319. };
  320. const orderHistory = () =>
  321. actionPromise(
  322. "history",
  323. gql(` query OrderFind{
  324. OrderFind(query:"[{}]"){
  325. _id total createdAt orderGoods{
  326. count good{
  327. _id name price images{
  328. url
  329. }
  330. }
  331. owner{
  332. _id login
  333. }
  334. }
  335. }
  336. }
  337. `)
  338. );
  339. store.subscribe(() => {
  340. const { rootCats } = store.getState().promise;
  341. if (rootCats?.payload) {
  342. aside.innerHTML = "";
  343. for (let { _id, name } of rootCats?.payload) {
  344. const a = document.createElement("a");
  345. a.href = `#/category/${_id}`;
  346. a.innerHTML = name;
  347. aside.append(a);
  348. }
  349. }
  350. });
  351. store.subscribe(() => {
  352. const { catById } = store.getState().promise;
  353. const [, route] = location.hash.split("/");
  354. if (catById?.payload && route === "category") {
  355. const { name, goods, subCategories } = catById?.payload;
  356. categoryName.innerHTML = `<h1>${name}</h1>`;
  357. var element = document.getElementById("productBlock");
  358. while (element.firstChild) {
  359. element.removeChild(element.firstChild);
  360. }
  361. if (subCategories) {
  362. for (let { name, _id } of subCategories) {
  363. const link = document.createElement("a");
  364. link.id = "subCategories";
  365. link.href = `#/category/${_id}`;
  366. link.innerText = name;
  367. productBlock.append(link);
  368. }
  369. }
  370. for (let { _id, name, price, images, } of goods) {
  371. // console.log()
  372. const description = document.createElement("div");
  373. const textBlock = document.createElement("div");
  374. const imgProduct = document.createElement("img");
  375. const a = document.createElement("p");
  376. const productPrice = document.createElement("p");
  377. const linkCard = document.createElement("a");
  378. const addToCartButton = document.createElement('button')
  379. addToCartButton.innerHTML = "add to cart"
  380. addToCartButton.id = "addToCartButtonn"
  381. linkCard.innerHTML = "About the product"
  382. linkCard.href = `#/good/${_id}`;
  383. linkCard.className = "linkCard"
  384. productBlock.append(description);
  385. description.setAttribute("class", "card");
  386. description.id = "card";
  387. description.append(imgProduct);
  388. imgProduct.src = `${backendURL}/${images[0].url}`;
  389. description.append(textBlock);
  390. a.innerHTML = name;
  391. textBlock.append(a);
  392. productPrice.innerHTML = "price: " + price;
  393. textBlock.append(productPrice);
  394. textBlock.append(linkCard);
  395. textBlock.append(addToCartButton)
  396. addToCartButton.onclick = () => {
  397. store.dispatch(actionCartAdd({_id, name, price, images,}));
  398. };
  399. }
  400. }
  401. });
  402. const flexBlockForGFO = document.createElement("div");
  403. flexBlockForGFO.id = "flexBlockForGFO";
  404. const goodFineOneImgBlock = document.createElement("div");
  405. const goodFineOneTextBlock = document.createElement("div");
  406. const goodFineOneName = document.createElement("h2");
  407. const goodFineOneImg = document.createElement("img");
  408. const goodFineOnePrice = document.createElement("p");
  409. const goodFineOneDescription = document.createElement("p");
  410. const goodFineOneAddToCartButton = document.createElement("button");
  411. const buttonPlus = document.createElement("button");
  412. const buttonMinus = document.createElement("button");
  413. buttonPlus.innerHTML = "+";
  414. buttonMinus.innerHTML = "-";
  415. store.subscribe(() => {
  416. const { GoodFineOne } = store.getState().promise;
  417. const [, route, _id] = location.hash.split("/");
  418. if (GoodFineOne?.payload && route === "good") {
  419. productBlock.innerHTML = "";
  420. const { name, images, price, description } = GoodFineOne?.payload;
  421. productBlock.append(flexBlockForGFO);
  422. flexBlockForGFO.append(goodFineOneImgBlock);
  423. goodFineOneImg.src = `${backendURL}/${images[0].url}`;
  424. goodFineOneImg.id = "goodOneImg";
  425. goodFineOneImgBlock.append(goodFineOneImg);
  426. flexBlockForGFO.append(goodFineOneTextBlock);
  427. goodFineOneName.innerHTML = name;
  428. goodFineOneTextBlock.append(goodFineOneName);
  429. goodFineOnePrice.innerHTML = "price: " + price;
  430. goodFineOneTextBlock.append(goodFineOnePrice);
  431. goodFineOneDescription.innerHTML = description;
  432. goodFineOneTextBlock.append(goodFineOneDescription);
  433. goodFineOneAddToCartButton.innerHTML = "add to cart";
  434. goodFineOneTextBlock.append(goodFineOneAddToCartButton);
  435. goodFineOneAddToCartButton.onclick = () => {
  436. store.dispatch(actionCartAdd(GoodFineOne.payload));
  437. };
  438. // const a = document.getElementById(addToCartButtonn)
  439. // a.onclick = () => {
  440. // store.dispatch(actionCartAdd(GoodFineOne.payload));
  441. // };
  442. }
  443. });
  444. const bPoputDeleteBlock = document.createElement("div");
  445. const bPoput = document.createElement("div");
  446. bPoput.className = "b-popup";
  447. bPoput.id = "b-popup";
  448. const bPoputContainer = document.createElement("div");
  449. bPoputContainer.className = "b-popup-content";
  450. bPoputContainer.id = "bPopupContent";
  451. const buttonGoodDeleteBlock = document.createElement("div");
  452. buttonGoodDeleteBlock.id = "buttonGoodDeleteBlock";
  453. const buttonCloseCart = document.createElement("button");
  454. buttonCloseCart.innerText = `×`;
  455. buttonCloseCart.id = "buttonCloseCartId";
  456. const buttonGoodDelete = document.createElement("button");
  457. buttonGoodDelete.innerText = "delete";
  458. buttonGoodDelete.id = "buttonDelete";
  459. shoppingCart.onclick = () => {
  460. header.append(bPoput);
  461. bPoput.append(bPoputContainer);
  462. };
  463. bPoputContainer.append(buttonGoodDeleteBlock);
  464. buttonGoodDeleteBlock.append(buttonGoodDelete);
  465. bPoputContainer.append(buttonCloseCart);
  466. const divToCardBlock = document.createElement("div");
  467. const goodByIdPrice = document.createElement("h2");
  468. const buyBlock = document.createElement("div");
  469. buyBlock.className = "buyBlock";
  470. const buttonBuy = document.createElement("button");
  471. buttonBuy.className = "buttonBuy";
  472. buttonBuy.id = "buttonBuy";
  473. const a = document.createElement('p')
  474. a.innerHTML = "clear"
  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. const removePosition = document.createElement("button")
  493. buttonBuy.style.display = "block";
  494. buttonBuy.innerHTML = "Buy";
  495. goodByIdPrice.innerHTML = "Total: " + priceSum;
  496. removePosition.innerHTML = "Remove"
  497. removePosition.id = "removePosition"
  498. buttonPlus.innerHTML = "+";
  499. buttonMinus.innerHTML = "-";
  500. buttonPlus.id = "buttonPlus";
  501. buttonMinus.id = "buttonMinus";
  502. divToCart.id = "divToCart";
  503. bPoputContainer.append(divToCardBlock);
  504. divToCardBlock.append(divToCart);
  505. divToCart.append(goodByIdImage);
  506. divToCart.append(goodByIdName);
  507. divToCart.append(goodByIdCount);
  508. divToCart.append(buttonPlus);
  509. divToCart.append(buttonMinus);
  510. divToCart.append(removePosition)
  511. bPoputContainer.append(buyBlock);
  512. buyBlock.append(goodByIdPrice);
  513. buyBlock.append(buttonBuy);
  514. goodByIdImage.src = `${backendURL}/${value.good.images[0].url}`;
  515. goodByIdName.innerText = good.name;
  516. goodByIdCount.innerText = count;
  517. buttonBuy.onclick = () => {
  518. store.dispatch(actionOrder());
  519. store.dispatch(orderHistory());
  520. };
  521. buttonPlus.onclick = () => store.dispatch(actionCartAdd(value.good));
  522. buttonMinus.onclick = () => {
  523. store.dispatch(actionCartDelete(value.good));
  524. console.log(value.good, "this");
  525. };
  526. removePosition.onclick = () => store.dispatch(actionCartRemove(value.good))
  527. }
  528. shoppingCart.innerHTML = "Cart: " + countSum;
  529. buttonCloseCart.onclick = () => {
  530. var parent = document.getElementById("header");
  531. var child = document.getElementById("b-popup");
  532. parent.removeChild(child);
  533. };
  534. const payload = store.getState().auth.token;
  535. if (payload) {
  536. shoppingCart.style.display = "block";
  537. } else {
  538. shoppingCart.style.display = "none";
  539. }
  540. });
  541. buttonGoodDelete.onclick = () => {
  542. store.dispatch(actionCartClear());
  543. let a = document.getElementById("divToCartBlock");
  544. a.innerHTML = "";
  545. let b = document.getElementById("shoppingCart");
  546. b.innerHTML = "Cart";
  547. let c = document.getElementById("buttonBuy");
  548. c.style.display = "none";
  549. };
  550. const goodByIdName = document.createElement("div");
  551. const h2text = document.createElement("h2");
  552. h2text.id = "h2text";
  553. qwer.append(h2text);
  554. const logoutButton = document.createElement("button");
  555. logoutButton.id = "logoutButton";
  556. qwer.append(logoutButton);
  557. store.subscribe(() => {
  558. const payload = store.getState().auth.token;
  559. if (payload) {
  560. logoutButton.style.display = "block";
  561. logoutButton.innerHTML = "Logout";
  562. login.style.display = "none";
  563. reg.style.display = "none";
  564. h2text.style.display = "block";
  565. h2text.innerText = jwtDecode(payload).sub.login;
  566. } else {
  567. h2text.style.display = "none";
  568. logoutButton.style.display = "none";
  569. }
  570. });
  571. // store.subscribe(() => {
  572. // const orders = store.dispatch()
  573. // })
  574. const buttonLogin = document.createElement("button");
  575. buttonLogin.id = "loginInputt";
  576. buttonLogin.innerText = "Login";
  577. const buttonReg = document.createElement("button");
  578. buttonReg.id = "regInput";
  579. buttonReg.innerText = "Registration";
  580. function bPopupCreate(text) {
  581. const bPopup = document.createElement("div");
  582. const bPopupContent = document.createElement("div");
  583. bPopup.id = "b-popup";
  584. bPopup.className = "b-popup";
  585. bPopupContent.className = "b-popup-content b-poput-container-flex";
  586. header.append(bPopup);
  587. bPopup.append(bPopupContent);
  588. const buttonCloseCart = document.createElement("button");
  589. buttonCloseCart.innerText = `×`;
  590. buttonCloseCart.id = "buttonCloseCartId";
  591. bPopupContent.append(buttonCloseCart);
  592. const loginText = document.createElement("h2");
  593. const passwordText = document.createElement("h2");
  594. loginText.innerText = "Enter Login:";
  595. bPopupContent.append(loginText);
  596. const loginInput = document.createElement("input");
  597. loginInput.type = "text";
  598. bPopupContent.append(loginInput);
  599. loginInput.id = "loginInput";
  600. loginInput.value = "illiaKozyr";
  601. passwordText.innerText = "Enter Password:";
  602. bPopupContent.append(passwordText);
  603. const loginInputPassword = document.createElement("input");
  604. loginInputPassword.type = "password";
  605. bPopupContent.append(loginInputPassword);
  606. loginInputPassword.id = "passwordInput";
  607. loginInputPassword.value = "qwerty123456";
  608. bPopupContent.append(text);
  609. buttonCloseCart.onclick = () => {
  610. var parent = document.getElementById("header");
  611. var child = document.getElementById("b-popup");
  612. parent.removeChild(child);
  613. };
  614. }
  615. window.onhashchange = () => {
  616. const [, route, _id] = location.hash.split("/");
  617. const routes = {
  618. category() {
  619. store.dispatch(actionCatById(_id));
  620. },
  621. good() {
  622. store.dispatch(actionGoodById(_id));
  623. },
  624. dashboard() {
  625. store.dispatch(orderHistory());
  626. },
  627. };
  628. if (route in routes) {
  629. routes[route]();
  630. }
  631. };
  632. window.onhashchange();
  633. store.dispatch(orderHistory());
  634. const h2 = document.createElement("h2");
  635. store.subscribe(() => {
  636. const { history } = store.getState().promise;
  637. const [, route] = location.hash.split("/");
  638. purchaseHistory.onclick = () => {
  639. const bPopup = document.createElement("div");
  640. const bPopupContent = document.createElement("div");
  641. bPopup.id = "b-popup";
  642. bPopup.className = "b-popup";
  643. bPopupContent.className = "b-popup-content b-poput-container-flex";
  644. header.append(bPopup);
  645. bPopup.append(bPopupContent);
  646. const buttonCloseCart = document.createElement("button");
  647. buttonCloseCart.innerText = `×`;
  648. buttonCloseCart.id = "buttonCloseCartId";
  649. bPopupContent.append(buttonCloseCart);
  650. for (let [key, value] of Object.entries(history.payload)) {
  651. const { _id, createdAt, total, orderGoods } = value;
  652. const historyDiv = document.createElement("div")
  653. historyDiv.style = 'padding-right: 100px'
  654. bPopupContent.append(historyDiv)
  655. const card = document.createElement('div')
  656. card.style = 'width: 100%;border-style: groove;border-color: #black;padding: 10px;border-radius: 10px;margin: 5px;'
  657. card.innerHTML = `<h3>Order: ${createdAt}</h3>`
  658. for (const {count, good} of orderGoods){{ _id, name, price, images }}
  659. const divGood = document.createElement('div')
  660. divGood.style= "display:flex;margin-bottom: 20px;"
  661. divGood.innerHTML += `<div>Product: <b>${good.name}</b><br> Price: <b>${good.price}</b><br> Count: <b>${count} </b></b></div><img style="max-width: 80px;margin-right: 20px;display: block;margin-left: auto;" src="http://shop-roles.node.ed.asmer.org.ua/${good.images[0].url}"/><br><br>`
  662. card.append(divGood)
  663. }
  664. card.innerHTML += 'Date: <b>'+new Date(+createdAt).toLocaleString().replace(/\//g, '.')+'</b>'
  665. card.innerHTML += `<br>Total: <b style="color:red;">${total}</b>`
  666. historyDiv.append(card)
  667. }
  668. if (Object.keys(history.payload).length == 0) {
  669. const p = document.createElement("p");
  670. p.innerHTML = "<p>No purchases made yet</p>";
  671. card.append(p);
  672. }
  673. buttonCloseCart.onclick = () => {
  674. var parent = document.getElementById("header");
  675. var child = document.getElementById("b-popup");
  676. parent.removeChild(child);
  677. };
  678. });
  679. login.onclick = () => {
  680. bPopupCreate(buttonLogin);
  681. buttonLogin.onclick = () => {
  682. store.dispatch(actionFullLogin(loginInput.value, passwordInput.value));
  683. logoutButton.style.display = "block";
  684. var parent = document.getElementById("header");
  685. var child = document.getElementById("b-popup");
  686. parent.removeChild(child);
  687. purchaseHistory.style.display = "block";
  688. };
  689. };
  690. reg.onclick = () => {
  691. bPopupCreate(buttonReg);
  692. buttonReg.onclick = () => {
  693. store.dispatch(
  694. actionFullRegister(loginInput.value, passwordInput.value),
  695. store.dispatch(actionCartClear())
  696. );
  697. var parent = document.getElementById("header");
  698. var child = document.getElementById("b-popup");
  699. parent.removeChild(child);
  700. };
  701. };
  702. logoutButton.onclick = () => {
  703. store.dispatch(actionAuthLogout());
  704. login.style.display = "block";
  705. reg.style.display = "block";
  706. purchaseHistory.style.display = "none";
  707. };