124 lines
3.0 KiB
Vue
124 lines
3.0 KiB
Vue
<script setup lang="ts">
|
||
import ForgotPasswordForm from "@/components/auth/ForgotPasswordForm.vue";
|
||
import PasswordRecoveryShell from "@/components/auth/PasswordRecoveryShell.vue";
|
||
import { useForgotPassword } from "@/composables/useForgotPassword";
|
||
const recoverySteps = [
|
||
{ title: "輸入已註冊手機門號", icon: "mdi-phone" },
|
||
{ title: "收起E-Mail,使用連結進行重設密碼", icon: "mdi-email-outline" },
|
||
];
|
||
|
||
const {
|
||
accepted,
|
||
loading,
|
||
disabled,
|
||
errorMessage,
|
||
fieldErrors,
|
||
remainingSeconds,
|
||
submit,
|
||
} = useForgotPassword();
|
||
</script>
|
||
|
||
<template>
|
||
<PasswordRecoveryShell title="忘記密碼">
|
||
<template #description>
|
||
<v-sheet class="pa-4 mb-6" color="background" rounded="lg">
|
||
<ol aria-label="密碼重設流程" class="recovery-flow ma-0 pa-0">
|
||
<li
|
||
v-for="(step, index) in recoverySteps"
|
||
:key="step.title"
|
||
class="recovery-step"
|
||
>
|
||
<v-avatar
|
||
class="recovery-step-icon"
|
||
color="primary"
|
||
rounded="lg"
|
||
size="40"
|
||
variant="tonal"
|
||
>
|
||
<v-icon aria-hidden="true" :icon="step.icon" size="22" />
|
||
</v-avatar>
|
||
<div class="recovery-step-content">
|
||
<span class="recovery-step-number text-primary">
|
||
步驟 {{ String(index + 1).padStart(2, "0") }}
|
||
</span>
|
||
<p class="text-title-small text-high-emphasis ma-0">
|
||
{{ step.title }}
|
||
</p>
|
||
</div>
|
||
</li>
|
||
</ol>
|
||
</v-sheet>
|
||
</template>
|
||
<template v-if="accepted">
|
||
<v-alert type="success" variant="tonal" role="status">
|
||
如果帳號存在,系統將寄送密碼重設信件。
|
||
</v-alert>
|
||
<p class="mt-4 text-body-large">請查看信箱與垃圾郵件匣。</p>
|
||
</template>
|
||
<template v-else>
|
||
<v-alert
|
||
v-if="errorMessage"
|
||
class="mb-4"
|
||
type="error"
|
||
variant="tonal"
|
||
role="alert"
|
||
>{{ errorMessage }}</v-alert
|
||
>
|
||
<ForgotPasswordForm
|
||
:loading="loading"
|
||
:disabled="disabled"
|
||
:errors="fieldErrors"
|
||
:remaining-seconds="remainingSeconds"
|
||
@submit="submit"
|
||
/>
|
||
</template>
|
||
</PasswordRecoveryShell>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.recovery-flow {
|
||
list-style: none;
|
||
}
|
||
|
||
.recovery-step {
|
||
position: relative;
|
||
display: grid;
|
||
grid-template-columns: 40px minmax(0, 1fr);
|
||
align-items: center;
|
||
column-gap: 16px;
|
||
}
|
||
|
||
.recovery-step:not(:last-child) {
|
||
padding-bottom: 24px;
|
||
}
|
||
|
||
.recovery-step:not(:last-child)::after {
|
||
position: absolute;
|
||
top: 48px;
|
||
bottom: 4px;
|
||
left: 19px;
|
||
width: 2px;
|
||
background: rgba(var(--v-theme-primary), 0.18);
|
||
content: "";
|
||
}
|
||
|
||
.recovery-step-icon {
|
||
align-self: start;
|
||
margin-top: 4px;
|
||
}
|
||
|
||
.recovery-step-content {
|
||
min-width: 0;
|
||
}
|
||
|
||
.recovery-step-number {
|
||
display: block;
|
||
margin-bottom: 2px;
|
||
font-size: 0.75rem;
|
||
font-weight: 500;
|
||
font-variant-numeric: tabular-nums;
|
||
line-height: 1.5;
|
||
letter-spacing: 0.04em;
|
||
}
|
||
</style>
|