/** * Common Utilities for OpenVPN Monitor */ // --- Global Variables --- var currentTheme = localStorage.getItem('theme') || 'light'; // --- Theme Functions --- function initTheme() { document.documentElement.setAttribute('data-theme', currentTheme); const icon = document.getElementById('themeIcon'); if (icon) { if (currentTheme === 'dark') { // In dark mode we want Sun icon (to switch to light) if (icon.classList.contains('fa-moon')) icon.classList.replace('fa-moon', 'fa-sun'); else icon.classList = 'fas fa-sun'; } else { // In light mode we want Moon icon (to switch to dark) if (icon.classList.contains('fa-sun')) icon.classList.replace('fa-sun', 'fa-moon'); else icon.classList = 'fas fa-moon'; } } } function toggleTheme(callback = null) { currentTheme = currentTheme === 'light' ? 'dark' : 'light'; localStorage.setItem('theme', currentTheme); initTheme(); if (callback) callback(); } // --- Formatting Functions --- function formatBytes(bytes, decimals = 2) { if (bytes === 0) return '0 B'; const k = 1024; const dm = decimals < 0 ? 0 : decimals; const sizes = ['B', 'KB', 'MB', 'GB', 'TB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; } function formatRate(rate) { return parseFloat(rate).toFixed(3) + ' Mbps'; } function parseServerDate(dateStr) { if (!dateStr) return null; let isoStr = dateStr.replace(' ', 'T'); if (!isoStr.endsWith('Z') && !isoStr.includes('+')) { isoStr += 'Z'; } return new Date(isoStr); } function formatCertDate(dateString) { if (!dateString || dateString === 'N/A') return 'N/A'; try { // Handle OpenSSL date format: "Jun 9 08:37:28 2024 GMT" if (dateString.includes('GMT')) { const months = { 'Jan': '01', 'Feb': '02', 'Mar': '03', 'Apr': '04', 'May': '05', 'Jun': '06', 'Jul': '07', 'Aug': '08', 'Sep': '09', 'Oct': '10', 'Nov': '11', 'Dec': '12' }; const parts = dateString.split(' '); const month = months[parts[0]]; const day = parts[1].padStart(2, '0'); const year = parts[3]; const time = parts[2]; return `${day}-${month}-${year} ${time}`; } // Try to parse as ISO date or other format const date = new Date(dateString); if (!isNaN(date.getTime())) { return date.toLocaleDateString('en-GB', { day: '2-digit', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit', hour12: false }).replace(',', ''); } return dateString; } catch (error) { console.log('Date formatting error:', error, 'for date:', dateString); return dateString; } }