src/components/patials/signinComponent.vue

mail@pastecode.io avatar
unknown
plain_text
a year ago
13 kB
2
Indexable
Never
<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>