// ©AngelaMos | 2026 // index.tsx import { useMitreHeatmap, useMitreTechniques } from '@/api/hooks' import styles from './mitre.module.scss' const TACTIC_ORDER = [ 'reconnaissance', 'initial-access', 'execution', 'credential-access', 'discovery', 'lateral-movement', 'command-and-control', 'persistence', 'impact', ] as const const HEAT_THRESHOLDS = [0, 5, 20, 50, 100] as const function heatLevel(count: number): number { for (let i = HEAT_THRESHOLDS.length - 1; i >= 0; i--) { if (count >= (HEAT_THRESHOLDS[i] ?? 0)) return i } return 0 } export function MitrePage() { const { data: techniques } = useMitreTechniques() const { data: heatmap } = useMitreHeatmap() const countMap = new Map(heatmap?.map((h) => [h.technique_id, h.count])) const byTactic = new Map() for (const t of techniques ?? []) { const existing = byTactic.get(t.tactic) ?? [] existing.push(t) byTactic.set(t.tactic, existing) } return (

MITRE ATT&CK

ADVERSARY TECHNIQUE HEATMAP
INTENSITY {HEAT_THRESHOLDS.map((t, i) => ( {t}+ ))}
{TACTIC_ORDER.map((tactic) => { const techs = byTactic.get(tactic) if (!techs) return null return (

{tactic.replace(/-/g, ' ')}

{techs.map((t) => { const count = countMap.get(t.id) ?? 0 const level = heatLevel(count) return (
{t.id} {t.name} {count > 0 && ( {count} )}
) })}
) })}
) }