// Global utility functions // Toast notifications function showToast(message, type = 'info') { const container = document.getElementById('toast-container'); const toast = document.createElement('div'); const colors = { success: 'bg-green-500', error: 'bg-red-500', info: 'bg-primary', warning: 'bg-yellow-500' }; toast.className = `${colors[type]} text-white px-6 py-3 rounded-lg shadow-lg flex items-center gap-3 animate-slide-in`; toast.innerHTML = ` ${type === 'success' ? 'check_circle' : type === 'error' ? 'error' : 'info'} ${message} `; container.appendChild(toast); setTimeout(() => { toast.style.opacity = '0'; toast.style.transform = 'translateX(100%)'; setTimeout(() => toast.remove(), 300); }, 3000); } // Format currency function formatCurrency(amount, currency = 'USD') { const symbols = { 'USD': '$', 'EUR': '€', 'GBP': '£', 'RON': 'lei' }; const symbol = symbols[currency] || currency; const formatted = parseFloat(amount).toFixed(2); if (currency === 'RON') { return `${formatted} ${symbol}`; } return `${symbol}${formatted}`; } // Format date function formatDate(dateString) { const date = new Date(dateString); const now = new Date(); const diff = now - date; const days = Math.floor(diff / (1000 * 60 * 60 * 24)); if (days === 0) return 'Today'; if (days === 1) return 'Yesterday'; if (days < 7) return `${days} days ago`; return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }); } // API helper async function apiCall(url, options = {}) { try { const response = await fetch(url, { ...options, headers: { ...options.headers, 'Content-Type': options.body instanceof FormData ? undefined : 'application/json', } }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return await response.json(); } catch (error) { console.error('API call failed:', error); showToast('An error occurred. Please try again.', 'error'); throw error; } } // Theme management function initTheme() { // Check for saved theme preference or default to system preference const savedTheme = localStorage.getItem('theme'); const systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; if (savedTheme === 'dark' || (!savedTheme && systemPrefersDark)) { document.documentElement.classList.add('dark'); updateThemeUI(true); } else { document.documentElement.classList.remove('dark'); updateThemeUI(false); } } function toggleTheme() { const isDark = document.documentElement.classList.contains('dark'); if (isDark) { document.documentElement.classList.remove('dark'); localStorage.setItem('theme', 'light'); updateThemeUI(false); } else { document.documentElement.classList.add('dark'); localStorage.setItem('theme', 'dark'); updateThemeUI(true); } // Dispatch custom event for other components to react to theme change window.dispatchEvent(new CustomEvent('theme-changed', { detail: { isDark: !isDark } })); } function updateThemeUI(isDark) { const themeIcon = document.getElementById('theme-icon'); const themeText = document.getElementById('theme-text'); if (themeIcon && themeText) { if (isDark) { themeIcon.textContent = 'dark_mode'; themeText.textContent = 'Dark Mode'; } else { themeIcon.textContent = 'light_mode'; themeText.textContent = 'Light Mode'; } } } // Mobile menu toggle document.addEventListener('DOMContentLoaded', () => { // Initialize theme initTheme(); // Theme toggle button const themeToggle = document.getElementById('theme-toggle'); if (themeToggle) { themeToggle.addEventListener('click', toggleTheme); } // Mobile menu const menuToggle = document.getElementById('menu-toggle'); const sidebar = document.getElementById('sidebar'); if (menuToggle && sidebar) { menuToggle.addEventListener('click', () => { sidebar.classList.toggle('hidden'); sidebar.classList.toggle('flex'); sidebar.classList.toggle('absolute'); sidebar.classList.toggle('z-50'); sidebar.style.left = '0'; }); // Close sidebar when clicking outside on mobile document.addEventListener('click', (e) => { if (window.innerWidth < 1024) { if (!sidebar.contains(e.target) && !menuToggle.contains(e.target)) { sidebar.classList.add('hidden'); sidebar.classList.remove('flex'); } } }); } });