fix: #178. refresh token. if not logged in then refresh token; else redirect to login page.

This commit is contained in:
Cindy Chang
2024-06-28 13:53:47 +08:00
parent 65fdb2a945
commit 8054bf89cd

132
src/views/Login/Login.vue Normal file
View File

@@ -0,0 +1,132 @@
<template>
<div class="container h-screen-main">
<div class="flex justify-center items-center min-h-full">
<div class="w-full max-w-md p-8">
<h2 class="text-center text-2xl mb-4 font-semibold">LOGIN</h2>
<form action="#" method="post" class="w-full grid gap-2" @submit.prevent="signIn">
<label for="account" class="relative">
<p class="text-sm font-normal mb-2">Account</p>
<span class="absolute flex bottom-1 left-0 items-center pl-2 pr-2 border-r border-neutral-300 h-[26px]">
<IconMember class="h-5 w-5 fill-current"/>
</span>
<input type="text" id="account" class="w-full border border-neutral-300 rounded py-1 pl-10 pr-2 focus:outline-none focus:border-primary focus:ring-1 "
:class="{'border-danger':isInvalid}" required autofocus v-model.trim="auth.username"
@change="changeHandler($event)"/>
</label>
<label for="passwordt" class="relative block">
<p class="text-sm font-normal mb-2">Password</p>
<span class="absolute flex bottom-1 left-0 items-center pl-2 pr-2 border-r border-neutral-300 h-[26px]">
<IconLockKey class="h-5 w-5 fill-current"/>
</span>
<input :type="showPassword ? 'text' : 'password'" id="password" aria-describedby="password-addon"
class="w-full border border-neutral-300 rounded py-1 pl-10 pr-2 focus:outline-none focus:border-primary focus:ring-1 "
:class="{'border-danger':isInvalid}" required v-model.trim="auth.password" @change="changeHandler($event)"/>
<span class="absolute bottom-2 right-4 inline-flex items-center cursor-pointer" v-show="auth.password"
@click="showPassword = !showPassword">
<IconEyeOpen class="h-5 w-5" v-if="showPassword"/>
<IconEyeClose class="h-5 w-5" v-else/>
</span>
</label>
<p class="my-4 text-danger">
<span v-show="isInvalid">
<IconWarnTriangle class="h-4 w-5 mx-2 mb-[2px] inline-block text-danger"/>
Incorrect account or password.
</span>
</p>
<button id="login_btn_main_btn" type="submit" class="w-full btn btn-lg"
:class="this.isDisabled ? 'btn-disable' : 'btn-c-primary'"
:disabled="isDisabledButton">
Log in
</button>
</form>
</div>
</div>
</div>
</template>
<script>
import { storeToRefs, mapActions } from 'pinia';
import loginStore from '@/stores/login.js';
import IconMember from '@/components/icons/IconMember.vue';
import IconLockKey from '@/components/icons/IconLockKey.vue';
import IconEyeOpen from '@/components/icons/IconEyeOpen.vue';
import IconEyeClose from '@/components/icons/IconEyeClose.vue';
import IconWarnTriangle from '@/components/icons/IconWarnTriangle.vue';
export default {
data(){
return {
isDisabled: true,
showPassword: false,
}
},
setup() {
// 調用函數,獲取 Store
const store = loginStore();
// 調用 store 裡的 state
const { auth, isInvalid } = storeToRefs(store);
// 調用 store 裡的 action
const { signIn } = store;
return {
auth,
isInvalid,
signIn,
}
},
components: {
IconMember,
IconLockKey,
IconEyeOpen,
IconEyeClose,
IconWarnTriangle
},
computed: {
/**
* if input no value , disabled.
*/
isDisabledButton() {
let inputAreSpaces = this.auth.username === '' || this.auth.password === '' || this.isInvalid === true;
return this.isDisabled = inputAreSpaces ? true : false;
},
},
methods: {
/**
* when input onChange value , isInvalid === false.
* @param {event} event input 傳入的事件
*/
changeHandler(event) {
let inputValue = event.target.value;
if(inputValue !== '') {
this.isInvalid = false;
}
},
...mapActions(loginStore, ['setRememberedReturnToUrl']),
},
created() {
// 考慮到使用者可能在未登入的情況下貼入一個頁面網址連結過來瀏覽器
// btoa: 對字串進行 Base64 編碼
if(this.$route.query['return-to']) {
this.setRememberedReturnToUrl(this.$route.query['return-to']);
}
},
};
</script>
<style scoped>
/* Hide the eyes from a password input in MS Edge */
input::-ms-reveal,
input::-ms-clear {
display: none;
}
/* Hide the keys from the inputs in safair */
input::-webkit-contacts-auto-fill-button,
input::-webkit-credentials-auto-fill-button {
visibility: hidden;
display: none !important;
pointer-events: none;
height: 0;
width: 0;
margin: 0;
}
</style>