You've already forked isop-mirror
Refactor password change functionality: move to separate change-password component and update navigation link
This commit is contained in:
@@ -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>
|
|
||||||
95
frontend/app/pages/account/change-password.vue
Normal file
95
frontend/app/pages/account/change-password.vue
Normal 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>
|
||||||
@@ -80,7 +80,7 @@ const user = useSanctumUser<User>();
|
|||||||
|
|
||||||
<v-list density="compact" class="readonly-list">
|
<v-list density="compact" class="readonly-list">
|
||||||
<v-list-item>
|
<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
|
Zmeniť heslo
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
|
|||||||
Reference in New Issue
Block a user