Files
sports-empower-hub/app/citizen-frontend/src/components/auth/ResetPasswordForm.vue
T
skytek_xinliang 12b067632f feat: 忘記密碼
2026-10-06 09:29:08 +08:00

80 lines
2.1 KiB
Vue

<script setup lang="ts">
import { computed, onScopeDispose, shallowRef } from "vue";
const props = defineProps<{
loading: boolean;
disabled: boolean;
errors: string[];
remainingSeconds: number;
}>();
const emit = defineEmits<{ submit: [newPassword: string] }>();
const newPassword = shallowRef("");
const confirmPassword = shallowRef("");
const passwordError = shallowRef("");
const confirmationError = shallowRef("");
const fieldErrors = computed(() =>
passwordError.value ? [passwordError.value] : props.errors,
);
function handleSubmit() {
if (props.disabled) return;
passwordError.value =
newPassword.value.length < 8 ? "密碼至少需要 8 碼。" : "";
confirmationError.value =
newPassword.value !== confirmPassword.value ? "兩次輸入的密碼不一致。" : "";
if (passwordError.value || confirmationError.value) return;
emit("submit", newPassword.value);
}
onScopeDispose(() => {
newPassword.value = "";
confirmPassword.value = "";
});
</script>
<template>
<v-form @submit.prevent="handleSubmit">
<v-text-field
v-model="newPassword"
autocomplete="new-password"
class="mb-4"
color="primary"
:disabled="loading"
:error-messages="fieldErrors"
label="新密碼"
hint="密碼至少需要 8 碼"
persistent-hint
prepend-inner-icon="mdi-lock-outline"
required
rounded="lg"
type="password"
variant="outlined"
@update:model-value="passwordError = ''"
/>
<v-text-field
v-model="confirmPassword"
autocomplete="new-password"
class="mb-4"
color="primary"
:disabled="loading"
:error-messages="confirmationError"
label="確認新密碼"
prepend-inner-icon="mdi-lock-check-outline"
required
rounded="lg"
type="password"
variant="outlined"
@update:model-value="confirmationError = ''"
/>
<v-btn
block
class="rounded-lg font-weight-bold"
color="secondary"
:disabled="disabled"
:loading="loading"
type="submit"
>
{{ remainingSeconds > 0 ? `${remainingSeconds} 秒後再試` : "重設密碼" }}
</v-btn>
</v-form>
</template>