/** * StatusBadge — renders a technique coverage status pill with a * CSS-only hover tooltip explaining what the status means. */ import type { TechniqueStatus } from "../types/models"; const BADGE_COLORS: Record = { validated: "bg-green-900/50 text-green-400 border-green-500/30", partial: "bg-yellow-900/50 text-yellow-400 border-yellow-500/30", in_progress: "bg-blue-900/50 text-blue-400 border-blue-500/30", not_covered: "bg-red-900/50 text-red-400 border-red-500/30", not_evaluated: "bg-gray-800/50 text-gray-400 border-gray-600/30", review_required:"bg-orange-900/50 text-orange-400 border-orange-500/30", }; const BADGE_LABELS: Record = { validated: "Validated", partial: "Partial", in_progress: "In Progress", not_covered: "Not Covered", not_evaluated: "Not Evaluated", review_required:"Review Required", }; interface TooltipLine { label: string; text: string } const TOOLTIPS: Record = { validated: { heading: "✅ Validated", lines: [ { label: "Meaning", text: "≥2 tests executed. Blue Team detected the attack in all of them." }, { label: "Action", text: "Maintain and re-test periodically." }, ], }, partial: { heading: "🟡 Partial", lines: [ { label: "Meaning", text: "Only 1 validated test, some tests still pending, or detection was not 100%." }, { label: "Action", text: "Run more tests and ensure all are validated with 'detected'." }, ], }, in_progress: { heading: "🔵 In Progress", lines: [ { label: "Meaning", text: "Tests exist but none have been validated yet (draft, executing, or in review)." }, { label: "Action", text: "Complete the Red/Blue validation workflow." }, ], }, not_covered: { heading: "🔴 Not Covered", lines: [ { label: "Meaning", text: "Tests were run but Blue Team did NOT detect the attack — coverage gap." }, { label: "Action", text: "Improve detection rules and re-test." }, ], }, not_evaluated: { heading: "⚫ Not Evaluated", lines: [ { label: "Meaning", text: "No tests have been created for this technique yet." }, { label: "Action", text: "Create a test from the available templates." }, ], }, review_required: { heading: "🟠 Review Required", lines: [ { label: "Meaning", text: "MITRE updated this technique, or new intel / detection rules were added." }, { label: "Action", text: "A lead should review the changes and mark as reviewed." }, ], }, }; interface StatusBadgeProps { status: TechniqueStatus; /** Extra classes on the outer wrapper (e.g. sizing) */ className?: string; /** Size variant — defaults to 'md' */ size?: "sm" | "md"; } export default function StatusBadge({ status, className = "", size = "md" }: StatusBadgeProps) { const tip = TOOLTIPS[status]; const pill = size === "sm" ? "px-2 py-0.5 text-[10px]" : "px-2.5 py-0.5 text-xs"; return ( {/* The badge itself */} {BADGE_LABELS[status]} {/* Tooltip — appears below the badge on hover */} {/* Arrow pointing up */}

{tip.heading}

{tip.lines.map(({ label, text }) => (
{label}

{text}

))}
); }