'use client' import { PieChart, Pie, Cell, Tooltip, ResponsiveContainer, Legend, BarChart, Bar, XAxis, YAxis, CartesianGrid, } from 'recharts' import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' import { Badge } from '@/components/ui/badge' interface DiversityData { total: number byCountry: { country: string; count: number; percentage: number }[] byCategory: { category: string; count: number; percentage: number }[] byOceanIssue: { issue: string; count: number; percentage: number }[] byTag: { tag: string; count: number; percentage: number }[] } interface DiversityMetricsProps { data: DiversityData } const PIE_COLORS = [ '#053d57', '#de0f1e', '#557f8c', '#f38a52', '#6ad82f', '#3be31e', '#c9c052', '#e6382f', '#ed6141', '#0bd90f', '#8884d8', '#82ca9d', '#ffc658', '#ff7c7c', '#8dd1e1', ] /** Convert ISO 3166-1 alpha-2 code to full country name using Intl API */ function getCountryName(code: string): string { if (code === 'Others') return 'Others' try { const displayNames = new Intl.DisplayNames(['en'], { type: 'region' }) return displayNames.of(code.toUpperCase()) || code } catch { return code } } /** Convert SCREAMING_SNAKE_CASE to Title Case */ function formatLabel(value: string): string { if (!value) return value return value .replace(/_/g, ' ') .toLowerCase() .replace(/\b\w/g, (c) => c.toUpperCase()) } /** Custom tooltip for the pie chart */ function CountryTooltip({ active, payload }: { active?: boolean; payload?: Array<{ payload: { country: string; count: number; percentage: number } }> }) { if (!active || !payload?.length) return null const d = payload[0].payload return (

{getCountryName(d.country)}

{d.count} projects ({d.percentage.toFixed(1)}%)

) } /** Custom tooltip for bar charts */ function BarTooltip({ active, payload, labelFormatter }: { active?: boolean; payload?: Array<{ value: number }>; label?: string; labelFormatter: (val: string) => string }) { if (!active || !payload?.length) return null const entry = payload[0] const rawPayload = entry as unknown as { payload: Record } const dataPoint = rawPayload.payload const rawLabel = (dataPoint.category || dataPoint.issue || '') as string return (

{labelFormatter(rawLabel)}

{entry.value} projects

) } export function DiversityMetricsChart({ data }: DiversityMetricsProps) { if (data.total === 0) { return (

No project data available

) } // Top countries for pie chart (max 10, others grouped) const topCountries = data.byCountry.slice(0, 10) const otherCountries = data.byCountry.slice(10) const countryPieData = otherCountries.length > 0 ? [...topCountries, { country: 'Others', count: otherCountries.reduce((sum, c) => sum + c.count, 0), percentage: otherCountries.reduce((sum, c) => sum + c.percentage, 0), }] : topCountries // Pre-format category and ocean issue data for display const formattedCategories = data.byCategory.slice(0, 10).map((c) => ({ ...c, category: formatLabel(c.category), })) const formattedOceanIssues = data.byOceanIssue.slice(0, 15).map((o) => ({ ...o, issue: formatLabel(o.issue), })) return (
{/* Summary */}
{data.total}

Total Projects

{data.byCountry.length}

Countries Represented

{data.byCategory.length}

Categories

{data.byTag.length}

Unique Tags

{/* Country Distribution */} Geographic Distribution
{ const p = props as { country: string; percentage: number } return `${getCountryName(p.country)} (${p.percentage.toFixed(0)}%)` }) as unknown as boolean} fontSize={13} > {countryPieData.map((_, index) => ( ))} } /> getCountryName(value)} wrapperStyle={{ fontSize: '13px' }} />
{/* Category Distribution */} Competition Categories {formattedCategories.length > 0 ? (
v} />} />
) : (

No category data

)}
{/* Ocean Issues */} {formattedOceanIssues.length > 0 && ( Ocean Issues Addressed
v} />} />
)} {/* Tags Cloud */} {data.byTag.length > 0 && ( Project Tags
{data.byTag.slice(0, 30).map((tag) => ( {tag.tag} ({tag.count}) ))}
)}
) }