// AutoBackups JavaScript Application class AutoBackupsApp { constructor() { this.init(); } init() { this.updateCurrentTime(); this.setupEventListeners(); // Update time every minute setInterval(() => this.updateCurrentTime(), 60000); } updateCurrentTime() { const now = new Date(); const timeString = now.toLocaleString('es-ES', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' }); const timeElement = document.getElementById('current-time'); if (timeElement) { timeElement.textContent = timeString; } } setupEventListeners() { // Global backup all button const backupAllBtn = document.getElementById('backup-all-btn'); if (backupAllBtn) { backupAllBtn.addEventListener('click', () => this.backupAllProjects()); } // Save project configuration const saveConfigBtn = document.getElementById('save-project-config-btn'); if (saveConfigBtn) { saveConfigBtn.addEventListener('click', () => this.saveProjectConfig()); } } backupAllProjects() { this.showAlert('info', 'Iniciando backup de todos los proyectos habilitados...'); // Get all enabled projects and trigger backup fetch('/api/projects') .then(response => response.json()) .then(data => { if (data.error) { this.showAlert('danger', `Error: ${data.error}`); return; } const enabledProjects = data.projects.filter(project => project.schedule_config && project.schedule_config.enabled ); if (enabledProjects.length === 0) { this.showAlert('warning', 'No hay proyectos habilitados para backup.'); return; } // Backup each enabled project let completed = 0; enabledProjects.forEach(project => { fetch(`/api/projects/${project.id}/backup`, { method: 'POST', headers: { 'Content-Type': 'application/json' } }) .then(response => response.json()) .then(backupData => { completed++; if (completed === enabledProjects.length) { this.showAlert('success', `Backup completado para ${enabledProjects.length} proyectos.`); } }) .catch(error => { console.error(`Error backing up project ${project.id}:`, error); }); }); }) .catch(error => { this.showAlert('danger', `Error de conexión: ${error.message}`); }); } saveProjectConfig() { const projectId = document.getElementById('modal-project-id').value; const schedule = document.getElementById('modal-project-schedule').value; const time = document.getElementById('modal-project-time').value; const enabled = document.getElementById('modal-project-enabled').checked; const config = { schedule_config: { schedule: schedule, schedule_time: time, enabled: enabled } }; fetch(`/api/projects/${projectId}/config`, { method: 'PUT', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(config) }) .then(response => response.json()) .then(data => { if (data.error) { this.showAlert('danger', `Error: ${data.error}`); } else { this.showAlert('success', 'Configuración guardada correctamente.'); // Close modal const modal = bootstrap.Modal.getInstance( document.getElementById('projectConfigModal') ); if (modal) { modal.hide(); } // Refresh page after a short delay setTimeout(() => location.reload(), 1500); } }) .catch(error => { this.showAlert('danger', `Error de conexión: ${error.message}`); }); } showAlert(type, message, duration = 5000) { const alertsContainer = document.getElementById('alerts-container'); if (!alertsContainer) return; const alertId = 'alert-' + Date.now(); const alertHtml = ` `; alertsContainer.insertAdjacentHTML('beforeend', alertHtml); // Auto-dismiss after duration if (duration > 0) { setTimeout(() => { const alertElement = document.getElementById(alertId); if (alertElement) { const alert = new bootstrap.Alert(alertElement); alert.close(); } }, duration); } } getAlertIcon(type) { const icons = { 'success': 'check-circle', 'danger': 'exclamation-triangle', 'warning': 'exclamation-triangle', 'info': 'info-circle', 'primary': 'info-circle', 'secondary': 'info-circle' }; return icons[type] || 'info-circle'; } // Utility method to format file sizes formatFileSize(bytes) { if (bytes === 0) return '0 Bytes'; const k = 1024; const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; } // Utility method to format dates formatDate(dateString) { if (!dateString) return 'N/A'; const date = new Date(dateString); return date.toLocaleString('es-ES', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' }); } // Method to show loading state showLoading(element) { if (element) { element.classList.add('loading'); const originalContent = element.innerHTML; element.innerHTML = ' Cargando...'; return originalContent; } } // Method to hide loading state hideLoading(element, originalContent) { if (element && originalContent) { element.classList.remove('loading'); element.innerHTML = originalContent; } } // Method to make API calls with error handling async apiCall(url, options = {}) { try { const response = await fetch(url, { headers: { 'Content-Type': 'application/json', ...options.headers }, ...options }); const data = await response.json(); if (!response.ok) { throw new Error(data.error || `HTTP error! status: ${response.status}`); } return data; } catch (error) { console.error('API call failed:', error); this.showAlert('danger', `Error de API: ${error.message}`); throw error; } } } // Global functions for backward compatibility function showAlert(type, message, duration = 5000) { if (window.autobackupsApp) { window.autobackupsApp.showAlert(type, message, duration); } } // Initialize app when DOM is loaded document.addEventListener('DOMContentLoaded', function() { window.autobackupsApp = new AutoBackupsApp(); }); // Export for modules if needed if (typeof module !== 'undefined' && module.exports) { module.exports = AutoBackupsApp; }