Refactor password change functionality: move to separate change-password component and update navigation link

This commit is contained in:
dkecskes
2025-11-04 18:43:41 +01:00
parent 66599f65f8
commit 0bbc658034
3 changed files with 96 additions and 116 deletions

View File

@@ -1,115 +0,0 @@
<script setup lang="ts">
definePageMeta({
middleware: ['sanctum:auth', 'student-only'],
});
useSeoMeta({
title: "Zmena hesla | ISOP",
ogTitle: "Zmena hesla",
description: "Zmena hesla študenta",
ogDescription: "Zmena hesla študenta",
});
const client = useSanctumClient();
// Form state
const form = ref({
password: '',
password_confirmation: ''
});
const loading = ref(false);
const error = ref<string | null>(null);
const success = ref(false);
// Validácie
const passwordsMatch = computed(() => {
if (!form.value.password || !form.value.password_confirmation) return true;
return form.value.password === form.value.password_confirmation;
});
const passwordLengthValid = computed(() => {
return form.value.password.length >= 8 || form.value.password.length === 0;
});
const canSubmit = computed(() => {
return passwordsMatch.value &&
passwordLengthValid.value &&
form.value.password.length >= 8 &&
form.value.password_confirmation.length >= 8;
});
// Funkcia na zmenu hesla
const changePassword = async () => {
error.value = null;
loading.value = true;
try {
await client('/api/students/change-password', {
method: 'POST',
body: form.value
});
success.value = true;
// Vyčisti formulár
form.value.password = '';
form.value.password_confirmation = '';
// Reset success alert po 5s
setTimeout(() => {
success.value = false;
}, 5000);
} catch (e: any) {
error.value = e.data?.message || 'Chyba pri zmene hesla.';
} finally {
loading.value = false;
}
};
</script>
<template>
<v-container>
<v-card class="mx-auto" max-width="600">
<v-card-title>
<h1>Zmena hesla</h1>
</v-card-title>
<v-card-text>
<v-form @submit.prevent="changePassword">
<!-- Nové heslo -->
<v-text-field v-model="form.password" label="Nové heslo" type="password" variant="outlined"
class="mb-3" hint="Minimálne 8 znakov" persistent-hint :error="!passwordLengthValid"
:error-messages="!passwordLengthValid ? 'Heslo musí mať aspoň 8 znakov' : ''"></v-text-field>
<!-- Potvrdenie hesla -->
<v-text-field v-model="form.password_confirmation" label="Potvrďte nové heslo" type="password"
variant="outlined" class="mb-3" :error="!passwordsMatch"
:error-messages="!passwordsMatch ? 'Heslá sa nezhodujú' : ''"></v-text-field>
<!-- Error alert -->
<v-alert v-if="error" type="error" density="compact" class="mb-3">
{{ error }}
</v-alert>
<!-- Success alert -->
<v-alert v-if="success" type="success" density="compact" class="mb-3">
Heslo bolo úspešne zmenené.
</v-alert>
<!-- Submit button -->
<v-btn type="submit" color="primary" :loading="loading" :disabled="!canSubmit || success" block>
Zmeniť heslo
</v-btn>
</v-form>
</v-card-text>
<v-card-actions>
<v-btn color="grey" variant="text" to="/dashboard/student">
Späť na dashboard
</v-btn>
</v-card-actions>
</v-card>
</v-container>
</template>

View File

@@ -0,0 +1,95 @@
<script setup lang="ts">
import { FetchError } from 'ofetch';
definePageMeta({
middleware: ['sanctum:auth'],
});
useSeoMeta({
title: "Zmena hesla | ISOP",
ogTitle: "Zmena hesla",
description: "Zmena hesla študenta",
ogDescription: "Zmena hesla študenta",
});
const client = useSanctumClient();
const password = ref('');
const password_confirmation = ref('');
const loading = ref(false);
const error = ref<string | null>(null);
const success = ref(false);
// Funkcia na zmenu hesla
const changePassword = async () => {
error.value = null;
loading.value = true;
try {
await client('/api/account/change-password', {
method: 'POST',
body: {
password: password.value,
}
});
success.value = true;
// Vyčisti formulár
password.value = '';
password_confirmation.value = '';
} catch (e) {
if (e instanceof FetchError) {
error.value = e.data?.message;
}
} finally {
loading.value = false;
}
};
</script>
<template>
<v-container fluid>
<v-card id="page-container-card">
<h1>Zmena hesla</h1>
<!-- Error alert -->
<v-alert v-if="error" type="error" density="compact" class="mb-3">
{{ error }}
</v-alert>
<!-- Success alert -->
<v-alert v-else-if="success" type="success" density="compact" class="mb-3">
Heslo bolo úspešne zmenené.
</v-alert>
<v-form v-else :disabled="loading" @submit.prevent="changePassword">
<!-- Nové heslo -->
<v-text-field v-model="password" label="Nové heslo" type="password" variant="outlined" class="mb-3"
hint="Minimálne 8 znakov" persistent-hint></v-text-field>
<!-- Potvrdenie hesla -->
<v-text-field v-model="password_confirmation" label="Potvrďte nové heslo" type="password"
variant="outlined" class="mb-3"></v-text-field>
<!-- Submit button -->
<v-btn type="submit" color="primary" :disabled="password !== password_confirmation" class="mb-2">
Zmeniť heslo
</v-btn>
</v-form>
<!-- Zrušiť -->
<v-btn type="submit" color="yellow" to="/dashboard" class="mb-2">
Späť na dashboard
</v-btn>
</v-card>
</v-container>
</template>
<style scoped>
#page-container-card {
padding-left: 10px;
padding-right: 10px;
}
</style>

View File

@@ -80,7 +80,7 @@ const user = useSanctumUser<User>();
<v-list density="compact" class="readonly-list">
<v-list-item>
<v-btn prepend-icon="mdi mdi-pencil" color="orange">
<v-btn prepend-icon="mdi mdi-pencil" color="orange" to="/account/change-password">
Zmeniť heslo
</v-btn>
</v-list-item>