header.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /**
  2. * ЭЛЕКТРОННЫЙ ЖУРНАЛ «ШКАЛА»: ХИДЕР, МЕНЮ И ФУТЕР СТРАНИЦ ЖУРНАЛА
  3. * Copyright © 2019, А.М.Гольдин. Modified BSD License
  4. */
  5. "use strict";
  6. // Показ блоков страницы в зависимости от выбранного пункта меню
  7. const blockShow = menuItem => {
  8. // Подсвечиваем выбранный пункт меню
  9. for (let mn of document.querySelectorAll("nav li"))
  10. mn.classList.remove("sel");
  11. dqs(`#mn${menuItem}`).className = "sel";
  12. // Сворачиваем мобильное меню
  13. if (dqs("header img").src.includes("MobClose")) dqs("header img").click();
  14. // Показываем соответствующий блок контента
  15. for (let sect of document.querySelectorAll("section"))
  16. sect.style.display = "none";
  17. dqs(`#${menuItem}`).style.display = "block";
  18. // Вызываем необходимую для этого блока функцию для подгрузки контента
  19. // (функции подгрузки для каждого блока определены в самих скриптах блоков)
  20. if (getContent[menuItem]) getContent[menuItem]();
  21. };
  22. // Генерирование меню в зависимости от выбранной роли пользователя
  23. // (константа menuItems определена в ini.js)
  24. const menuGen = () => {
  25. let role = dqs("#selRole").value;
  26. let res = "<ul>";
  27. for (let mi of menuItems[role])
  28. res += `<li id="mn${mi[0]}" onClick="blockShow('${mi[0]}')">${mi[1]}</li>\n`;
  29. res += "</ul>";
  30. dqs("nav").innerHTML = res;
  31. blockShow(menuItems[role][0][0]);
  32. dqs("#selRole").blur();
  33. };
  34. // Формирование опций для селекта выбора роли пользователя
  35. // (константа roleNames определена в ini.js)
  36. const headerOptGen = roles => {
  37. let res = '';
  38. for (let i = 0; i < roles.length; i++)
  39. res += `<option value=${roles[i]}>${roleNames[roles[i]]}</option>`;
  40. return res;
  41. };
  42. // Обработка кликания на иконке мобильного меню
  43. const showMenuMob = () => {
  44. let mmiDisp = dqs("nav").style.display || "none";
  45. dqs("nav").style.display =
  46. (mmiDisp == "none") ? "block" : "none";
  47. dqs("header img").src =
  48. (mmiDisp == "none") ? "static/menuMobClose.svg" : "static/menuMob.svg";
  49. }
  50. // Запрос к API для смены пароля и сообщение о результате
  51. const chPwdApi = async () => {
  52. let pwd = dqs("#newPwd").value.trim(),
  53. pwd1 = dqs("#newPwd1").value.trim();
  54. dqs("#chPwdWarn").style.display = "none";
  55. if (pwd != pwd1) {
  56. dqs("#chPwdWarn").innerHTML = "Пароли не совпадают!";
  57. dqs("#chPwdWarn").style.display = "block";
  58. return;
  59. }
  60. if (pwd.length < 8) {
  61. dqs("#chPwdWarn").innerHTML =
  62. "Пароль должен содержать<br>не менее 8 символов!";
  63. dqs("#chPwdWarn").style.display = "block";
  64. return;
  65. }
  66. let apiResp = await apireq("usChPwd", [uLogin, pwd]);
  67. if (apiResp == "none") info(1, "Запрашиваемая операция отклонена.");
  68. else {
  69. dqs("#chPwdWin").style.display = "none";
  70. info(0,
  71. "Пароль успешно заменен.<br>Авторизуйтесь заново с новым паролем.");
  72. document.body.onclick = () => location.reload();
  73. }
  74. }
  75. // Показ модального окна для смены пароля
  76. const chPwd = () => {
  77. let role = dqs("#selRole").value;
  78. if (role == "root") info(1,
  79. "Смена пароля главного администратора веб-интерфейсом невозможна.");
  80. else if (role == "pupil" || role == "parent") info(0,
  81. "Для смены пароля обратитесь к администратору электронного журнала.");
  82. else {
  83. elems.chPwdElem = document.createElement("div");
  84. elems.chPwdElem.innerHTML = `
  85. <h1>Смена пароля</h1>
  86. <input type="password" id="newPwd" placeholder="Пароль">
  87. <input type="password" id="newPwd1" placeholder="Повторите пароль"
  88. onKeyDown="if (event.keyCode == 13) chPwdApi()">
  89. <button type="button" onClick="chPwdApi()">Сменить пароль</button>
  90. <button id="clButt" type="button" onClick="elems.chPwdElem.remove()"
  91. style="margin-top:-30px">Отмена</button>
  92. <div id="chPwdWarn"></div>
  93. `;
  94. elems.chPwdElem.id = "chPwdWin";
  95. dqs("#content").appendChild(elems.chPwdElem);
  96. elems.chPwdElem.style.display = "block";
  97. dqs("#newPwd").focus();
  98. }
  99. }
  100. // Формирование хидера и включение футера
  101. const headerGen = async () => {
  102. dqs("#content").innerHTML += `
  103. <header>
  104. <img src="static/menuMob.svg" title="Меню" onClick="showMenuMob()">
  105. <span id="progName">ЭЖ «Шкала»</span>
  106. <span>${uLogin}:<span>
  107. <select id="selRole" onChange="menuGen()" title="Роль пользователя">
  108. ${headerOptGen(uRoles)}
  109. </select>
  110. <span id="chPwd" title="Сменить пароль" onClick="chPwd()">&#9874;</span>
  111. <a href='' title="Выход">&#9635;</a>
  112. </header>
  113. <nav></nav>
  114. `;
  115. menuGen();
  116. try {
  117. let adminCont = await (await fetch("/a.a")).text();
  118. let versCont = await (await fetch("/history.html", {method: "GET"})).text();
  119. let histUrl = URL.createObjectURL(new Blob([versCont], {type: "text/html"}));
  120. versCont = versCont.split("<pre>")[1].trim().split(' ')[0];
  121. dqs("footer").innerHTML += `Адм.: ${adminCont} &bull;
  122. <a href=${histUrl} target="_blank">v.&nbsp;${versCont}</a>`;
  123. dqs("footer").style.display = "block";
  124. } catch(e) {;}
  125. };