import { useQuery } from '@tanstack/react-query';
import { useAuth } from '../context/AuthContext';
import { issues, reports } from '../services/api';
import { AreaChart, Area, BarChart, Bar, PieChart, Pie, Cell, XAxis, YAxis, Tooltip, ResponsiveContainer, CartesianGrid } from 'recharts';
import { TicketCheck, CheckCircle2, GitPullRequest, Target, TrendingUp, TrendingDown, ArrowUpRight, Clock, AlertCircle, Building2 } from 'lucide-react';
import { cn } from '../lib/utils';
const CHART_COLORS = ['#6366f1', '#22c55e', '#f59e0b', '#ef4444', '#8b5cf6', '#06b6d4'];
const StatSkeleton = () => (
);
const ChartSkeleton = () => (
);
const CustomTooltip = ({ active, payload, label }) => {
if (!active || !payload) return null;
return (
{label}
{payload.map((item, i) => (
{item.name}: {item.value}
))}
);
};
export default function Dashboard() {
const { currentOrg } = useAuth();
const { data: stats, isLoading: statsLoading } = useQuery({
queryKey: ['issues-stats', currentOrg?.id],
queryFn: () => issues.stats(currentOrg.id),
enabled: !!currentOrg
});
const { data: report, isLoading: reportLoading } = useQuery({
queryKey: ['report-summary', currentOrg?.id],
queryFn: () => reports.summary(currentOrg.id, 14),
enabled: !!currentOrg
});
if (!currentOrg) {
return (
Select an organization
Choose an organization from the sidebar to view your dashboard and manage issues.
);
}
const s = stats?.data || {};
const r = report?.data || {};
const loading = statsLoading || reportLoading;
const statCards = [
{ label: 'Total Issues', value: s.total || 0, icon: TicketCheck, color: 'text-blue-400', bg: 'bg-blue-500/10', trend: '+12%', up: true },
{ label: 'Analyzed', value: s.analyzed || 0, icon: CheckCircle2, color: 'text-emerald-400', bg: 'bg-emerald-500/10', trend: '+8%', up: true },
{ label: 'PRs Created', value: s.pr_created || 0, icon: GitPullRequest, color: 'text-purple-400', bg: 'bg-purple-500/10', trend: '+15%', up: true },
{ label: 'Avg Confidence', value: s.avg_confidence ? `${(s.avg_confidence * 100).toFixed(0)}%` : 'N/A', icon: Target, color: 'text-amber-400', bg: 'bg-amber-500/10', trend: '+3%', up: true },
];
const statusData = [
{ name: 'Pending', value: s.pending || 0 },
{ name: 'Analyzing', value: s.analyzing || 0 },
{ name: 'Analyzed', value: s.analyzed || 0 },
{ name: 'PR Created', value: s.pr_created || 0 },
{ name: 'Error', value: s.error || 0 }
].filter(d => d.value > 0);
const sourceData = Object.entries(s.by_source || {}).map(([name, value]) => ({
name: name.replace('_', ' ').replace(/\b\w/g, l => l.toUpperCase()),
value
}));
return (
Dashboard
Overview of your issue analysis pipeline
System operational
{/* Stats */}
{loading ? (
Array(4).fill(0).map((_, i) =>
)
) : (
statCards.map(stat => {
const Icon = stat.icon;
return (
{stat.label}
{stat.value}
{stat.up ? : }
{stat.trend}
vs last week
);
})
)}
{/* Charts row */}
{loading ? (
<>
>
) : (
<>
{/* Trend chart */}
Issues Trend
Last 14 days
{/* Status distribution */}
Status Distribution
{statusData.length > 0 ? (
`${name} ${(percent * 100).toFixed(0)}%`}
>
{statusData.map((entry, index) => (
|
))}
} />
) : (
)}
>
)}
{/* By source */}
{loading ? (
) : (
Issues by Source
{sourceData.length > 0 ? (
} />
) : (
No data yet
Connect an integration to start tracking
)}
)}
);
}