WIP my account page
This commit is contained in:
@@ -30,8 +30,7 @@
|
||||
{{ i18next.t("AcctMgmt.AccountNotUnique") }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-row w-full flex py-2 h-[40px] mb-4 items-center
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="general my-account flex justify-center w-full h-full p-8">
|
||||
<div class="general my-account flex flex-col items-center w-full h-full p-8">
|
||||
<main class="flex main-part flex-col px-6 mt-6 w-[536px]">
|
||||
<h1 id="general_acct_info_user_name" class="text-[32px] leading-[64px] font-medium mb-2">
|
||||
{{ name }}
|
||||
@@ -15,20 +15,115 @@
|
||||
</span> times.
|
||||
</div>
|
||||
</main>
|
||||
<main class="flex flex-col pt-6 px-6 w-[536px]">
|
||||
<h1 class="text-[20px] font-medium mb-4">
|
||||
{{ i18next.t("AcctMgmt.UserInfo") }}
|
||||
</h1>
|
||||
<div class="row w-full flex py-2 h-[40px] mb-4 items-center">
|
||||
<div class="field-label text-sm flex items-center font-medium mr-4">
|
||||
<span class="align-right-span flex w-[80px]">
|
||||
{{ i18next.t("AcctMgmt.Account") }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="account flex flex-col">
|
||||
<span class="flex text-[#0F172A] text-[14px]">{{ username }}</span>
|
||||
<div v-show="false" class="error-wrapper my-2">
|
||||
<div class="error-msg-section flex justify-start">
|
||||
<img src="@/assets/icon-alert.svg" alt="!" class="exclamation-img flex mr-2">
|
||||
<span class="error-msg-text flex text-[#FF3366] h-[24px]">
|
||||
{{ i18next.t("AcctMgmt.AccountNotUnique") }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row w-full flex py-2 h-[40px] mb-4 items-center">
|
||||
<div class="field-label text-sm flex items-center font-medium mr-4">
|
||||
<span class="align-right-span flex w-[80px]">
|
||||
{{ i18next.t("AcctMgmt.FullName") }}
|
||||
</span>
|
||||
</div>
|
||||
<input v-if='isNameEditable' id="input_name_field"
|
||||
class="w-[280px] h-[40px] rounded p-1 border border-[1px] border-[#64748B] flex items-center outline-none"
|
||||
v-model="inputName" :readonly="!isNameEditable"
|
||||
autocomplete="off"
|
||||
/>
|
||||
<span v-else class="not-editable displayable name w-[280px]">
|
||||
{{ name }}
|
||||
</span>
|
||||
<button v-if='isNameEditable' class="flex save-btn rounded-full text-[#FFFFFF] h-[40px] w-[80px] items-center
|
||||
bg-[#0099FF] justify-center cursor-pointer ml-20
|
||||
">
|
||||
{{ i18next.t("Global.Save") }}
|
||||
</button>
|
||||
<button v-else class="flex save-btn rounded-full text-[#666666] h-[40px] w-[80px] items-center
|
||||
bg-[#FFFFFF] justify-center cursor-pointer ml-20 border border-[#666666]"
|
||||
@click="onEditNameClick"
|
||||
>
|
||||
{{ i18next.t("Global.Edit") }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="row w-full flex py-2 mb-4">
|
||||
<div class="field-label flex flex-col text-sm font-medium mr-4">
|
||||
<span class="flex h-[40px] w-[80px] items-center">
|
||||
{{ i18next.t("AcctMgmt.Password") }}
|
||||
</span>
|
||||
<div class="flex dummy-cell"></div>
|
||||
</div>
|
||||
<div class="flex input-and-error-msg flex-col w-[242px]">
|
||||
<!-- 280 扣掉 24 眼睛的寬度 是 256 ,還要扣掉留白的寬度 -->
|
||||
<div v-if='isPwdEditable' class="input-and-eye flex items-center h-[40px] relative border-[1px] rounded"
|
||||
:class="{'border-[#FF3366]': !isPwdLengthValid, 'border-[#64748B]': isPwdLengthValid,}"
|
||||
>
|
||||
<input class="outline-none p-1 w-[242px]" :type="isPwdEyeOn ? 'text' : 'password'"
|
||||
v-model="inputPwd"
|
||||
autocomplete="off" :class="{'color-[#FF3366]': !isPwdLengthValid,
|
||||
'color-[#64748B]': isPwdLengthValid,}"/>
|
||||
<img id='eye_button' v-if="isPwdEyeOn" src='@/assets/icon-eye-open.svg' class="absolute right-[8px] cursor-pointer"
|
||||
@mousedown="togglePwdEyeBtn(true)" @mouseup="togglePwdEyeBtn(false)" alt=""/>
|
||||
<img v-else src='@/assets/icon-eye-hide.svg' class="absolute right-[8px] cursor-pointer"
|
||||
@mousedown="togglePwdEyeBtn(true)" @mouseup="togglePwdEyeBtn(false)" alt="eye"/>
|
||||
</div>
|
||||
<div class="error-msg-section flex justify-start mt-4">
|
||||
<img v-show="!isPwdLengthValid" src="@/assets/icon-alert.svg" alt="!" class="exclamation-img flex mr-2">
|
||||
<span class="error-msg-text flex text-[#FF3366] h-[24px]">
|
||||
{{ isPwdLengthValid ? "" : i18next.t("AcctMgmt.PwdLengthNotEnough") }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="button-column flex flex-col">
|
||||
<button v-if='isPwdEditable' class="flex save-btn rounded-full text-[#FFFFFF] h-[40px] w-[80px] items-center
|
||||
bg-[#0099FF] justify-center cursor-pointer ml-20"
|
||||
@click="onSavePwdClick">
|
||||
{{ i18next.t("Global.Save") }}
|
||||
</button>
|
||||
<button v-else class="flex reset-btn rounded-full text-[#666666] h-[40px] w-[80px] items-center
|
||||
bg-[#FFFFFF] justify-center cursor-pointer ml-20 border border-[#666666]"
|
||||
@click="onResetPwdClick"
|
||||
>
|
||||
{{ i18next.t("Global.Reset") }}
|
||||
</button>
|
||||
<div class="flex dummy-cell h-[40px]"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { onMounted, onBeforeMount, computed, ref } from 'vue';
|
||||
import { onMounted, computed, ref, onBeforeMount, } from 'vue';
|
||||
import i18next from '@/i18n/i18n.js';
|
||||
import LoginStore from '@/stores/login';
|
||||
import useAcctMgmtStore from '@/stores/acctMgmt.ts';
|
||||
import ModalHeader from './ModalHeader.vue';
|
||||
import Badge from '../../components/Badge.vue';
|
||||
import LoadingStore from '@/stores/loading.js';
|
||||
import { PWD_VALID_LENGTH } from '@/constants/constants.js';
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
const loadingStore = LoadingStore();
|
||||
const loginStore = LoginStore();
|
||||
const acctMgmtStore = useAcctMgmtStore();
|
||||
const visitTime = ref(0);
|
||||
const currentViewingUser = computed(() => acctMgmtStore.currentViewingUser);
|
||||
@@ -39,6 +134,42 @@ export default {
|
||||
is_active,
|
||||
} = currentViewingUser.value;
|
||||
|
||||
const inputName = ref(name);
|
||||
const inputPwd = ref('');
|
||||
const isNameEditable = ref(false);
|
||||
const isPwdEditable = ref(false);
|
||||
const isPwdEyeOn = ref(false);
|
||||
const isPwdLengthValid = ref(true);
|
||||
|
||||
const onEditNameClick = () => {
|
||||
isNameEditable.value = true;
|
||||
}
|
||||
|
||||
const onResetPwdClick = () => {
|
||||
isPwdEditable.value = true;
|
||||
}
|
||||
|
||||
const onSavePwdClick = () => {
|
||||
validatePwdLength();
|
||||
if (isPwdLengthValid.value) {
|
||||
isPwdEditable.value = false;
|
||||
inputPwd.value = '';
|
||||
}
|
||||
}
|
||||
|
||||
const togglePwdEyeBtn = (toBeOpen) => {
|
||||
isPwdEyeOn.value = toBeOpen;
|
||||
};
|
||||
|
||||
const validatePwdLength = () => {
|
||||
isPwdLengthValid.value = inputPwd.value.length >= PWD_VALID_LENGTH;
|
||||
}
|
||||
|
||||
onBeforeMount(async() => {
|
||||
// 在此設定 current viewing user 的來源是登入者的身分
|
||||
await acctMgmtStore.getUserDetail(loginStore.userData.username);
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
loadingStore.setIsLoading(false);
|
||||
});
|
||||
@@ -50,6 +181,16 @@ export default {
|
||||
is_admin,
|
||||
is_active,
|
||||
visitTime,
|
||||
inputName,
|
||||
inputPwd,
|
||||
isNameEditable,
|
||||
isPwdEditable,
|
||||
isPwdEyeOn,
|
||||
isPwdLengthValid,
|
||||
onEditNameClick,
|
||||
onResetPwdClick,
|
||||
onSavePwdClick,
|
||||
togglePwdEyeBtn,
|
||||
};
|
||||
},
|
||||
components: {
|
||||
|
||||
Reference in New Issue
Block a user