fix: complete Spanish-to-English translation for RoadmapTab

Added missing translation keys for visible UI elements:
- Investment Scenarios section (title, subtitle, tooltip)
- Table headers (Scenario, Investment, Recurring, Savings, Margin, Payback, ROI, Risk)
- Risk labels (Low, Medium, High)
- Wave card labels (Savings/year, Margin/year, Savings:)
- Timeline badges (Conditional, risk indicators)
- Tooltips (enabler wave, negative margin, projected ROI, adjusted ROI)

Build verified successfully

https://claude.ai/code/session_03272424-c661-4002-a75e-2f81579fdd6e
This commit is contained in:
Claude
2026-02-07 21:23:40 +00:00
parent b4cd8933c2
commit cce483c5b1
3 changed files with 56 additions and 26 deletions

View File

@@ -1160,11 +1160,11 @@ function WaveCard({
<p className="text-sm font-bold text-amber-700">{formatCurrency(wave.costoRecurrenteAnual)}</p> <p className="text-sm font-bold text-amber-700">{formatCurrency(wave.costoRecurrenteAnual)}</p>
</div> </div>
<div className="p-2 bg-emerald-50 rounded border border-emerald-100"> <div className="p-2 bg-emerald-50 rounded border border-emerald-100">
<p className="text-[10px] text-emerald-600 font-medium">Ahorro/año</p> <p className="text-[10px] text-emerald-600 font-medium">{t('roadmap.comparison.savingsPerYear')}</p>
<p className="text-sm font-bold text-emerald-700">{formatCurrency(wave.ahorroAnual)}</p> <p className="text-sm font-bold text-emerald-700">{formatCurrency(wave.ahorroAnual)}</p>
</div> </div>
<div className="p-2 bg-blue-50 rounded border border-blue-100"> <div className="p-2 bg-blue-50 rounded border border-blue-100">
<p className="text-[10px] text-blue-600 font-medium">Margen/año</p> <p className="text-[10px] text-blue-600 font-medium">{t('roadmap.comparison.marginPerYear')}</p>
<p className="text-sm font-bold text-blue-700">{formatCurrency(margenAnual)}</p> <p className="text-sm font-bold text-blue-700">{formatCurrency(margenAnual)}</p>
</div> </div>
</div> </div>
@@ -1248,11 +1248,11 @@ function ScenarioComparison({ escenarios }: { escenarios: EscenarioData[] }) {
<div className="p-4 border-b border-gray-200 bg-gray-50"> <div className="p-4 border-b border-gray-200 bg-gray-50">
<h3 className="font-semibold text-gray-800 flex items-center gap-2"> <h3 className="font-semibold text-gray-800 flex items-center gap-2">
<Target className="w-5 h-5 text-blue-500" /> <Target className="w-5 h-5 text-blue-500" />
Escenarios de Inversión {t('roadmap.comparison.title')}
</h3> </h3>
<p className="text-xs text-gray-500 mt-1"> <p className="text-xs text-gray-500 mt-1">
Comparación de opciones según nivel de compromiso {t('roadmap.comparison.subtitle')}
<span className="ml-2 text-gray-400" title="ROI basado en benchmarks de industria. El ROI ajustado considera factores de riesgo de implementación."> <span className="ml-2 text-gray-400" title={t('roadmap.comparison.tooltip')}>
</span> </span>
</p> </p>
@@ -1262,20 +1262,20 @@ function ScenarioComparison({ escenarios }: { escenarios: EscenarioData[] }) {
<table className="w-full text-sm"> <table className="w-full text-sm">
<thead className="bg-gray-50"> <thead className="bg-gray-50">
<tr> <tr>
<th className="text-left py-3 px-4 font-medium text-gray-600">Escenario</th> <th className="text-left py-3 px-4 font-medium text-gray-600">{t('roadmap.comparison.scenario')}</th>
<th className="text-right py-3 px-4 font-medium text-gray-600">Inversión</th> <th className="text-right py-3 px-4 font-medium text-gray-600">{t('roadmap.comparison.investment')}</th>
<th className="text-right py-3 px-4 font-medium text-gray-600">Recurrente</th> <th className="text-right py-3 px-4 font-medium text-gray-600">{t('roadmap.comparison.recurring')}</th>
<th className="text-right py-3 px-4 font-medium text-gray-600"> <th className="text-right py-3 px-4 font-medium text-gray-600">
Ahorro {t('roadmap.comparison.savings')}
<span className="block text-[10px] text-gray-400 font-normal">(ajustado)</span> <span className="block text-[10px] text-gray-400 font-normal">({t('roadmap.comparison.adjusted')})</span>
</th> </th>
<th className="text-right py-3 px-4 font-medium text-gray-600">Margen</th> <th className="text-right py-3 px-4 font-medium text-gray-600">{t('roadmap.comparison.margin')}</th>
<th className="text-right py-3 px-4 font-medium text-gray-600">Payback</th> <th className="text-right py-3 px-4 font-medium text-gray-600">{t('roadmap.comparison.payback')}</th>
<th className="text-right py-3 px-4 font-medium text-gray-600"> <th className="text-right py-3 px-4 font-medium text-gray-600">
ROI 3a {t('roadmap.comparison.roi3y')}
<span className="block text-[10px] text-gray-400 font-normal">(ajustado)</span> <span className="block text-[10px] text-gray-400 font-normal">({t('roadmap.comparison.adjusted')})</span>
</th> </th>
<th className="text-center py-3 px-4 font-medium text-gray-600">Riesgo</th> <th className="text-center py-3 px-4 font-medium text-gray-600">{t('roadmap.comparison.risk')}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -1296,10 +1296,10 @@ function ScenarioComparison({ escenarios }: { escenarios: EscenarioData[] }) {
<td className="py-3 px-4"> <td className="py-3 px-4">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
{esc.esHabilitador && ( {esc.esHabilitador && (
<span className="text-blue-500" title="Wave habilitadora - su valor está en desbloquear waves posteriores">💡</span> <span className="text-blue-500" title={t('roadmap.comparison.enablerWaveTooltip')}>💡</span>
)} )}
{!esc.esRentable && !esc.esHabilitador && ( {!esc.esRentable && !esc.esHabilitador && (
<span className="text-red-500" title="Margen anual negativo"></span> <span className="text-red-500" title={t('roadmap.comparison.negativeMarginTooltip')}></span>
)} )}
<span className={`font-medium ${ <span className={`font-medium ${
esc.esHabilitador ? 'text-blue-700' : esc.esHabilitador ? 'text-blue-700' :
@@ -1383,12 +1383,12 @@ function ScenarioComparison({ escenarios }: { escenarios: EscenarioData[] }) {
}`}> }`}>
{roiInfo.text} {roiInfo.text}
{roiInfo.isHighWarning && ( {roiInfo.isHighWarning && (
<span className="ml-1" title="ROI proyectado. Validar con piloto."></span> <span className="ml-1" title={t('roadmap.comparison.projectedRoiTooltip')}></span>
)} )}
</span> </span>
{roiInfo.showAjustado && esc.roi3AnosAjustado > 0 && ( {roiInfo.showAjustado && esc.roi3AnosAjustado > 0 && (
<span className="text-[10px] text-gray-500" title="ROI ajustado por riesgo de implementación"> <span className="text-[10px] text-gray-500" title={t('roadmap.comparison.adjustedRoiTooltip')}>
({esc.roi3AnosAjustado.toFixed(1)}% ajust.) ({esc.roi3AnosAjustado.toFixed(1)}% {t('roadmap.comparison.adjusted').slice(0, 5)}.)
</span> </span>
)} )}
</div> </div>
@@ -1396,7 +1396,7 @@ function ScenarioComparison({ escenarios }: { escenarios: EscenarioData[] }) {
</td> </td>
<td className="text-center py-3 px-4"> <td className="text-center py-3 px-4">
<span className={`text-xs px-2 py-1 rounded-full ${riesgoColors[esc.riesgo]}`}> <span className={`text-xs px-2 py-1 rounded-full ${riesgoColors[esc.riesgo]}`}>
{esc.riesgo.charAt(0).toUpperCase() + esc.riesgo.slice(1)} {t(`roadmap.comparison.risk${esc.riesgo.charAt(0).toUpperCase() + esc.riesgo.slice(1)}`)}
</span> </span>
</td> </td>
</tr> </tr>
@@ -1566,7 +1566,7 @@ function RoadmapTimeline({ waves }: { waves: WaveData[] }) {
<span className="font-semibold text-gray-700 ml-1">{formatCurrency(wave.inversionSetup)}</span> <span className="font-semibold text-gray-700 ml-1">{formatCurrency(wave.inversionSetup)}</span>
</div> </div>
<div className="bg-white/60 rounded px-1.5 py-1"> <div className="bg-white/60 rounded px-1.5 py-1">
<span className="text-gray-500">Ahorro:</span> <span className="text-gray-500">{t('roadmap.comparison.savingsLabel')}</span>
<span className="font-semibold text-emerald-600 ml-1">{formatCurrency(wave.ahorroAnual)}</span> <span className="font-semibold text-emerald-600 ml-1">{formatCurrency(wave.ahorroAnual)}</span>
</div> </div>
</div> </div>
@@ -1574,7 +1574,7 @@ function RoadmapTimeline({ waves }: { waves: WaveData[] }) {
{/* Conditional badge */} {/* Conditional badge */}
{wave.esCondicional && ( {wave.esCondicional && (
<div className="absolute -top-2 -right-2 bg-amber-500 text-white text-[8px] px-1.5 py-0.5 rounded-full font-medium"> <div className="absolute -top-2 -right-2 bg-amber-500 text-white text-[8px] px-1.5 py-0.5 rounded-full font-medium">
Condicional {t('roadmap.comparison.conditional')}
</div> </div>
)} )}
@@ -1584,7 +1584,7 @@ function RoadmapTimeline({ waves }: { waves: WaveData[] }) {
wave.riesgo === 'medio' ? 'bg-amber-500 text-white' : wave.riesgo === 'medio' ? 'bg-amber-500 text-white' :
'bg-red-500 text-white' 'bg-red-500 text-white'
}`}> }`}>
{wave.riesgo === 'bajo' ? '● Bajo' : wave.riesgo === 'medio' ? '● Medio' : '● Alto'} {t(`roadmap.comparison.risk${wave.riesgo.charAt(0).toUpperCase() + wave.riesgo.slice(1)}`)}
</div> </div>
</div> </div>
</motion.div> </motion.div>

View File

@@ -686,9 +686,13 @@
"legendRisk": "= Risk" "legendRisk": "= Risk"
}, },
"comparison": { "comparison": {
"title": "Investment Scenarios",
"subtitle": "Comparison of options by commitment level",
"tooltip": "ROI based on industry benchmarks. Adjusted ROI considers implementation risk factors.",
"investment": "Investment", "investment": "Investment",
"recurring": "Recurring", "recurring": "Recurring",
"savings": "Savings", "savings": "Savings",
"adjusted": "adjusted",
"margin": "Margin", "margin": "Margin",
"payback": "Payback", "payback": "Payback",
"roi3y": "3y ROI", "roi3y": "3y ROI",
@@ -697,7 +701,18 @@
"recommendation": "Recommendation", "recommendation": "Recommendation",
"recommendationEnabler": "Recommendation (Enabler)", "recommendationEnabler": "Recommendation (Enabler)",
"enabler": "Enabler", "enabler": "Enabler",
"recommended": "Recommended" "recommended": "Recommended",
"savingsPerYear": "Savings/year",
"marginPerYear": "Margin/year",
"savingsLabel": "Savings:",
"conditional": "Conditional",
"riskLow": "Low",
"riskMedium": "Medium",
"riskHigh": "High",
"enablerWaveTooltip": "Enabler wave - its value is in unlocking subsequent waves",
"negativeMarginTooltip": "Negative annual margin",
"projectedRoiTooltip": "Projected ROI. Validate with pilot.",
"adjustedRoiTooltip": "ROI adjusted for implementation risk"
}, },
"entryCriteria": { "entryCriteria": {
"wave1TierFrom": "HUMAN-ONLY (4), AUGMENT (3)", "wave1TierFrom": "HUMAN-ONLY (4), AUGMENT (3)",

View File

@@ -686,9 +686,13 @@
"legendRisk": "= Riesgo" "legendRisk": "= Riesgo"
}, },
"comparison": { "comparison": {
"title": "Escenarios de Inversión",
"subtitle": "Comparación de opciones según nivel de compromiso",
"tooltip": "ROI basado en benchmarks de industria. El ROI ajustado considera factores de riesgo de implementación.",
"investment": "Inversión", "investment": "Inversión",
"recurring": "Recurrente", "recurring": "Recurrente",
"savings": "Ahorro", "savings": "Ahorro",
"adjusted": "ajustado",
"margin": "Margen", "margin": "Margen",
"payback": "Payback", "payback": "Payback",
"roi3y": "ROI 3a", "roi3y": "ROI 3a",
@@ -697,7 +701,18 @@
"recommendation": "Recomendación", "recommendation": "Recomendación",
"recommendationEnabler": "Recomendación (Habilitador)", "recommendationEnabler": "Recomendación (Habilitador)",
"enabler": "Habilitador", "enabler": "Habilitador",
"recommended": "Recomendado" "recommended": "Recomendado",
"savingsPerYear": "Ahorro/año",
"marginPerYear": "Margen/año",
"savingsLabel": "Ahorro:",
"conditional": "Condicional",
"riskLow": "Bajo",
"riskMedium": "Medio",
"riskHigh": "Alto",
"enablerWaveTooltip": "Wave habilitadora - su valor está en desbloquear waves posteriores",
"negativeMarginTooltip": "Margen anual negativo",
"projectedRoiTooltip": "ROI proyectado. Validar con piloto.",
"adjustedRoiTooltip": "ROI ajustado por riesgo de implementación"
}, },
"entryCriteria": { "entryCriteria": {
"wave1TierFrom": "HUMAN-ONLY (4), AUGMENT (3)", "wave1TierFrom": "HUMAN-ONLY (4), AUGMENT (3)",