Spaces:
Sleeping
Sleeping
| /** | |
| * Configuration UI Management | |
| * Provides UI components for managing frontend configuration | |
| */ | |
| (() => { | |
| 'use strict'; | |
| class ConfigUI { | |
| constructor() { | |
| this.config = window.AIMHSA?.Config; | |
| this.init(); | |
| } | |
| init() { | |
| this.createConfigPanel(); | |
| this.bindEvents(); | |
| console.log('⚙️ Configuration UI initialized'); | |
| } | |
| /** | |
| * Create configuration panel | |
| */ | |
| createConfigPanel() { | |
| const configPanel = document.createElement('div'); | |
| configPanel.id = 'configPanel'; | |
| configPanel.className = 'config-panel'; | |
| configPanel.innerHTML = ` | |
| <div class="config-header"> | |
| <h3><i class="fas fa-cog"></i> Configuration</h3> | |
| <button class="btn btn-sm btn-outline-secondary" id="toggleConfigPanel"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| </div> | |
| <div class="config-content"> | |
| <div class="config-section"> | |
| <h4>API Configuration</h4> | |
| <div class="form-group"> | |
| <label>API Base URL</label> | |
| <input type="url" id="apiBaseUrl" class="form-control" | |
| value="${this.config?.getApiBaseUrl() || ''}" | |
| placeholder="https://prodevroger-ishingiro.hf.space"> | |
| <small class="form-text text-muted"> | |
| Base URL for the backend API server | |
| </small> | |
| </div> | |
| <div class="form-group"> | |
| <label>Environment</label> | |
| <select id="environment" class="form-control"> | |
| <option value="development">Development</option> | |
| <option value="staging">Staging</option> | |
| <option value="production">Production</option> | |
| </select> | |
| </div> | |
| <button class="btn btn-primary btn-sm" id="testConnection"> | |
| <i class="fas fa-plug"></i> Test Connection | |
| </button> | |
| </div> | |
| <div class="config-section"> | |
| <h4>UI Configuration</h4> | |
| <div class="form-group"> | |
| <label>Theme</label> | |
| <select id="theme" class="form-control"> | |
| <option value="dark">Dark</option> | |
| <option value="light">Light</option> | |
| </select> | |
| </div> | |
| <div class="form-group"> | |
| <label>Auto-refresh Interval (seconds)</label> | |
| <input type="number" id="autoRefresh" class="form-control" | |
| value="${this.config?.get('ui.autoRefreshInterval', 30000) / 1000}" | |
| min="5" max="300"> | |
| </div> | |
| </div> | |
| <div class="config-actions"> | |
| <button class="btn btn-success btn-sm" id="saveConfig"> | |
| <i class="fas fa-save"></i> Save Configuration | |
| </button> | |
| <button class="btn btn-warning btn-sm" id="resetConfig"> | |
| <i class="fas fa-undo"></i> Reset to Defaults | |
| </button> | |
| </div> | |
| <div class="config-info"> | |
| <h4>Environment Information</h4> | |
| <pre id="envInfo"></pre> | |
| </div> | |
| </div> | |
| `; | |
| // Add styles | |
| const style = document.createElement('style'); | |
| style.textContent = ` | |
| .config-panel { | |
| position: fixed; | |
| top: 20px; | |
| right: -400px; | |
| width: 380px; | |
| height: calc(100vh - 40px); | |
| background: var(--surface, #1e293b); | |
| border: 1px solid var(--border, #334155); | |
| border-radius: 12px; | |
| box-shadow: 0 10px 25px rgba(0,0,0,0.3); | |
| z-index: 10000; | |
| transition: right 0.3s ease; | |
| overflow-y: auto; | |
| } | |
| .config-panel.open { | |
| right: 20px; | |
| } | |
| .config-header { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| padding: 1rem; | |
| border-bottom: 1px solid var(--border, #334155); | |
| background: var(--primary, #7c3aed); | |
| color: white; | |
| border-radius: 12px 12px 0 0; | |
| } | |
| .config-header h3 { | |
| margin: 0; | |
| font-size: 1.1rem; | |
| } | |
| .config-content { | |
| padding: 1rem; | |
| } | |
| .config-section { | |
| margin-bottom: 1.5rem; | |
| padding-bottom: 1rem; | |
| border-bottom: 1px solid var(--border-light, #475569); | |
| } | |
| .config-section:last-child { | |
| border-bottom: none; | |
| } | |
| .config-section h4 { | |
| color: var(--text, #f8fafc); | |
| font-size: 1rem; | |
| margin-bottom: 1rem; | |
| } | |
| .config-actions { | |
| display: flex; | |
| gap: 0.5rem; | |
| margin-bottom: 1rem; | |
| } | |
| .config-info pre { | |
| background: var(--background, #0f172a); | |
| padding: 0.5rem; | |
| border-radius: 4px; | |
| font-size: 0.8rem; | |
| color: var(--text-secondary, #cbd5e1); | |
| border: 1px solid var(--border, #334155); | |
| max-height: 200px; | |
| overflow-y: auto; | |
| } | |
| .config-toggle { | |
| position: fixed; | |
| top: 20px; | |
| right: 20px; | |
| z-index: 9999; | |
| background: var(--primary, #7c3aed); | |
| color: white; | |
| border: none; | |
| border-radius: 50%; | |
| width: 50px; | |
| height: 50px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 1.2rem; | |
| cursor: pointer; | |
| transition: all 0.3s ease; | |
| box-shadow: 0 4px 12px rgba(124, 58, 237, 0.3); | |
| } | |
| .config-toggle:hover { | |
| background: var(--primary-dark, #5b21b6); | |
| transform: scale(1.1); | |
| } | |
| `; | |
| document.head.appendChild(style); | |
| document.body.appendChild(configPanel); | |
| // Create toggle button | |
| const toggleBtn = document.createElement('button'); | |
| toggleBtn.id = 'configToggle'; | |
| toggleBtn.className = 'config-toggle'; | |
| toggleBtn.innerHTML = '<i class="fas fa-cog"></i>'; | |
| toggleBtn.title = 'Configuration Settings'; | |
| document.body.appendChild(toggleBtn); | |
| this.updateEnvironmentInfo(); | |
| } | |
| /** | |
| * Bind event handlers | |
| */ | |
| bindEvents() { | |
| // Toggle panel | |
| document.getElementById('configToggle').addEventListener('click', () => { | |
| this.togglePanel(); | |
| }); | |
| document.getElementById('toggleConfigPanel').addEventListener('click', () => { | |
| this.togglePanel(); | |
| }); | |
| // Save configuration | |
| document.getElementById('saveConfig').addEventListener('click', () => { | |
| this.saveConfiguration(); | |
| }); | |
| // Reset configuration | |
| document.getElementById('resetConfig').addEventListener('click', () => { | |
| this.resetConfiguration(); | |
| }); | |
| // Test connection | |
| document.getElementById('testConnection').addEventListener('click', () => { | |
| this.testConnection(); | |
| }); | |
| // Real-time updates | |
| document.getElementById('apiBaseUrl').addEventListener('input', (e) => { | |
| if (this.config) { | |
| this.config.setApiBaseUrl(e.target.value); | |
| } | |
| }); | |
| // Close panel on Escape key | |
| document.addEventListener('keydown', (e) => { | |
| if (e.key === 'Escape') { | |
| this.closePanel(); | |
| } | |
| }); | |
| } | |
| /** | |
| * Toggle configuration panel | |
| */ | |
| togglePanel() { | |
| const panel = document.getElementById('configPanel'); | |
| panel.classList.toggle('open'); | |
| if (panel.classList.contains('open')) { | |
| this.loadCurrentSettings(); | |
| this.updateEnvironmentInfo(); | |
| } | |
| } | |
| /** | |
| * Close configuration panel | |
| */ | |
| closePanel() { | |
| const panel = document.getElementById('configPanel'); | |
| panel.classList.remove('open'); | |
| } | |
| /** | |
| * Load current settings into UI | |
| */ | |
| loadCurrentSettings() { | |
| if (!this.config) return; | |
| document.getElementById('apiBaseUrl').value = this.config.getApiBaseUrl(); | |
| document.getElementById('environment').value = this.config.environment; | |
| document.getElementById('theme').value = this.config.get('ui.theme', 'dark'); | |
| document.getElementById('autoRefresh').value = this.config.get('ui.autoRefreshInterval', 30000) / 1000; | |
| } | |
| /** | |
| * Save configuration | |
| */ | |
| saveConfiguration() { | |
| if (!this.config) return; | |
| const apiBaseUrl = document.getElementById('apiBaseUrl').value; | |
| const environment = document.getElementById('environment').value; | |
| const theme = document.getElementById('theme').value; | |
| const autoRefresh = parseInt(document.getElementById('autoRefresh').value) * 1000; | |
| // Update configuration | |
| this.config.setApiBaseUrl(apiBaseUrl); | |
| this.config.set('ui.theme', theme); | |
| this.config.set('ui.autoRefreshInterval', autoRefresh); | |
| // Show success message | |
| this.showToast('Configuration saved successfully!', 'success'); | |
| // Optionally reload the page to apply changes | |
| if (confirm('Configuration saved. Reload the page to apply changes?')) { | |
| window.location.reload(); | |
| } | |
| } | |
| /** | |
| * Reset configuration to defaults | |
| */ | |
| resetConfiguration() { | |
| if (!this.config) return; | |
| if (confirm('Are you sure you want to reset all configuration to defaults?')) { | |
| this.config.reset(); | |
| this.loadCurrentSettings(); | |
| this.updateEnvironmentInfo(); | |
| this.showToast('Configuration reset to defaults', 'info'); | |
| } | |
| } | |
| /** | |
| * Test API connection | |
| */ | |
| async testConnection() { | |
| if (!this.config) return; | |
| const button = document.getElementById('testConnection'); | |
| const originalText = button.innerHTML; | |
| button.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Testing...'; | |
| button.disabled = true; | |
| try { | |
| const isConnected = await this.config.validateApiConnection(); | |
| if (isConnected) { | |
| this.showToast('API connection successful!', 'success'); | |
| } else { | |
| this.showToast('API connection failed', 'error'); | |
| } | |
| } catch (error) { | |
| this.showToast('Connection test failed: ' + error.message, 'error'); | |
| } finally { | |
| button.innerHTML = originalText; | |
| button.disabled = false; | |
| } | |
| } | |
| /** | |
| * Update environment information display | |
| */ | |
| updateEnvironmentInfo() { | |
| if (!this.config) return; | |
| const envInfo = this.config.getEnvironmentInfo(); | |
| const formattedInfo = JSON.stringify(envInfo, null, 2); | |
| document.getElementById('envInfo').textContent = formattedInfo; | |
| } | |
| /** | |
| * Show toast notification | |
| */ | |
| showToast(message, type = 'info') { | |
| // Use SweetAlert2 if available | |
| if (typeof Swal !== 'undefined') { | |
| Swal.fire({ | |
| toast: true, | |
| position: 'top-end', | |
| showConfirmButton: false, | |
| timer: 3000, | |
| icon: type === 'error' ? 'error' : type === 'success' ? 'success' : 'info', | |
| title: message | |
| }); | |
| return; | |
| } | |
| // Fallback to simple alert | |
| const alertClass = type === 'error' ? 'alert-danger' : | |
| type === 'success' ? 'alert-success' : 'alert-info'; | |
| const toast = document.createElement('div'); | |
| toast.className = `alert ${alertClass} alert-dismissible fade show`; | |
| toast.style.cssText = ` | |
| position: fixed; | |
| top: 20px; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| z-index: 10001; | |
| min-width: 300px; | |
| `; | |
| toast.innerHTML = ` | |
| ${message} | |
| <button type="button" class="close" onclick="this.parentElement.remove()"> | |
| <span>×</span> | |
| </button> | |
| `; | |
| document.body.appendChild(toast); | |
| setTimeout(() => { | |
| if (toast.parentElement) { | |
| toast.remove(); | |
| } | |
| }, 3000); | |
| } | |
| } | |
| // Initialize when DOM is ready | |
| if (document.readyState === 'loading') { | |
| document.addEventListener('DOMContentLoaded', () => { | |
| new ConfigUI(); | |
| }); | |
| } else { | |
| new ConfigUI(); | |
| } | |
| })(); | |