174 lines
5.4 KiB
Vue
174 lines
5.4 KiB
Vue
<template>
|
|
<dialog class="panel-password-change">
|
|
<img src="/images/password-change.svg" />
|
|
<div>
|
|
<Button v-bind="btns.close.props" @click="dialogRef.close()" />
|
|
<h2>{{ $t("changePassword") }}</h2>
|
|
<p>{{ $t("enterCurrentAndNewPassword") }}</p>
|
|
<ul>
|
|
<li v-for="(item, key) in fields.changePassword" :key="key">
|
|
<Password v-model="form[key]" v-bind="item.props" :inputId="key" />
|
|
<label :for="key"> {{ $t(key) }} </label>
|
|
<small v-if="errors[key]">{{ errors[key] }}</small>
|
|
</li>
|
|
</ul>
|
|
<Button v-bind="btns.save.props" :loading="loading" @click="save()" />
|
|
<!-- <div>
|
|
<p>{{ $t("forgetPassword") }}</p>
|
|
<Button v-bind="btns.recovery.props" @click="recovery()" />
|
|
</div> -->
|
|
</div>
|
|
</dialog>
|
|
</template>
|
|
|
|
<script setup>
|
|
const { meta } = useRoute()
|
|
const { btns, fields } = meta.init;
|
|
const { device, dialog, toast, t } = inject('service')
|
|
const dialogRef = inject('dialogRef')
|
|
|
|
const form = reactive({});
|
|
const errors = ref({});
|
|
|
|
const loading = ref(false);
|
|
btns.save.props.disabled = computed(() => Object.keys(errors.value).length > 1)
|
|
|
|
const save = async () => {
|
|
loading.value = true
|
|
|
|
const { status, data, error } = await useFetch('/api/users/setpass', {
|
|
headers: { Authorization: useCookie('token') }, method: 'post', body: Object.assign({}, form)
|
|
})
|
|
|
|
if (status.value == 'success') {
|
|
const token = useCookie('token')
|
|
token.value = data.value.accessToken
|
|
toast.add({
|
|
life: 3000, severity: 'success', summary: t('success'), detail: t('updatePasswordSuccessfull')
|
|
})
|
|
dialogRef.value.close()
|
|
} else {
|
|
if (error.value.statusCode == 422)
|
|
errors.value = error.value.data
|
|
else
|
|
toast.add({
|
|
life: 3000, severity: 'error', summary: t('error'), detail: error.value.message
|
|
})
|
|
}
|
|
loading.value = false
|
|
}
|
|
|
|
const recovery = () => {
|
|
if (device.value == 'desktop')
|
|
dialogRef.value.close()
|
|
|
|
dialog.show('PanelDialogPasswordRestore')
|
|
}
|
|
|
|
watch(computed(() => form), (value, old) => {
|
|
Object.keys(errors.value).forEach(key => {
|
|
if (value[key] != old[key]) delete errors.value[key]
|
|
});
|
|
})
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.panel-password-change {
|
|
@apply w-full lg:w-[61.6rem] lg:h-[36.9rem] bg-white rounded-t-2xl lg:rounded-2xl flex p-6 lg:p-4 lg:pl-6 relative;
|
|
|
|
&::after {
|
|
@apply content-['_'] absolute inset-x-0 bottom-16 h-3 shadow-[0px_-2px_5px_#0000000a] lg:shadow-none;
|
|
}
|
|
|
|
&>img {
|
|
@apply hidden lg:block w-[27.2rem];
|
|
}
|
|
|
|
&>div {
|
|
@apply flex flex-col gap-4 lg:pt-2 items-center w-full;
|
|
|
|
&>h2 {
|
|
@apply self-start -mt-[3.4rem] text-[#333333] text-sm font-bold font-vazir leading-[1.7rem];
|
|
@apply lg:text-white lg:text-xl lg:-mt-10 lg:-mr-[25.3rem];
|
|
}
|
|
|
|
&>p {
|
|
@apply self-start w-[17.8rem] -mt-2 text-[#7F7F7F] text-[0.7em] font-vazir mb-5;
|
|
@apply lg:w-[22.9rem] lg:text-[#E5E5E5] lg:text-base lg:leading-[1.7rem] lg:-mr-[25.3rem];
|
|
}
|
|
|
|
&>button:nth-of-type(1) {
|
|
@apply self-end -ml-5 -mt-5 lg:-mt-2 lg:-ml-2;;
|
|
|
|
.p-button-icon {
|
|
@apply text-xl text-[#333333];
|
|
@apply lg:text-[2em] lg:text-[#b2b2b29b];
|
|
}
|
|
}
|
|
|
|
&>ul {
|
|
@apply flex flex-col items-center gap-6 mt-auto w-full sm:w-auto lg:-mt-16;
|
|
|
|
li {
|
|
@apply w-[21.4rem] lg:w-[23.3rem] h-[3.4rem] lg:h-14 relative;
|
|
|
|
label {
|
|
@apply w-max absolute right-3 top-4 px-1 bg-white transition-['top'] pointer-events-none;
|
|
@apply text-neutral-400 text-sm lg:text-base font-medium cursor-text font-vazir;
|
|
}
|
|
|
|
.p-password {
|
|
input {
|
|
@apply w-full rounded-[0.6rem] border text-sm lg:text-base shadow-none border-[#CCCCCC] text-zinc-800 font-vazir;
|
|
}
|
|
|
|
svg {
|
|
@apply text-[#CCCCCC] w-5 h-5 -mt-2.5;
|
|
}
|
|
}
|
|
|
|
&:has(input:focus),
|
|
&:has(input:not(:placeholder-shown)) {
|
|
label {
|
|
@apply -top-2 h-4;
|
|
@apply text-zinc-800 text-xs font-normal font-vazir;
|
|
}
|
|
}
|
|
|
|
small {
|
|
@apply text-red-500 font-vazir float-left;
|
|
}
|
|
|
|
&:has(small) * {
|
|
@apply border-red-500 #{!important};
|
|
}
|
|
}
|
|
}
|
|
|
|
&>button:nth-of-type(2) {
|
|
@apply w-[21.4rem] lg:w-[23.3rem] h-[2.9rem] mt-4 lg:h-14 lg:mt-16 #{!important};
|
|
|
|
.p-button-label {
|
|
@apply font-bold font-vazir leading-tight text-sm lg:text-base;
|
|
}
|
|
}
|
|
|
|
&>div {
|
|
@apply flex items-center justify-center -my-4 hidden;
|
|
|
|
p {
|
|
@apply text-[#999999] text-xs lg:text-sm font-medium font-vazir;
|
|
}
|
|
|
|
button {
|
|
@apply px-2;
|
|
|
|
.p-button-label {
|
|
@apply text-xs lg:text-sm font-bold font-vazir text-primary-600;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|