import { Link } from 'react-router-dom' import { Plus, MapPin } from 'lucide-react' import { cn } from '@/lib/utils' import type { CoverageResponse } from '@/types/flowpilot-analytics' interface CoverageHeatmapProps { data: CoverageResponse } function getCellStyle(value: number, thresholds: { green: number; amber: number }, inverse?: boolean) { if (inverse) { if (value <= thresholds.green) return 'bg-emerald-400/10 text-emerald-400' if (value <= thresholds.amber) return 'bg-amber-400/10 text-amber-400' return 'bg-rose-500/10 text-rose-500' } if (value >= thresholds.green) return 'bg-emerald-400/10 text-emerald-400' if (value >= thresholds.amber) return 'bg-amber-400/10 text-amber-400' return 'bg-rose-500/10 text-rose-500' } function getCellTitle(value: number, label: string, thresholds: { green: number; amber: number }, inverse?: boolean): string { const pct = (value * 100).toFixed(1) if (inverse) { if (value <= thresholds.green) return `${label}: ${pct}% (Good — below ${(thresholds.green * 100).toFixed(0)}%)` if (value <= thresholds.amber) return `${label}: ${pct}% (Needs Improvement — below ${(thresholds.amber * 100).toFixed(0)}%)` return `${label}: ${pct}% (Critical — above ${(thresholds.amber * 100).toFixed(0)}%)` } if (value >= thresholds.green) return `${label}: ${pct}% (Good — above ${(thresholds.green * 100).toFixed(0)}%)` if (value >= thresholds.amber) return `${label}: ${pct}% (Needs Improvement — above ${(thresholds.amber * 100).toFixed(0)}%)` return `${label}: ${pct}% (Critical — below ${(thresholds.amber * 100).toFixed(0)}%)` } function getFlowCountStyle(count: number) { if (count >= 5) return 'bg-emerald-400/10 text-emerald-400' if (count >= 1) return 'bg-amber-400/10 text-amber-400' return 'bg-rose-500/10 text-rose-500' } export default function CoverageHeatmap({ data }: CoverageHeatmapProps) { if (data.domains.length === 0) { return (

Domain Coverage

No session data for this period. Start using FlowPilot to see coverage metrics.

) } return (

Domain Coverage

Resolution coverage and knowledge gaps by problem domain

{data.domains.map((row) => ( ))} {data.unmapped_session_count > 0 && ( )}
Domain Flows Sessions Resolution % Escalation % Guided % Avg Resolution
{row.domain} {row.flow_count === 0 ? ( Create Flow ) : ( = 5 ? 'Good' : row.flow_count >= 1 ? 'Needs Improvement' : 'Critical'}`} > {row.flow_count} )} {row.session_count} {(row.resolution_rate * 100).toFixed(1)}% {(row.escalation_rate * 100).toFixed(1)}% {(row.guided_rate * 100).toFixed(1)}% {row.avg_resolution_minutes == null ? ( ) : ( 20 min)'}`} > {row.avg_resolution_minutes.toFixed(1)} min )}
{data.unmapped_session_count} sessions had no domain classification
Good Needs Improvement Critical
) }