| |
|
| | |
| | document.addEventListener('DOMContentLoaded', async () => { |
| | |
| | const timeframe = document.querySelector('select').value; |
| | const data = await fetchDashboardData(timeframe); |
| | updateDashboard(data); |
| | |
| | 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); |
| | }); |
| | }); |
| | |
| | |
| | document.querySelectorAll('a[href^="#"]').forEach(anchor => { |
| | anchor.addEventListener('click', function (e) { |
| | e.preventDefault(); |
| | document.querySelector(this.getAttribute('href')).scrollIntoView({ |
| | behavior: 'smooth' |
| | }); |
| | }); |
| | }); |
| | }); |
| | |
| | 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); |
| | |
| | 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 } |
| | ] |
| | }; |
| | } |
| | } |
| | |
| | function updateDashboard(data) { |
| | |
| | const topPieChart = Chart.getChart('topPieChart'); |
| | topPieChart.data.datasets[0].data = data.topCategories.map(c => c.value); |
| | topPieChart.update(); |
| | |
| | |
| | const revenueContainer = document.querySelector('.grid-cols-4'); |
| | if (revenueContainer && data.revenueOpportunities) { |
| | |
| | revenueContainer.innerHTML = ''; |
| | |
| | |
| | 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 = ` |
| | <div class="flex justify-between items-start"> |
| | <div> |
| | <p class="text-gray-500">${opp.name}</p> |
| | <h3 class="text-2xl font-bold text-gray-800 mt-1">${formatNumber(opp.value)}</h3> |
| | </div> |
| | <div class="bg-indigo-100 p-2 rounded-lg"> |
| | <i data-feather="dollar-sign" class="text-indigo-600 w-5 h-5"></i> |
| | </div> |
| | </div> |
| | <p class="text-green-500 text-sm mt-2 flex items-center"> |
| | <i data-feather="trending-up" class="w-4 h-4 mr-1"></i> |
| | Potential revenue |
| | </p> |
| | `; |
| | revenueContainer.appendChild(metricCard); |
| | }); |
| | |
| | |
| | feather.replace(); |
| | } |
| | } |
| |
|
| | |
| | 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(); |
| | } |