feat: add notifications for profile updates, personal data changes, and password updates

This commit is contained in:
fabio
2026-07-26 17:56:33 +02:00
parent 7a2b80381d
commit cd858b0d8c
8 changed files with 54 additions and 1 deletions

View File

@@ -99,7 +99,7 @@ export default defineConfig((/* ctx */) => {
// directives: [],
// Quasar plugins
plugins: []
plugins: ['Notify']
},
// animations: 'all', // --- includes all animations

View File

@@ -75,6 +75,14 @@ const messages = {
created: 'Created',
updated: 'Updated',
},
notifications: {
profileCreated: 'Profile created.',
profileUpdated: 'Profile updated.',
personalDataUpdated: 'Personal data updated.',
roleUpdated: 'Role updated.',
statusUpdated: 'Status updated.',
passwordUpdated: 'Password updated.',
},
},
profile: {
title: 'My profile',
@@ -196,6 +204,14 @@ const messages = {
created: 'Creato',
updated: 'Aggiornato',
},
notifications: {
profileCreated: 'Profilo creato.',
profileUpdated: 'Profilo aggiornato.',
personalDataUpdated: 'Dati personali aggiornati.',
roleUpdated: 'Ruolo aggiornato.',
statusUpdated: 'Stato aggiornato.',
passwordUpdated: 'Password aggiornata.',
},
},
profile: {
title: 'Il mio profilo',
@@ -317,6 +333,14 @@ const messages = {
created: 'Créé',
updated: 'Mis à jour',
},
notifications: {
profileCreated: 'Profil créé.',
profileUpdated: 'Profil mis à jour.',
personalDataUpdated: 'Données personnelles mises à jour.',
roleUpdated: 'Rôle mis à jour.',
statusUpdated: 'Statut mis à jour.',
passwordUpdated: 'Mot de passe mis à jour.',
},
},
profile: {
title: 'Mon profil',
@@ -438,6 +462,14 @@ const messages = {
created: 'Erstellt',
updated: 'Aktualisiert',
},
notifications: {
profileCreated: 'Profil erstellt.',
profileUpdated: 'Profil aktualisiert.',
personalDataUpdated: 'Persönliche Daten aktualisiert.',
roleUpdated: 'Rolle aktualisiert.',
statusUpdated: 'Status aktualisiert.',
passwordUpdated: 'Passwort aktualisiert.',
},
},
profile: {
title: 'Mein Profil',
@@ -559,6 +591,14 @@ const messages = {
created: 'Creado',
updated: 'Actualizado',
},
notifications: {
profileCreated: 'Perfil creado.',
profileUpdated: 'Perfil actualizado.',
personalDataUpdated: 'Datos personales actualizados.',
roleUpdated: 'Rol actualizado.',
statusUpdated: 'Estado actualizado.',
passwordUpdated: 'Contraseña actualizada.',
},
},
profile: {
title: 'Mi perfil',

View File

@@ -228,6 +228,7 @@
<script setup lang="ts">
import { computed, nextTick, onMounted, reactive, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { Notify } from 'quasar';
import { useRoute, useRouter } from 'vue-router';
import { countries } from '@/data/countries';
import { AuthSetPasswordParamsSchema, ProfilesPersonalDataParamsSchema, ProfilesProfileParamsSchema } from '@/encore/zod';
@@ -352,6 +353,7 @@ async function save() {
const parsed = validatePersonalForm();
if (!parsed) return;
await profilesStore.savePersonalData(parsed);
Notify.create({ type: 'positive', message: t('admin.notifications.personalDataUpdated') });
} else if (profileTab.value === 'password') {
const parsed = validatePasswordForm();
if (!parsed) return;

View File

@@ -40,6 +40,7 @@
<script setup lang="ts">
import { nextTick, reactive, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { Notify } from 'quasar';
import { useAdminStore, type RegisterParams } from '@/stores/admin-store';
import AvatarUpload from '@/components/AvatarUpload.vue';
@@ -66,6 +67,7 @@ watch(open, (isOpen) => {
async function save() {
try {
await adminStore.insertProfile({ ...createForm });
Notify.create({ type: 'positive', message: t('admin.notifications.profileCreated') });
open.value = false;
} catch {
// adminStore.error already holds the failure message

View File

@@ -98,6 +98,7 @@
<script setup lang="ts">
import { nextTick, reactive, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { Notify } from 'quasar';
import { useAdminStore, type PersonalDataParams, type Profile, type ProfileParams } from '@/stores/admin-store';
import { countries } from '@/data/countries';
import { AdminPersonalDataParamsSchema, AdminProfileParamsSchema } from '@/encore/zod';
@@ -188,10 +189,12 @@ async function save() {
const parsed = validateEditForm();
if (!parsed) return;
await adminStore.updateProfile(props.profile.user_id, parsed);
Notify.create({ type: 'positive', message: t('admin.notifications.profileUpdated') });
} else {
const parsed = validatePersonalForm();
if (!parsed) return;
await adminStore.upsertPersonalData(props.profile.user_id, parsed);
Notify.create({ type: 'positive', message: t('admin.notifications.personalDataUpdated') });
}
open.value = false;
} catch {

View File

@@ -43,6 +43,7 @@
<script setup lang="ts">
import { nextTick, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { Notify } from 'quasar';
import { useAdminStore, type Profile } from '@/stores/admin-store';
type Focusable = { focus: () => void };
@@ -82,6 +83,7 @@ async function save() {
try {
await adminStore.updateProfilePassword(props.profile.user_id, { password: password.value });
Notify.create({ type: 'positive', message: t('admin.notifications.passwordUpdated') });
open.value = false;
} catch {
// adminStore.error already holds the failure message

View File

@@ -35,6 +35,7 @@
<script setup lang="ts">
import { nextTick, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { Notify } from 'quasar';
import { useAdminStore, type Profile } from '@/stores/admin-store';
type Focusable = { focus: () => void };
@@ -63,6 +64,7 @@ async function save() {
if (!props.profile) return;
try {
await adminStore.updateProfileRole(props.profile.user_id, selectedRole.value);
Notify.create({ type: 'positive', message: t('admin.notifications.roleUpdated') });
open.value = false;
} catch {
// adminStore.error already holds the failure message

View File

@@ -35,6 +35,7 @@
<script setup lang="ts">
import { nextTick, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { Notify } from 'quasar';
import { useAdminStore, type Profile } from '@/stores/admin-store';
import type { Status } from '@/stores/profiles-store';
@@ -64,6 +65,7 @@ async function save() {
if (!props.profile) return;
try {
await adminStore.updateProfileStatus(props.profile.user_id, selectedStatus.value);
Notify.create({ type: 'positive', message: t('admin.notifications.statusUpdated') });
open.value = false;
} catch {
// adminStore.error already holds the failure message