You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

291 lines
11 KiB

2 years ago
  1. <template>
  2. <div class="tw-bg-white tw-mt-[30px] md:tw-rounded-[24px] md:tw-pt-[60px] md:tw-pb-[150px] md:tw-px-[30px]">
  3. <h1 class="tw-text-[40px] tw-font-bold tw-mb-[20px] md:tw-text-[24px]">{{ $t('Login') }}</h1>
  4. <p class="tw-body-3 tw-text-neutral-400 tw-mb-[16px] md:tw-mb-[12px]">
  5. {{ $t('Welcome back! Please enter your details') }}
  6. </p>
  7. <p class="tw-body-3 tw-mb-[24px] md:tw-mb-[32px]">{{ $t('Not a member?') }} <nuxt-link
  8. :to="localePath('/user/signup')" class="primary--text text-decoration-none">{{ $t('Sign up') }}</nuxt-link>
  9. </p>
  10. <!-- <div class="tw-grid tw-grid-cols-1 tw-gap-[10px] tw-mb-[30px] md:tw-gap-[12px] md:tw-mb-[12px]">
  11. <button @click="googleLogin"
  12. class="tw-block tw-w-full tw-py-[8px] tw-rounded-[16px] tw-border tw-border-solid tw-text-black tw-border-neutrals-200"><img
  13. width="20px" height="20px" src="~/assets/img/g-normal.png" class="mr-5" />{{ $t('Login with Google')
  14. }}</button>
  15. <button @click="facebookLogin"
  16. class="tw-block tw-w-full tw-py-[8px] tw-rounded-[16px] tw-border tw-border-solid tw-text-black tw-border-neutrals-200"><img
  17. width="20px" height="20px" src="~/assets/img/f_logo_RGB-Blue_72.png" class="mr-5" />
  18. {{ $t("Login with Facebook")
  19. }}</button>
  20. </div>
  21. <div class="tw-grid tw-grid-cols-[auto_16px_auto] tw-gap-[28px] tw-mb-[6px]">
  22. <div class="tw-flex tw-justify-center tw-items-center">
  23. <div class="tw-w-full tw-h-[1px] tw-bg-neutral-200"></div>
  24. </div>
  25. <div class="tw-text-neutral-400 tw-body-3 tw-font-normal">{{ $t("or") }}</div>
  26. <div class="tw-flex tw-justify-center tw-items-center">
  27. <div class="tw-w-full tw-h-[1px] tw-bg-neutral-200"></div>
  28. </div>
  29. </div> -->
  30. <div v-if="wrongMessageActive" class="warning--text text-size-14 ps-1 mb-3">
  31. {{ $t('The username or password entered is incorrect') }}
  32. </div>
  33. <v-form ref="loginFormRef" lazy-validation>
  34. <v-text-field
  35. v-model="userData.Account" background-color="neutrals darken-1" :label="this.$t('Email')"
  36. :placeholder="this.$t('Email')" height="40px" filled rounded dense single-line persistent-placeholder
  37. :rules="[rules.email,rules.require]" v-on:input="updateValid"
  38. />
  39. <v-text-field
  40. v-model="userData.Password" background-color="neutrals darken-1" :label="this.$t('Password')"
  41. :type=" showPass ? 'text' : 'password'" :placeholder="this.$t('Password')" filled rounded dense single-line
  42. persistent-placeholder :append-icon=" showPass ? 'mdi-eye' : 'mdi-eye-off'" @click:append="showPass = !showPass"
  43. :rules="[rules.checkPassword,rules.require]" v-on:input="updateValid"
  44. />
  45. </v-form>
  46. <div class="tw-flex tw-justify-between tw-items-center tw-mb-[28px] md:tw-mb-[32px]">
  47. <div class="tw-flex tw-items-center">
  48. <div class="tw-flex tw-items-center">
  49. <div class="tw-flex tw-flex-col">
  50. <label class="tw-body-4 container-checkbox" for="remember">
  51. {{ $t('Remember me')
  52. }}
  53. <input id="remember" type="checkbox" value="remember" />
  54. <span class="checkmark"></span>
  55. </label>
  56. </div>
  57. </div>
  58. </div>
  59. <div class="tw-flex tw-items-center">
  60. <nuxt-link class="complementary--text text-decoration-none text-size-14" :to="localePath('/user/forgot')">{{
  61. $t('Forgot Password?') }}</nuxt-link>
  62. </div>
  63. </div>
  64. <div class="md:tw-flex md:tw-justify-center md:tw-items-center"> <button @click="userLogin" :disabled="!valid"
  65. :class="['tw-block tw-w-full tw-py-[10px] tw-rounded-[16px] tw-border tw-border-solid tw-body-3 tw-font-normal tw-transition-all tw-duration-200 tw-ease-in-out',valid?'tw-text-white tw-bg-primary-default tw-border-primary-default':'tw-text-base-disable tw-bg-neutral-100 tw-border-neutral-100']">{{
  66. $t("Login")
  67. }}</button></div>
  68. <v-dialog v-model="resendDialog" :width=" $vuetify.breakpoint.smAndUp ? 423 : 294 "
  69. @click:outside="$router.push(localePath('/user'))">
  70. <v-card class="pa-7 " v-if="!verifyEmailSent" :height=" $vuetify.breakpoint.smAndUp ? 249 : 206 ">
  71. <v-spacer class="d-flex">
  72. <v-spacer class="text-size-20 neutrals--text text--darken-5">{{ $t('Verify your email') }}</v-spacer>
  73. <v-btn icon @click="resendDialog = !resendDialog">
  74. <v-icon>mdi-close</v-icon>
  75. </v-btn>
  76. </v-spacer>
  77. <v-spacer class="text-size-16 my-7 neutrals--text text--darken-4">
  78. {{ $t("We've sent a verification email to")}}
  79. <br />
  80. <span class="primary--text">
  81. {{ userData.Password }}
  82. </span>. {{ $t("Please click the link within to activate your account.") }}
  83. </v-spacer>
  84. <v-btn @click="resendVerifyEmail" class="primary no-text-transform" width="100%" rounded>
  85. {{ $t("Resend verification email") }}
  86. </v-btn>
  87. </v-card>
  88. <v-card class="pa-7 " v-else :height=" $vuetify.breakpoint.smAndUp ? 249 : 206 ">
  89. <v-spacer class="text-size-20 neutrals--text text--darken-5">
  90. {{ $t('Verify your email') }}
  91. </v-spacer>
  92. <v-spacer class="text-size-16 my-7 neutrals--text text--darken-4">
  93. {{ $t("We've sent a verification email to")
  94. }}
  95. <br />
  96. <span class="primary--text">
  97. {{ userData.Password }}
  98. </span>. {{ $t("Please click the link within to activate your account.") }}
  99. </v-spacer>
  100. <v-btn @click="resendVerifyEmail" class="primary no-text-transform" width="100%" rounded
  101. :disabled="countdown > 0">
  102. {{ $t("Resend") }}
  103. <span v-if="countdown > 0">
  104. {{ `(${this.countdown})` }}
  105. </span>
  106. </v-btn>
  107. </v-card>
  108. </v-dialog>
  109. </div>
  110. </template>
  111. <script>
  112. export default {
  113. name: "login",
  114. layout: "login",
  115. auth: false,
  116. data() {
  117. return {
  118. showPass: false,
  119. resendDialog: false,
  120. wrongMessageActive: false,
  121. verifyEmailSent: false,
  122. valid: false,
  123. countdown: 60,
  124. userData: {
  125. Account: '',
  126. Password: '',
  127. },
  128. rules: {
  129. require: value => !!value || this.$t('Required.'),
  130. email: v => /^([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$/.test(v) || this.$t('Invalid email'),
  131. // checkPassword: v => (/(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])/.test(v) && v.length >= 8 && v.length <= 20) || '請輸入密碼',
  132. checkPassword: v => v.length >= 1 || '請輸入密碼',
  133. },
  134. }
  135. },
  136. methods: {
  137. async userLogin() {
  138. let that = this;
  139. if (!that.$refs.loginFormRef.validate()) return;
  140. console.log("測試登錄接口請求開始:" + that.getCurrentTime());
  141. try {
  142. const response =await that.$auth.loginWith('local', { data: that.userData });
  143. console.log("測試登錄接口請求結束:" + that.getCurrentTime());
  144. let data = response.data.DATA;
  145. console.log(JSON.stringify(data.rel));
  146. if(data.rel){
  147. const authtoken = data.rel.token;
  148. this.$auth.$storage.removeUniversal('authtoken');
  149. this.$auth.$storage.setUniversal('authtoken', authtoken);
  150. this.$auth.loggedIn ? this.$router.push(this.$auth.$storage.getUniversal('userBeforePath')) : this.$auth.redirect('login');
  151. }
  152. } catch(err) {
  153. err.response.status === 403 ? this.resendDialog = !this.resendDialog : err.response.status === 401 ? this.wrongMessageActive = true : this.resendDialog
  154. }
  155. },
  156. resendVerifyEmail() {
  157. },
  158. getCurrentTime() {
  159. //获取当前时间并打印
  160. var _this = this;
  161. let yy = new Date().getFullYear();
  162. let mm = new Date().getMonth() + 1;
  163. let dd = new Date().getDate();
  164. let hh = new Date().getHours();
  165. let mf = new Date().getMinutes() < 10
  166. ? "0" + new Date().getMinutes()
  167. : new Date().getMinutes();
  168. let ss = new Date().getSeconds() < 10
  169. ? "0" + new Date().getSeconds()
  170. : new Date().getSeconds();
  171. _this.gettime = yy + "/" + mm + "/" + dd + " " + hh + ":" + mf + ":" + ss;
  172. return _this.gettime;
  173. },
  174. updateValid(){
  175. if(this.userData.Account !=='' && this.userData.Password !==''){
  176. this.valid = true;
  177. }else{
  178. this.valid = false;
  179. }
  180. }
  181. },
  182. }
  183. </script>
  184. <style lang="scss" scoped>
  185. $border-style: 1px solid #E5E5E5;
  186. .title {
  187. font-weight: 700;
  188. font-size: 26px;
  189. line-height: 34px;
  190. letter-spacing: 0.02em;
  191. color: #232323;
  192. }
  193. .btn-border {
  194. border: $border-style;
  195. }
  196. .seperator {
  197. border-bottom: $border-style;
  198. text-align: center;
  199. height: 12px;
  200. margin: 20px 0 30px;
  201. }
  202. :deep(.v-text-field.v-text-field--enclosed .v-text-field__details) {
  203. margin-bottom: 0;
  204. padding: 0;
  205. .v-messages {
  206. display: none;
  207. }
  208. .v-messages.error--text {
  209. display: block;
  210. margin-top: 4px;
  211. margin-bottom: 16px;
  212. }
  213. }
  214. /* The container */
  215. .container-checkbox {
  216. display: block;
  217. position: relative;
  218. padding-left: 28px;
  219. cursor: pointer;
  220. -webkit-user-select: none;
  221. -moz-user-select: none;
  222. -ms-user-select: none;
  223. user-select: none;
  224. }
  225. /* Hide the browser's default checkbox */
  226. .container-checkbox input {
  227. position: absolute;
  228. opacity: 0;
  229. cursor: pointer;
  230. }
  231. /* Create a custom checkbox */
  232. .container-checkbox .checkmark {
  233. position: absolute;
  234. top: 0;
  235. left: 0;
  236. height: 18px;
  237. width: 18px;
  238. background-color: transparent;
  239. border: 1px solid #f48800;
  240. border-radius: 4px;
  241. }
  242. /* On mouse-over, add a grey background color */
  243. .container-checkbox:hover input~.checkmark {
  244. border-color: #f48800;
  245. }
  246. /* When the checkbox is checked, add a blue background */
  247. .container-checkbox input:checked~.checkmark {
  248. background-color: #f48800;
  249. border-color: #f48800;
  250. }
  251. /* Create the checkmark/indicator (hidden when not checked) */
  252. .container-checkbox .checkmark:after {
  253. content: "";
  254. position: absolute;
  255. display: none;
  256. }
  257. /* Show the checkmark when checked */
  258. .container-checkbox input:checked~.checkmark:after {
  259. display: block;
  260. }
  261. /* Style the checkmark/indicator */
  262. .container-checkbox .checkmark:after {
  263. left: 5px;
  264. top: 2px;
  265. width: 5px;
  266. height: 10px;
  267. border: solid #ffffff;
  268. border-width: 0 2px 2px 0;
  269. -webkit-transform: rotate(45deg);
  270. -ms-transform: rotate(45deg);
  271. transform: rotate(45deg);
  272. }
  273. </style>