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.
 
 

292 lines
11 KiB

<template>
<div class="tw-bg-white tw-mt-[30px] md:tw-rounded-[24px] md:tw-pt-[60px] md:tw-pb-[150px] md:tw-px-[30px]">
<h1 class="tw-text-[40px] tw-font-bold tw-mb-[20px] md:tw-text-[24px]">{{ $t('Login') }}</h1>
<p class="tw-body-3 tw-text-neutral-400 tw-mb-[16px] md:tw-mb-[12px]">
{{ $t('Welcome back! Please enter your details') }}
</p>
<p class="tw-body-3 tw-mb-[24px] md:tw-mb-[32px]">{{ $t('Not a member?') }} <nuxt-link
:to="localePath('/user/signup')" class="primary--text text-decoration-none">{{ $t('Sign up') }}</nuxt-link>
</p>
<!-- <div class="tw-grid tw-grid-cols-1 tw-gap-[10px] tw-mb-[30px] md:tw-gap-[12px] md:tw-mb-[12px]">
<button @click="googleLogin"
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
width="20px" height="20px" src="~/assets/img/g-normal.png" class="mr-5" />{{ $t('Login with Google')
}}</button>
<button @click="facebookLogin"
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
width="20px" height="20px" src="~/assets/img/f_logo_RGB-Blue_72.png" class="mr-5" />
{{ $t("Login with Facebook")
}}</button>
</div>
<div class="tw-grid tw-grid-cols-[auto_16px_auto] tw-gap-[28px] tw-mb-[6px]">
<div class="tw-flex tw-justify-center tw-items-center">
<div class="tw-w-full tw-h-[1px] tw-bg-neutral-200"></div>
</div>
<div class="tw-text-neutral-400 tw-body-3 tw-font-normal">{{ $t("or") }}</div>
<div class="tw-flex tw-justify-center tw-items-center">
<div class="tw-w-full tw-h-[1px] tw-bg-neutral-200"></div>
</div>
</div> -->
<div v-if="wrongMessageActive" class="warning--text text-size-14 ps-1 mb-3">
{{ $t('The username or password entered is incorrect') }}
</div>
<v-form ref="loginFormRef" lazy-validation>
<v-text-field
v-model="userData.Account" background-color="neutrals darken-1" :label="this.$t('Email')"
:placeholder="this.$t('Email')" height="40px" filled rounded dense single-line persistent-placeholder
:rules="[rules.email,rules.require]" v-on:input="updateValid"
/>
<v-text-field
v-model="userData.Password" background-color="neutrals darken-1" :label="this.$t('Password')"
:type=" showPass ? 'text' : 'password'" :placeholder="this.$t('Password')" filled rounded dense single-line
persistent-placeholder :append-icon=" showPass ? 'mdi-eye' : 'mdi-eye-off'" @click:append="showPass = !showPass"
:rules="[rules.checkPassword,rules.require]" v-on:input="updateValid"
/>
</v-form>
<div class="tw-flex tw-justify-between tw-items-center tw-mb-[28px] md:tw-mb-[32px]">
<div class="tw-flex tw-items-center">
<div class="tw-flex tw-items-center">
<div class="tw-flex tw-flex-col">
<label class="tw-body-4 container-checkbox" for="remember">
{{ $t('Remember me')
}}
<input id="remember" type="checkbox" value="remember" />
<span class="checkmark"></span>
</label>
</div>
</div>
</div>
<div class="tw-flex tw-items-center">
<nuxt-link class="complementary--text text-decoration-none text-size-14" :to="localePath('/user/forgot')">{{
$t('Forgot Password?') }}</nuxt-link>
</div>
</div>
<div class="md:tw-flex md:tw-justify-center md:tw-items-center"> <button @click="userLogin" :disabled="!valid"
: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']">{{
$t("Login")
}}</button></div>
<v-dialog v-model="resendDialog" :width=" $vuetify.breakpoint.smAndUp ? 423 : 294 "
@click:outside="$router.push(localePath('/user'))">
<v-card class="pa-7 " v-if="!verifyEmailSent" :height=" $vuetify.breakpoint.smAndUp ? 249 : 206 ">
<v-spacer class="d-flex">
<v-spacer class="text-size-20 neutrals--text text--darken-5">{{ $t('Verify your email') }}</v-spacer>
<v-btn icon @click="resendDialog = !resendDialog">
<v-icon>mdi-close</v-icon>
</v-btn>
</v-spacer>
<v-spacer class="text-size-16 my-7 neutrals--text text--darken-4">
{{ $t("We've sent a verification email to")}}
<br />
<span class="primary--text">
{{ userData.Password }}
</span>. {{ $t("Please click the link within to activate your account.") }}
</v-spacer>
<v-btn @click="resendVerifyEmail" class="primary no-text-transform" width="100%" rounded>
{{ $t("Resend verification email") }}
</v-btn>
</v-card>
<v-card class="pa-7 " v-else :height=" $vuetify.breakpoint.smAndUp ? 249 : 206 ">
<v-spacer class="text-size-20 neutrals--text text--darken-5">
{{ $t('Verify your email') }}
</v-spacer>
<v-spacer class="text-size-16 my-7 neutrals--text text--darken-4">
{{ $t("We've sent a verification email to")
}}
<br />
<span class="primary--text">
{{ userData.Password }}
</span>. {{ $t("Please click the link within to activate your account.") }}
</v-spacer>
<v-btn @click="resendVerifyEmail" class="primary no-text-transform" width="100%" rounded
:disabled="countdown > 0">
{{ $t("Resend") }}
<span v-if="countdown > 0">
{{ `(${this.countdown})` }}
</span>
</v-btn>
</v-card>
</v-dialog>
</div>
</template>
<script>
export default {
name: "login",
layout: "login",
auth: false,
data() {
return {
showPass: false,
resendDialog: false,
wrongMessageActive: false,
verifyEmailSent: false,
valid: false,
countdown: 60,
userData: {
Account: '',
Password: '',
},
rules: {
require: value => !!value || this.$t('Required.'),
email: v => /^([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$/.test(v) || this.$t('Invalid email'),
// checkPassword: v => (/(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])/.test(v) && v.length >= 8 && v.length <= 20) || '請輸入密碼',
checkPassword: v => v.length >= 1 || '請輸入密碼',
},
}
},
methods: {
async userLogin() {
let that = this;
if (!that.$refs.loginFormRef.validate()) return;
console.log("測試登錄接口請求開始:" + that.getCurrentTime());
try {
const response =await that.$auth.loginWith('local', { data: that.userData });
console.log("測試登錄接口請求結束:" + that.getCurrentTime());
let data = response.data.DATA;
console.log(JSON.stringify(data.rel));
if(data.rel){
const authtoken = data.rel.token;
this.$auth.$storage.removeUniversal('authtoken');
this.$auth.$storage.setUniversal('authtoken', authtoken);
this.$auth.loggedIn ? this.$router.push(this.$auth.$storage.getUniversal('userBeforePath')) : this.$auth.redirect('login');
}
} catch(err) {
err.response.status === 403 ? this.resendDialog = !this.resendDialog : err.response.status === 401 ? this.wrongMessageActive = true : this.resendDialog
}
},
resendVerifyEmail() {
},
getCurrentTime() {
//获取当前时间并打印
var _this = this;
let yy = new Date().getFullYear();
let mm = new Date().getMonth() + 1;
let dd = new Date().getDate();
let hh = new Date().getHours();
let mf = new Date().getMinutes() < 10
? "0" + new Date().getMinutes()
: new Date().getMinutes();
let ss = new Date().getSeconds() < 10
? "0" + new Date().getSeconds()
: new Date().getSeconds();
_this.gettime = yy + "/" + mm + "/" + dd + " " + hh + ":" + mf + ":" + ss;
return _this.gettime;
},
updateValid(){
if(this.userData.Account !=='' && this.userData.Password !==''){
this.valid = true;
}else{
this.valid = false;
}
}
},
}
</script>
<style lang="scss" scoped>
$border-style: 1px solid #E5E5E5;
.title {
font-weight: 700;
font-size: 26px;
line-height: 34px;
letter-spacing: 0.02em;
color: #232323;
}
.btn-border {
border: $border-style;
}
.seperator {
border-bottom: $border-style;
text-align: center;
height: 12px;
margin: 20px 0 30px;
}
:deep(.v-text-field.v-text-field--enclosed .v-text-field__details) {
margin-bottom: 0;
padding: 0;
.v-messages {
display: none;
}
.v-messages.error--text {
display: block;
margin-top: 4px;
margin-bottom: 16px;
}
}
/* The container */
.container-checkbox {
display: block;
position: relative;
padding-left: 28px;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
/* Hide the browser's default checkbox */
.container-checkbox input {
position: absolute;
opacity: 0;
cursor: pointer;
}
/* Create a custom checkbox */
.container-checkbox .checkmark {
position: absolute;
top: 0;
left: 0;
height: 18px;
width: 18px;
background-color: transparent;
border: 1px solid #f48800;
border-radius: 4px;
}
/* On mouse-over, add a grey background color */
.container-checkbox:hover input~.checkmark {
border-color: #f48800;
}
/* When the checkbox is checked, add a blue background */
.container-checkbox input:checked~.checkmark {
background-color: #f48800;
border-color: #f48800;
}
/* Create the checkmark/indicator (hidden when not checked) */
.container-checkbox .checkmark:after {
content: "";
position: absolute;
display: none;
}
/* Show the checkmark when checked */
.container-checkbox input:checked~.checkmark:after {
display: block;
}
/* Style the checkmark/indicator */
.container-checkbox .checkmark:after {
left: 5px;
top: 2px;
width: 5px;
height: 10px;
border: solid #ffffff;
border-width: 0 2px 2px 0;
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}
</style>