header.html 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
  2. <!-- <link rel="stylesheet" href="{{ " /css/main.css" | prepend: site.baseurl }}"> -->
  3. <style>
  4. .user-icon {
  5. display: inline-block;
  6. position: relative;
  7. }
  8. .dropdown_header {
  9. display: inline-block;
  10. position: relative;
  11. z-index: 1000;
  12. background-color: #FFC907;
  13. }
  14. .dropdown-content_header {
  15. display: none;
  16. position: absolute;
  17. width: auto;
  18. overflow: auto;
  19. box-shadow: 0px 10px 10px 0px rgba(0, 0, 0, 0.4);
  20. /* background-color: rgba(255, 255, 255, 0); */
  21. background-color: white;
  22. font-family: Reforma2018, serif;
  23. font-size: 1em;
  24. }
  25. .dropdown_header.active .dropdown-content_header {
  26. display: block;
  27. }
  28. .dropdown-content_header a {
  29. display: block;
  30. color: #000000;
  31. padding: 5px;
  32. text-decoration: none;
  33. }
  34. .dropdown-content_header a:hover {
  35. color: #FFFFFF;
  36. background-color: #FFC907;
  37. }
  38. .dropdown_header:hover {
  39. /* Resetting styles for hover state */
  40. border: none;
  41. box-shadow: none;
  42. display: block;
  43. /* Or any other appropriate display value */
  44. grid-template-columns: initial;
  45. /* Or any other appropriate value */
  46. }
  47. /* Style for the modal */
  48. /* #navBar.modal {
  49. display: flex;
  50. flex-direction: column;
  51. align-items: center;
  52. } */
  53. #emailCode,
  54. #emailCodeVerify {
  55. flex-direction: row;
  56. align-items: center;
  57. margin-bottom: 10px;
  58. }
  59. #emailCode {
  60. display: block;
  61. }
  62. #emailCodeVerify {
  63. display: none;
  64. }
  65. .modal {
  66. display: none;
  67. position: fixed;
  68. top: 50%;
  69. left: 50%;
  70. transform: translate(-50%, -50%);
  71. padding: 20px;
  72. background-color: white;
  73. border: 2px solid #ccc;
  74. z-index: 2000;
  75. width: 60%;
  76. height: 20%;
  77. text-align: center;
  78. font-family: Reforma2018, serif;
  79. font-size: 1em;
  80. }
  81. /* Additional styling for buttons */
  82. .btn_login_logout {
  83. position: relative;
  84. border-radius: 4px;
  85. background-color: transparent;
  86. border: 1px solid #29335C;
  87. font-family: Reforma2018, serif;
  88. margin: 10px;
  89. padding-left: 2px;
  90. padding-right: 2px;
  91. }
  92. .btn_login_logout.primary_login_logout {
  93. background-color: #FFC907;
  94. color: black;
  95. border: 1px solid #d3a500;
  96. }
  97. .btn_login_logout.is-large_login_logout {
  98. font-size: 1em;
  99. text-align: center;
  100. }
  101. .btn_login_logout:hover {
  102. cursor: pointer;
  103. background-color: #d3a500
  104. }
  105. </style>
  106. <header class="site-header">
  107. <div class="wrapper">
  108. <a class="site-title" href="{{ site.baseurl }}/">{{ site.title }}</a>
  109. <img src="{% link assets/elements/icon_do.svg %}" alt="do-ocracy icon"
  110. style="height:40px; padding: 5px 0 0 20px;" />
  111. <nav class="site-nav">
  112. <a href="#" class="menu-icon">
  113. <svg viewBox="0 0 18 15">
  114. <path fill="#424242"
  115. d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.031C17.335,0,18,0.665,18,1.484L18,1.484z" />
  116. <path fill="#424242"
  117. d="M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0c0-0.82,0.665-1.484,1.484-1.484 h15.031C17.335,6.031,18,6.696,18,7.516L18,7.516z" />
  118. <path fill="#424242"
  119. d="M18,13.516C18,14.335,17.335,15,16.516,15H1.484C0.665,15,0,14.335,0,13.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.031C17.335,12.031,18,12.696,18,13.516L18,13.516z" />
  120. </svg>
  121. </a>
  122. <div class="trigger" style="display: inline-block;">
  123. {% for my_page in site.pages %}
  124. {% if my_page.title %}
  125. <a class="page-link{% if page.url == my_page.url %} page-link-active{% endif %}"
  126. href="{{ my_page.url | prepend: site.baseurl }}">{{ my_page.title }}</a>
  127. {% endif %}
  128. {% endfor %}
  129. <div class="user-icon" id="loginLogoutButton">
  130. <div id="login">
  131. <button class="btn_login_logout primary_login_logout is-large_login_logout" onclick="showLoginModal()"
  132. style="height: 42px; width: 100px; padding: 2px; text-align: center">
  133. <img src="{% link assets/tabler_icons/login.svg %}" alt="Login"> Login
  134. </button>
  135. </div>
  136. <div id="logout" class="dropdown_header">
  137. <button class="btn_login_logout primary_login_logout is-large_login_logout" onclick="toggleDropdown()"
  138. style="height: 40px; width: 40px; padding: 2px; text-align: center">
  139. <img src="{% link assets/tabler_icons/user.svg %}" alt="Login">
  140. </button>
  141. <div class="dropdown-content_header">
  142. <div id="emailText"
  143. style="padding: 10px; padding-top: 20px; margin-top: 1px; margin-bottom: 1px; height: 10 px">
  144. </div>
  145. <a href="#" style="padding: 10px; margin-top: 1px; margin-bottom: 1px; height: 10 px"
  146. @click="logout">Logout</a>
  147. </div>
  148. </div>
  149. </div>
  150. </div>
  151. </div>
  152. <div id="navBar" class="modal">
  153. <div id="emailCode" style="align-items: center;">
  154. <label for="emailInput">Enter your email:</label>
  155. <input type="email" id="emailInput" v-model="loginEmail" required>
  156. <button class="btn_login_logout primary_login_logout is-large_login_logout" @click="sendOTP"
  157. style="text-align:center;">Send Code</button>
  158. </div>
  159. <div id="emailCodeVerify">
  160. <label for="otpInput">Enter Code to Login:</label>
  161. <input type="text" id="otpInput" v-model="otpCode" required>
  162. <button class="btn_login_logout primary_login_logout is-large_login_logout" @click="verifyOTP">Verify
  163. Code</button>
  164. <button class="btn_login_logout primary_login_logout is-large_login_logout" @click="sendOTPAagin"> Send Code
  165. Again</button>
  166. </div>
  167. <button class="btn_login_logout primary_login_logout is-large_login_logout" @click="closeModal">Close</button>
  168. </div>
  169. </div>
  170. </div>
  171. </nav>
  172. </div>
  173. </header>
  174. <script>
  175. function toggleDropdown() {
  176. var dropdown = document.getElementById('logout');
  177. dropdown.classList.toggle('active');
  178. var myDiv = document.getElementById('emailText'); // Get the div element by ID
  179. myDiv.textContent = localStorage.getItem('userEmail');
  180. }
  181. function showLoginModal() {
  182. // Show the modal and overlay
  183. document.getElementById('navBar').style.display = 'block';
  184. document.getElementById('overlay').style.display = 'block';
  185. }
  186. function logout() {
  187. // Remove email from local storage
  188. localStorage.removeItem('userEmail');
  189. // Hide the dropdown and overlay
  190. document.getElementById('login').style.display = 'block';
  191. document.getElementById('logout').style.display = 'none';
  192. document.getElementById('emailCode').style.display = 'block';
  193. document.getElementById('emailCodeVerify').style.display = 'none';
  194. window.location.reload();
  195. }
  196. // function showLoginModal() {
  197. // document.getElementById('navBar').style.display = 'block';
  198. // // document.getElementById('overlay').style.display = 'block';
  199. // }
  200. function hideLoginModal() {
  201. document.getElementById('navBar').style.display = 'none';
  202. document.getElementById('overlay').style.display = 'none';
  203. }
  204. function isValidEmail(email) {
  205. // Regular expression for a basic email validation
  206. const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  207. return emailRegex.test(email);
  208. }
  209. new Vue({
  210. el: '#loginLogoutButton',
  211. data: {
  212. email: localStorage.getItem('userEmail') || null,
  213. showDropdown: false,
  214. },
  215. mounted() {
  216. // Retrieve email from local storage on component mount
  217. this.email = localStorage.getItem('userEmail');
  218. if (this.email) {
  219. document.getElementById('login').style.display = 'none';
  220. document.getElementById('logout').style.display = 'block';
  221. } else {
  222. document.getElementById('login').style.display = 'block';
  223. document.getElementById('logout').style.display = 'none';
  224. }
  225. },
  226. });
  227. new Vue({
  228. el: '#navBar',
  229. data: {
  230. loginEmail: '',
  231. email: localStorage.getItem('userEmail'),
  232. otpCode: "",
  233. backendUrlOtp: "/api/send_otp",
  234. backendUrlValidateOtp: "/api/validate_otp"
  235. },
  236. methods: {
  237. sendOTPAagin() {
  238. document.getElementById('emailCode').style.display = 'block';
  239. document.getElementById('emailCodeVerify').style.display = 'none';
  240. },
  241. sendOTP() {
  242. const requestData = {
  243. email: this.loginEmail
  244. }
  245. if (isValidEmail(this.loginEmail)) {
  246. fetch(this.backendUrlOtp, {
  247. method: 'POST',
  248. headers: {
  249. 'Content-Type': 'application/json',
  250. 'Access-Control-Allow-Methods': 'POST',
  251. 'Access-Control-Allow-Headers': 'Content-Type'
  252. // Add any other headers you may need, such as authorization headers
  253. },
  254. body: JSON.stringify(requestData),
  255. }).then(response => {
  256. if (!response.ok) {
  257. alert('Error while sending OTP');
  258. } else {
  259. alert(`Code sent to: ${this.loginEmail}`);
  260. document.getElementById('emailCode').style.display = 'none';
  261. document.getElementById('emailCodeVerify').style.display = 'block';
  262. }
  263. })
  264. } else {
  265. alert(`Please enter valid email address`);
  266. }
  267. },
  268. verifyOTP() {
  269. const requestData = {
  270. email: this.loginEmail,
  271. otp: this.otpCode
  272. }
  273. fetch(this.backendUrlValidateOtp, {
  274. method: 'POST',
  275. headers: {
  276. 'Content-Type': 'application/json',
  277. 'Access-Control-Allow-Methods': 'POST',
  278. 'Access-Control-Allow-Headers': 'Content-Type'
  279. // Add any other headers you may need, such as authorization headers
  280. },
  281. body: JSON.stringify(requestData),
  282. }).then(response => {
  283. if (response.status == 500) {
  284. alert('Error while validating code');
  285. } else if (response.status == 200) {
  286. alert('Logged in successfully');
  287. localStorage.setItem('userEmail', this.loginEmail)
  288. document.getElementById('login').style.display = 'none';
  289. document.getElementById('logout').style.display = 'block';
  290. document.getElementById('logout').classList.remove('active');
  291. this.closeModal();
  292. } else {
  293. alert('Invalid code, please enter valid code');
  294. }
  295. })
  296. },
  297. closeModal() {
  298. document.getElementById('navBar').style.display = 'none';
  299. },
  300. },
  301. });
  302. </script>