feat(frontend): use Password component in password update settings

Replace FormField with Password component for new password input:
- Provides real-time validation feedback (8-72 char requirement)
- Remove redundant password confirmation field
- Disable save button when form is invalid (validation errors or empty fields)
This commit is contained in:
kolaente
2026-02-25 13:35:06 +01:00
parent d1e1cb3b4f
commit a11d705571

View File

@@ -5,24 +5,17 @@
:loading="passwordUpdateService.loading"
>
<form @submit.prevent="updatePassword">
<FormField
id="newPassword"
v-model="passwordUpdate.newPassword"
:label="$t('user.settings.newPassword')"
autocomplete="new-password"
:placeholder="$t('user.auth.passwordPlaceholder')"
type="password"
@keyup.enter="updatePassword"
/>
<FormField
id="newPasswordConfirm"
v-model="passwordConfirm"
:label="$t('user.settings.newPasswordConfirm')"
autocomplete="new-password"
:placeholder="$t('user.auth.passwordPlaceholder')"
type="password"
@keyup.enter="updatePassword"
/>
<div class="field">
<label
class="label"
for="password"
>{{ $t('user.settings.newPassword') }}</label>
<Password
:validate-initially="true"
@update:modelValue="v => passwordUpdate.newPassword = v"
@submit="updatePassword"
/>
</div>
<FormField
id="currentPassword"
v-model="passwordUpdate.oldPassword"
@@ -36,6 +29,7 @@
<XButton
:loading="passwordUpdateService.loading"
:disabled="!isValid"
class="is-fullwidth mbs-4"
@click="updatePassword"
>
@@ -46,35 +40,32 @@
<script setup lang="ts">
import {ref, reactive, shallowReactive, computed} from 'vue'
import {reactive, shallowReactive, computed} from 'vue'
import {useI18n} from 'vue-i18n'
import PasswordUpdateService from '@/services/passwordUpdateService'
import PasswordUpdateModel from '@/models/passwordUpdate'
import FormField from '@/components/input/FormField.vue'
import Password from '@/components/input/Password.vue'
import {useTitle} from '@/composables/useTitle'
import {success, error} from '@/message'
import {success} from '@/message'
import {useAuthStore} from '@/stores/auth'
import {validatePassword} from '@/helpers/validatePasswort'
defineOptions({name: 'UserSettingsPasswordUpdate'})
const passwordUpdateService = shallowReactive(new PasswordUpdateService())
const passwordUpdate = reactive(new PasswordUpdateModel())
const passwordConfirm = ref('')
const {t} = useI18n({useScope: 'global'})
useTitle(() => `${t('user.settings.newPasswordTitle')} - ${t('user.settings.title')}`)
const authStore = useAuthStore()
const isLocalUser = computed(() => authStore.info?.isLocalUser)
const isValid = computed(() => validatePassword(passwordUpdate.newPassword) === true && passwordUpdate.oldPassword !== '')
async function updatePassword() {
if (passwordConfirm.value !== passwordUpdate.newPassword) {
error({message: t('user.settings.passwordsDontMatch')})
return
}
await passwordUpdateService.update(passwordUpdate)
success({message: t('user.settings.passwordUpdateSuccess')})
}