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...
No notifications match your filter criteria
| 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 ? '...' : ''}` : '-'} |