Cloudtopiaa_Reseller_Frontend/src/pages/Analytics.tsx
2025-08-11 00:47:45 +05:30

359 lines
16 KiB
TypeScript

import React, { useState } from 'react';
import {
BarChart3,
TrendingUp,
Users,
DollarSign,
ShoppingCart,
Award,
Target,
Calendar,
Filter,
Download,
Eye,
EyeOff,
RefreshCw,
ArrowUp,
ArrowDown,
Activity,
PieChart,
LineChart,
BarChart,
AreaChart
} from 'lucide-react';
const Analytics: React.FC = () => {
const [dateRange, setDateRange] = useState('30d');
const [showDetailedMetrics, setShowDetailedMetrics] = useState(false);
// Mock data
const analyticsData = {
totalRevenue: 1250000,
totalResellers: 156,
activeResellers: 142,
totalDeals: 89,
conversionRate: 23.5,
averageDealSize: 14000,
monthlyGrowth: 12.8,
topPerformingResellers: [
{ name: 'John Smith', revenue: 89000, deals: 12, growth: 15.2 },
{ name: 'Sarah Johnson', revenue: 76000, deals: 9, growth: 8.7 },
{ name: 'Mike Davis', revenue: 68000, deals: 11, growth: 22.1 },
{ name: 'Lisa Wilson', revenue: 54000, deals: 7, growth: 5.3 },
{ name: 'David Brown', revenue: 48000, deals: 6, growth: 18.9 }
],
revenueByMonth: [
{ month: 'Jan', revenue: 85000, deals: 8 },
{ month: 'Feb', revenue: 92000, deals: 9 },
{ month: 'Mar', revenue: 78000, deals: 7 },
{ month: 'Apr', revenue: 105000, deals: 10 },
{ month: 'May', revenue: 118000, deals: 11 },
{ month: 'Jun', revenue: 125000, deals: 12 }
],
categoryPerformance: [
{ category: 'Cloud Services', revenue: 450000, percentage: 36 },
{ category: 'Security Solutions', revenue: 320000, percentage: 25.6 },
{ category: 'Data Analytics', revenue: 280000, percentage: 22.4 },
{ category: 'Consulting', revenue: 200000, percentage: 16 }
],
regionalPerformance: [
{ region: 'North America', revenue: 520000, growth: 15.2 },
{ region: 'Europe', revenue: 380000, growth: 8.7 },
{ region: 'Asia Pacific', revenue: 250000, growth: 22.1 },
{ region: 'Latin America', revenue: 100000, growth: 5.3 }
]
};
const getGrowthColor = (growth: number) => {
return growth >= 0 ? 'text-success-600 dark:text-success-400' : 'text-danger-600 dark:text-danger-400';
};
const getGrowthIcon = (growth: number) => {
return growth >= 0 ? <ArrowUp className="w-4 h-4" /> : <ArrowDown className="w-4 h-4" />;
};
return (
<div className="space-y-6">
{/* Header */}
<div className="flex flex-col sm:flex-row items-start sm:items-center justify-between space-y-4 sm:space-y-0">
<div className="flex items-center space-x-3">
<div className="p-2 bg-primary-100 dark:bg-primary-900 rounded-lg">
<BarChart3 className="w-6 h-6 text-primary-600 dark:text-primary-400" />
</div>
<div>
<h1 className="text-2xl sm:text-3xl font-bold text-secondary-900 dark:text-white">
Analytics Dashboard
</h1>
<p className="text-secondary-600 dark:text-secondary-400 mt-1">
Comprehensive insights into your business performance
</p>
</div>
</div>
<div className="flex items-center space-x-3">
<select
value={dateRange}
onChange={(e) => setDateRange(e.target.value)}
className="input text-sm"
>
<option value="7d">Last 7 days</option>
<option value="30d">Last 30 days</option>
<option value="90d">Last 90 days</option>
<option value="1y">Last year</option>
</select>
<button
onClick={() => setShowDetailedMetrics(!showDetailedMetrics)}
className="inline-flex items-center px-3 py-2 bg-secondary-100 dark:bg-secondary-800 text-secondary-700 dark:text-secondary-300 rounded-lg text-sm font-medium hover:bg-secondary-200 dark:hover:bg-secondary-700 transition-colors"
>
{showDetailedMetrics ? <EyeOff className="w-4 h-4 mr-2" /> : <Eye className="w-4 h-4 mr-2" />}
{showDetailedMetrics ? 'Hide Details' : 'Show Details'}
</button>
</div>
</div>
{/* Key Metrics */}
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
<div className="card p-6">
<div className="flex items-center justify-between">
<div>
<p className="text-sm font-medium text-secondary-600 dark:text-secondary-400">Total Revenue</p>
<p className="text-2xl font-bold text-secondary-900 dark:text-white">
${((Number(analyticsData.totalRevenue) || 0) / 1000).toFixed(0)}K
</p>
</div>
<div className="p-3 bg-primary-100 dark:bg-primary-900 rounded-lg">
<DollarSign className="w-6 h-6 text-primary-600 dark:text-primary-400" />
</div>
</div>
<div className="flex items-center mt-4">
<TrendingUp className="w-4 h-4 text-success-600 mr-1" />
<span className="text-sm text-success-600">+{analyticsData.monthlyGrowth}% from last month</span>
</div>
</div>
<div className="card p-6">
<div className="flex items-center justify-between">
<div>
<p className="text-sm font-medium text-secondary-600 dark:text-secondary-400">Active Resellers</p>
<p className="text-2xl font-bold text-secondary-900 dark:text-white">{analyticsData.activeResellers}</p>
</div>
<div className="p-3 bg-success-100 dark:bg-success-900 rounded-lg">
<Users className="w-6 h-6 text-success-600 dark:text-success-400" />
</div>
</div>
<div className="flex items-center mt-4">
<TrendingUp className="w-4 h-4 text-success-600 mr-1" />
<span className="text-sm text-success-600">+8% from last month</span>
</div>
</div>
<div className="card p-6">
<div className="flex items-center justify-between">
<div>
<p className="text-sm font-medium text-secondary-600 dark:text-secondary-400">Total Deals</p>
<p className="text-2xl font-bold text-secondary-900 dark:text-white">{analyticsData.totalDeals}</p>
</div>
<div className="p-3 bg-warning-100 dark:bg-warning-900 rounded-lg">
<ShoppingCart className="w-6 h-6 text-warning-600 dark:text-warning-400" />
</div>
</div>
<div className="flex items-center mt-4">
<TrendingUp className="w-4 h-4 text-success-600 mr-1" />
<span className="text-sm text-success-600">+15% from last month</span>
</div>
</div>
<div className="card p-6">
<div className="flex items-center justify-between">
<div>
<p className="text-sm font-medium text-secondary-600 dark:text-secondary-400">Conversion Rate</p>
<p className="text-2xl font-bold text-secondary-900 dark:text-white">{analyticsData.conversionRate}%</p>
</div>
<div className="p-3 bg-danger-100 dark:bg-danger-900 rounded-lg">
<Target className="w-6 h-6 text-danger-600 dark:text-danger-400" />
</div>
</div>
<div className="flex items-center mt-4">
<TrendingUp className="w-4 h-4 text-success-600 mr-1" />
<span className="text-sm text-success-600">+2.3% from last month</span>
</div>
</div>
</div>
{/* Charts Section */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
{/* Revenue Trend */}
<div className="card p-6">
<div className="flex items-center justify-between mb-6">
<h3 className="text-lg font-semibold text-secondary-900 dark:text-white">Revenue Trend</h3>
<button className="text-sm text-primary-600 hover:text-primary-700 dark:text-primary-400 dark:hover:text-primary-300">
View Details
</button>
</div>
<div className="h-64 bg-gray-50 dark:bg-gray-800 rounded-lg flex items-center justify-center">
<div className="text-center">
<LineChart className="w-16 h-16 text-secondary-400 mx-auto mb-4" />
<p className="text-secondary-600 dark:text-secondary-400">Revenue trend chart</p>
<p className="text-sm text-secondary-500">Monthly revenue progression</p>
</div>
</div>
<div className="mt-4 grid grid-cols-2 gap-4">
{analyticsData.revenueByMonth.slice(-4).map((item, index) => (
<div key={index} className="text-center">
<p className="text-sm text-secondary-600 dark:text-secondary-400">{item.month}</p>
<p className="font-semibold text-secondary-900 dark:text-white">${((Number(item.revenue) || 0) / 1000).toFixed(0)}K</p>
</div>
))}
</div>
</div>
{/* Category Performance */}
<div className="card p-6">
<div className="flex items-center justify-between mb-6">
<h3 className="text-lg font-semibold text-secondary-900 dark:text-white">Category Performance</h3>
<button className="text-sm text-primary-600 hover:text-primary-700 dark:text-primary-400 dark:hover:text-primary-300">
View Details
</button>
</div>
<div className="h-64 bg-gray-50 dark:bg-gray-800 rounded-lg flex items-center justify-center">
<div className="text-center">
<PieChart className="w-16 h-16 text-secondary-400 mx-auto mb-4" />
<p className="text-secondary-600 dark:text-secondary-400">Category distribution chart</p>
<p className="text-sm text-secondary-500">Revenue by product category</p>
</div>
</div>
<div className="mt-4 space-y-3">
{analyticsData.categoryPerformance.map((category, index) => (
<div key={index} className="flex items-center justify-between">
<span className="text-sm text-secondary-600 dark:text-secondary-400">{category.category}</span>
<div className="flex items-center space-x-2">
<div className="w-20 bg-gray-200 dark:bg-gray-700 rounded-full h-2">
<div
className="bg-primary-600 h-2 rounded-full"
style={{ width: `${category.percentage}%` }}
></div>
</div>
<span className="text-sm font-medium text-secondary-900 dark:text-white">{category.percentage}%</span>
</div>
</div>
))}
</div>
</div>
</div>
{/* Top Performing Resellers */}
<div className="card p-6">
<div className="flex items-center justify-between mb-6">
<h3 className="text-lg font-semibold text-secondary-900 dark:text-white">Top Performing Resellers</h3>
<button className="text-sm text-primary-600 hover:text-primary-700 dark:text-primary-400 dark:hover:text-primary-300">
View All
</button>
</div>
<div className="overflow-x-auto">
<table className="w-full">
<thead>
<tr className="border-b border-gray-200 dark:border-gray-700">
<th className="text-left py-3 px-4 text-sm font-medium text-secondary-600 dark:text-secondary-400">Reseller</th>
<th className="text-left py-3 px-4 text-sm font-medium text-secondary-600 dark:text-secondary-400">Revenue</th>
<th className="text-left py-3 px-4 text-sm font-medium text-secondary-600 dark:text-secondary-400">Deals</th>
<th className="text-left py-3 px-4 text-sm font-medium text-secondary-600 dark:text-secondary-400">Growth</th>
<th className="text-left py-3 px-4 text-sm font-medium text-secondary-600 dark:text-secondary-400">Status</th>
</tr>
</thead>
<tbody>
{analyticsData.topPerformingResellers.map((reseller, index) => (
<tr key={index} className="border-b border-gray-100 dark:border-gray-800">
<td className="py-3 px-4">
<div className="flex items-center space-x-3">
<div className="w-8 h-8 bg-primary-100 dark:bg-primary-900 rounded-full flex items-center justify-center">
<Users className="w-4 h-4 text-primary-600 dark:text-primary-400" />
</div>
<span className="text-sm font-medium text-secondary-900 dark:text-white">{reseller.name}</span>
</div>
</td>
<td className="py-3 px-4 text-sm text-secondary-900 dark:text-white">
${((Number(reseller.revenue) || 0) / 1000).toFixed(0)}K
</td>
<td className="py-3 px-4 text-sm text-secondary-600 dark:text-secondary-400">
{reseller.deals}
</td>
<td className="py-3 px-4">
<div className="flex items-center space-x-1">
{getGrowthIcon(reseller.growth)}
<span className={`text-sm ${getGrowthColor(reseller.growth)}`}>
{reseller.growth}%
</span>
</div>
</td>
<td className="py-3 px-4">
<span className="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-success-100 text-success-800 dark:bg-success-900 dark:text-success-300">
Active
</span>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
{/* Regional Performance */}
<div className="card p-6">
<h3 className="text-lg font-semibold text-secondary-900 dark:text-white mb-6">Regional Performance</h3>
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-6">
{analyticsData.regionalPerformance.map((region, index) => (
<div key={index} className="bg-gray-50 dark:bg-gray-800 rounded-lg p-4">
<div className="flex items-center justify-between mb-3">
<h4 className="font-medium text-secondary-900 dark:text-white">{region.region}</h4>
<div className="flex items-center space-x-1">
{getGrowthIcon(region.growth)}
<span className={`text-sm ${getGrowthColor(region.growth)}`}>
{region.growth}%
</span>
</div>
</div>
<p className="text-2xl font-bold text-secondary-900 dark:text-white">
${((Number(region.revenue) || 0) / 1000).toFixed(0)}K
</p>
<p className="text-sm text-secondary-600 dark:text-secondary-400 mt-1">Revenue</p>
</div>
))}
</div>
</div>
{/* Export Options */}
<div className="card p-6">
<div className="flex items-center justify-between">
<div>
<h3 className="text-lg font-semibold text-secondary-900 dark:text-white">Export Analytics</h3>
<p className="text-sm text-secondary-600 dark:text-secondary-400">Download analytics data in various formats</p>
</div>
<div className="flex items-center space-x-3">
<button
onClick={() => console.log('Exporting PDF...')}
className="inline-flex items-center px-4 py-2 bg-primary-600 text-white rounded-lg text-sm font-medium hover:bg-primary-700 transition-colors"
>
<Download className="w-4 h-4 mr-2" />
Export PDF
</button>
<button
onClick={() => console.log('Exporting Excel...')}
className="inline-flex items-center px-4 py-2 bg-success-600 text-white rounded-lg text-sm font-medium hover:bg-success-700 transition-colors"
>
<Download className="w-4 h-4 mr-2" />
Export Excel
</button>
<button
onClick={() => console.log('Exporting CSV...')}
className="inline-flex items-center px-4 py-2 bg-warning-600 text-white rounded-lg text-sm font-medium hover:bg-warning-700 transition-colors"
>
<Download className="w-4 h-4 mr-2" />
Export CSV
</button>
</div>
</div>
</div>
</div>
);
};
export default Analytics;