Layout 100%, Notificações, SetupWizard
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
// src/stores/notificationStore.js
|
||||
import { defineStore } from 'pinia'
|
||||
import { supabase } from '@/lib/supabase/client'
|
||||
|
||||
export const useNotificationStore = defineStore('notifications', {
|
||||
state: () => ({
|
||||
items: [],
|
||||
drawerOpen: false,
|
||||
_channel: null
|
||||
}),
|
||||
|
||||
getters: {
|
||||
unreadCount: (state) =>
|
||||
state.items.filter((n) => !n.read_at && !n.archived).length,
|
||||
|
||||
unreadItems: (state) =>
|
||||
state.items.filter((n) => !n.read_at && !n.archived),
|
||||
|
||||
allItems: (state) =>
|
||||
state.items.filter((n) => !n.archived)
|
||||
},
|
||||
|
||||
actions: {
|
||||
async load (ownerId) {
|
||||
const { data, error } = await supabase
|
||||
.from('notifications')
|
||||
.select('*')
|
||||
.eq('owner_id', ownerId)
|
||||
.eq('archived', false)
|
||||
.order('created_at', { ascending: false })
|
||||
.limit(50)
|
||||
|
||||
if (error) {
|
||||
console.error('[notificationStore] load error:', error.message)
|
||||
return
|
||||
}
|
||||
|
||||
this.items = data || []
|
||||
},
|
||||
|
||||
subscribeRealtime (ownerId) {
|
||||
if (this._channel) return
|
||||
|
||||
const channel = supabase
|
||||
.channel(`notifications:${ownerId}`)
|
||||
.on(
|
||||
'postgres_changes',
|
||||
{
|
||||
event: 'INSERT',
|
||||
schema: 'public',
|
||||
table: 'notifications',
|
||||
filter: `owner_id=eq.${ownerId}`
|
||||
},
|
||||
(payload) => {
|
||||
this.items.unshift(payload.new)
|
||||
}
|
||||
)
|
||||
.subscribe()
|
||||
|
||||
this._channel = channel
|
||||
},
|
||||
|
||||
async markRead (id) {
|
||||
const now = new Date().toISOString()
|
||||
const { error } = await supabase
|
||||
.from('notifications')
|
||||
.update({ read_at: now })
|
||||
.eq('id', id)
|
||||
|
||||
if (error) {
|
||||
console.error('[notificationStore] markRead error:', error.message)
|
||||
return
|
||||
}
|
||||
|
||||
const item = this.items.find((n) => n.id === id)
|
||||
if (item) item.read_at = now
|
||||
},
|
||||
|
||||
async markAllRead () {
|
||||
const unreadIds = this.items
|
||||
.filter((n) => !n.read_at && !n.archived)
|
||||
.map((n) => n.id)
|
||||
|
||||
if (!unreadIds.length) return
|
||||
|
||||
const now = new Date().toISOString()
|
||||
const { error } = await supabase
|
||||
.from('notifications')
|
||||
.update({ read_at: now })
|
||||
.in('id', unreadIds)
|
||||
|
||||
if (error) {
|
||||
console.error('[notificationStore] markAllRead error:', error.message)
|
||||
return
|
||||
}
|
||||
|
||||
this.items.forEach((n) => {
|
||||
if (unreadIds.includes(n.id)) n.read_at = now
|
||||
})
|
||||
},
|
||||
|
||||
async archive (id) {
|
||||
const { error } = await supabase
|
||||
.from('notifications')
|
||||
.update({ archived: true })
|
||||
.eq('id', id)
|
||||
|
||||
if (error) {
|
||||
console.error('[notificationStore] archive error:', error.message)
|
||||
return
|
||||
}
|
||||
|
||||
this.items = this.items.filter((n) => n.id !== id)
|
||||
},
|
||||
|
||||
unsubscribe () {
|
||||
if (this._channel) {
|
||||
supabase.removeChannel(this._channel)
|
||||
this._channel = null
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user