|
|
<template> <div :class="['tw-h-full tw-p-[30px] tw-bg-white md:tw-bg-primary-pale']"> <div class="xl:tw-grid xl:tw-grid-cols-[auto_414px] xl:tw-gap-[96px] xl:tw-max-w-[1246px] xl:tw-mx-auto xl:tw-px-[60px]"> <div class="tw-hidden xl:tw-block xl:tw-mt-[30px]"> <p class="welcome tw-text-primary-light">{{ $t("Welcome to ShowEasy") }}</p> <p class="sub tw-text-neutral-400"> {{ $t("Your best guide from trip to show and from show to the world.") }} </p> <img class="mt-11 ml-15" :src="require('@/assets/img/UserLoginMain.png')" /> </div> <div class="md:tw-w-[414px] md:tw-mx-auto"> <div class="tw-bg-white md:tw-rounded-[24px] md:tw-mt-[30px] md:tw-pt-[60px] md:tw-pb-[150px] md:tw-px-[30px]"> <v-spacer v-if="emailSignUp"> <h1 class="tw-text-[40px] tw-font-bold tw-mb-[20px] md:tw-text-[24px] md:tw-mb-[14px]">{{ $t("Sign Up") }}</h1> <p class="tw-body-3 tw-text-neutral-400 tw-mb-[16px] md:tw-mb-[12px]"> {{ $t("Welcome to ShowEasy!") }} </p> <p class="tw-body-3 tw-mb-[45px] md:tw-mb-[32px]"> {{ $t("Already have an account?") }} <nuxt-link :to="localePath('/user')" class="primary--text text-decoration-none">{{ $t("Login") }}</nuxt-link> </p> <div class="tw-grid tw-grid-cols-1 tw-gap-[10px] md:tw-gap-[12px]"> <!-- <button @click="googleLogin" class="tw-flex tw-justify-center tw-items-center tw-w-full tw-py-[8px] tw-rounded-[16px] tw-border tw-border-solid tw-text-black tw-border-neutrals-200"><img width="24px" height="24px" src="~/assets/img/g-normal.png" class="mr-5" />{{ $t("Sign up with Google") }}</button> <button @click="facebookLogin" class="tw-flex tw-justify-center tw-items-center 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("Sign up with Facebook") }} </button> --> <button @click="emailSignUp = !emailSignUp" class="tw-flex tw-justify-center tw-items-center tw-w-full tw-py-[8px] tw-rounded-[16px] tw-border tw-border-solid tw-text-black tw-border-neutrals-200"> <unicon name="envelope" width="20px" height="20px" class="tw-flex tw-justify-center tw-items-center tw-mr-[20px]"> </unicon>{{ $t("Sign up with Email") }} </button> </div> </v-spacer> <v-spacer v-if="!emailSignUp"> <p class="title">{{ $t("Sign up with Email") }}</p> <p class="neutrals--text text--darken-3 text-size-14"> {{ $t("Welcome to ShowEasy!") }} </p> <v-form v-model="valid"> <v-text-field v-model="user.FirstName" background-color="neutrals darken-1" :label="this.$t('First Name') + '*'" placeholder="" filled rounded dense single-line :rules="[rules.require]"> </v-text-field> <v-text-field v-model="user.LastName" background-color="neutrals darken-1" :label="this.$t('Last Name') + '*'" placeholder="" filled rounded dense single-line :rules="[rules.require]"> </v-text-field> <v-text-field v-model="user.Email" background-color="neutrals darken-1" :label="this.$t('Email') + '*'" filled rounded dense single-line :rules="[rules.email, rules.require]" validate-on-blur></v-text-field> <v-text-field v-model="user.Password" background-color="neutrals darken-1" :label="this.$t('Password') + '*'" :type="showPass ? 'text' : 'password'" placeholder="" filled rounded dense single-line :rules="[rules.checkPassword, rules.require]" :hint=" this.$t( 'userProfile.passwordsHint' ) " persistent-hint :append-icon="showPass ? 'mdi-eye' : 'mdi-eye-off'" @click:append="showPass = !showPass" validate-on-blur></v-text-field> <v-text-field v-model="confirmPasswordText" background-color="neutrals darken-1" :label="this.$t('Confirm Password') + '*'" :type="showConfirmPass ? 'text' : 'password'" placeholder="" filled rounded dense single-line :rules="[rules.checkConfirmPassword, rules.require]" :append-icon="showConfirmPass ? 'mdi-eye' : 'mdi-eye-off'" @click:append="showConfirmPass = !showConfirmPass" validate-on-blur></v-text-field> </v-form> <v-checkbox v-model="user.Subscribe" class="mt-n2 ml-1"> <template v-slot:label> <span class="neutrals--text text--darken-4 text-size-14"> {{ $t("Subscribe to ShowEasy\’s newsletter") }} </span> </template> </v-checkbox> <div class="md:tw-flex md:tw-justify-center md:tw-items-center"> <button @click="userRegister" :disabled="!validFormat" :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("Sign Up") }} </button> </div> <!-- 原註冊流程Modal(信箱連結認證) --> <v-dialog v-model="dialog" :width="$vuetify.breakpoint.smAndUp ? 423 : 294" @click:outside="$router.push(localePath('/user'))"> <v-card class="pa-7" :height="$vuetify.breakpoint.smAndUp ? 249 : 290"> <v-spacer class="d-flex align-center text-size-20 neutrals--text text--darken-5"> {{ $t("Verify your email") }} <v-spacer></v-spacer> <v-btn @click="$router.push(localePath('/user'))" icon> <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">{{ user.Email }}</span>{{ $t(". Please click the link within to activate your account.") }} </v-spacer> <v-btn @click="resendVerifyEmail" class="primary no-text-transform" width="153px" rounded :disabled="countdown > 0"> {{ $t("Resend") }} <span v-if="countdown > 0"> {{ `(${this.countdown})` }} </span> </v-btn> </v-card> </v-dialog> <!-- 帳號已存在Modal --> <v-dialog v-model="errorDialog" :width="$vuetify.breakpoint.smAndUp ? 423 : 294"> <v-card class="pa-7 border-radius-16" :max-height="$vuetify.breakpoint.smAndUp ? 249 : 290"> <v-spacer class="d-flex align-center text-size-20 neutrals--text text--darken-5"> {{ $t("Error") }} <v-spacer></v-spacer> <v-btn @click="errorDialog = !errorDialog" icon> <v-icon> mdi-close </v-icon> </v-btn> </v-spacer> <v-spacer class="text-size-16 my-7 neutrals--text text--darken-4"> {{ $t("Same email has been created already.") }} </v-spacer> <v-spacer class="d-flex justify-center"> <v-btn class="border-radius-16" color="primary" @click="errorDialog = !errorDialog">{{ $t("ok") }}</v-btn> </v-spacer> </v-card> </v-dialog> <p align="center" class="neutrals--text text--darken-3 text-size-14 mt-7"> {{ $t("By signing up,") }}<br /> {{ $t("you agree to the") }} <nuxt-link :to="localePath('/termsandconditions')" target="_blank" class="text-decoration-none"> {{ $t("Terms & Conditions") }}</nuxt-link> {{ $t("and") }} <nuxt-link :to="localePath('/privacypolicy')" target="_blank" class="text-decoration-none"> {{ $t("Privacy Policy") }}</nuxt-link> </p> <p align="center" class="neutrals--text text--darken-5 text-size-14"> {{ $t("Already have an account?") }} <nuxt-link :to="localePath('/user')" class="primary--text text-decoration-none">{{ $t("Login") }}</nuxt-link> </p> </v-spacer> <loading :isLoading="isPageLoading"></loading> <VerifyCode @user-verifyCode="userVerifyCode" @resend-mail="resendVerifyEmail" :error="error" :account="user.Account"></VerifyCode> </div> </div> </div> </div> </template> <script> import loading from "@/components/newComponent/loading/loading.vue"; import VerifyCode from "@/components/newcomponent/modal/VerifyCodeModal.vue"; export default { name: "SignUp", layout: "login", auth: false, components: { loading, VerifyCode }, data() { return { valid: false, showPass: false, showConfirmPass: false, emailSignUp: true, Subscribe: true, dialog: false, errorDialog: false, btnText: "Sign up", confirmPasswordText: "", countdown: 60, isPageLoading: false, 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) || this.$t( "Passwords must be 8-20 characters with at least 1 number, 1 lower case letter and 1 upper case letter" ), checkConfirmPassword: (v) => this.confirmPasswordText === this.user.Password || this.$t("Your password and confirmation password do not match"), }, user: { FirstName: "", LastName: "", Account: "", Password: "", Email: "", Subscribe: true, }, signUp: false, userInfo: {}, error: false, userData: { Account: '', Password: '', }, }; }, watch: { signUp: { handler: function () { if (this.signUp == true) { this.$auth.$storage.removeUniversal("userPassword"); this.$auth.$storage.removeUniversal("userAccount"); } }, }, }, methods: { //會員註冊
userRegister() { const postUserData = { ...this.user }; this.isPageLoading = true; this.$axios .post( `/trending/api/Signup/SignupWithEmail`, postUserData ) .then((response) => { //console.log(JSON.stringify(response));
if(response.data.STATUSCODE == "400"){ this.errorDialog = true; this.isPageLoading = false; } if(response && response.data && response.data.DATA && response.data.DATA.rel){ let data = response.data.DATA.rel if(data){ this.userInfo = data; this.$modal.show('VerifyCode'); this.signUp = true; this.isPageLoading = false; //this.dialog = !this.dialog; //原先的認證流程Modal
} } }) .catch((err) => { console.log(err); }); }, //重新寄出認證碼
resendVerifyEmail() { this.countdown = 60; this.$axios .post( `/trending/api/Signup/ReSendVerifyMail?Email=${this.user.Email}` ) .then((res) => { }) .catch((err) => { console.log(err); }); }, //認證會員
userVerifyCode(value){ this.error = false; this.$axios .get( `/trending/api/Signup/VerifyAccount?OrgID=${this.userInfo.OrgID}&MemberID=${this.userInfo.MemberID}&Code=${value}` ) .then((response) => { //console.log(response);
if(response.data.STATUSCODE == 200){ this.$modal.hide('VerifyCode'); this.Login(); } else{ this.error = true; } }) .catch((err) => { console.log(err); }); }, //登入
async Login(){ this.userData.Account = this.userInfo.Account; this.userData.Password = this.user.Password; const response = await this.$auth.loginWith('local', { data: this.userData }); if(response.data.STATUSCODE == 200){ let data = response.data.DATA; if(data.authtoken){ const authtoken = data.authtoken; this.$auth.$storage.removeUniversal('authtoken'); this.$auth.$storage.setUniversal('authtoken', authtoken); let path = this.$auth.$storage.getUniversal('userBeforePath'); if(path == "/user"){ path = "/"; } this.$router.push({path: path}); } } } }, computed: { validFormat() { if (this.valid && this.user.Password === this.confirmPasswordText) { return true; } else { return false; } }, }, beforeUnmount() { clearInterval(this.timer); }, }; </script>
<style lang="scss" scoped> #app { overflow-y: hidden; }
.welcome { color: #f5cda8; font-family: Damion; font-size: 48px; margin-bottom: 0px; font-weight: 400; line-height: 66px; letter-spacing: 0.02em; }
.sub { color: #9c9c9c; font-style: italic; font-weight: 400; font-size: 22px; line-height: 29px; letter-spacing: 0.02em; }
:deep(.v-text-field.v-text-field--enclosed .v-text-field__details) { padding: 0; margin: 0; }
:deep(.v-messages__message) { font-size: 14px; }
$border-style: 1px solid #e5e5e5;
.title { font-weight: 700; font-size: 26px; line-height: 34px; letter-spacing: 0.02em; color: #232323; }
:deep(.v-text-field.v-text-field--enclosed .v-text-field__details) { margin-bottom: 0; padding: 0;
.v-messages { color: #9c9c9c; display: none; }
.v-messages.error--text { display: block; margin-top: 4px; margin-bottom: 16px; } }
.btn-border { border: $border-style; } </style>
|