Login.vue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. <script setup lang="ts">
  2. import { ref, onMounted } from "vue";
  3. import { useRoute } from "vue-router";
  4. import Toast from "toasters";
  5. import { useUserAuthStore } from "@/stores/userAuth";
  6. import { useModalsStore } from "@/stores/modals";
  7. const route = useRoute();
  8. const email = ref("");
  9. const password = ref({
  10. value: "",
  11. visible: false
  12. });
  13. const apiDomain = ref("");
  14. const siteSettings = ref({
  15. registrationDisabled: false,
  16. githubAuthentication: false
  17. });
  18. const passwordElement = ref();
  19. const { login } = useUserAuthStore();
  20. const { openModal, closeCurrentModal } = useModalsStore();
  21. const submitModal = () => {
  22. login({
  23. email: email.value,
  24. password: password.value.value
  25. })
  26. .then((res: any) => {
  27. if (res.status === "success") window.location.reload();
  28. })
  29. .catch(err => new Toast(err.message));
  30. };
  31. const checkForAutofill = event => {
  32. if (
  33. event.target.value !== "" &&
  34. event.inputType === undefined &&
  35. event.data === undefined &&
  36. event.dataTransfer === undefined &&
  37. event.isComposing === undefined
  38. )
  39. submitModal();
  40. };
  41. const togglePasswordVisibility = () => {
  42. if (passwordElement.value.type === "password") {
  43. passwordElement.value.type = "text";
  44. password.value.visible = true;
  45. } else {
  46. passwordElement.value.type = "password";
  47. password.value.visible = false;
  48. }
  49. };
  50. const changeToRegisterModal = () => {
  51. closeCurrentModal();
  52. openModal("register");
  53. };
  54. const githubRedirect = () => {
  55. localStorage.setItem("github_redirect", route.path);
  56. };
  57. onMounted(async () => {
  58. apiDomain.value = await lofig.get("backend.apiDomain");
  59. siteSettings.value = await lofig.get("siteSettings");
  60. });
  61. </script>
  62. <template>
  63. <div>
  64. <modal
  65. title="Login"
  66. class="login-modal"
  67. :size="'slim'"
  68. @closed="closeCurrentModal()"
  69. >
  70. <template #body>
  71. <form>
  72. <!-- email address -->
  73. <p class="control">
  74. <label class="label">Username/Email</label>
  75. <input
  76. v-model="email"
  77. class="input"
  78. type="email"
  79. placeholder="Username/Email..."
  80. @keyup.enter="submitModal()"
  81. />
  82. </p>
  83. <!-- password -->
  84. <p class="control">
  85. <label class="label">Password</label>
  86. </p>
  87. <div id="password-visibility-container">
  88. <input
  89. v-model="password.value"
  90. class="input"
  91. type="password"
  92. ref="passwordElement"
  93. placeholder="Password..."
  94. @input="checkForAutofill($event)"
  95. @keyup.enter="submitModal()"
  96. />
  97. <a @click="togglePasswordVisibility()">
  98. <i class="material-icons">
  99. {{
  100. !password.visible
  101. ? "visibility"
  102. : "visibility_off"
  103. }}
  104. </i>
  105. </a>
  106. </div>
  107. <p class="content-box-optional-helper">
  108. <router-link
  109. id="forgot-password"
  110. to="/reset_password"
  111. @click="closeCurrentModal()"
  112. >
  113. Forgot password?
  114. </router-link>
  115. </p>
  116. <br />
  117. <p>
  118. By logging in you agree to our
  119. <router-link to="/terms" @click="closeCurrentModal()">
  120. Terms of Service
  121. </router-link>
  122. and
  123. <router-link to="/privacy" @click="closeCurrentModal()">
  124. Privacy Policy</router-link
  125. >.
  126. </p>
  127. </form>
  128. </template>
  129. <template #footer>
  130. <div id="actions">
  131. <button class="button is-primary" @click="submitModal()">
  132. Login
  133. </button>
  134. <a
  135. v-if="siteSettings.githubAuthentication"
  136. class="button is-github"
  137. :href="apiDomain + '/auth/github/authorize'"
  138. @click="githubRedirect()"
  139. >
  140. <div class="icon">
  141. <img
  142. class="invert"
  143. src="/assets/social/github.svg"
  144. />
  145. </div>
  146. &nbsp;&nbsp;Login with GitHub
  147. </a>
  148. </div>
  149. <p
  150. v-if="!siteSettings.registrationDisabled"
  151. class="content-box-optional-helper"
  152. >
  153. <a @click="changeToRegisterModal()">
  154. Don't have an account?
  155. </a>
  156. </p>
  157. </template>
  158. </modal>
  159. </div>
  160. </template>
  161. <style lang="less" scoped>
  162. .night-mode {
  163. .modal-card,
  164. .modal-card-head,
  165. .modal-card-body,
  166. .modal-card-foot {
  167. background-color: var(--dark-grey-3);
  168. }
  169. .label,
  170. p:not(.help) {
  171. color: var(--light-grey-2);
  172. }
  173. }
  174. .modal-card-foot {
  175. display: flex;
  176. justify-content: space-between;
  177. flex-wrap: wrap;
  178. .content-box-optional-helper {
  179. margin-top: 0;
  180. }
  181. }
  182. .button.is-github {
  183. background-color: var(--dark-grey-2);
  184. color: var(--white) !important;
  185. }
  186. .is-github:focus {
  187. background-color: var(--dark-grey-4);
  188. }
  189. .is-primary:focus {
  190. background-color: var(--primary-color) !important;
  191. }
  192. .invert {
  193. filter: brightness(5);
  194. }
  195. </style>