feat(sprint-1-5): cierre Etapa 2 - formatPayback + fixes de marca
[
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { TrendingDown, Calendar, BarChart3, DollarSign, Percent } from 'lucide-react'
|
||||
import { formatCurrency, formatPercent } from '@/lib/format'
|
||||
import { formatCurrency, formatPayback, formatPercent } from '@/lib/format'
|
||||
import type { RoiResult } from '@/domain/roi'
|
||||
|
||||
interface RoiKpiBarProps {
|
||||
@@ -9,7 +9,7 @@ interface RoiKpiBarProps {
|
||||
}
|
||||
|
||||
function RoiKpiCard({
|
||||
label, value, sub, icon, iconColor, valueColor,
|
||||
label, value, sub, icon, iconColor, valueColor, compact,
|
||||
}: {
|
||||
label: string
|
||||
value: string
|
||||
@@ -17,6 +17,7 @@ function RoiKpiCard({
|
||||
icon: React.ReactNode
|
||||
iconColor: string
|
||||
valueColor?: string
|
||||
compact?: boolean
|
||||
}) {
|
||||
return (
|
||||
<div data-testid="roi-kpi-card" className="bg-white rounded-xl border border-slate-200 shadow-sm p-5 flex items-start gap-4">
|
||||
@@ -25,7 +26,7 @@ function RoiKpiCard({
|
||||
</div>
|
||||
<div className="min-w-0 flex-1">
|
||||
<p className="text-xs font-medium text-slate-500 uppercase tracking-wide mb-1">{label}</p>
|
||||
<p className={`text-2xl font-bold font-mono leading-tight ${valueColor ?? 'text-slate-900'}`}>{value}</p>
|
||||
<p className={`${compact ? 'text-sm' : 'text-2xl'} font-bold font-mono leading-tight ${valueColor ?? 'text-slate-900'}`}>{value}</p>
|
||||
{sub && <p className="text-xs text-slate-400 mt-0.5 leading-snug">{sub}</p>}
|
||||
</div>
|
||||
</div>
|
||||
@@ -33,13 +34,7 @@ function RoiKpiCard({
|
||||
}
|
||||
|
||||
export function RoiKpiBar({ roi, currency, horizonYears }: RoiKpiBarProps) {
|
||||
const paybackStr = !isFinite(roi.paybackMonths)
|
||||
? 'No se recupera'
|
||||
: roi.paybackMonths === 0
|
||||
? 'Inmediato'
|
||||
: roi.paybackMonths < 24
|
||||
? `${roi.paybackMonths.toFixed(1)} meses`
|
||||
: `${roi.paybackYears.toFixed(1)} años`
|
||||
const paybackStr = formatPayback(roi.paybackMonths)
|
||||
|
||||
const roiStr = !isFinite(roi.roiAnnualPercent)
|
||||
? '∞%'
|
||||
@@ -88,6 +83,7 @@ export function RoiKpiBar({ roi, currency, horizonYears }: RoiKpiBarProps) {
|
||||
icon={<Calendar className="h-5 w-5 text-primary" />}
|
||||
iconColor="bg-primary/10"
|
||||
valueColor={roi.breaksEvenInHorizon ? 'text-emerald-700' : 'text-slate-900'}
|
||||
compact
|
||||
/>
|
||||
<RoiKpiCard
|
||||
label={`Acumulado (${horizonYears} años)`}
|
||||
|
||||
@@ -73,7 +73,7 @@ export function TransparencySection({ activities, investment, roi }: Transparenc
|
||||
<span className="font-medium">
|
||||
ROI inusualmente alto detectado: {formatPercent(roi.roiAnnualPercent)}.
|
||||
</span>{' '}
|
||||
Un ROI superior al {formatPercent(ROI_HIGH_THRESHOLD)} anual suele indicar uno de estos casos:
|
||||
Un ROI superior al {formatPercent(ROI_HIGH_THRESHOLD, 0)} anual suele indicar uno de estos casos:
|
||||
</p>
|
||||
<ul className="list-disc list-inside space-y-0.5 ml-1">
|
||||
<li>Frecuencia anual del proceso sobreestimada</li>
|
||||
|
||||
Reference in New Issue
Block a user