File size: 4,535 Bytes
bbc658a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

// 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: 38 },
                { name: 'Scientific Research', value: 28 },
                { name: 'Business Strategy', value: 15 },
                { name: 'Creative Arts', value: 10 },
                { name: 'Technical Solutions', value: 7 },
                { name: 'Other', value: 2 }
            ],
            revenueOpportunities: [
                { name: 'AI Consulting Services', value: 1850000 },
                { name: 'Premium API Access', value: 1200000 },
                { name: 'Custom Model Training', value: 2200000 },
                { name: 'Enterprise Solutions', value: 3100000 }
            ]
};
}
}
// 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 = `
                <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);
        });
        
        // 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();
}