class NotificationSettings extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open' }); this.config = null; this.isLoading = false; this.error = null; this.whatsAppStatusInterval = null; this.currentQrCode = null; } static get observedAttributes() { return ['loading', 'error', 'config']; } connectedCallback() { this.render(); this.loadSettings(); } disconnectedCallback() { this.stopWhatsAppPolling(); } async loadSettings() { this.isLoading = true; this.error = null; this.render(); try { // Simulated API call await new Promise(r => setTimeout(r, 800)); this.config = { telegram: { enabled: true, chatId: '-1001234567890', hasToken: true }, whatsapp: { enabled: false, gatewayUrl: 'http://localhost:3000', phoneNumber: '+1234567890', hasApiKey: false } }; this.isLoading = false; this.render(); this.startWhatsAppPolling(); } catch (err) { this.isLoading = false; this.error = err.message || 'Failed to load settings'; this.render(); } } startWhatsAppPolling() { this.refreshWhatsAppStatus(); this.whatsAppStatusInterval = setInterval(() => this.refreshWhatsAppStatus(), 3000); } stopWhatsAppPolling() { if (this.whatsAppStatusInterval) { clearInterval(this.whatsAppStatusInterval); this.whatsAppStatusInterval = null; } } async refreshWhatsAppStatus() { // Simulated status fetch const states = ['connected', 'disconnected', 'connecting']; const state = Math.random() < 0.6 ? 'connected' : (Math.random() < 0.5 ? 'connecting' : 'disconnected'); const status = { state: state, phoneNumber: state === 'connected' ? this.config?.whatsapp?.phoneNumber : null, qrCode: state === 'disconnected' ? 'mock-qr-' + Date.now() : null, timestamp: new Date().toISOString() }; this.updateWhatsAppStatusUI(status); } updateWhatsAppStatusUI(status) { const container = this.shadowRoot.getElementById('whatsapp-status-badge'); if (!container) return; const isConnected = status.state === 'connected'; const isConnecting = status.state === 'connecting'; let badgeClass = 'bg-gray-100 text-gray-800'; let dotClass = 'bg-gray-500'; let text = 'Checking...'; if (isConnected) { badgeClass = 'bg-green-100 text-green-800'; dotClass = 'bg-green-500 animate-pulse'; text = 'Connected'; } else if (isConnecting) { badgeClass = 'bg-yellow-100 text-yellow-800'; dotClass = 'bg-yellow-500 animate-pulse'; text = 'Connecting...'; } else { badgeClass = 'bg-red-100 text-red-800'; dotClass = 'bg-red-500'; text = 'Not connected'; } container.className = `inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${badgeClass}`; container.innerHTML = `${text}`; // Update status info const stateEl = this.shadowRoot.getElementById('status-state'); const phoneEl = this.shadowRoot.getElementById('status-phone'); const updatedEl = this.shadowRoot.getElementById('status-updated'); const qrContainer = this.shadowRoot.getElementById('qr-code-container'); const qrInstructions = this.shadowRoot.getElementById('qr-instructions'); if (stateEl) stateEl.textContent = status.state.charAt(0).toUpperCase() + status.state.slice(1); if (phoneEl) phoneEl.textContent = status.phoneNumber || '-'; if (updatedEl) updatedEl.textContent = new Date(status.timestamp).toLocaleTimeString(); // QR Code handling if (status.state === 'disconnected' && status.qrCode) { if (status.qrCode !== this.currentQrCode) { this.currentQrCode = status.qrCode; this.renderQRCode(status.qrCode); } if (qrInstructions) qrInstructions.classList.remove('hidden'); } else { this.currentQrCode = null; if (qrContainer) { if (isConnected) { qrContainer.innerHTML = `
Connected
${status.phoneNumber || 'WhatsApp Web active'}
Waiting for connection...
${data.slice(0, 20)}...
Loading settings...
${this.error}
Bot notifications via Telegram
The chat ID where notifications will be sent
Token: ${this.config.telegram.hasToken ? 'Set' : 'Not set'}
Notifications via Baileys gateway
API Key: ${this.config.whatsapp.hasApiKey ? 'Set' : 'Not set'}
Configure and monitor Telegram and WhatsApp notification channels