Login.vue 4.3 KB

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