diff --git a/ui/src/App.vue b/ui/src/App.vue index dd4e2d8..56c4abf 100644 --- a/ui/src/App.vue +++ b/ui/src/App.vue @@ -2,6 +2,7 @@ import { watchEffect, computed } from 'vue' // Added computed import TopBar from '@/components/ui/TopBar.vue' import NavBar from '@/components/ui/NavBar.vue' +import SnackbarContainer from '@/components/ui/SnackbarContainer.vue' import { useUi } from '@/stores/useUi' const ui = useUi() @@ -80,6 +81,7 @@ const transitionDurationStyle = computed(() => { + diff --git a/ui/src/components/ui/SnackbarContainer.vue b/ui/src/components/ui/SnackbarContainer.vue new file mode 100644 index 0000000..8d6e676 --- /dev/null +++ b/ui/src/components/ui/SnackbarContainer.vue @@ -0,0 +1,67 @@ + + + + + diff --git a/ui/src/stores/useRealtime.js b/ui/src/stores/useRealtime.js index cf34662..09c444e 100644 --- a/ui/src/stores/useRealtime.js +++ b/ui/src/stores/useRealtime.js @@ -3,6 +3,7 @@ import { usePlanillasStore } from './usePlanillas' import { useEmpleadosStore } from './useEmpleados' import { useTareasStore } from './useTareas' import { useAsistenciasStore } from './useAsistencias' +import { useSnackbarStore } from './useSnackbar' export const useRealtimeStore = defineStore('realtime', { state: () => ({ @@ -55,6 +56,11 @@ export const useRealtimeStore = defineStore('realtime', { addEvent(); } + const snackbar = useSnackbarStore(); + const idPart = payload.new?.id || payload.old?.id; + const message = `${payload.operation} ${payload.table}${idPart ? ' #' + idPart : ''}`; + snackbar.push({ text: message }); + // mark badge for module and operation if (this.badges[payload.table]) { this.badges[payload.table][payload.operation] = true; diff --git a/ui/src/stores/useSnackbar.js b/ui/src/stores/useSnackbar.js new file mode 100644 index 0000000..7b01c32 --- /dev/null +++ b/ui/src/stores/useSnackbar.js @@ -0,0 +1,22 @@ +import { defineStore } from 'pinia' + +export const useSnackbarStore = defineStore('snackbar', { + state: () => ({ + snacks: [] + }), + actions: { + push({ text, type = 'info', duration = 4000 }) { + const id = crypto.randomUUID ? crypto.randomUUID() : Date.now().toString(36) + Math.random().toString(36).slice(2) + const snack = { id, text, type } + this.snacks.push(snack) + if (duration > 0) { + setTimeout(() => this.remove(id), duration) + } + return id + }, + remove(id) { + const index = this.snacks.findIndex(s => s.id === id) + if (index !== -1) this.snacks.splice(index, 1) + } + } +})