index.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779
  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 authReducer(state, { type, token }) {
  28. if (!state) {
  29. if (localStorage.authToken) {
  30. type = "AUTH_LOGIN";
  31. token = localStorage.authToken;
  32. } else {
  33. return {};
  34. }
  35. }
  36. if (type === "AUTH_LOGIN") {
  37. localStorage.authToken = token;
  38. let payload = jwtDecode(token);
  39. if (typeof payload !== "object") {
  40. return {};
  41. }
  42. return { token, payload };
  43. }
  44. if (type === "AUTH_LOGOUT") {
  45. localStorage.authToken = "";
  46. return {};
  47. }
  48. return state;
  49. }
  50. const actionAuthLogin = (token) => ({
  51. type: "AUTH_LOGIN",
  52. token,
  53. });
  54. const actionAuthLogout = () => ({ type: "AUTH_LOGOUT" });
  55. function cartReducer(state = {}, { type, good = {}, count }) {
  56. const { _id } = good;
  57. const types = {
  58. CART_ADD() {
  59. count = +count;
  60. if (!count) {
  61. return state;
  62. }
  63. return {
  64. ...state,
  65. [_id]: { good, count: count + (state[_id]?.count || 0) },
  66. };
  67. },
  68. CART_CHANGE() {
  69. count = +count;
  70. if (!count) {
  71. return state;
  72. }
  73. return {
  74. ...state,
  75. [_id]: { good, count },
  76. };
  77. },
  78. CART_REMOVE() {
  79. let { [_id]: remove, ...goods } = state;
  80. return goods;
  81. },
  82. CART_CLEAR() {
  83. return {};
  84. },
  85. CART_SHOW() {
  86. state = JSON.parse(localStorage.cart);
  87. return state;
  88. },
  89. };
  90. if (type in types) {
  91. return types[type]();
  92. }
  93. return state;
  94. }
  95. function promiseReducer(state = {}, { type, status, payload, errors, name }) {
  96. if (!state) {
  97. return {};
  98. }
  99. if (type === "PROMISE") {
  100. return {
  101. ...state,
  102. [name]: { status, payload, errors },
  103. };
  104. }
  105. return state;
  106. }
  107. const actionPending = (name) => ({ type: "PROMISE", status: "PENDING", name });
  108. const actionResolved = (name, payload) => ({
  109. type: "PROMISE",
  110. status: "RESOLVED",
  111. name,
  112. payload,
  113. });
  114. const actionRejected = (name, errors) => ({
  115. type: "PROMISE",
  116. status: "REJECTED",
  117. name,
  118. errors,
  119. });
  120. const actionPromise = (name, promise) => async (dispatch) => {
  121. dispatch(actionPending(name));
  122. try {
  123. let data = await promise;
  124. dispatch(actionResolved(name, data));
  125. return data;
  126. } catch (error) {
  127. dispatch(actionRejected(name, error));
  128. }
  129. };
  130. function combineReducers(reducers) {
  131. return (state = {}, action) => {
  132. const newState = {};
  133. let newSubState;
  134. for (const [reducerName, reducer] of Object.entries(reducers)) {
  135. newSubState = reducer(state[reducerName], action);
  136. if (state[reducerName] !== newSubState) {
  137. newState[reducerName] = newSubState;
  138. }
  139. }
  140. if (Object.keys(newState).length !== 0) {
  141. return { ...state, ...newState };
  142. } else {
  143. return state;
  144. }
  145. };
  146. }
  147. const combinedReducer = combineReducers({
  148. promise: promiseReducer,
  149. auth: authReducer,
  150. cart: cartReducer,
  151. });
  152. const store = createStore(combinedReducer);
  153. const actionCartAdd = (good, count) => ({
  154. type: "CART_ADD",
  155. good,
  156. count,
  157. });
  158. const actionCartChange = (good, count) => ({
  159. type: "CART_CHANGE",
  160. good,
  161. count,
  162. });
  163. const actionCartRemove = (good) => ({ type: "CART_REMOVE", good });
  164. const actionCartClear = () => ({ type: "CART_CLEAR" });
  165. const actionCartShow = () => ({ type: "CART_SHOW" });
  166. const actionOrder = () => async (dispatch, getState) => {
  167. let { cart } = getState();
  168. const orderGoods = Object.entries(cart).map(([_id, { count }]) => ({
  169. good: { _id },
  170. count,
  171. }));
  172. let result = await dispatch(
  173. actionPromise(
  174. "order",
  175. gql(
  176. `
  177. mutation newOrder($order:OrderInput){
  178. OrderUpsert(order:$order)
  179. { _id total }
  180. }
  181. `,
  182. { order: { orderGoods } }
  183. )
  184. )
  185. );
  186. if (result?._id) {
  187. dispatch(actionCleanCart());
  188. }
  189. };
  190. const getGQL =
  191. (url) =>
  192. async (query, variables = {}) => {
  193. let obj = await fetch(url, {
  194. method: "POST",
  195. headers: {
  196. "Content-Type": "application/json",
  197. },
  198. body: JSON.stringify({ query, variables }),
  199. });
  200. let a = await obj.json();
  201. if (!a.data && a.errors) throw new Error(JSON.stringify(a.errors));
  202. return a.data[Object.keys(a.data)[0]];
  203. };
  204. const backURL = "http://shop-roles.asmer.fs.a-level.com.ua";
  205. const gql = getGQL(backURL + "/graphql");
  206. const actionRootCats = () =>
  207. actionPromise(
  208. "rootCats",
  209. gql(`query {
  210. CategoryFind(query: "[{\\"parent\\":null}]"){
  211. _id name
  212. }
  213. }`)
  214. );
  215. const actionCatById = (_id) =>
  216. actionPromise(
  217. "catById",
  218. gql(
  219. `query catById($q: String){
  220. CategoryFindOne(query: $q){
  221. _id name,
  222. goods{
  223. _id name price images {
  224. url
  225. }
  226. },
  227. subCategories{
  228. name, subCategories{
  229. name
  230. }
  231. }
  232. }
  233. }`,
  234. { q: JSON.stringify([{ _id }]) }
  235. )
  236. );
  237. const actionGoodById = (_id) =>
  238. actionPromise(
  239. "goodById",
  240. gql(
  241. `query goodById($q: String){
  242. GoodFindOne(query: $q){
  243. _id name description price images{
  244. url
  245. }
  246. }
  247. }`,
  248. { q: JSON.stringify([{ _id }]) }
  249. )
  250. );
  251. const actionLogin = (login, password) =>
  252. actionPromise(
  253. "login",
  254. gql(
  255. `query log($login: String, $password: String) {
  256. login(login: $login, password: $password)
  257. }`,
  258. { login: login, password: password }
  259. )
  260. );
  261. const actionFullLogin = (login, password) => async (dispatch) => {
  262. console.log(login, password);
  263. let token = await dispatch(actionLogin(login, password));
  264. console.log(token);
  265. if (token) {
  266. dispatch(actionAuthLogin(token));
  267. }
  268. };
  269. const actionRegister = (login, password) =>
  270. actionPromise(
  271. "registration",
  272. gql(
  273. `mutation reg2($user:UserInput) {
  274. UserUpsert(user:$user) {
  275. _id login
  276. }
  277. }
  278. `,
  279. { user: { login: login, password: password } }
  280. )
  281. );
  282. const actionFullRegister = (login, password) => async (dispatch) => {
  283. console.log(login, password);
  284. let check = await dispatch(actionRegister(login, password));
  285. console.log(check);
  286. if (check) {
  287. dispatch(actionFullLogin(login, password));
  288. }
  289. };
  290. store.dispatch(actionRootCats());
  291. store.dispatch(actionGoodById());
  292. store.subscribe(() => {
  293. const { promise } = store.getState();
  294. if (promise?.rootCats?.payload) {
  295. asideList.innerHTML = "";
  296. let count = -1;
  297. for (const { _id, name } of promise.rootCats.payload) {
  298. count++;
  299. const link = document.createElement("a");
  300. link.href = `#/category/${_id}`;
  301. link.innerText = name;
  302. link.className = "nav-link";
  303. link.id = `rootCat${count}`;
  304. asideList.appendChild(link);
  305. }
  306. }
  307. });
  308. const openCart = () => {
  309. const [, route] = location.hash.split("/");
  310. if (route === "cart") {
  311. main.innerHTML = "";
  312. const { cart } = store.getState();
  313. for (let good in cart) {
  314. let {
  315. good: {
  316. _id: id,
  317. name: name,
  318. price: price,
  319. images: [{ url }],
  320. },
  321. count,
  322. } = cart[good];
  323. let cardMain = document.createElement("div");
  324. cardMain.id = "cardMain";
  325. let goodImgBlock = document.createElement("div");
  326. goodImgBlock.innerHTML = `
  327. <img src="${backURL}/${url}" width="400" height="200"/>
  328. `;
  329. cardMain.appendChild(goodImgBlock);
  330. let goodInfoBlock = document.createElement("div");
  331. let goodName = document.createElement("h2");
  332. goodName.innerText = `${name}`;
  333. let goodPrice = document.createElement("p");
  334. goodPrice.innerText = `${price * count}$`;
  335. let goodCount = document.createElement("p");
  336. goodCount.innerText = `${count} шт.`;
  337. goodInfoBlock.appendChild(goodName);
  338. goodInfoBlock.appendChild(goodPrice);
  339. goodInfoBlock.appendChild(goodCount);
  340. cardMain.appendChild(goodInfoBlock);
  341. let br = document.createElement("br");
  342. let goodEditBlock = document.createElement("div");
  343. goodEditBlock.className = "form-outline";
  344. let deleteBtn = document.createElement("button");
  345. deleteBtn.innerText = "Delete";
  346. deleteBtn.id = "deleteBtn";
  347. deleteBtn.type = "button";
  348. deleteBtn.className = "btn btn-danger";
  349. goodEditBlock.appendChild(deleteBtn);
  350. goodEditBlock.appendChild(br);
  351. deleteBtn.onclick = () => {
  352. store.dispatch(actionCartRemove(cart[good].good));
  353. cardMain.remove();
  354. console.log(store.getState());
  355. };
  356. let countLabel = document.createElement("label");
  357. countLabel.className = "form-label";
  358. countLabel.htmlFor = "countField";
  359. countLabel.innerText = "Change count";
  360. let countField = document.createElement("input");
  361. countField.type = "number";
  362. countField.value = cart[good].count;
  363. countField.min = "1";
  364. countField.id = "countField";
  365. countField.className = "form-control";
  366. goodEditBlock.appendChild(countLabel);
  367. goodEditBlock.appendChild(countField);
  368. countField.oninput = () => {
  369. goodPrice.innerText = `${price * +countField.value}$`;
  370. goodCount.innerText = `${countField.value} шт.`;
  371. store.dispatch(actionCartChange(cart[good].good, countField.value));
  372. };
  373. cardMain.appendChild(goodEditBlock);
  374. main.appendChild(cardMain);
  375. }
  376. let clearBtn = document.createElement("button");
  377. clearBtn.innerText = "Clear Cart";
  378. clearBtn.id = "clearBtn";
  379. clearBtn.type = "button";
  380. clearBtn.className = "btn btn-dark";
  381. let makeOrder = document.createElement("button");
  382. makeOrder.innerText = "Make Order";
  383. makeOrder.id = "makeOrder";
  384. makeOrder.type = "button";
  385. makeOrder.className = "btn btn-success";
  386. if (Object.keys(cart).length !== 0) {
  387. main.appendChild(makeOrder);
  388. main.appendChild(clearBtn);
  389. } else {
  390. main.innerHTML = "<h2>Your cart is empty!</h2>";
  391. }
  392. makeOrder.onclick = () => {
  393. store.dispatch(actionOrder());
  394. alert("Thanks for your order!");
  395. store.dispatch(actionCartClear());
  396. document.location.reload();
  397. };
  398. clearBtn.onclick = () => {
  399. store.dispatch(actionCartClear());
  400. document.location.reload();
  401. };
  402. }
  403. };
  404. window.onhashchange = () => {
  405. const [, route, _id] = location.hash.split("/");
  406. let signOut = document.createElement("button");
  407. signOut.innerText = "Sign Out";
  408. signOut.id = "signoutBtn";
  409. signOut.className = "btn btn-secondary";
  410. const routes = {
  411. category() {
  412. store.dispatch(actionCatById(_id));
  413. },
  414. good() {
  415. store.dispatch(actionGoodById(_id));
  416. },
  417. login() {
  418. let loginInput = document.getElementById("loginInput");
  419. let passwordInput = document.getElementById("pass1Input");
  420. if (
  421. loginInput &&
  422. passwordInput &&
  423. loginInput.value &&
  424. passwordInput.value
  425. ) {
  426. store.dispatch(
  427. actionFullLogin(
  428. loginInput.value.slice(0, loginInput.value.indexOf("@")),
  429. passwordInput.value
  430. )
  431. );
  432. } else {
  433. throw new Error("Error login");
  434. }
  435. },
  436. register() {
  437. let regInput = document.getElementById("regInput");
  438. let passwordInput = document.getElementById("pass2Input");
  439. if (regInput && passwordInput && regInput.value && passwordInput.value) {
  440. store.dispatch(
  441. actionFullRegister(
  442. regInput.value.slice(0, regInput.value.indexOf("@")),
  443. passwordInput.value
  444. )
  445. );
  446. } else {
  447. throw new Error("Error register");
  448. }
  449. },
  450. cart() {
  451. openCart();
  452. },
  453. };
  454. if (route in routes) routes[route]();
  455. };
  456. window.onhashchange();
  457. store.subscribe(() => {
  458. const [, route] = location.hash.split("/");
  459. const { cart } = store.getState();
  460. if (Object.keys(cart).length === 0 && route === "cart") {
  461. let makeOrderBtn = document.getElementById("makeOrder");
  462. let clearCartBtn = document.getElementById("clearBtn");
  463. if (makeOrderBtn) {
  464. makeOrderBtn.remove();
  465. }
  466. if (clearCartBtn) {
  467. clearCartBtn.remove();
  468. }
  469. localStorage.cart = "";
  470. main.innerHTML = "<h2>Your cart is empty!</h2>";
  471. } else if (Object.keys(cart).length !== 0) {
  472. let cartStr = JSON.stringify(cart);
  473. localStorage.cart = cartStr;
  474. }
  475. });
  476. window.onunload = () => {
  477. if (localStorage.cart !== "") {
  478. store.dispatch(actionCartShow());
  479. openCart();
  480. }
  481. };
  482. window.onunload();
  483. store.subscribe(() => {
  484. const { promise } = store.getState();
  485. const [, route, _id] = location.hash.split("/");
  486. if (promise?.catById?.payload && route === "category") {
  487. const { name } = promise.catById.payload;
  488. main.innerHTML = `<h1>${name}</h1>`;
  489. if (promise.catById.payload?.subCategories) {
  490. for (const { _id, name } of promise.catById.payload.subCategories) {
  491. const rootCat = document.querySelector(
  492. `a[href="#/category/${promise.catById.payload._id}"]`
  493. );
  494. const subNav = document.createElement("nav");
  495. subNav.className = "nav nav-pills flex-column";
  496. const link = document.createElement("a");
  497. link.href = `#/category/${_id}`;
  498. link.innerText = name;
  499. link.className = "nav-link ms-3 my-1";
  500. subNav.appendChild(link);
  501. rootCat.appendChild(subNav);
  502. }
  503. }
  504. if (promise.catById.payload?.goods) {
  505. for (const good of promise.catById.payload.goods) {
  506. const { _id, name, price, images } = good;
  507. const card = document.createElement("div");
  508. const link = document.createElement("a");
  509. card.innerHTML = `<h2>${name}</h2>
  510. <img src="${backURL}/${images[0].url}" width="400" height="200"/><br/>
  511. <strong>${price}$</strong><br/>
  512. `;
  513. link.innerText = name;
  514. link.href = `#/good/${_id}`;
  515. card.appendChild(link);
  516. let buyBtn = document.createElement("button");
  517. buyBtn.className = "btn btn-success";
  518. buyBtn.textContent = "Buy";
  519. buyBtn.onclick = () => {
  520. store.dispatch(actionCartAdd(good, 1));
  521. };
  522. card.appendChild(buyBtn);
  523. main.append(card);
  524. }
  525. }
  526. }
  527. });
  528. store.subscribe(() => {
  529. const { cart } = store.getState();
  530. let countGoods = 0;
  531. for (let good of Object.keys(cart)) {
  532. countGoods += cart[good].count;
  533. }
  534. cartIcon.innerText = `Товаров в корзине: ${countGoods}`;
  535. cartIcon.onclick = () => {
  536. window.location.href = "#/cart";
  537. };
  538. });
  539. store.subscribe(() => {
  540. const { promise } = store.getState();
  541. const [, route, _id] = location.hash.split("/");
  542. if (promise?.goodById?.payload && route === "good") {
  543. main.innerHTML = "";
  544. const { name, description, price, images } = promise.goodById.payload;
  545. main.innerHTML = `
  546. <div>
  547. <div>
  548. <img src="${backURL}/${images[0].url}" width="400" height="200"/>
  549. </div>
  550. <div>
  551. <h2>${name}</h2>
  552. <p><strong>${price}$</strong></p>
  553. <p><span>${description}</span></p>
  554. </div>
  555. </div>`;
  556. }
  557. });
  558. store.subscribe(() => console.log(store.getState()));
  559. function jwtDecode(token) {
  560. try {
  561. return JSON.parse(atob(token.split(".")[1]));
  562. } catch (error) {
  563. console.log(error);
  564. }
  565. }
  566. store.subscribe(async () => {
  567. const { promise } = store.getState();
  568. let signinBtn = document.getElementById("signinBtn");
  569. let signupBtn = document.getElementById("signupBtn");
  570. if (promise?.rootCats?.payload && !signinBtn && !signupBtn) {
  571. let signIn = document.createElement("button");
  572. signIn.innerText = "Sign In";
  573. signIn.id = "signinBtn";
  574. signIn.type = "button";
  575. signIn.className = "btn btn-light";
  576. let signUp = document.createElement("button");
  577. signUp.innerText = "Sign Up";
  578. signUp.id = "signupBtn";
  579. signUp.type = "button";
  580. signUp.className = "btn btn-light";
  581. let authBlock = document.createElement("div");
  582. authBlock.id = "authBlock";
  583. authBlock.appendChild(signIn);
  584. authBlock.appendChild(signUp);
  585. authnav.appendChild(authBlock);
  586. }
  587. });
  588. store.subscribe(async () => {
  589. let signinBtn = document.getElementById("signinBtn");
  590. if (signinBtn) {
  591. signinBtn.onclick = () => {
  592. try {
  593. let registerFields = document.getElementById("registerFields");
  594. if (registerFields !== null) {
  595. registerFields.style.display = "none";
  596. }
  597. signinBtn.style.display = "none";
  598. signupBtn.style.display = "inline";
  599. let fieldsBlock = document.createElement("div");
  600. fieldsBlock.className = "fields";
  601. fieldsBlock.id = "loginFields";
  602. let email = document.createElement("input");
  603. email.type = "email";
  604. email.placeholder = "Enter your email";
  605. email.className = "form-control";
  606. email.id = "loginInput";
  607. let password = document.createElement("input");
  608. password.type = "password";
  609. password.placeholder = "Enter your password";
  610. password.className = "form-control";
  611. password.id = "pass1Input";
  612. let login = document.createElement("button");
  613. login.innerText = "Login";
  614. login.id = "loginBtn";
  615. login.className = "btn btn-primary";
  616. fieldsBlock.appendChild(email);
  617. fieldsBlock.appendChild(password);
  618. fieldsBlock.appendChild(login);
  619. authBlock.prepend(fieldsBlock);
  620. loginBtn.onclick = () => {
  621. window.location.href = "#/login";
  622. console.log(store.getState());
  623. };
  624. } catch (error) {
  625. console.log(error);
  626. }
  627. };
  628. }
  629. });
  630. store.subscribe(async () => {
  631. let signupBtn = document.getElementById("signupBtn");
  632. if (signupBtn) {
  633. signupBtn.onclick = () => {
  634. try {
  635. let loginFields = document.getElementById("loginFields");
  636. if (loginFields !== null) {
  637. loginFields.style.display = "none";
  638. }
  639. signinBtn.style.display = "inline";
  640. signupBtn.style.display = "none";
  641. let fieldsBlock = document.createElement("div");
  642. fieldsBlock.className = "fields";
  643. fieldsBlock.id = "registerFields";
  644. let email = document.createElement("input");
  645. email.type = "email";
  646. email.placeholder = "Enter your email";
  647. email.className = "form-control";
  648. email.id = "regInput";
  649. let password = document.createElement("input");
  650. password.type = "password";
  651. password.placeholder = "Enter your password";
  652. password.className = "form-control";
  653. password.id = "pass2Input";
  654. let register = document.createElement("button");
  655. register.innerText = "Register";
  656. register.id = "regBtn";
  657. register.className = "btn btn-primary";
  658. fieldsBlock.appendChild(email);
  659. fieldsBlock.appendChild(password);
  660. fieldsBlock.appendChild(register);
  661. authBlock.prepend(fieldsBlock);
  662. regBtn.onclick = () => {
  663. window.location.href = "#/register";
  664. console.log(store.getState());
  665. };
  666. } catch (error) {
  667. console.log(error);
  668. }
  669. };
  670. }
  671. });
  672. store.subscribe(async () => {
  673. const { promise, auth } = store.getState();
  674. let accountLink = document.getElementById("accountLink");
  675. let signoutBtn = document.getElementById("signoutBtn");
  676. let signinBtn = document.getElementById("signinBtn");
  677. let signupBtn = document.getElementById("signupBtn");
  678. if (auth?.token && !signoutBtn && !accountLink) {
  679. signinBtn.style.display = "none";
  680. signupBtn.style.display = "none";
  681. if (promise?.register?.status === "RESOLVED") {
  682. let registerBlock = document.getElementById("registerFields");
  683. registerBlock.style.display = "none";
  684. signupBtn.style.display = "none";
  685. window.location.href = window.location.href.replace("#/register", "");
  686. console.log(store.getState());
  687. }
  688. if (promise?.login?.status === "RESOLVED") {
  689. let loginBlock = document.getElementById("loginFields");
  690. loginBlock.style.display = "none";
  691. signinBtn.style.display = "none";
  692. window.location.href = window.location.href.replace("#/login", "");
  693. console.log(store.getState());
  694. }
  695. let signOut = document.createElement("button");
  696. signOut.innerText = "Sign Out";
  697. signOut.id = "signoutBtn";
  698. signOut.className = "btn btn-secondary";
  699. let authBlock = document.createElement("div");
  700. authBlock.id = "authBlock";
  701. authBlock.appendChild(signOut);
  702. let nickname = auth.payload.sub.login;
  703. let account = document.createElement("button");
  704. account.textContent = nickname;
  705. account.type = "button";
  706. account.id = "accountLink";
  707. account.className = "btn btn-success";
  708. authBlock.prepend(account);
  709. authnav.appendChild(authBlock);
  710. signOut.onclick = () => {
  711. signOut.style.display = "none";
  712. store.dispatch(actionAuthLogout());
  713. signinBtn.style.display = "inline";
  714. signupBtn.style.display = "inline";
  715. account.remove();
  716. };
  717. }
  718. });