view client/src/views/Login.vue @ 158:992e17912405

feat: Improve login against real db In order to log into our real db, we need to consume the new JSON document consuming experies, username, roles, etc. Token is stored securly in browser session. Other data is stored in vue store.
author Thomas Junk <thomas.junk@intevation.de>
date Tue, 03 Jul 2018 16:18:29 +0200
parents 2ba329e82fb0
children 8f49ba6cddd9
line wrap: on
line source

(<template>
  <div :class="loginStyle">
    <div>
      <div class="logogroup d-flex flex-row justify-content-center">
        <div class="logo"><img src="../assets/logo.png"></div>
        <div class="title"><h1>{{ appTitle }}</h1></div>
      </div>
    </div>
    <div class="login-wrapper d-flex flex-row justify-content-center">
      <form class="loginform form-signin" @submit.prevent="login">
           <div v-if="loginFailed" class="loginerrormessage alert alert-danger" role="alert">
             <span class="loginerror"><translate>Login failed</translate></span>
           </div>
        <div class="input-group mb-3 emailgroup">
          <input type="text" v-model="user" id="inputEmail" class="form-control" :placeholder="emailLabel" required autofocus>
        </div>
        <div class="input-group mb-3 passwordgroup">
          <input :type="isPasswordVisible" v-model="password" id="inputPassword" class="form-control" :placeholder='passwordLabel' required>
          <div class="input-group-append">
            <span class="input-group-text" id="basic-addon2" @click="showPassword"><i :class="eyeIcon"></i></span>
          </div>
        </div>
        <button class="submitbutton btn btn-primary btn-block" :disabled="submitted" type="submit"><translate>Login</translate></button>
        <div class="forgottenlink small"><a href="#"><translate>Forgot password</translate></a></div>
        <div class="secondary-logo"><img :src="secondaryLogo"></div>
      </form>
    </div>
  </div>
</template>)

<style lang="scss">
@import "../assets/application.scss";
$logincollapsed: 470px;
$loginextended: 550px;

.emailgroup {
  box-shadow: $basic-shadow-light !important;
}
.forgottenlink {
  text-align: right;
  margin-top: $small-offset;
  margin-bottom: $small-offset;
}
#inputPassword {
  border-right: none;
}
.input-group-text {
  background-color: white !important;
}

.login {
  width: 375px;
  @extend %fully-centered;
  padding-top: $offset;
  padding-bottom: $offset;
  box-shadow: $basic-shadow;
}
.logincollapsed {
  height: $logincollapsed;
}

.loginextended {
  height: $loginextended;
}
.loginerror {
  white-space: pre;
}
.loginerrormessage {
  box-shadow: $basic-shadow-light !important;
}
.loginform {
  width: 300px;
}
.logogroup {
  margin-top: $offset;
  margin-bottom: $offset;
}
.mail-icon {
  width: $iconwidth;
}
.passwordgroup {
  box-shadow: $basic-shadow-light !important;
}
.password-icon {
  position: relative;
  top: 10px;
  font-size: $iconsize;
  line-height: $iconLineHeight;
  width: $iconwidth;
}
.submitbutton {
  box-shadow: $basic-shadow-light !important;
}
.title {
  margin-left: $offset;
}
</style>

<script>
import { mapGetters } from "vuex";

export default {
  name: "login",
  data() {
    return {
      user: "",
      password: "",
      submitted: false,
      loginFailed: false,
      readablePassword: false
    };
  },
  computed: {
    passwordLabel() {
      return this.$gettext("Enter passphrase");
    },
    emailLabel() {
      return this.$gettext("Enter email");
    },
    isPasswordVisible() {
      return this.readablePassword ? "text" : "password";
    },
    eyeIcon() {
      return {
        fa: true,
        "fa-eye": !this.readablePassword,
        "fa-eye-slash": this.readablePassword
      };
    },
    loginStyle() {
      return {
        login: true,
        logincollapsed: !this.loginFailed,
        loginextended: this.loginFailed,
        "bg-white": true,
        rounded: true
      };
    },
    ...mapGetters("application", ["appTitle", "secondaryLogo"])
  },
  methods: {
    login() {
      this.submitted = true;
      const { user, password } = this;
      this.$store
        .dispatch("user/login", { user, password })
        .then(() => {
          this.loginFailed = false;
          this.$router.push("/");
        })
        .catch(() => {
          this.loginFailed = true;
          this.submitted = false;
        });
    },
    showPassword() {
      this.readablePassword = !this.readablePassword;
    }
  }
};
</script>