src/components/patials/signinComponent.vue
unknown
plain_text
2 years ago
13 kB
5
Indexable
<template>
<div class="pt-5">
<v-card flat class="mt-6">
<v-card-text class="text-center">
<v-row>
<v-col cols="12" class="text-center">
<center>
<v-img src="/img/app_name.png" width="100" class="mb-3"></v-img>
<h3 class="font-weight-light" v-if="!showOTP">
Log into your account
</h3>
<h3 class="font-weight-light" v-else>
A verification code was sent to your phone number. Enter the
code to log into your account
</h3>
</center>
</v-col>
</v-row>
<v-stepper v-model="step" style="box-shadow: none" class="p-0">
<v-stepper-items>
<div
style="display: flex; justify-content: center"
class="my-2"
v-if="!showOTP"
>
<div
class="mr-2"
:style="{
borderBottom: isEmailLogin ? '3px solid #267DD4' : '',
color: isEmailLogin ? '#267DD4' : '',
cursor: 'pointer',
}"
@click="switchForm()"
>
Login with email
</div>
<div
:style="{
borderBottom: !isEmailLogin ? '3px solid #267DD4' : '',
color: !isEmailLogin ? '#267DD4' : '',
cursor: 'pointer',
}"
@click="switchForm()"
>
Login with phone
</div>
</div>
<v-stepper-content step="1">
<v-form
ref="login_form"
v-model="valid_form"
@keyup.native.enter="valid_form && login()"
>
<div v-if="isEmailLogin">
<v-text-field
label="E-Mail"
outlined
:rules="email_rules"
v-model="email"
type="email"
:autofocus="true"
class="mt-2"
></v-text-field>
<v-text-field
v-model="password"
:append-icon="
show_pass ? 'mdi-eye-outline' : 'mdi-eye-off-outline'
"
:rules="password_rules"
:type="show_pass ? 'text' : 'password'"
label="Password"
counter
outlined
@click:append="show_pass = !show_pass"
></v-text-field>
</div>
<div v-else class="mt-2">
<div v-if="!showOTP">
<phone-number-input
:isEmailLogin="isEmailLogin"
@input="(ph) => (phone_number = ph)"
></phone-number-input>
</div>
<div v-else>
<v-progress-linear
indeterminate
v-if="verifying"
></v-progress-linear>
<v-otp-input
length="6"
v-model="verification_code"
@finish="phoneVerification"
/>
</div>
</div>
<p class="text-left" v-if="!showOTP">
Forgot your password?
<a :href="$store.state.URL + 'passwordreset'"
>Reset Password</a
><br />
</p>
<p class="text-left" v-else>
Didn't receive OTP?
<span style="color: #267dd4; cursor: pointer"
>Resend OTP</span
>
</p>
</v-form>
<div v-if="!showOTP">
<v-btn
:loading="progress"
block
color="success"
dark
@click="login"
rounded
x-large
depressed
>
Login
</v-btn>
<v-btn
v-if="isEmailLogin"
class="mt-3"
color="blue"
outlined
dark
x-large
rounded
:loading="progress"
depressed
block
style="text-decoration: none"
:href="$store.state.URL + 'login/google'"
>Login with google <v-icon>mdi-google</v-icon></v-btn
>
</div>
</v-stepper-content>
<v-stepper-content step="2">
<v-icon x-large>mdi-lock-outline</v-icon>
<h3>A verification code was sent to {{ maskedEmail }}</h3>
<strong>Enter the code to continue</strong>
<v-form ref="verify_form">
<v-text-field
v-model="verification_code"
outlined
label="Verification code"
>
</v-text-field>
</v-form>
<v-checkbox
class="mt-0 pt-0"
v-model="trusted"
color="blue darken-4"
label="Trust this device for 60 days"
></v-checkbox>
<v-alert color="red lighten-5 red--text" v-if="verify_error">{{
verify_error_message
}}</v-alert>
<v-btn
@click="verifiedCode"
:loading="verifying"
block
rounded
large
depressed
color="blue darken-4"
dark
>Verify<v-icon>mdi-check-circle</v-icon></v-btn
>
<v-btn
:disabled="verifying"
class="mt-2"
block
rounded
large
depressed
color="blue"
text
dark
@click="step = 1"
><v-icon>mdi-arrow-left</v-icon>Back</v-btn
>
</v-stepper-content>
</v-stepper-items>
</v-stepper>
<v-alert type="error" v-if="login_error">
<h5>{{ error_msg }}</h5>
</v-alert>
<p class="mt-5">
Don't have a Built account?
<v-btn color="blue" dark text rounded to="/register"
>Create Account</v-btn
>
</p>
</v-card-text>
<v-snackbar color="red" v-model="otpError">{{ otpMessage }}</v-snackbar>
<v-snackbar color="red" v-model="phoneError">{{
phoneErrorMessage
}}</v-snackbar>
</v-card>
</div>
</template>
<script>
import axios from "axios";
import { getAccessToken, setAccessToken } from "../../utils";
import PhoneNumberInput from "../agents/PhoneNumberInput.vue";
export default {
name: "signinComponent",
components: { PhoneNumberInput },
data() {
return {
trusted: false,
verify_error: false,
verify_error_message: "",
verification_code: null,
verifying: false,
hash: null,
step: 1,
read_terms: false,
checking: false,
exist: false,
loggingin: false,
service_pop: false,
retail_pop: false,
success_msg: false,
success_message: "",
code: "",
logo: [],
imgsrc: "/img/logo_place.png",
previewURL: "/img/logo_place.png",
logo_file: {},
business_email: "",
business_email_rules: [
(v) => !!v || "E-mail is required",
(v) => /.+@.+/.test(v) || "E-mail must be valid",
],
business_location: "",
business_valid: false,
account_infor: false,
personal_infor: false,
first_name: "",
last_name: "",
call_code: "",
flag: "",
phone_number: "",
new_password: "",
confirm_password: "",
new_email: "",
progress: false,
show_pass: false,
show_pass1: false,
show_pass2: false,
remember_me: true,
valid_form: false,
login_error: false,
error_msg: "",
countries: null,
password: "",
email: "",
is_service: false,
is_retail_wholesale: true,
preview: "",
password_rules: [(value) => !!value || "Password is Required."],
first_name_rules: [(value) => !!value || "Name is Required."],
required_rules: [(value) => !!value || this.$t("main.required")],
phone_number_rules: [(value) => !!value || "Phone number is Required."],
email_rules: [(value) => !!value || "E-mail is Required."],
show: false,
tab: null,
user: {},
isEmailLogin: true,
phone_number: "",
showOTP: false,
otpError: false,
otpMessage: "",
phoneError: false,
phoneErrorMessage: "",
otpProgress: false,
};
},
computed: {
maskedEmail() {
const str = this.email.split("");
let finalArr = [];
let len = str.indexOf("@");
str.forEach((item, pos) => {
pos >= 1 && pos <= len - 2
? finalArr.push("*")
: finalArr.push(str[pos]);
});
return finalArr.join("");
},
},
mounted() {
if (this.$store.state.user && this.$store.state.user.is_loged_in) {
this.$router.back();
}
},
methods: {
phoneVerification() {
this.verify_error = false;
this.verifying = true;
const formData = new FormData();
formData.append("code", this.verification_code);
formData.append("hash", this.hash);
formData.append("should_trust", this.trusted);
axios
.post("/api/auth/varifycode", formData)
.then((res) => {
if (res.data.status) {
setAccessToken(res.data.access_token);
location.reload();
} else {
this.verifying = false;
this.verify_error_message = res.data.message;
this.verify_error = true;
}
})
.catch((e) => {
this.otpError = true;
this.otpMessage = e.response.data;
this.verifying = false;
});
},
verifiedCode() {
if (this.$refs.verify_form.validate()) {
this.phoneVerification();
}
},
switchForm() {
this.isEmailLogin = !this.isEmailLogin;
},
login() {
if (this.$refs.login_form.validate()) {
if (this.isEmailLogin) {
this.loggingin = true;
this.progress = true;
let formdata = {
email: this.email,
password: this.password,
remember_me: this.remember_me,
};
axios
.post("/api/auth/v2/login", formdata)
.then((user) => {
setAccessToken(user.data.access_token);
localStorage.removeItem("WGPassport");
if (user.data.twoFA) {
this.hash = user.data.hash;
this.verification_code = "";
this.step = 2;
this.progress = false;
} else {
if (!user.data.user.has_business) {
this.$router.push({ path: "/onboard" });
location.reload();
} else {
this.$router.push({ path: "/" });
this.$store.commit("init_app");
}
}
})
.catch((error) => {
this.progress = false;
this.login_error = true;
if (error.response.status === 401) {
this.error_msg =
"Unauthorised: The credentials you provided could not be found in our records";
} else {
this.error_msg =
"Something went wrong, could not process login. please check your connections and try again ";
}
});
} else {
this.progress = true;
const reqData = {
phone_number: this.phone_number,
};
axios
.post("/api/auth/v2/login/phone", reqData)
.then((res) => {
const { hash } = res.data;
this.hash = hash;
this.trusted = true;
this.showOTP = true;
})
.catch((e) => {
this.progress = false;
this.phoneError = true;
this.phoneErrorMessage = e.response.data.message;
});
}
}
},
},
};
</script>
<style scoped></style>
Editor is loading...