Enhance admin stats dashboard

Add data quality metrics, growth trends visualization, entity comparison views, and automated health checks to the AdminDatabaseStats dashboard, including new TS types, hooks, UI components, and integrated tabbed layout.
This commit is contained in:
gpt-engineer-app[bot]
2025-11-11 17:11:11 +00:00
parent f036776dce
commit 947964482f
14 changed files with 1579 additions and 88 deletions

View File

@@ -1,11 +1,16 @@
import { Building2, Bike, Factory, Users, FileText, TrendingUp, Box, MapPin, Calendar, Image as ImageIcon } from 'lucide-react';
import { Building2, Bike, Factory, Users, FileText, TrendingUp, Box, Image as ImageIcon, Activity, BarChart3, Shield } from 'lucide-react';
import { AdminLayout } from '@/components/layout/AdminLayout';
import { useAdminGuard } from '@/hooks/useAdminGuard';
import { DatabaseStatsCard } from '@/components/admin/database-stats/DatabaseStatsCard';
import { RecentAdditionsTable } from '@/components/admin/database-stats/RecentAdditionsTable';
import { DataQualityOverview } from '@/components/admin/database-stats/DataQualityOverview';
import { GrowthTrendsChart } from '@/components/admin/database-stats/GrowthTrendsChart';
import { EntityComparisonDashboard } from '@/components/admin/database-stats/EntityComparisonDashboard';
import { DatabaseHealthDashboard } from '@/components/admin/database-stats/DatabaseHealthDashboard';
import { useAdminDatabaseStats } from '@/hooks/useAdminDatabaseStats';
import { useRecentAdditions } from '@/hooks/useRecentAdditions';
import { Alert, AlertDescription } from '@/components/ui/alert';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { AlertCircle } from 'lucide-react';
export default function AdminDatabaseStats() {
@@ -58,103 +63,166 @@ export default function AdminDatabaseStats() {
<div>
<h1 className="text-3xl font-bold tracking-tight">Database Statistics</h1>
<p className="text-muted-foreground mt-2">
Complete overview of database content and activity
Comprehensive analytics, quality metrics, and health monitoring
</p>
</div>
{/* Stats Grid */}
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
<DatabaseStatsCard
title="Total Entities"
icon={Box}
iconClassName="text-blue-500"
stats={[
{ label: 'All Entities', value: totalEntities },
{ label: 'Parks', value: stats?.parks.total || 0 },
{ label: 'Rides', value: stats?.rides.total || 0 },
{ label: 'Companies', value: stats?.companies.total || 0 },
{ label: 'Ride Models', value: stats?.ride_models.total || 0 },
]}
/>
<Tabs defaultValue="overview" className="space-y-6">
<TabsList className="grid w-full grid-cols-5">
<TabsTrigger value="overview" className="flex items-center gap-2">
<Box className="h-4 w-4" />
Overview
</TabsTrigger>
<TabsTrigger value="growth" className="flex items-center gap-2">
<TrendingUp className="h-4 w-4" />
Growth Trends
</TabsTrigger>
<TabsTrigger value="comparisons" className="flex items-center gap-2">
<BarChart3 className="h-4 w-4" />
Comparisons
</TabsTrigger>
<TabsTrigger value="quality" className="flex items-center gap-2">
<Activity className="h-4 w-4" />
Data Quality
</TabsTrigger>
<TabsTrigger value="health" className="flex items-center gap-2">
<Shield className="h-4 w-4" />
Health Checks
</TabsTrigger>
</TabsList>
<DatabaseStatsCard
title="Recent Activity"
icon={TrendingUp}
iconClassName="text-green-500"
stats={[
{
label: 'Added (7 days)',
value: recentAdditions7d,
},
{
label: 'Added (30 days)',
value: recentAdditions30d,
},
]}
/>
{/* Overview Tab */}
<TabsContent value="overview" className="space-y-6">
{/* Stats Grid */}
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
<DatabaseStatsCard
title="Total Entities"
icon={Box}
iconClassName="text-blue-500"
stats={[
{ label: 'All Entities', value: totalEntities },
{ label: 'Parks', value: stats?.parks.total || 0 },
{ label: 'Rides', value: stats?.rides.total || 0 },
{ label: 'Companies', value: stats?.companies.total || 0 },
{ label: 'Ride Models', value: stats?.ride_models.total || 0 },
]}
/>
<DatabaseStatsCard
title="Parks & Rides"
icon={Building2}
iconClassName="text-purple-500"
stats={[
{ label: 'Active Parks', value: stats?.parks.active || 0 },
{ label: 'Historical Parks', value: stats?.parks.historical || 0 },
{ label: 'Active Rides', value: stats?.rides.active || 0 },
{ label: 'Historical Rides', value: stats?.rides.historical || 0 },
]}
/>
<DatabaseStatsCard
title="Recent Activity"
icon={TrendingUp}
iconClassName="text-green-500"
stats={[
{
label: 'Added (7 days)',
value: recentAdditions7d,
},
{
label: 'Added (30 days)',
value: recentAdditions30d,
},
]}
/>
<DatabaseStatsCard
title="Content"
icon={ImageIcon}
iconClassName="text-orange-500"
stats={[
{ label: 'Photos', value: stats?.photos.total || 0 },
{ label: 'Locations', value: stats?.locations.total || 0 },
{ label: 'Timeline Events', value: stats?.timeline_events.total || 0 },
]}
/>
<DatabaseStatsCard
title="Parks & Rides"
icon={Building2}
iconClassName="text-purple-500"
stats={[
{ label: 'Active Parks', value: stats?.parks.active || 0 },
{ label: 'Historical Parks', value: stats?.parks.historical || 0 },
{ label: 'Active Rides', value: stats?.rides.active || 0 },
{ label: 'Historical Rides', value: stats?.rides.historical || 0 },
]}
/>
<DatabaseStatsCard
title="Companies"
icon={Factory}
iconClassName="text-amber-500"
stats={[
{ label: 'Total', value: stats?.companies.total || 0 },
{ label: 'Manufacturers', value: stats?.companies.manufacturers || 0 },
{ label: 'Operators', value: stats?.companies.operators || 0 },
{ label: 'Designers', value: stats?.companies.designers || 0 },
]}
/>
<DatabaseStatsCard
title="Content"
icon={ImageIcon}
iconClassName="text-orange-500"
stats={[
{ label: 'Photos', value: stats?.photos.total || 0 },
{ label: 'Locations', value: stats?.locations.total || 0 },
{ label: 'Timeline Events', value: stats?.timeline_events.total || 0 },
]}
/>
<DatabaseStatsCard
title="User Activity"
icon={Users}
iconClassName="text-teal-500"
stats={[
{ label: 'Total Users', value: stats?.users.total || 0 },
{ label: 'Active (30 days)', value: stats?.users.active_30d || 0 },
]}
/>
<DatabaseStatsCard
title="Companies"
icon={Factory}
iconClassName="text-amber-500"
stats={[
{ label: 'Total', value: stats?.companies.total || 0 },
{ label: 'Manufacturers', value: stats?.companies.manufacturers || 0 },
{ label: 'Operators', value: stats?.companies.operators || 0 },
{ label: 'Designers', value: stats?.companies.designers || 0 },
]}
/>
<DatabaseStatsCard
title="Submissions"
icon={FileText}
iconClassName="text-pink-500"
stats={[
{ label: 'Pending', value: stats?.submissions.pending || 0 },
{ label: 'Approved', value: stats?.submissions.approved || 0 },
{ label: 'Rejected', value: stats?.submissions.rejected || 0 },
]}
/>
</div>
<DatabaseStatsCard
title="User Activity"
icon={Users}
iconClassName="text-teal-500"
stats={[
{ label: 'Total Users', value: stats?.users.total || 0 },
{ label: 'Active (30 days)', value: stats?.users.active_30d || 0 },
]}
/>
{/* Recent Additions Table */}
<RecentAdditionsTable
additions={recentAdditions || []}
isLoading={additionsLoading}
/>
<DatabaseStatsCard
title="Submissions"
icon={FileText}
iconClassName="text-pink-500"
stats={[
{ label: 'Pending', value: stats?.submissions.pending || 0 },
{ label: 'Approved', value: stats?.submissions.approved || 0 },
{ label: 'Rejected', value: stats?.submissions.rejected || 0 },
]}
/>
</div>
{/* Data Quality Overview */}
<DataQualityOverview />
{/* Recent Additions Table */}
<RecentAdditionsTable
additions={recentAdditions || []}
isLoading={additionsLoading}
/>
</TabsContent>
{/* Growth Trends Tab */}
<TabsContent value="growth" className="space-y-6">
<GrowthTrendsChart />
</TabsContent>
{/* Entity Comparisons Tab */}
<TabsContent value="comparisons" className="space-y-6">
<EntityComparisonDashboard />
</TabsContent>
{/* Data Quality Tab */}
<TabsContent value="quality" className="space-y-6">
<DataQualityOverview />
<div className="p-6 border rounded-lg bg-muted/50">
<h3 className="text-lg font-semibold mb-2">Full Data Completeness Dashboard</h3>
<p className="text-sm text-muted-foreground mb-4">
For detailed analysis of data completeness by entity, missing fields, and improvement opportunities.
</p>
<a
href="/admin/data-completeness"
className="inline-flex items-center gap-2 text-primary hover:underline"
>
View Full Dashboard
</a>
</div>
</TabsContent>
{/* Database Health Tab */}
<TabsContent value="health" className="space-y-6">
<DatabaseHealthDashboard />
</TabsContent>
</Tabs>
</div>
</AdminLayout>
);