// Shared functionality document.addEventListener('DOMContentLoaded', async () => { // Fetch real data from API const timeframe = document.querySelector('select').value; const data = await fetchDashboardData(timeframe); updateDashboard(data); // Initialize tooltips const tooltips = document.querySelectorAll('[data-tooltip]'); tooltips.forEach(tooltip => { tooltip.addEventListener('mouseenter', () => { const tooltipText = tooltip.getAttribute('data-tooltip'); const tooltipElement = document.createElement('div'); tooltipElement.className = 'tooltip-element absolute bg-gray-900 text-white text-sm px-2 py-1 rounded'; tooltipElement.textContent = tooltipText; tooltip.appendChild(tooltipElement); setTimeout(() => { tooltipElement.classList.add('opacity-0'); setTimeout(() => tooltipElement.remove(), 300); }, 2000); }); }); // Smooth scrolling for anchor links document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { e.preventDefault(); document.querySelector(this.getAttribute('href')).scrollIntoView({ behavior: 'smooth' }); }); }); }); // Data fetching functions async function fetchDashboardData(timeframe = '30d') { try { const response = await fetch(`/api/dashboard?timeframe=${timeframe}`); if (!response.ok) throw new Error('Network response was not ok'); return await response.json(); } catch (error) { console.error('Error fetching dashboard data:', error); console.error('Error fetching dashboard data:', error); // Fallback to mock data if API fails return { topCategories: [ { name: 'AI Development', value: 32 }, { name: 'Scientific Research', value: 24 }, { name: 'Business Strategy', value: 18 }, { name: 'Creative Arts', value: 12 }, { name: 'Technical Solutions', value: 9 }, { name: 'Other', value: 5 } ], revenueOpportunities: [ { name: 'AI Consulting Services', value: 1200000 }, { name: 'Premium API Access', value: 850000 }, { name: 'Custom Model Training', value: 1800000 }, { name: 'Enterprise Solutions', value: 2500000 } ] }; } } // Update dashboard with live data function updateDashboard(data) { // Update top categories chart const topPieChart = Chart.getChart('topPieChart'); topPieChart.data.datasets[0].data = data.topCategories.map(c => c.value); topPieChart.update(); // Update revenue opportunities const revenueContainer = document.querySelector('.grid-cols-4'); if (revenueContainer && data.revenueOpportunities) { // Clear existing metrics revenueContainer.innerHTML = ''; // Add new metrics data.revenueOpportunities.forEach(opp => { const metricCard = document.createElement('div'); metricCard.className = 'bg-white p-6 rounded-xl shadow-sm border border-gray-100'; metricCard.innerHTML = `
${opp.name}
Potential revenue
`; revenueContainer.appendChild(metricCard); }); // Refresh feather icons feather.replace(); } } // Utility function to format numbers function formatNumber(num, decimals = 1) { if (num >= 1000000000) { return (num / 1000000000).toFixed(1) + 'B'; } if (num >= 1000000) { return (num / 1000000).toFixed(1) + 'M'; } if (num >= 1000) { return (num / 1000).toFixed(1) + 'K'; } return num.toString(); }