# ๐Ÿฆถ FOOTER - Documentazione Completa NetGescon > **Componente Footer dell'interfaccia universale** > **๐Ÿ“… Creato:** 21/07/2025 > **๐Ÿ”„ Ultimo aggiornamento:** 21/07/2025 > **๐ŸŽฏ Prioritร :** ๐Ÿ”ฅ CRITICA --- ## ๐Ÿ“‹ **OVERVIEW FOOTER** Il Footer NetGescon รจ il componente **FIXED BOTTOM** che contiene: - ๐Ÿ“Š **Progress Bar Sistema** - โ„น๏ธ **Info Applicazione** - ๐Ÿ‘ค **User Status Quick** - ๐Ÿ• **Sistema Timestamp** - ๐Ÿ“ก **Connection Status** - ๐Ÿ”„ **Auto-refresh Indicator** ### ๐Ÿ“ **Specifiche Layout** - **Altezza:** `70px` fisso - **Posizione:** `fixed bottom-0` sempre visibile - **Z-index:** `999` sopra content ma sotto header - **Background:** Sfumatura grigio scuro NetGescon --- ## ๐ŸŽจ **DESIGN SPECIFICATIONS** ### ๐ŸŒˆ **Color Palette** ```css /* Footer Background */ .netgescon-footer { background: linear-gradient(135deg, var(--netgescon-gray-800) 0%, var(--netgescon-gray-900) 100% ); border-top: 1px solid var(--netgescon-gray-700); color: var(--netgescon-gray-300); } /* Progress Bar */ .footer-progress { background: var(--netgescon-primary); height: 3px; transition: width 0.3s ease; } /* Status Indicators */ .status-online { color: var(--netgescon-success); } .status-offline { color: var(--netgescon-danger); } .status-warning { color: var(--netgescon-warning); } ``` ### ๐Ÿ“ **Dimensions** ```css .netgescon-footer { height: 70px; padding: 0 1.5rem; position: fixed; bottom: 0; left: 0; right: 0; z-index: 999; display: flex; align-items: center; justify-content: space-between; } ``` --- ## ๐Ÿงฉ **STRUTTURA FOOTER** ### ๐Ÿ“ **File:** `components/menu/sections/footer.blade.php` ```blade ``` --- ## โšก **JAVASCRIPT FUNCTIONALITY** ### ๐Ÿ“ **File:** `/public/js/components/footer.js` ```javascript /** * Footer NetGescon - JavaScript Functions */ let autoRefreshInterval; let autoRefreshEnabled = false; let autoRefreshCountdown = 30; let sessionStartTime = new Date(); // Inizializza footer function initializeFooter() { updateDateTime(); updateSessionTimer(); monitorConnection(); initializeSystemStatus(); initializeProgressBar(); // Update ogni secondo setInterval(() => { updateDateTime(); updateSessionTimer(); updateAutoRefreshTimer(); }, 1000); // System stats ogni 30 secondi setInterval(() => { updateSystemStats(); }, 30000); } // Date/Time updates function updateDateTime() { const now = new Date(); // Time const timeString = now.toLocaleTimeString('it-IT', { hour: '2-digit', minute: '2-digit', second: '2-digit' }); document.getElementById('current-time').textContent = timeString; // Date (desktop only) const dateString = now.toLocaleDateString('it-IT', { weekday: 'short', day: '2-digit', month: 'short', year: 'numeric' }); const dateEl = document.getElementById('current-date'); if (dateEl) dateEl.textContent = dateString; } // Session timer function updateSessionTimer() { const now = new Date(); const diff = now - sessionStartTime; const hours = Math.floor(diff / (1000 * 60 * 60)); const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)); document.getElementById('session-time').textContent = `${hours}h ${minutes}m`; } // Auto-refresh functionality function toggleAutoRefresh() { autoRefreshEnabled = !autoRefreshEnabled; const icon = document.getElementById('refresh-icon'); const button = document.getElementById('auto-refresh-toggle'); if (autoRefreshEnabled) { icon.classList.add('fa-spin'); button.classList.add('text-blue-400'); button.classList.remove('text-gray-400'); startAutoRefresh(); } else { icon.classList.remove('fa-spin'); button.classList.remove('text-blue-400'); button.classList.add('text-gray-400'); stopAutoRefresh(); } } function startAutoRefresh() { autoRefreshCountdown = 30; autoRefreshInterval = setInterval(() => { // Refresh current page data refreshPageData(); autoRefreshCountdown = 30; // Reset }, 30000); } function stopAutoRefresh() { if (autoRefreshInterval) { clearInterval(autoRefreshInterval); autoRefreshInterval = null; } document.getElementById('refresh-timer').textContent = '30s'; } function updateAutoRefreshTimer() { if (autoRefreshEnabled && autoRefreshCountdown > 0) { autoRefreshCountdown--; document.getElementById('refresh-timer').textContent = `${autoRefreshCountdown}s`; } } // Connection monitoring function monitorConnection() { const updateConnectionStatus = (online) => { const icon = document.getElementById('connection-icon'); const text = document.getElementById('connection-text'); if (online) { icon.className = 'fas fa-wifi status-online'; text.textContent = 'Online'; } else { icon.className = 'fas fa-wifi-slash status-offline'; text.textContent = 'Offline'; } }; // Check connection status window.addEventListener('online', () => updateConnectionStatus(true)); window.addEventListener('offline', () => updateConnectionStatus(false)); // Initial check updateConnectionStatus(navigator.onLine); // Periodic ping check setInterval(async () => { try { const response = await fetch('/api/ping', { method: 'HEAD', cache: 'no-cache' }); updateConnectionStatus(response.ok); } catch { updateConnectionStatus(false); } }, 10000); } // System status monitoring function initializeSystemStatus() { updateSystemStats(); } async function updateSystemStats() { try { const response = await fetch('/api/system-stats'); const stats = await response.json(); // CPU Usage document.getElementById('cpu-usage').textContent = `${stats.cpu}%`; document.getElementById('cpu-usage').className = getCpuClass(stats.cpu); // Memory Usage document.getElementById('mem-usage').textContent = `${stats.memory}%`; document.getElementById('mem-usage').className = getMemClass(stats.memory); // Active Users document.getElementById('active-users').textContent = stats.activeUsers; // System Status updateSystemStatus(stats.status); } catch (error) { console.warn('Unable to fetch system stats:', error); } } function getCpuClass(cpu) { if (cpu < 50) return 'text-green-400'; if (cpu < 80) return 'text-yellow-400'; return 'text-red-400'; } function getMemClass(memory) { if (memory < 60) return 'text-blue-400'; if (memory < 85) return 'text-yellow-400'; return 'text-red-400'; } function updateSystemStatus(status) { const icon = document.getElementById('system-icon'); const text = document.getElementById('system-text'); switch (status) { case 'ok': icon.className = 'fas fa-server status-online'; text.textContent = 'Sistema OK'; break; case 'warning': icon.className = 'fas fa-exclamation-triangle status-warning'; text.textContent = 'Attenzione'; break; case 'error': icon.className = 'fas fa-exclamation-circle status-offline'; text.textContent = 'Errore'; break; } } // Progress bar for page loading function initializeProgressBar() { const progressBar = document.getElementById('footer-progress'); // Show progress on AJAX requests let activeRequests = 0; // Listen to fetch requests const originalFetch = window.fetch; window.fetch = function(...args) { activeRequests++; updateProgressBar(); return originalFetch.apply(this, args) .finally(() => { activeRequests--; updateProgressBar(); }); }; } function updateProgressBar() { const progressBar = document.getElementById('footer-progress'); if (activeRequests > 0) { progressBar.style.width = '70%'; setTimeout(() => { if (activeRequests === 0) { progressBar.style.width = '100%'; setTimeout(() => { progressBar.style.width = '0%'; }, 200); } }, 500); } } // Page data refresh async function refreshPageData() { try { const currentPath = window.location.pathname; const response = await fetch(currentPath, { headers: { 'X-Requested-With': 'XMLHttpRequest', 'X-Refresh-Data': 'true' } }); if (response.ok) { // Update dynamic content only const data = await response.json(); updateDynamicContent(data); } } catch (error) { console.warn('Auto-refresh failed:', error); } } function updateDynamicContent(data) { // Update stats cards if (data.stats) { Object.keys(data.stats).forEach(key => { const element = document.querySelector(`[data-stat="${key}"]`); if (element) { element.textContent = data.stats[key]; } }); } // Update notifications badge if (data.notifications) { const badge = document.querySelector('.notification-badge'); if (badge) { badge.textContent = data.notifications.count; badge.style.display = data.notifications.count > 0 ? 'flex' : 'none'; } } // Show update indicator showUpdateIndicator(); } function showUpdateIndicator() { const indicator = document.createElement('div'); indicator.className = 'update-indicator fixed top-20 right-6 bg-green-500 text-white px-3 py-1 rounded text-sm z-50'; indicator.innerHTML = ' Aggiornato'; document.body.appendChild(indicator); setTimeout(() => { indicator.style.opacity = '0'; setTimeout(() => indicator.remove(), 300); }, 2000); } // Initialize on DOM ready document.addEventListener('DOMContentLoaded', initializeFooter); ``` --- ## ๐Ÿ“ฑ **RESPONSIVE BEHAVIOR** ### ๐Ÿ–ฅ๏ธ **Desktop (โ‰ฅ1024px)** ```css .netgescon-footer { padding: 0 24px; } .footer-center { display: flex; } .footer-right .hidden { display: block; } ``` ### ๐Ÿ“ฑ **Tablet (768px - 1023px)** ```css .footer-center { display: none; } .footer-left, .footer-right { flex-wrap: wrap; } ``` ### ๐Ÿ“ฑ **Mobile (โ‰ค767px)** ```css .netgescon-footer { padding: 0 16px; font-size: 0.875rem; } .footer-left { flex-direction: column; align-items: flex-start; space-y: 2px; } .footer-right { flex-direction: column; align-items: flex-end; space-y: 2px; } .hidden-mobile { display: none; } ``` --- ## ๐Ÿ”ง **CONFIGURATION OPTIONS** ### โš™๏ธ **Footer Settings** ```javascript // Configuration object const footerConfig = { autoRefresh: { enabled: true, interval: 30000, // 30 seconds showTimer: true }, systemStats: { enabled: true, interval: 30000, showCpu: true, showMemory: true, showUsers: true }, connection: { monitoring: true, pingInterval: 10000, pingEndpoint: '/api/ping' }, progress: { showOnAjax: true, animationDuration: 300 } }; ``` ### ๐ŸŽ›๏ธ **Customization Options** ```css /* Custom footer height */ :root { --footer-height: 70px; } /* Custom progress bar color */ .footer-progress { background: var(--netgescon-accent); } /* Custom status colors */ .status-custom { color: #your-color; } ``` --- ## ๐Ÿงช **TESTING CHECKLIST** ### โœ… **Functional Tests** - [ ] Date/time updates correctly - [ ] Session timer accurate - [ ] Auto-refresh toggle works - [ ] Connection status monitoring - [ ] System stats display - [ ] Progress bar animations ### โœ… **Visual Tests** - [ ] Footer height consistent (70px) - [ ] Elements alignment correct - [ ] Icons display properly - [ ] Text readability good - [ ] Mobile layout responsive ### โœ… **Performance Tests** - [ ] No memory leaks in timers - [ ] Efficient update intervals - [ ] Smooth animations - [ ] Low CPU usage --- ## ๐Ÿ› **COMMON ISSUES & FIXES** ### ๐Ÿšจ **Footer copre contenuto** **Causa:** Padding bottom mancante nel body **Fix:** ```css body { padding-bottom: 70px; } .content-area { margin-bottom: 70px; } ``` ### ๐Ÿšจ **Timer non funziona** **Causa:** JavaScript intervals non inizializzati **Fix:** Verifica initializeFooter() chiamata ### ๐Ÿšจ **Stats non si aggiornano** **Causa:** Endpoint API `/api/system-stats` mancante **Fix:** Implementa route API o disabilita feature ### ๐Ÿšจ **Progress bar non appare** **Causa:** CSS z-index conflicts **Fix:** Verifica z-index footer e progress bar --- ## ๐Ÿ“Š **PERFORMANCE METRICS** ### ๐ŸŽฏ **Target Performance** - **Update Frequency:** 1Hz (1 update/second) - **API Calls:** Max 2/minute - **Memory Usage:** < 5MB - **CPU Impact:** < 1% ### ๐Ÿ“ˆ **Monitoring** ```javascript // Performance monitoring const footerPerformance = { updateCount: 0, lastUpdate: Date.now(), avgUpdateTime: 0, measureUpdate(fn) { const start = performance.now(); fn(); const end = performance.now(); this.updateCount++; this.avgUpdateTime = (this.avgUpdateTime + (end - start)) / 2; this.lastUpdate = Date.now(); } }; ``` --- ## ๐Ÿ“š **FILES CORRELATI** ### ๐Ÿงฉ **Templates** - `/resources/views/components/menu/sections/footer.blade.php` ### ๐ŸŽจ **Styles** - `/public/css/components/footer.css` - `/public/css/netgescon-admin.css` ### โšก **JavaScript** - `/public/js/components/footer.js` - `/public/js/netgescon-admin.js` ### ๐Ÿ”— **API Endpoints** - `/api/ping` - Connection check - `/api/system-stats` - System statistics - `/api/refresh-data` - Page data refresh --- ## ๐ŸŽฏ **NEXT STEPS** ### ๐Ÿ”ฎ **Planned Improvements** - [ ] **Real-time Notifications** - WebSocket integration - [ ] **System Health Dashboard** - Detailed metrics - [ ] **User Activity Tracker** - Session analytics - [ ] **Quick Actions Menu** - Footer dropdown - [ ] **Theme Preferences** - Footer controls --- *๐Ÿ“ Documento mantenuto da: GitHub Copilot AI Assistant* *๐Ÿ”— Componente: Footer NetGescon Interface v2.1.0*