161 lines
4.7 KiB
Vue
161 lines
4.7 KiB
Vue
<template>
|
|
<dialog class="panel-otp-code-enter">
|
|
<Button v-bind="btns.close.props" @click="dialogRef.close()" />
|
|
<h2>
|
|
<i class="isax isax-message-notif" />
|
|
<span>{{ $t("enterReceivedCode") }}</span>
|
|
</h2>
|
|
<p>{{ $t("enterReceivedCodeDesc") }}</p>
|
|
<ul ref="list">
|
|
<li v-for="(_, i) in 6" :key="i">
|
|
<InputNumber
|
|
v-model="code[i]"
|
|
@input="events.input($event, i)"
|
|
@keyup="events.keyup($event, i)"
|
|
@focus="events.focus($event, i)"
|
|
:disabled="inputs.length < 1"
|
|
/>
|
|
</li>
|
|
</ul>
|
|
<span :class="{ invisible: seconds < 1 }">
|
|
{{ $t("moreSecondReceiveCode", { seconds }) }}
|
|
</span>
|
|
<Button v-bind="btns.next.props" @click="events.next()" />
|
|
<div v-show="seconds < 1">
|
|
<p>{{ $t("notReceivedCode") }}</p>
|
|
<Button :label="$t('tryAgain')" link @click="events.try()" />
|
|
</div>
|
|
</dialog>
|
|
</template>
|
|
|
|
<script setup>
|
|
const { btns } = inject('init');
|
|
|
|
const seconds = ref(0);
|
|
const code = ref([]);
|
|
const form = reactive({});
|
|
const userStore = useUserStore();
|
|
const optCodeStore = useOtpCodeStore();
|
|
|
|
const list = ref();
|
|
let inputs = reactive([]);
|
|
const events = reactive({
|
|
next: async () => {
|
|
if (code.value.length == 6) {
|
|
if (optCodeStore.type == "email") form.email = optCodeStore.email;
|
|
else form.phoneNumber = optCodeStore.number;
|
|
form.code = code.value.join("");
|
|
|
|
const { status } = await userStore.forgetPassword(form);
|
|
// if (status == "success")
|
|
emit("dialog", "PanelPasswordRenewal");
|
|
}
|
|
},
|
|
try: async () => {
|
|
const form = { number: otpCode.number };
|
|
const { status } = await otpCode.first(form);
|
|
if (status == "success") seconds.value = 30;
|
|
},
|
|
input: (e, i) => {
|
|
if (e.value != null) inputs[i++].value = e.originalEvent.key;
|
|
if (i < 6) inputs[i].focus();
|
|
else {
|
|
inputs[5].blur();
|
|
events.next();
|
|
}
|
|
},
|
|
keyup: (e, i) => {
|
|
if (e.code == "Backspace" && i > 0) {
|
|
code.value[i - 1] = null;
|
|
inputs[i - 1].focus();
|
|
}
|
|
},
|
|
focus: (e, i) => {
|
|
const length = code.value.filter((c) => typeof c == "number").length;
|
|
if (length < i) inputs[length].focus();
|
|
},
|
|
});
|
|
|
|
onMounted(() => {
|
|
inputs.push(...list.value.querySelectorAll("input"));
|
|
setTimeout(() => inputs[0].focus(), 1);
|
|
seconds.value = 30;
|
|
setInterval(() => {
|
|
if (seconds.value > 0) seconds.value--;
|
|
}, 1000);
|
|
});
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.panel-otp-code-enter {
|
|
@apply w-full lg:w-[47.9rem] lg:h-[31.2rem] bg-white rounded-t-2xl lg:rounded-2xl flex flex-col items-center p-6 lg:p-8 relative;
|
|
|
|
&::after {
|
|
@apply content-['_'] absolute inset-x-0 bottom-[7.2rem] h-3 shadow-[0px_-2px_5px_#0000000a] lg:shadow-none;
|
|
}
|
|
|
|
& > button:nth-of-type(1) {
|
|
@apply self-end -mt-2 -ml-2;
|
|
|
|
.p-button-icon {
|
|
@apply text-sm text-[#333333] before:content-['\e90b'];
|
|
@apply lg:text-[2em] lg:text-[#b2b2b29b] lg:before:content-['\e90c'];
|
|
}
|
|
}
|
|
|
|
& > h2 {
|
|
@apply flex items-center gap-4 -mt-12 lg:mt-0.5 max-lg:self-start;
|
|
|
|
i {
|
|
@apply max-lg:hidden text-[2em];
|
|
}
|
|
|
|
span {
|
|
@apply text-[#333333] text-sm lg:text-xl font-bold font-vazir leading-[2.8rem];
|
|
}
|
|
}
|
|
|
|
& > p {
|
|
@apply self-start w-[18.1rem] text-[#B2B2B2] text-[0.7em] font-vazir mb-5;
|
|
@apply lg:w-[23.2rem] lg:text-base lg:mt-2 lg:mb-0 lg:leading-snug lg:self-center lg:text-center;
|
|
}
|
|
|
|
& > ul {
|
|
@apply flex gap-2.5 mt-4 lg:mt-10 ltr;
|
|
|
|
li {
|
|
input {
|
|
@apply w-9 h-9 lg:w-10 lg:h-10 p-0 rounded-lg border border-neutral-200 text-center;
|
|
@apply focus:text-primary-600 lg:text-xl font-medium font-vazir leading-[1.9rem];
|
|
}
|
|
}
|
|
}
|
|
|
|
& > span {
|
|
@apply text-[#999999] text-[0.7em] lg:text-sm font-medium font-vazir mt-5 lg:mt-4;
|
|
}
|
|
|
|
& > button:nth-of-type(2) {
|
|
@apply w-[21.4rem] lg:w-[19.5rem] h-[2.9rem] lg:h-14 mt-8 lg:mt-11;
|
|
|
|
.p-button-label {
|
|
@apply text-sm lg:text-base font-bold font-vazir leading-tight;
|
|
}
|
|
}
|
|
|
|
& > div {
|
|
@apply flex items-center -mb-3 whitespace-nowrap;
|
|
|
|
p {
|
|
@apply text-[#999999] text-sm font-medium font-vazir;
|
|
}
|
|
|
|
button {
|
|
.p-button-label {
|
|
@apply text-sm font-bold font-vazir;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|