header.html 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
  2. <style>
  3. .user-icon {
  4. display: inline-block;
  5. position: relative;
  6. }
  7. /* Style for the modal */
  8. .modal {
  9. display: none;
  10. position: fixed;
  11. top: 50%;
  12. left: 50%;
  13. transform: translate(-50%, -50%);
  14. padding: 20px;
  15. background-color: #FFC907;
  16. border: 2px solid #ccc;
  17. z-index: 2000;
  18. }
  19. .dropdown {
  20. display: inline-block;
  21. position: relative;
  22. z-index: 1000;
  23. }
  24. .dropdown-content {
  25. display: none;
  26. position: absolute;
  27. width: auto;
  28. overflow: auto;
  29. box-shadow: 0px 10px 10px 0px rgba(0, 0, 0, 0.4);
  30. /* background-color: rgba(255, 255, 255, 0); */
  31. background-color: white;
  32. }
  33. .dropdown.active .dropdown-content {
  34. display: block;
  35. }
  36. .dropdown-content a {
  37. display: block;
  38. color: #000000;
  39. padding: 5px;
  40. text-decoration: none;
  41. }
  42. .dropdown-content a:hover {
  43. color: #FFFFFF;
  44. background-color: #FFC907;
  45. }
  46. .dropdown:hover {
  47. /* Resetting styles for hover state */
  48. border: none;
  49. box-shadow: none;
  50. display: block;
  51. /* Or any other appropriate display value */
  52. grid-template-columns: initial;
  53. /* Or any other appropriate value */
  54. }
  55. </style>
  56. <header class="site-header">
  57. <div class="wrapper">
  58. <a class="site-title" href="{{ site.baseurl }}/">{{ site.title }}</a>
  59. <img src="{% link assets/elements/icon_do.svg %}" alt="do-ocracy icon"
  60. style="height:40px; padding: 5px 0 0 20px;" />
  61. <nav class="site-nav">
  62. <a href="#" class="menu-icon">
  63. <svg viewBox="0 0 18 15">
  64. <path fill="#424242"
  65. 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" />
  66. <path fill="#424242"
  67. 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" />
  68. <path fill="#424242"
  69. 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" />
  70. </svg>
  71. </a>
  72. <div class="trigger" style="display: inline-block;">
  73. {% for my_page in site.pages %}
  74. {% if my_page.title %}
  75. <a class="page-link{% if page.url == my_page.url %} page-link-active{% endif %}"
  76. href="{{ my_page.url | prepend: site.baseurl }}">{{ my_page.title }}</a>
  77. {% endif %}
  78. {% endfor %}
  79. <div class="user-icon">
  80. <div id="loginLogoutButton">
  81. <div id="login" style="height: 20px; width: 30px;">
  82. <button onclick="showLoginModal()"
  83. style="background-color: #FFC907; height: 30px; width: 35px; padding:0px; border-color: #FFC907;">
  84. <img src="{% link assets/elements/loginIcon.png %}" alt="Login" style="width: 100%; height: 100%;">
  85. </button>
  86. </div>
  87. <div id="logout" class="dropdown disable-hover"
  88. style="background-color: #FFC907; height: 30px; width: 35px; ">
  89. <button onclick="toggleDropdown()"
  90. style="background-color: #FFC907; height: 30px; width: 32px; padding:0px;">
  91. <img src="{% link assets/elements/loggedin.png %}" alt="Profile" style="width: 100%; height: 100%;">
  92. </button>
  93. <div class="dropdown-content">
  94. <div id="emailText"
  95. style="padding: 10px; padding-top: 20px; margin-top: 1px; margin-bottom: 1px; height: 10 px"> </div>
  96. <a href="#" style="padding: 10px; margin-top: 1px; margin-bottom: 1px; height: 10 px"
  97. @click="logout">Logout</a>
  98. </div>
  99. </div>
  100. </div>
  101. </div>
  102. <div id="navBar" class="modal">
  103. <div id="emailCode">
  104. <label for="emailInput">Enter your email:</label>
  105. <input type="email" id="emailInput" v-model="loginEmail" required>
  106. <button @click="sendOTP" style="font-family: Arial, Helvetica, sans-serif;">Send Code</button>
  107. </div>
  108. <div id="emailCodeVerify" style="display: none;">
  109. <label for="otpInput">Enter Code to Login:</label>
  110. <input type="text" id="otpInput" v-model="otpCode" required>
  111. <button @click="verifyOTP" style="font-family: Arial, Helvetica, sans-serif;">Verify Code</button>
  112. <button @click="sendOTPAagin" style="font-family: Arial, Helvetica, sans-serif;"> Send Code again</button>
  113. </div>
  114. <button @click="closeModal" style="font-family: Arial;">Close</button>
  115. </div>
  116. </div>
  117. </div>
  118. </nav>
  119. </div>
  120. </header>
  121. <script>
  122. function toggleDropdown() {
  123. var dropdown = document.getElementById('logout');
  124. dropdown.classList.toggle('active');
  125. var myDiv = document.getElementById('emailText'); // Get the div element by ID
  126. myDiv.textContent = localStorage.getItem('userEmail');
  127. }
  128. function showLoginModal() {
  129. // Show the modal and overlay
  130. document.getElementById('navBar').style.display = 'block';
  131. document.getElementById('overlay').style.display = 'block';
  132. }
  133. function logout() {
  134. // Remove email from local storage
  135. localStorage.removeItem('userEmail');
  136. // Hide the dropdown and overlay
  137. document.getElementById('login').style.display = 'block';
  138. document.getElementById('logout').style.display = 'none';
  139. document.getElementById('emailCode').style.display = 'block';
  140. document.getElementById('emailCodeVerify').style.display = 'none';
  141. window.location.reload();
  142. }
  143. function showLoginModal() {
  144. document.getElementById('navBar').style.display = 'block';
  145. // document.getElementById('overlay').style.display = 'block';
  146. }
  147. function hideLoginModal() {
  148. document.getElementById('navBar').style.display = 'none';
  149. document.getElementById('overlay').style.display = 'none';
  150. }
  151. function isValidEmail(email) {
  152. // Regular expression for a basic email validation
  153. const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  154. return emailRegex.test(email);
  155. }
  156. new Vue({
  157. el: '#loginLogoutButton',
  158. data: {
  159. email: localStorage.getItem('userEmail') || null,
  160. showDropdown: false,
  161. },
  162. mounted() {
  163. // Retrieve email from local storage on component mount
  164. this.email = localStorage.getItem('userEmail');
  165. if (this.email) {
  166. document.getElementById('login').style.display = 'none';
  167. document.getElementById('logout').style.display = 'block';
  168. } else {
  169. document.getElementById('login').style.display = 'block';
  170. document.getElementById('logout').style.display = 'none';
  171. }
  172. },
  173. });
  174. new Vue({
  175. el: '#navBar',
  176. data: {
  177. loginEmail: '',
  178. email: localStorage.getItem('userEmail'),
  179. otpCode: "",
  180. backendUrlOtp: "http://localhost:3000/api/send_otp",
  181. backendUrlValidateOtp: "http://localhost:3000/api/validate_otp"
  182. },
  183. methods: {
  184. sendOTPAagin() {
  185. document.getElementById('emailCode').style.display = 'block';
  186. document.getElementById('emailCodeVerify').style.display = 'none';
  187. },
  188. sendOTP() {
  189. const requestData = {
  190. email: this.loginEmail
  191. }
  192. if (isValidEmail(this.loginEmail)) {
  193. fetch(this.backendUrlOtp, {
  194. method: 'POST',
  195. headers: {
  196. 'Content-Type': 'application/json',
  197. 'Access-Control-Allow-Methods': 'POST',
  198. 'Access-Control-Allow-Headers': 'Content-Type'
  199. // Add any other headers you may need, such as authorization headers
  200. },
  201. body: JSON.stringify(requestData),
  202. }).then(response => {
  203. if (!response.ok) {
  204. alert('Error while sending OTP');
  205. } else {
  206. alert(`Code sent to: ${this.loginEmail}`);
  207. document.getElementById('emailCode').style.display = 'none';
  208. document.getElementById('emailCodeVerify').style.display = 'block';
  209. }
  210. })
  211. } else {
  212. alert(`Please enter valid email address`);
  213. }
  214. },
  215. verifyOTP() {
  216. const requestData = {
  217. email: this.loginEmail,
  218. otp: this.otpCode
  219. }
  220. fetch(this.backendUrlValidateOtp, {
  221. method: 'POST',
  222. headers: {
  223. 'Content-Type': 'application/json',
  224. 'Access-Control-Allow-Methods': 'POST',
  225. 'Access-Control-Allow-Headers': 'Content-Type'
  226. // Add any other headers you may need, such as authorization headers
  227. },
  228. body: JSON.stringify(requestData),
  229. }).then(response => {
  230. if (response.status == 500) {
  231. alert('Error while validating code');
  232. } else if (response.status == 200) {
  233. alert('Logged in successfully');
  234. localStorage.setItem('userEmail', this.loginEmail)
  235. document.getElementById('login').style.display = 'none';
  236. document.getElementById('logout').style.display = 'block';
  237. document.getElementById('logout').classList.remove('active');
  238. this.closeModal();
  239. } else {
  240. alert('Invalid code, please enter valid code');
  241. }
  242. })
  243. },
  244. closeModal() {
  245. document.getElementById('navBar').style.display = 'none';
  246. },
  247. },
  248. });
  249. </script>