Login.vue 4.4 KB

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