Some checks failed
Deploy to Test Environment / deploy-to-test (push) Failing after 46s
84 lines
3.0 KiB
TypeScript
84 lines
3.0 KiB
TypeScript
// src/pages/admin/AdminStatsPage.tsx
|
|
import React from 'react';
|
|
import { Link } from 'react-router-dom';
|
|
import { LoadingSpinner } from '../../components/LoadingSpinner';
|
|
import { useApplicationStatsQuery } from '../../hooks/queries/useApplicationStatsQuery';
|
|
import { ChartBarIcon } from '../../components/icons/ChartBarIcon';
|
|
import { UsersIcon } from '../../components/icons/UsersIcon';
|
|
import { DocumentDuplicateIcon } from '../../components/icons/DocumentDuplicateIcon';
|
|
import { BuildingStorefrontIcon } from '../../components/icons/BuildingStorefrontIcon';
|
|
import { BellAlertIcon } from '../../components/icons/BellAlertIcon';
|
|
import { BookOpenIcon } from '../../components/icons/BookOpenIcon';
|
|
import { StatCard } from '../../components/StatCard';
|
|
|
|
export const AdminStatsPage: React.FC = () => {
|
|
// Use TanStack Query for data fetching (ADR-0005 Phase 5)
|
|
const { data: stats, isLoading, error } = useApplicationStatsQuery();
|
|
|
|
return (
|
|
<div className="max-w-5xl mx-auto py-8 px-4">
|
|
<div className="mb-8">
|
|
<Link to="/admin" className="text-brand-primary hover:underline">
|
|
← Back to Admin Dashboard
|
|
</Link>
|
|
<h1 className="text-3xl font-bold text-gray-800 dark:text-white mt-2">
|
|
Application Statistics
|
|
</h1>
|
|
<p className="text-gray-500 dark:text-gray-400">
|
|
A high-level overview of key application metrics.
|
|
</p>
|
|
</div>
|
|
|
|
{isLoading && (
|
|
<div
|
|
role="status"
|
|
aria-label="Loading stats"
|
|
className="flex justify-center items-center h-64"
|
|
>
|
|
<LoadingSpinner />
|
|
</div>
|
|
)}
|
|
{error && (
|
|
<div className="text-red-500 bg-red-100 dark:bg-red-900/20 p-4 rounded-lg">
|
|
{error.message}
|
|
</div>
|
|
)}
|
|
|
|
{stats && !isLoading && !error && (
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
|
<StatCard
|
|
title="Total Users"
|
|
value={stats.userCount.toLocaleString()}
|
|
icon={<UsersIcon className="w-6 h-6" />}
|
|
/>
|
|
<StatCard
|
|
title="Flyers Processed"
|
|
value={stats.flyerCount.toLocaleString()}
|
|
icon={<DocumentDuplicateIcon className="w-6 h-6" />}
|
|
/>
|
|
<StatCard
|
|
title="Total Flyer Items"
|
|
value={stats.flyerItemCount.toLocaleString()}
|
|
icon={<ChartBarIcon className="w-6 h-6" />}
|
|
/>
|
|
<StatCard
|
|
title="Stores Tracked"
|
|
value={stats.storeCount.toLocaleString()}
|
|
icon={<BuildingStorefrontIcon className="w-6 h-6" />}
|
|
/>
|
|
<StatCard
|
|
title="Pending Corrections"
|
|
value={stats.pendingCorrectionCount.toLocaleString()}
|
|
icon={<BellAlertIcon className="w-6 h-6" />}
|
|
/>
|
|
<StatCard
|
|
title="Total Recipes"
|
|
value={stats.recipeCount.toLocaleString()}
|
|
icon={<BookOpenIcon className="w-6 h-6" />}
|
|
/>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|