2026-01-30 13:41:32 +01:00
|
|
|
'use client'
|
Observer platform overhaul: Nivo charts, round-type stats, UX improvements
Phase 1: Fix 6 backend data bugs in analytics.ts (roundName filtering,
unscored projects, criteria scores, activeRoundCount scoping, email
privacy leaks in juror consistency + workload)
Phase 2-3: Migrate all 9 chart components from Recharts to Nivo
(@nivo/bar, @nivo/line, @nivo/pie, @nivo/scatterplot) with shared brand
theme, scoreGradient colors, and STATUS_COLORS map. Fixes scatter plot
outlier coloring and pie chart label visibility bugs.
Phase 4: Add round-type-aware stats (getRoundTypeStats backend +
RoundTypeStatsCards component) showing appropriate metrics per round
type (intake/filtering/evaluation/submission/mentoring/live/deliberation).
Phase 5: UX improvements — Stage→Round terminology, clickable dashboard
round links, URL-based round selection (?round=), round type indicators
in selectors, accessible Toggle-based cross-round comparison, sortable
project table columns (title/score/evaluations), brand score colors on
dashboard bar chart with aria labels.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 21:44:38 +01:00
|
|
|
|
|
|
|
|
import { ResponsivePie } from '@nivo/pie'
|
2026-01-30 13:41:32 +01:00
|
|
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
Observer platform overhaul: Nivo charts, round-type stats, UX improvements
Phase 1: Fix 6 backend data bugs in analytics.ts (roundName filtering,
unscored projects, criteria scores, activeRoundCount scoping, email
privacy leaks in juror consistency + workload)
Phase 2-3: Migrate all 9 chart components from Recharts to Nivo
(@nivo/bar, @nivo/line, @nivo/pie, @nivo/scatterplot) with shared brand
theme, scoreGradient colors, and STATUS_COLORS map. Fixes scatter plot
outlier coloring and pie chart label visibility bugs.
Phase 4: Add round-type-aware stats (getRoundTypeStats backend +
RoundTypeStatsCards component) showing appropriate metrics per round
type (intake/filtering/evaluation/submission/mentoring/live/deliberation).
Phase 5: UX improvements — Stage→Round terminology, clickable dashboard
round links, URL-based round selection (?round=), round type indicators
in selectors, accessible Toggle-based cross-round comparison, sortable
project table columns (title/score/evaluations), brand score colors on
dashboard bar chart with aria labels.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 21:44:38 +01:00
|
|
|
import { nivoTheme, getStatusColor, formatStatus } from './chart-theme'
|
2026-01-30 13:41:32 +01:00
|
|
|
|
|
|
|
|
interface StatusDataPoint {
|
|
|
|
|
status: string
|
|
|
|
|
count: number
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface StatusBreakdownProps {
|
|
|
|
|
data: StatusDataPoint[]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function StatusBreakdownChart({ data }: StatusBreakdownProps) {
|
2026-02-20 13:42:31 +01:00
|
|
|
if (!data?.length) return null
|
|
|
|
|
|
2026-01-30 13:41:32 +01:00
|
|
|
const total = data.reduce((sum, item) => sum + item.count, 0)
|
|
|
|
|
|
Observer platform overhaul: Nivo charts, round-type stats, UX improvements
Phase 1: Fix 6 backend data bugs in analytics.ts (roundName filtering,
unscored projects, criteria scores, activeRoundCount scoping, email
privacy leaks in juror consistency + workload)
Phase 2-3: Migrate all 9 chart components from Recharts to Nivo
(@nivo/bar, @nivo/line, @nivo/pie, @nivo/scatterplot) with shared brand
theme, scoreGradient colors, and STATUS_COLORS map. Fixes scatter plot
outlier coloring and pie chart label visibility bugs.
Phase 4: Add round-type-aware stats (getRoundTypeStats backend +
RoundTypeStatsCards component) showing appropriate metrics per round
type (intake/filtering/evaluation/submission/mentoring/live/deliberation).
Phase 5: UX improvements — Stage→Round terminology, clickable dashboard
round links, URL-based round selection (?round=), round type indicators
in selectors, accessible Toggle-based cross-round comparison, sortable
project table columns (title/score/evaluations), brand score colors on
dashboard bar chart with aria labels.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 21:44:38 +01:00
|
|
|
const pieData = data.map((d) => ({
|
|
|
|
|
id: d.status,
|
|
|
|
|
label: formatStatus(d.status),
|
|
|
|
|
value: d.count,
|
|
|
|
|
color: getStatusColor(d.status),
|
2026-01-30 13:41:32 +01:00
|
|
|
}))
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Card>
|
|
|
|
|
<CardHeader>
|
|
|
|
|
<CardTitle className="flex items-center justify-between">
|
|
|
|
|
<span>Project Status Distribution</span>
|
|
|
|
|
<span className="text-sm font-normal text-muted-foreground">
|
|
|
|
|
{total} projects
|
|
|
|
|
</span>
|
|
|
|
|
</CardTitle>
|
|
|
|
|
</CardHeader>
|
|
|
|
|
<CardContent>
|
Observer platform overhaul: Nivo charts, round-type stats, UX improvements
Phase 1: Fix 6 backend data bugs in analytics.ts (roundName filtering,
unscored projects, criteria scores, activeRoundCount scoping, email
privacy leaks in juror consistency + workload)
Phase 2-3: Migrate all 9 chart components from Recharts to Nivo
(@nivo/bar, @nivo/line, @nivo/pie, @nivo/scatterplot) with shared brand
theme, scoreGradient colors, and STATUS_COLORS map. Fixes scatter plot
outlier coloring and pie chart label visibility bugs.
Phase 4: Add round-type-aware stats (getRoundTypeStats backend +
RoundTypeStatsCards component) showing appropriate metrics per round
type (intake/filtering/evaluation/submission/mentoring/live/deliberation).
Phase 5: UX improvements — Stage→Round terminology, clickable dashboard
round links, URL-based round selection (?round=), round type indicators
in selectors, accessible Toggle-based cross-round comparison, sortable
project table columns (title/score/evaluations), brand score colors on
dashboard bar chart with aria labels.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 21:44:38 +01:00
|
|
|
<div style={{ height: '300px' }}>
|
|
|
|
|
<ResponsivePie
|
|
|
|
|
data={pieData}
|
|
|
|
|
theme={nivoTheme}
|
|
|
|
|
colors={{ datum: 'data.color' }}
|
|
|
|
|
innerRadius={0.5}
|
|
|
|
|
padAngle={0.7}
|
|
|
|
|
cornerRadius={3}
|
|
|
|
|
activeOuterRadiusOffset={8}
|
|
|
|
|
margin={{ top: 40, right: 80, bottom: 80, left: 80 }}
|
|
|
|
|
enableArcLinkLabels={true}
|
|
|
|
|
arcLinkLabelsSkipAngle={10}
|
|
|
|
|
arcLinkLabelsTextColor="#374151"
|
|
|
|
|
arcLinkLabelsThickness={2}
|
|
|
|
|
arcLinkLabelsColor={{ from: 'color' }}
|
|
|
|
|
enableArcLabels={true}
|
|
|
|
|
arcLabelsSkipAngle={10}
|
|
|
|
|
arcLabelsTextColor={{ from: 'color', modifiers: [['darker', 2]] }}
|
|
|
|
|
legends={[
|
|
|
|
|
{
|
|
|
|
|
anchor: 'bottom',
|
|
|
|
|
direction: 'row',
|
|
|
|
|
justify: false,
|
|
|
|
|
translateX: 0,
|
|
|
|
|
translateY: 56,
|
|
|
|
|
itemsSpacing: 0,
|
|
|
|
|
itemWidth: 100,
|
|
|
|
|
itemHeight: 18,
|
|
|
|
|
itemTextColor: '#374151',
|
|
|
|
|
itemDirection: 'left-to-right',
|
|
|
|
|
itemOpacity: 1,
|
|
|
|
|
symbolSize: 12,
|
|
|
|
|
symbolShape: 'circle',
|
|
|
|
|
},
|
|
|
|
|
]}
|
|
|
|
|
/>
|
2026-01-30 13:41:32 +01:00
|
|
|
</div>
|
|
|
|
|
</CardContent>
|
|
|
|
|
</Card>
|
|
|
|
|
)
|
|
|
|
|
}
|