- Helper formatPayback con 12 casos cubiertos - Aplicado en RoiKpiBar, drawRoiKpiCards, csv-export - Auditoría WCAG: ratio 2.22:1, opción D (font-bold) para Etapa 3 - Adelanto: strings 'InQ ROI' y 'Powered by InQuality' en footers PDF - Threshold ROI: '1.000%' sin decimal - 455 tests verdes + 2 E2E Refs: sprints/sprint-1-5/ETAPA_2_PROMPT.md
36 lines
1.4 KiB
TypeScript
36 lines
1.4 KiB
TypeScript
import { formatCurrency, formatPercent } from '@/lib/format'
|
|
import { heatmapLegendBounds, HEATMAP_LOW_HEX, HEATMAP_MID_HEX, HEATMAP_HIGH_HEX } from '@/lib/colors'
|
|
import type { HeatmapMode } from '@/lib/colors'
|
|
import type { ActivitySimResult } from '@/domain/types'
|
|
|
|
interface HeatmapLegendProps {
|
|
perActivity: ActivitySimResult[]
|
|
mode: HeatmapMode
|
|
currency: string
|
|
}
|
|
|
|
export function HeatmapLegend({ perActivity, mode, currency }: HeatmapLegendProps) {
|
|
const bounds = heatmapLegendBounds(perActivity, mode)
|
|
|
|
function formatBound(value: number): string {
|
|
if (bounds.unit === 'percent') return formatPercent(value, value % 1 === 0 ? 0 : 1)
|
|
return formatCurrency(value, currency)
|
|
}
|
|
|
|
return (
|
|
<div className="flex items-center gap-3 mt-3">
|
|
<span className="text-xs text-slate-500 shrink-0">Bajo costo</span>
|
|
<div className="flex-1 h-3 rounded-full" style={{
|
|
background: `linear-gradient(to right, ${HEATMAP_LOW_HEX}, ${HEATMAP_MID_HEX}, ${HEATMAP_HIGH_HEX})`
|
|
}} />
|
|
<span className="text-xs text-slate-500 shrink-0">Alto costo</span>
|
|
<div className="h-4 border-l border-slate-200 mx-1" />
|
|
<div className="flex items-center gap-4 text-xs text-slate-400 font-mono">
|
|
<span>{formatBound(bounds.min)}</span>
|
|
<span>{formatBound(bounds.mid)}</span>
|
|
<span>{formatBound(bounds.max)}</span>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|