import { useState } from 'react';
import { useQuery } from '@tanstack/react-query';
import { analyticsApi } from '../api/client';
import { AlertCircle, Database } from 'lucide-react';
import { PieChart, Pie, Cell, BarChart, Bar, LineChart, Line, XAxis, YAxis, Tooltip, ResponsiveContainer, Legend } from 'recharts';
import { useChartTheme } from '../context/useChartTheme';
const COLORS = ['#6366f1', '#0ea5e9', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6', '#ec4899', '#14b8a6'];
export function AnalyticsPage() {
const [days, setDays] = useState(30);
const chartTheme = useChartTheme();
const { data, isLoading, isError, refetch } = useQuery({
queryKey: ['analytics', days],
queryFn: () => analyticsApi.getAnalytics(days),
});
const trendsQuery = useQuery({
queryKey: ['analytics-trends', days],
queryFn: () => analyticsApi.getTrends(days),
});
if (isLoading) {
return (
Analytics Dashboard
Loading analytics data...
{/* Skeleton cards */}
{[1, 2, 3].map((i) => (
))}
{/* Skeleton charts */}
);
}
if (isError) {
return (
Analytics Dashboard
Unable to Load Analytics
Could not connect to the analytics database. Ensure PostgreSQL is running and
DATABASE_URL is configured correctly.
);
}
if (!data || (data.total_messages === 0 && data.by_company.length === 0)) {
return (
Analytics Dashboard
Track historical analysis data and view insights.
No analytics data available yet. Run some analyses first!
);
}
const companyData = data.by_company.map((c) => ({
name: (c.company_name || 'Unknown').toUpperCase(),
value: c.count,
}));
const typeData = data.by_type.map((t) => ({
name: t.analysis_type || 'Unknown',
count: t.count,
}));
return (
{/* Header */}
Analytics Dashboard
Track historical analysis data and view insights.
{/* Time Range Selector */}
{/* Summary Metrics */}
{/* Charts */}
{/* Pie Chart - Distribution by Company */}
{companyData.length > 0 && (
Distribution by Company
`${name} ${(percent * 100).toFixed(0)}%`}
labelLine={false}
>
{companyData.map((_, index) => (
|
))}
)}
{/* Bar Chart - Analysis Types */}
{typeData.length > 0 && (
Analysis Types
)}
{/* Trend Charts */}
{trendsQuery.data && (
Trends Over Time
{/* Patent count over time per company (line chart) */}
{trendsQuery.data.by_month.length > 0 && (() => {
// Pivot data: each month as a row, companies as columns
const companies = [...new Set(trendsQuery.data!.by_month.map(d => d.company_name))];
const months = [...new Set(trendsQuery.data!.by_month.map(d => d.month))].sort();
const pivoted = months.map(month => {
const row: Record
= { month };
for (const c of companies) {
const entry = trendsQuery.data!.by_month.find(d => d.month === month && d.company_name === c);
row[c] = entry?.count || 0;
}
return row;
});
return (
Analyses per Company Over Time
{companies.map((company, idx) => (
))}
);
})()}
{/* Analysis type distribution over time (stacked bar) */}
{trendsQuery.data.by_type_over_time.length > 0 && (() => {
const types = [...new Set(trendsQuery.data!.by_type_over_time.map(d => d.analysis_type))];
const months = [...new Set(trendsQuery.data!.by_type_over_time.map(d => d.month))].sort();
const pivoted = months.map(month => {
const row: Record = { month };
for (const t of types) {
const entry = trendsQuery.data!.by_type_over_time.find(d => d.month === month && d.analysis_type === t);
row[t] = entry?.count || 0;
}
return row;
});
return (
Analysis Types Over Time
{types.map((type, idx) => (
))}
);
})()}
{trendsQuery.data.by_month.length === 0 && (
No trend data available yet. Run analyses over multiple days to see trends.
)}
)}
);
}
function MetricCard({ label, value }: { label: string; value: number }) {
return (
);
}