script.js 22 KB

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