Login.vue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  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. import Modal from "../Modal.vue";
  103. export default {
  104. components: {
  105. Modal
  106. },
  107. data() {
  108. return {
  109. email: "",
  110. password: {
  111. value: "",
  112. visible: false
  113. },
  114. apiDomain: "",
  115. registrationDisabled: false
  116. };
  117. },
  118. async mounted() {
  119. this.apiDomain = await lofig.get("backend.apiDomain");
  120. this.registrationDisabled = await lofig.get(
  121. "siteSettings.registrationDisabled"
  122. );
  123. },
  124. methods: {
  125. checkForAutofill(event) {
  126. if (
  127. event.target.value !== "" &&
  128. event.inputType === undefined &&
  129. event.data === undefined &&
  130. event.dataTransfer === undefined &&
  131. event.isComposing === undefined
  132. )
  133. this.submitModal();
  134. },
  135. submitOnEnter(cb, event) {
  136. if (event.which === 13) cb();
  137. },
  138. submitModal() {
  139. this.login({
  140. email: this.email,
  141. password: this.password.value
  142. })
  143. .then(res => {
  144. if (res.status === "success") window.location.reload();
  145. })
  146. .catch(err => new Toast(err.message));
  147. },
  148. togglePasswordVisibility() {
  149. if (this.$refs.password.type === "password") {
  150. this.$refs.password.type = "text";
  151. this.password.visible = true;
  152. } else {
  153. this.$refs.password.type = "password";
  154. this.password.visible = false;
  155. }
  156. },
  157. changeToRegisterModal() {
  158. this.closeLoginModal();
  159. this.openModal("register");
  160. },
  161. closeLoginModal() {
  162. this.closeModal("login");
  163. },
  164. githubRedirect() {
  165. localStorage.setItem("github_redirect", this.$route.path);
  166. },
  167. ...mapActions("modalVisibility", ["closeModal", "openModal"]),
  168. ...mapActions("user/auth", ["login"])
  169. }
  170. };
  171. </script>
  172. <style lang="less" scoped>
  173. .night-mode {
  174. .modal-card,
  175. .modal-card-head,
  176. .modal-card-body,
  177. .modal-card-foot {
  178. background-color: var(--dark-grey-3);
  179. }
  180. .label,
  181. p:not(.help) {
  182. color: var(--light-grey-2);
  183. }
  184. }
  185. .modal-card-foot {
  186. display: flex;
  187. justify-content: space-between;
  188. flex-wrap: wrap;
  189. .content-box-optional-helper {
  190. margin-top: 0;
  191. }
  192. }
  193. .button.is-github {
  194. background-color: var(--dark-grey-2);
  195. color: var(--white) !important;
  196. }
  197. .is-github:focus {
  198. background-color: var(--dark-grey-4);
  199. }
  200. .is-primary:focus {
  201. background-color: var(--primary-color) !important;
  202. }
  203. .invert {
  204. filter: brightness(5);
  205. }
  206. </style>