140 lines
4.4 KiB
TypeScript
140 lines
4.4 KiB
TypeScript
'use client'
|
|
|
|
import { useState, useEffect } from 'react'
|
|
import { UserGrowthChart } from '@/components/charts/UserGrowthChart'
|
|
import { MembershipDistributionChart } from '@/components/charts/MembershipDistributionChart'
|
|
import { RevenueChart } from '@/components/charts/RevenueChart'
|
|
import { Card, CardHeader, CardContent } from '@/components/ui/Card'
|
|
|
|
interface ChartData {
|
|
label: string
|
|
value: number
|
|
color?: string
|
|
}
|
|
|
|
export function AnalyticsDashboard() {
|
|
const [userGrowthData, setUserGrowthData] = useState<ChartData[]>([])
|
|
const [membershipData, setMembershipData] = useState<ChartData[]>([])
|
|
const [revenueData, setRevenueData] = useState<ChartData[]>([])
|
|
const [loading, setLoading] = useState(true)
|
|
|
|
useEffect(() => {
|
|
fetchAnalyticsData()
|
|
}, [])
|
|
|
|
const fetchAnalyticsData = async () => {
|
|
setLoading(true)
|
|
try {
|
|
// Mock data for demonstration - replace with real API calls
|
|
const mockUserGrowth = [
|
|
{ label: 'Jan', value: 45 },
|
|
{ label: 'Feb', value: 52 },
|
|
{ label: 'Mar', value: 61 },
|
|
{ label: 'Apr', value: 58 },
|
|
{ label: 'May', value: 67 },
|
|
{ label: 'Jun', value: 74 },
|
|
]
|
|
|
|
const mockMembershipData = [
|
|
{ label: 'Basic', value: 45, color: '#6b7280' },
|
|
{ label: 'Premium', value: 28, color: '#3b82f6' },
|
|
{ label: 'VIP', value: 12, color: '#f59e0b' },
|
|
]
|
|
|
|
const mockRevenueData = [
|
|
{ label: 'Jan', value: 12500, color: '#10b981' },
|
|
{ label: 'Feb', value: 14200, color: '#10b981' },
|
|
{ label: 'Mar', value: 16800, color: '#10b981' },
|
|
{ label: 'Apr', value: 15900, color: '#10b981' },
|
|
{ label: 'May', value: 18200, color: '#10b981' },
|
|
{ label: 'Jun', value: 19400, color: '#10b981' },
|
|
]
|
|
|
|
setUserGrowthData(mockUserGrowth)
|
|
setMembershipData(mockMembershipData)
|
|
setRevenueData(mockRevenueData)
|
|
} catch (error) {
|
|
console.error('Failed to fetch analytics data:', error)
|
|
} finally {
|
|
setLoading(false)
|
|
}
|
|
}
|
|
|
|
const totalUsers = userGrowthData.length > 0 ? userGrowthData[userGrowthData.length - 1].value : 0
|
|
const totalRevenue = revenueData.reduce((sum, item) => sum + item.value, 0)
|
|
const activeMembers = membershipData.reduce((sum, item) => sum + item.value, 0)
|
|
|
|
if (loading) {
|
|
return (
|
|
<div className="flex justify-center items-center h-64">
|
|
<div className="text-lg">Loading analytics...</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
<h2 className="text-2xl font-bold">Analytics Dashboard</h2>
|
|
|
|
{/* Key Metrics */}
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
<Card>
|
|
<CardContent>
|
|
<div className="text-center">
|
|
<div className="text-3xl font-bold text-blue-600">{totalUsers}</div>
|
|
<div className="text-gray-600">Total Users</div>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Card>
|
|
<CardContent>
|
|
<div className="text-center">
|
|
<div className="text-3xl font-bold text-green-600">${totalRevenue.toLocaleString()}</div>
|
|
<div className="text-gray-600">Total Revenue</div>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Card>
|
|
<CardContent>
|
|
<div className="text-center">
|
|
<div className="text-3xl font-bold text-purple-600">{activeMembers}</div>
|
|
<div className="text-gray-600">Active Members</div>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
|
|
{/* Charts */}
|
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
|
<Card>
|
|
<CardHeader>
|
|
<h3 className="text-lg font-semibold">User Growth</h3>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<UserGrowthChart data={userGrowthData} />
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Card>
|
|
<CardHeader>
|
|
<h3 className="text-lg font-semibold">Membership Distribution</h3>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<MembershipDistributionChart data={membershipData} />
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
|
|
<Card>
|
|
<CardHeader>
|
|
<h3 className="text-lg font-semibold">Monthly Revenue</h3>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<RevenueChart data={revenueData} />
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
)
|
|
} |