sto-k-odnomu/admin/src/pages/DashboardPage.tsx
2026-01-07 16:24:30 +03:00

166 lines
6.3 KiB
TypeScript

import { useQuery } from '@tanstack/react-query'
import { Users, Package, TrendingUp, Activity } from 'lucide-react'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { analyticsApi, type DashboardStats } from '@/api/analytics'
import { useAuthStore } from '@/stores/authStore'
export default function DashboardPage() {
const { isAuthenticated, token } = useAuthStore()
// Only make requests if authenticated and token exists
const isReady = isAuthenticated && !!token && !!localStorage.getItem('admin_token')
const { data: dashboardData, isLoading: dashboardLoading } = useQuery<DashboardStats>({
queryKey: ['dashboard'],
queryFn: analyticsApi.getDashboard,
enabled: isReady,
})
if (dashboardLoading) {
return (
<div className="space-y-6">
<div>
<h1 className="text-3xl font-bold tracking-tight">Dashboard</h1>
<p className="text-muted-foreground">
Welcome to Sto k Odnomu Admin Panel
</p>
</div>
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
{[...Array(4)].map((_, i) => (
<Card key={i}>
<CardContent className="pt-6">
<div className="animate-pulse">
<div className="h-4 bg-gray-200 rounded w-3/4 mb-2"></div>
<div className="h-8 bg-gray-200 rounded w-1/2"></div>
</div>
</CardContent>
</Card>
))}
</div>
</div>
)
}
return (
<div className="space-y-6">
<div>
<h1 className="text-3xl font-bold tracking-tight">Dashboard</h1>
<p className="text-muted-foreground">
Welcome to Sto k Odnomu Admin Panel
</p>
</div>
{/* Stats Cards */}
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Total Users</CardTitle>
<Users className="h-4 w-4 text-muted-foreground" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">{dashboardData?.users || 0}</div>
<p className="text-xs text-muted-foreground">
Registered users
</p>
</CardContent>
</Card>
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Active Users</CardTitle>
<Activity className="h-4 w-4 text-muted-foreground" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">{dashboardData?.activeUsers || 0}</div>
<p className="text-xs text-muted-foreground">
Active in last 7 days
</p>
</CardContent>
</Card>
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Question Packs</CardTitle>
<Package className="h-4 w-4 text-muted-foreground" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">{dashboardData?.publicPacks || 0}</div>
<p className="text-xs text-muted-foreground">
of {dashboardData?.questionPacks || 0} total packs
</p>
</CardContent>
</Card>
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Games Today</CardTitle>
<TrendingUp className="h-4 w-4 text-muted-foreground" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">{dashboardData?.gamesToday || 0}</div>
<p className="text-xs text-muted-foreground">
of {dashboardData?.gamesPlayed || 0} total games
</p>
</CardContent>
</Card>
</div>
{/* Rooms Stats */}
<div className="grid gap-4 md:grid-cols-2">
<Card>
<CardHeader>
<CardTitle>Room Statistics</CardTitle>
<CardDescription>
Current room status overview
</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-4">
<div className="flex items-center justify-between">
<div>
<p className="font-medium">Total Rooms</p>
<p className="text-sm text-muted-foreground">All time</p>
</div>
<div className="text-2xl font-bold">{dashboardData?.rooms || 0}</div>
</div>
<div className="flex items-center justify-between">
<div>
<p className="font-medium">Active Rooms</p>
<p className="text-sm text-muted-foreground">Currently playing or waiting</p>
</div>
<div className="text-2xl font-bold text-green-600">{dashboardData?.activeRooms || 0}</div>
</div>
</div>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>Game Statistics</CardTitle>
<CardDescription>
Overall game activity
</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-4">
<div className="flex items-center justify-between">
<div>
<p className="font-medium">Total Games</p>
<p className="text-sm text-muted-foreground">All time completed games</p>
</div>
<div className="text-2xl font-bold">{dashboardData?.gamesPlayed || 0}</div>
</div>
<div className="flex items-center justify-between">
<div>
<p className="font-medium">Today's Games</p>
<p className="text-sm text-muted-foreground">Completed today</p>
</div>
<div className="text-2xl font-bold text-blue-600">{dashboardData?.gamesToday || 0}</div>
</div>
</div>
</CardContent>
</Card>
</div>
</div>
)
}