80 lines
2.1 KiB
Vue
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>
|