301 lines
8.7 KiB
JavaScript
301 lines
8.7 KiB
JavaScript
import { ref } from 'vue'
|
|
|
|
export const useNotificationLogs = () => {
|
|
// Use Nuxt's useFetch instead of $fetch
|
|
const config = useRuntimeConfig()
|
|
|
|
// Logs data state
|
|
const logs = ref([])
|
|
const loading = ref(false)
|
|
const error = ref(null)
|
|
const pagination = ref({
|
|
page: 1,
|
|
limit: 10,
|
|
total: 0,
|
|
pages: 1
|
|
})
|
|
const summaryStats = ref({
|
|
totalLogs: 0,
|
|
failedDeliveries: 0,
|
|
successfulDeliveries: 0,
|
|
successRate: 0
|
|
})
|
|
|
|
// Filters state
|
|
const filters = ref({
|
|
startDate: null,
|
|
endDate: null,
|
|
action: null,
|
|
channel: null,
|
|
status: null,
|
|
actor: '',
|
|
keyword: ''
|
|
})
|
|
|
|
// Analytics state
|
|
const analyticsData = ref(null)
|
|
const analyticsLoading = ref(false)
|
|
const analyticsError = ref(null)
|
|
|
|
// Monitoring state
|
|
const monitoringData = ref(null)
|
|
const monitoringLoading = ref(false)
|
|
const monitoringError = ref(null)
|
|
|
|
// Fetch logs with filters and pagination
|
|
const fetchLogs = async () => {
|
|
try {
|
|
loading.value = true
|
|
error.value = null
|
|
|
|
// Build query parameters
|
|
const queryParams = new URLSearchParams()
|
|
queryParams.append('page', pagination.value.page)
|
|
queryParams.append('limit', pagination.value.limit)
|
|
|
|
// Add filters if they exist
|
|
if (filters.value.startDate) queryParams.append('startDate', filters.value.startDate)
|
|
if (filters.value.endDate) queryParams.append('endDate', filters.value.endDate)
|
|
if (filters.value.action) queryParams.append('action', filters.value.action)
|
|
if (filters.value.channel) queryParams.append('channel', filters.value.channel)
|
|
if (filters.value.status) queryParams.append('status', filters.value.status)
|
|
if (filters.value.actor) queryParams.append('actor', filters.value.actor)
|
|
if (filters.value.keyword) queryParams.append('keyword', filters.value.keyword)
|
|
|
|
// Make API call with useFetch
|
|
const { data, error: fetchError } = await useFetch(`/api/notifications/logs`, {
|
|
method: 'GET',
|
|
params: {
|
|
page: pagination.value.page,
|
|
limit: pagination.value.limit,
|
|
...filters.value
|
|
}
|
|
})
|
|
|
|
if (fetchError.value) {
|
|
throw new Error(fetchError.value.message || 'Failed to fetch logs');
|
|
}
|
|
|
|
if (data.value && data.value.body && data.value.body.success) {
|
|
logs.value = data.value.body.data.logs || [];
|
|
pagination.value = data.value.body.data.pagination || pagination.value;
|
|
|
|
// Ensure summary stats are properly assigned
|
|
if (data.value.body.data.summary) {
|
|
summaryStats.value = {
|
|
totalLogs: data.value.body.data.summary.totalLogs || 0,
|
|
failedDeliveries: data.value.body.data.summary.failedDeliveries || 0,
|
|
successfulDeliveries: data.value.body.data.summary.successfulDeliveries || 0,
|
|
successRate: data.value.body.data.summary.successRate || 0
|
|
};
|
|
}
|
|
|
|
console.log('Logs fetched successfully:', {
|
|
logsCount: logs.value.length,
|
|
pagination: pagination.value,
|
|
summaryStats: summaryStats.value
|
|
});
|
|
} else {
|
|
throw new Error('Failed to fetch logs: ' + (data.value?.body?.message || 'Unknown error'))
|
|
}
|
|
} catch (err) {
|
|
error.value = err.message || 'An error occurred'
|
|
console.error('Error fetching logs:', err)
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
// Get a specific log by ID
|
|
const getLogById = async (id) => {
|
|
try {
|
|
loading.value = true
|
|
error.value = null
|
|
|
|
// Make API call
|
|
const { data } = await useFetch(`/api/notifications/logs/${id}`, {
|
|
method: 'GET'
|
|
})
|
|
|
|
if (data.value && data.value.body && data.value.body.success) {
|
|
return data.value.body.data
|
|
} else {
|
|
throw new Error('Failed to fetch log details')
|
|
}
|
|
} catch (err) {
|
|
error.value = err.message || 'An error occurred'
|
|
console.error('Error fetching log details:', err)
|
|
return null
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
// Update filters and fetch logs
|
|
const applyFilters = async (newFilters) => {
|
|
filters.value = { ...filters.value, ...newFilters }
|
|
pagination.value.page = 1 // Reset to first page when filters change
|
|
await fetchLogs()
|
|
}
|
|
|
|
// Clear all filters
|
|
const clearFilters = async () => {
|
|
filters.value = {
|
|
startDate: null,
|
|
endDate: null,
|
|
action: null,
|
|
channel: null,
|
|
status: null,
|
|
actor: '',
|
|
keyword: ''
|
|
}
|
|
pagination.value.page = 1
|
|
await fetchLogs()
|
|
}
|
|
|
|
// Change page
|
|
const changePage = async (page) => {
|
|
pagination.value.page = page
|
|
await fetchLogs()
|
|
}
|
|
|
|
// Fetch analytics data
|
|
const fetchAnalytics = async (period = '7d', channel = 'all') => {
|
|
try {
|
|
analyticsLoading.value = true
|
|
analyticsError.value = null
|
|
|
|
// Make API call
|
|
const { data } = await useFetch(`/api/notifications/logs/analytics`, {
|
|
method: 'GET',
|
|
params: {
|
|
period,
|
|
channel
|
|
}
|
|
})
|
|
|
|
if (data.value && data.value.body && data.value.body.success) {
|
|
analyticsData.value = data.value.body.data
|
|
} else {
|
|
throw new Error('Failed to fetch analytics data')
|
|
}
|
|
} catch (err) {
|
|
analyticsError.value = err.message || 'An error occurred'
|
|
console.error('Error fetching analytics data:', err)
|
|
} finally {
|
|
analyticsLoading.value = false
|
|
}
|
|
}
|
|
|
|
// Fetch monitoring data
|
|
const fetchMonitoringData = async () => {
|
|
try {
|
|
monitoringLoading.value = true
|
|
monitoringError.value = null
|
|
|
|
// Make API call
|
|
const { data } = await useFetch('/api/notifications/logs/monitoring', {
|
|
method: 'GET'
|
|
})
|
|
|
|
if (data.value && data.value.body && data.value.body.success) {
|
|
monitoringData.value = data.value.body.data
|
|
} else {
|
|
throw new Error('Failed to fetch monitoring data')
|
|
}
|
|
} catch (err) {
|
|
monitoringError.value = err.message || 'An error occurred'
|
|
console.error('Error fetching monitoring data:', err)
|
|
} finally {
|
|
monitoringLoading.value = false
|
|
}
|
|
}
|
|
|
|
// Format date for display
|
|
const formatDate = (date, includeTime = false) => {
|
|
if (!date) return ''
|
|
const options = { year: 'numeric', month: 'short', day: 'numeric' }
|
|
if (includeTime) {
|
|
options.hour = '2-digit'
|
|
options.minute = '2-digit'
|
|
}
|
|
return new Date(date).toLocaleDateString(undefined, options)
|
|
}
|
|
|
|
// Format time ago (e.g., "2 minutes ago")
|
|
const formatTimeAgo = (timestamp) => {
|
|
const now = new Date()
|
|
const time = new Date(timestamp)
|
|
const diffInMinutes = Math.floor((now - time) / (1000 * 60))
|
|
|
|
if (diffInMinutes < 1) return "Just now"
|
|
if (diffInMinutes < 60) return `${diffInMinutes} minutes ago`
|
|
if (diffInMinutes < 1440) return `${Math.floor(diffInMinutes / 60)} hours ago`
|
|
return `${Math.floor(diffInMinutes / 1440)} days ago`
|
|
}
|
|
|
|
// Get available actions for filters
|
|
const availableActions = [
|
|
{ label: 'All Actions', value: null },
|
|
{ label: 'Notification Created', value: 'Notification Created' },
|
|
{ label: 'Notification Sent', value: 'Notification Sent' },
|
|
{ label: 'Delivery Attempted', value: 'Delivery Attempted' },
|
|
{ label: 'Delivery Failed', value: 'Delivery Failed' },
|
|
{ label: 'Notification Opened', value: 'Notification Opened' },
|
|
{ label: 'Template Updated', value: 'Template Updated' },
|
|
{ label: 'Notification Queued', value: 'Notification Queued' },
|
|
]
|
|
|
|
// Get available channels for filters
|
|
const availableChannels = [
|
|
{ label: 'All Channels', value: null },
|
|
{ label: 'Email', value: 'Email' },
|
|
{ label: 'SMS', value: 'SMS' },
|
|
{ label: 'Push Notification', value: 'Push Notification' },
|
|
{ label: 'Webhook', value: 'Webhook' }
|
|
]
|
|
|
|
// Get available statuses for filters
|
|
const availableStatuses = [
|
|
{ label: 'All Statuses', value: null },
|
|
{ label: 'Sent', value: 'Sent' },
|
|
{ label: 'Failed', value: 'Failed' },
|
|
{ label: 'Bounced', value: 'Bounced' },
|
|
{ label: 'Opened', value: 'Opened' },
|
|
{ label: 'Queued', value: 'Queued' },
|
|
{ label: 'Created', value: 'Created' },
|
|
{ label: 'Updated', value: 'Updated' }
|
|
]
|
|
|
|
return {
|
|
// State
|
|
logs,
|
|
loading,
|
|
error,
|
|
pagination,
|
|
summaryStats,
|
|
filters,
|
|
analyticsData,
|
|
analyticsLoading,
|
|
analyticsError,
|
|
monitoringData,
|
|
monitoringLoading,
|
|
monitoringError,
|
|
|
|
// Methods
|
|
fetchLogs,
|
|
getLogById,
|
|
applyFilters,
|
|
clearFilters,
|
|
changePage,
|
|
fetchAnalytics,
|
|
fetchMonitoringData,
|
|
formatDate,
|
|
formatTimeAgo,
|
|
|
|
// Filter options
|
|
availableActions,
|
|
availableChannels,
|
|
availableStatuses
|
|
}
|
|
}
|