class NotificationLog extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open' }); this.notifications = []; this.filteredNotifications = []; this.isLoading = false; this.channelFilter = 'all'; this.statusFilter = 'all'; } static get observedAttributes() { return ['loading', 'channel-filter', 'status-filter']; } connectedCallback() { this.loadNotifications(); } async loadNotifications() { this.isLoading = true; this.render(); try { // Simulated API call await new Promise(r => setTimeout(r, 600)); this.notifications = [ { id: 1, channel: 'telegram', recipient: '-1001234567890', message: 'Alert: Suspicious activity detected on @elonmusk', status: 'sent', error: null, createdAt: '2024-03-20T10:30:00Z' }, { id: 2, channel: 'whatsapp', recipient: '+1234567890', message: 'Alert: New post from monitored account @sama', status: 'sent', error: null, createdAt: '2024-03-20T09:15:00Z' }, { id: 3, channel: 'telegram', recipient: '-1001234567890', message: 'Alert: Status change on account +1-555-0123', status: 'failed', error: 'Chat not found', createdAt: '2024-03-20T08:45:00Z' }, { id: 4, channel: 'whatsapp', recipient: '+1234567890', message: 'Test message: WhatsApp configuration verified', status: 'pending', error: null, createdAt: '2024-03-20T08:30:00Z' }, { id: 5, channel: 'telegram', recipient: '-1001234567890', message: 'Alert: Multiple failed login attempts detected', status: 'sent', error: null, createdAt: '2024-03-19T22:00:00Z' }, { id: 6, channel: 'whatsapp', recipient: '+1234567890', message: 'Alert: Account @naval posted flagged content', status: 'sent', error: null, createdAt: '2024-03-19T18:30:00Z' } ]; this.isLoading = false; this.applyFilters(); } catch (err) { this.isLoading = false; this.dispatchEvent(new CustomEvent('toast', { detail: { type: 'error', title: 'Error', message: 'Failed to load notifications' }, bubbles: true, composed: true })); this.render(); } } applyFilters() { this.filteredNotifications = this.notifications.filter(n => { const matchChannel = this.channelFilter === 'all' || n.channel === this.channelFilter; const matchStatus = this.statusFilter === 'all' || n.status === this.statusFilter; return matchChannel && matchStatus; }); this.render(); } onChannelChange(value) { this.channelFilter = value; this.applyFilters(); } onStatusChange(value) { this.statusFilter = value; this.applyFilters(); } formatDate(dateString) { const date = new Date(dateString); return date.toLocaleString('en-US', { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }); } timeAgo(dateString) { const date = new Date(dateString); const now = new Date(); const seconds = Math.floor((now - date) / 1000); let interval = Math.floor(seconds / 86400); if (interval > 1) return `${interval} days ago`; if (interval === 1) return 'Yesterday'; interval = Math.floor(seconds / 3600); if (interval > 1) return `${interval} hours ago`; if (interval === 1) return '1 hour ago'; interval = Math.floor(seconds / 60); if (interval > 1) return `${interval} minutes ago`; return 'Just now'; } escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } getStatusConfig(status) { const configs = { sent: { bg: 'bg-green-100', text: 'text-green-800', dot: 'bg-green-500' }, pending: { bg: 'bg-yellow-100', text: 'text-yellow-800', dot: 'bg-yellow-500' }, failed: { bg: 'bg-red-100', text: 'text-red-800', dot: 'bg-red-500' } }; return configs[status] || configs.pending; } render() { const loadingHtml = `

Loading notifications...

`; const emptyHtml = `

No notifications found

No notifications match your filter criteria

`; const tableHtml = this.filteredNotifications.length > 0 ? `
${this.filteredNotifications.map((n, i) => { const sc = this.getStatusConfig(n.status); return ` `; }).join('')}
Created Channel Recipient Status Message Error
${this.formatDate(n.createdAt)}
${this.timeAgo(n.createdAt)}
${n.channel === 'telegram' ? '' : ''} ${n.channel} ${n.recipient} ${n.status.charAt(0).toUpperCase() + n.status.slice(1)}

${this.escapeHtml(n.message)}

${n.error ? `${this.escapeHtml(n.error.slice(0, 30))}${n.error.length > 30 ? '...' : ''}` : '-'}
` : emptyHtml; this.shadowRoot.innerHTML = `

Notification Log

${this.isLoading ? loadingHtml : tableHtml}
`; // Attach event listeners if (!this.isLoading) { this.shadowRoot.getElementById('channel-filter')?.addEventListener('change', (e) => this.onChannelChange(e.target.value)); this.shadowRoot.getElementById('status-filter')?.addEventListener('change', (e) => this.onStatusChange(e.target.value)); } } } customElements.define('notification-log', NotificationLog);