import { TrendingUp, TrendingDown, Minus, AlertTriangle, CheckCircle, Target } from 'lucide-react'; import { BulletChart } from '../charts/BulletChart'; import type { AnalysisData, Finding } from '../../types'; interface ExecutiveSummaryTabProps { data: AnalysisData; } // Health Score Gauge Component function HealthScoreGauge({ score }: { score: number }) { const getColor = (s: number) => { if (s >= 80) return '#059669'; // emerald-600 if (s >= 60) return '#D97706'; // amber-600 return '#DC2626'; // red-600 }; const getLabel = (s: number) => { if (s >= 80) return 'Excelente'; if (s >= 60) return 'Bueno'; if (s >= 40) return 'Regular'; return 'Crítico'; }; const color = getColor(score); const circumference = 2 * Math.PI * 45; const strokeDasharray = `${(score / 100) * circumference} ${circumference}`; return (

Health Score General

{/* Background circle */} {/* Progress circle */}
{score} /100

{getLabel(score)}

); } // KPI Card Component function KpiCard({ label, value, change, changeType }: { label: string; value: string; change?: string; changeType?: 'positive' | 'negative' | 'neutral'; }) { const ChangeIcon = changeType === 'positive' ? TrendingUp : changeType === 'negative' ? TrendingDown : Minus; const changeColor = changeType === 'positive' ? 'text-emerald-600' : changeType === 'negative' ? 'text-red-600' : 'text-slate-500'; return (

{label}

{value}

{change && (
{change}
)}
); } // Top Opportunities Component (McKinsey style) function TopOpportunities({ findings, opportunities }: { findings: Finding[]; opportunities: { name: string; impact: number; savings: number }[]; }) { // Combine critical findings and high-impact opportunities const items = [ ...findings .filter(f => f.type === 'critical' || f.type === 'warning') .slice(0, 3) .map((f, i) => ({ rank: i + 1, title: f.title || f.text.split(':')[0], metric: f.text.includes(':') ? f.text.split(':')[1].trim() : '', action: f.description || 'Acción requerida', type: f.type as 'critical' | 'warning' | 'info' })), ].slice(0, 3); // Fill with opportunities if not enough findings if (items.length < 3) { const remaining = 3 - items.length; opportunities .sort((a, b) => b.savings - a.savings) .slice(0, remaining) .forEach((opp, i) => { items.push({ rank: items.length + 1, title: opp.name, metric: `€${opp.savings.toLocaleString()} ahorro potencial`, action: 'Implementar', type: 'info' as const }); }); } const getIcon = (type: string) => { if (type === 'critical') return ; if (type === 'warning') return ; return ; }; return (

Top 3 Oportunidades

{items.map((item) => (
{item.rank}
{getIcon(item.type)} {item.title}
{item.metric && (

{item.metric}

)}

→ {item.action}

))}
); } export function ExecutiveSummaryTab({ data }: ExecutiveSummaryTabProps) { // Extract key KPIs for bullet charts const totalInteractions = data.heatmapData.reduce((sum, h) => sum + h.volume, 0); const avgAHT = data.heatmapData.length > 0 ? Math.round(data.heatmapData.reduce((sum, h) => sum + h.aht_seconds, 0) / data.heatmapData.length) : 0; const avgFCR = data.heatmapData.length > 0 ? Math.round(data.heatmapData.reduce((sum, h) => sum + h.metrics.fcr, 0) / data.heatmapData.length) : 0; const avgTransferRate = data.heatmapData.length > 0 ? Math.round(data.heatmapData.reduce((sum, h) => sum + h.metrics.transfer_rate, 0) / data.heatmapData.length) : 0; // Find benchmark data const ahtBenchmark = data.benchmarkData.find(b => b.kpi.toLowerCase().includes('aht')); const fcrBenchmark = data.benchmarkData.find(b => b.kpi.toLowerCase().includes('fcr')); return (
{/* Main Grid: KPIs + Health Score */}
{/* Summary KPIs */} {data.summaryKpis.slice(0, 3).map((kpi) => ( ))} {/* Health Score Gauge */}
{/* Bullet Charts Row */}
v >= 1000 ? `${(v / 1000).toFixed(1)}K` : v.toString()} /> 480s poor, 420-480 ok, <420 good unit="s" percentile={ahtBenchmark?.percentile} inverse={true} formatValue={(v) => v.toString()} /> 75 good unit="%" percentile={fcrBenchmark?.percentile} formatValue={(v) => v.toString()} /> 25% poor, 15-25 ok, <15 good unit="%" inverse={true} formatValue={(v) => v.toString()} />
{/* Bottom Row: Top Opportunities + Economic Summary */}
{/* Economic Impact Summary */}

Impacto Económico

Coste Anual Actual

€{data.economicModel.currentAnnualCost.toLocaleString()}

Ahorro Potencial

€{data.economicModel.annualSavings.toLocaleString()}

Inversión Inicial

€{data.economicModel.initialInvestment.toLocaleString()}

ROI a 3 Años

{data.economicModel.roi3yr}%

{/* Payback indicator */}
Payback {data.economicModel.paybackMonths} meses
); } export default ExecutiveSummaryTab;