feat: add notifications for profile updates, personal data changes, and password updates
This commit is contained in:
@@ -99,7 +99,7 @@ export default defineConfig((/* ctx */) => {
|
|||||||
// directives: [],
|
// directives: [],
|
||||||
|
|
||||||
// Quasar plugins
|
// Quasar plugins
|
||||||
plugins: []
|
plugins: ['Notify']
|
||||||
},
|
},
|
||||||
|
|
||||||
// animations: 'all', // --- includes all animations
|
// animations: 'all', // --- includes all animations
|
||||||
|
|||||||
@@ -75,6 +75,14 @@ const messages = {
|
|||||||
created: 'Created',
|
created: 'Created',
|
||||||
updated: 'Updated',
|
updated: 'Updated',
|
||||||
},
|
},
|
||||||
|
notifications: {
|
||||||
|
profileCreated: 'Profile created.',
|
||||||
|
profileUpdated: 'Profile updated.',
|
||||||
|
personalDataUpdated: 'Personal data updated.',
|
||||||
|
roleUpdated: 'Role updated.',
|
||||||
|
statusUpdated: 'Status updated.',
|
||||||
|
passwordUpdated: 'Password updated.',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
title: 'My profile',
|
title: 'My profile',
|
||||||
@@ -196,6 +204,14 @@ const messages = {
|
|||||||
created: 'Creato',
|
created: 'Creato',
|
||||||
updated: 'Aggiornato',
|
updated: 'Aggiornato',
|
||||||
},
|
},
|
||||||
|
notifications: {
|
||||||
|
profileCreated: 'Profilo creato.',
|
||||||
|
profileUpdated: 'Profilo aggiornato.',
|
||||||
|
personalDataUpdated: 'Dati personali aggiornati.',
|
||||||
|
roleUpdated: 'Ruolo aggiornato.',
|
||||||
|
statusUpdated: 'Stato aggiornato.',
|
||||||
|
passwordUpdated: 'Password aggiornata.',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
title: 'Il mio profilo',
|
title: 'Il mio profilo',
|
||||||
@@ -317,6 +333,14 @@ const messages = {
|
|||||||
created: 'Créé',
|
created: 'Créé',
|
||||||
updated: 'Mis à jour',
|
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: {
|
profile: {
|
||||||
title: 'Mon profil',
|
title: 'Mon profil',
|
||||||
@@ -438,6 +462,14 @@ const messages = {
|
|||||||
created: 'Erstellt',
|
created: 'Erstellt',
|
||||||
updated: 'Aktualisiert',
|
updated: 'Aktualisiert',
|
||||||
},
|
},
|
||||||
|
notifications: {
|
||||||
|
profileCreated: 'Profil erstellt.',
|
||||||
|
profileUpdated: 'Profil aktualisiert.',
|
||||||
|
personalDataUpdated: 'Persönliche Daten aktualisiert.',
|
||||||
|
roleUpdated: 'Rolle aktualisiert.',
|
||||||
|
statusUpdated: 'Status aktualisiert.',
|
||||||
|
passwordUpdated: 'Passwort aktualisiert.',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
title: 'Mein Profil',
|
title: 'Mein Profil',
|
||||||
@@ -559,6 +591,14 @@ const messages = {
|
|||||||
created: 'Creado',
|
created: 'Creado',
|
||||||
updated: 'Actualizado',
|
updated: 'Actualizado',
|
||||||
},
|
},
|
||||||
|
notifications: {
|
||||||
|
profileCreated: 'Perfil creado.',
|
||||||
|
profileUpdated: 'Perfil actualizado.',
|
||||||
|
personalDataUpdated: 'Datos personales actualizados.',
|
||||||
|
roleUpdated: 'Rol actualizado.',
|
||||||
|
statusUpdated: 'Estado actualizado.',
|
||||||
|
passwordUpdated: 'Contraseña actualizada.',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
title: 'Mi perfil',
|
title: 'Mi perfil',
|
||||||
|
|||||||
@@ -228,6 +228,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, nextTick, onMounted, reactive, ref, watch } from 'vue';
|
import { computed, nextTick, onMounted, reactive, ref, watch } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { Notify } from 'quasar';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
import { countries } from '@/data/countries';
|
import { countries } from '@/data/countries';
|
||||||
import { AuthSetPasswordParamsSchema, ProfilesPersonalDataParamsSchema, ProfilesProfileParamsSchema } from '@/encore/zod';
|
import { AuthSetPasswordParamsSchema, ProfilesPersonalDataParamsSchema, ProfilesProfileParamsSchema } from '@/encore/zod';
|
||||||
@@ -352,6 +353,7 @@ async function save() {
|
|||||||
const parsed = validatePersonalForm();
|
const parsed = validatePersonalForm();
|
||||||
if (!parsed) return;
|
if (!parsed) return;
|
||||||
await profilesStore.savePersonalData(parsed);
|
await profilesStore.savePersonalData(parsed);
|
||||||
|
Notify.create({ type: 'positive', message: t('admin.notifications.personalDataUpdated') });
|
||||||
} else if (profileTab.value === 'password') {
|
} else if (profileTab.value === 'password') {
|
||||||
const parsed = validatePasswordForm();
|
const parsed = validatePasswordForm();
|
||||||
if (!parsed) return;
|
if (!parsed) return;
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { nextTick, reactive, ref, watch } from 'vue';
|
import { nextTick, reactive, ref, watch } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { Notify } from 'quasar';
|
||||||
import { useAdminStore, type RegisterParams } from '@/stores/admin-store';
|
import { useAdminStore, type RegisterParams } from '@/stores/admin-store';
|
||||||
import AvatarUpload from '@/components/AvatarUpload.vue';
|
import AvatarUpload from '@/components/AvatarUpload.vue';
|
||||||
|
|
||||||
@@ -66,6 +67,7 @@ watch(open, (isOpen) => {
|
|||||||
async function save() {
|
async function save() {
|
||||||
try {
|
try {
|
||||||
await adminStore.insertProfile({ ...createForm });
|
await adminStore.insertProfile({ ...createForm });
|
||||||
|
Notify.create({ type: 'positive', message: t('admin.notifications.profileCreated') });
|
||||||
open.value = false;
|
open.value = false;
|
||||||
} catch {
|
} catch {
|
||||||
// adminStore.error already holds the failure message
|
// adminStore.error already holds the failure message
|
||||||
|
|||||||
@@ -98,6 +98,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { nextTick, reactive, ref, watch } from 'vue';
|
import { nextTick, reactive, ref, watch } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { Notify } from 'quasar';
|
||||||
import { useAdminStore, type PersonalDataParams, type Profile, type ProfileParams } from '@/stores/admin-store';
|
import { useAdminStore, type PersonalDataParams, type Profile, type ProfileParams } from '@/stores/admin-store';
|
||||||
import { countries } from '@/data/countries';
|
import { countries } from '@/data/countries';
|
||||||
import { AdminPersonalDataParamsSchema, AdminProfileParamsSchema } from '@/encore/zod';
|
import { AdminPersonalDataParamsSchema, AdminProfileParamsSchema } from '@/encore/zod';
|
||||||
@@ -188,10 +189,12 @@ async function save() {
|
|||||||
const parsed = validateEditForm();
|
const parsed = validateEditForm();
|
||||||
if (!parsed) return;
|
if (!parsed) return;
|
||||||
await adminStore.updateProfile(props.profile.user_id, parsed);
|
await adminStore.updateProfile(props.profile.user_id, parsed);
|
||||||
|
Notify.create({ type: 'positive', message: t('admin.notifications.profileUpdated') });
|
||||||
} else {
|
} else {
|
||||||
const parsed = validatePersonalForm();
|
const parsed = validatePersonalForm();
|
||||||
if (!parsed) return;
|
if (!parsed) return;
|
||||||
await adminStore.upsertPersonalData(props.profile.user_id, parsed);
|
await adminStore.upsertPersonalData(props.profile.user_id, parsed);
|
||||||
|
Notify.create({ type: 'positive', message: t('admin.notifications.personalDataUpdated') });
|
||||||
}
|
}
|
||||||
open.value = false;
|
open.value = false;
|
||||||
} catch {
|
} catch {
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { nextTick, ref, watch } from 'vue';
|
import { nextTick, ref, watch } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { Notify } from 'quasar';
|
||||||
import { useAdminStore, type Profile } from '@/stores/admin-store';
|
import { useAdminStore, type Profile } from '@/stores/admin-store';
|
||||||
|
|
||||||
type Focusable = { focus: () => void };
|
type Focusable = { focus: () => void };
|
||||||
@@ -82,6 +83,7 @@ async function save() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await adminStore.updateProfilePassword(props.profile.user_id, { password: password.value });
|
await adminStore.updateProfilePassword(props.profile.user_id, { password: password.value });
|
||||||
|
Notify.create({ type: 'positive', message: t('admin.notifications.passwordUpdated') });
|
||||||
open.value = false;
|
open.value = false;
|
||||||
} catch {
|
} catch {
|
||||||
// adminStore.error already holds the failure message
|
// adminStore.error already holds the failure message
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { nextTick, ref, watch } from 'vue';
|
import { nextTick, ref, watch } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { Notify } from 'quasar';
|
||||||
import { useAdminStore, type Profile } from '@/stores/admin-store';
|
import { useAdminStore, type Profile } from '@/stores/admin-store';
|
||||||
|
|
||||||
type Focusable = { focus: () => void };
|
type Focusable = { focus: () => void };
|
||||||
@@ -63,6 +64,7 @@ async function save() {
|
|||||||
if (!props.profile) return;
|
if (!props.profile) return;
|
||||||
try {
|
try {
|
||||||
await adminStore.updateProfileRole(props.profile.user_id, selectedRole.value);
|
await adminStore.updateProfileRole(props.profile.user_id, selectedRole.value);
|
||||||
|
Notify.create({ type: 'positive', message: t('admin.notifications.roleUpdated') });
|
||||||
open.value = false;
|
open.value = false;
|
||||||
} catch {
|
} catch {
|
||||||
// adminStore.error already holds the failure message
|
// adminStore.error already holds the failure message
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { nextTick, ref, watch } from 'vue';
|
import { nextTick, ref, watch } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { Notify } from 'quasar';
|
||||||
import { useAdminStore, type Profile } from '@/stores/admin-store';
|
import { useAdminStore, type Profile } from '@/stores/admin-store';
|
||||||
import type { Status } from '@/stores/profiles-store';
|
import type { Status } from '@/stores/profiles-store';
|
||||||
|
|
||||||
@@ -64,6 +65,7 @@ async function save() {
|
|||||||
if (!props.profile) return;
|
if (!props.profile) return;
|
||||||
try {
|
try {
|
||||||
await adminStore.updateProfileStatus(props.profile.user_id, selectedStatus.value);
|
await adminStore.updateProfileStatus(props.profile.user_id, selectedStatus.value);
|
||||||
|
Notify.create({ type: 'positive', message: t('admin.notifications.statusUpdated') });
|
||||||
open.value = false;
|
open.value = false;
|
||||||
} catch {
|
} catch {
|
||||||
// adminStore.error already holds the failure message
|
// adminStore.error already holds the failure message
|
||||||
|
|||||||
Reference in New Issue
Block a user