Merge pull request #19 from sujucu70/claude/check-agent-readiness-status-Exnpc

Claude/check agent readiness status exnpc
This commit is contained in:
sujucu70
2026-02-08 15:28:27 +01:00
committed by GitHub
4 changed files with 151 additions and 83 deletions

View File

@@ -58,56 +58,56 @@ interface EnrichedOpportunity extends Opportunity {
annualCost?: number; annualCost?: number;
} }
// Tier configuration // Tier configuration - labels and descriptions will be translated at usage time
const TIER_CONFIG: Record<AgenticTier, { const TIER_CONFIG: Record<AgenticTier, {
icon: React.ReactNode; icon: React.ReactNode;
label: string; labelKey: string;
color: string; color: string;
bgColor: string; bgColor: string;
borderColor: string; borderColor: string;
savingsRate: string; savingsRate: string;
timeline: string; timelineKey: string;
description: string; descriptionKey: string;
}> = { }> = {
'AUTOMATE': { 'AUTOMATE': {
icon: <Bot size={18} />, icon: <Bot size={18} />,
label: 'Automatizar', labelKey: 'opportunityPrioritizer.tierLabels.automate',
color: 'text-emerald-700', color: 'text-emerald-700',
bgColor: 'bg-emerald-50', bgColor: 'bg-emerald-50',
borderColor: 'border-emerald-300', borderColor: 'border-emerald-300',
savingsRate: '70%', savingsRate: '70%',
timeline: '3-6 meses', timelineKey: 'opportunityPrioritizer.timelines.automate',
description: 'Automatización completa con agentes IA' descriptionKey: 'opportunityPrioritizer.tierDescriptions.automate'
}, },
'ASSIST': { 'ASSIST': {
icon: <Headphones size={18} />, icon: <Headphones size={18} />,
label: 'Asistir', labelKey: 'opportunityPrioritizer.tierLabels.assist',
color: 'text-blue-700', color: 'text-blue-700',
bgColor: 'bg-blue-50', bgColor: 'bg-blue-50',
borderColor: 'border-blue-300', borderColor: 'border-blue-300',
savingsRate: '30%', savingsRate: '30%',
timeline: '6-9 meses', timelineKey: 'opportunityPrioritizer.timelines.assist',
description: 'Copilot IA para agentes humanos' descriptionKey: 'opportunityPrioritizer.tierDescriptions.assist'
}, },
'AUGMENT': { 'AUGMENT': {
icon: <BookOpen size={18} />, icon: <BookOpen size={18} />,
label: 'Optimizar', labelKey: 'opportunityPrioritizer.tierLabels.augment',
color: 'text-amber-700', color: 'text-amber-700',
bgColor: 'bg-amber-50', bgColor: 'bg-amber-50',
borderColor: 'border-amber-300', borderColor: 'border-amber-300',
savingsRate: '15%', savingsRate: '15%',
timeline: '9-12 meses', timelineKey: 'opportunityPrioritizer.timelines.augment',
description: 'Estandarización y mejora de procesos' descriptionKey: 'opportunityPrioritizer.tierDescriptions.augment'
}, },
'HUMAN-ONLY': { 'HUMAN-ONLY': {
icon: <Users size={18} />, icon: <Users size={18} />,
label: 'Humano', labelKey: 'opportunityPrioritizer.tierLabels.human',
color: 'text-slate-600', color: 'text-slate-600',
bgColor: 'bg-slate-50', bgColor: 'bg-slate-50',
borderColor: 'border-slate-300', borderColor: 'border-slate-300',
savingsRate: '0%', savingsRate: '0%',
timeline: 'N/A', timelineKey: 'N/A',
description: 'Requiere intervención humana' descriptionKey: 'opportunityPrioritizer.tierDescriptions.humanOnly'
} }
}; };
@@ -177,29 +177,23 @@ const OpportunityPrioritizer: React.FC<OpportunityPrioritizerProps> = ({
// Timeline based on tier // Timeline based on tier
const timelineMonths = tier === 'AUTOMATE' ? 4 : tier === 'ASSIST' ? 7 : 10; const timelineMonths = tier === 'AUTOMATE' ? 4 : tier === 'ASSIST' ? 7 : 10;
// Generate "why" explanation // Generate "why" explanation - store keys for translation
const whyPrioritized: string[] = []; const whyPrioritized: { key: string; params?: any }[] = [];
if (opp.savings > 50000) whyPrioritized.push(`Alto ahorro potencial (€${(opp.savings / 1000).toFixed(0)}K/año)`); if (opp.savings > 50000) whyPrioritized.push({ key: 'reasons.highSavingsPotential', params: { amount: (opp.savings / 1000).toFixed(0) } });
if (lookupData?.volume && lookupData.volume > 1000) whyPrioritized.push(`Alto volumen (${lookupData.volume.toLocaleString()} interacciones)`); if (lookupData?.volume && lookupData.volume > 1000) whyPrioritized.push({ key: 'reasons.highVolume', params: { volume: lookupData.volume.toLocaleString() } });
if (tier === 'AUTOMATE') whyPrioritized.push('Proceso altamente predecible y repetitivo'); if (tier === 'AUTOMATE') whyPrioritized.push({ key: 'reasons.highlyPredictable' });
if (cv < 60) whyPrioritized.push('Baja variabilidad en tiempos de gestión'); if (cv < 60) whyPrioritized.push({ key: 'reasons.lowVariability' });
if (transfer < 15) whyPrioritized.push('Baja tasa de transferencias'); if (transfer < 15) whyPrioritized.push({ key: 'reasons.lowTransferRate' });
if (opp.feasibility >= 7) whyPrioritized.push('Alta factibilidad técnica'); if (opp.feasibility >= 7) whyPrioritized.push({ key: 'reasons.highFeasibility' });
// Generate next steps // Generate next steps - store keys for translation
const nextSteps: string[] = []; const nextSteps: string[] = [];
if (tier === 'AUTOMATE') { if (tier === 'AUTOMATE') {
nextSteps.push('Definir flujos conversacionales principales'); nextSteps.push('steps.automate1', 'steps.automate2', 'steps.automate3');
nextSteps.push('Identificar integraciones necesarias (CRM, APIs)');
nextSteps.push('Crear piloto con 10% del volumen');
} else if (tier === 'ASSIST') { } else if (tier === 'ASSIST') {
nextSteps.push('Mapear puntos de fricción del agente'); nextSteps.push('steps.assist1', 'steps.assist2', 'steps.assist3');
nextSteps.push('Diseñar sugerencias contextuales');
nextSteps.push('Piloto con equipo seleccionado');
} else { } else {
nextSteps.push('Analizar causa raíz de variabilidad'); nextSteps.push('steps.augment1', 'steps.augment2', 'steps.augment3');
nextSteps.push('Estandarizar procesos y scripts');
nextSteps.push('Capacitar equipo en mejores prácticas');
} }
return { return {
@@ -250,8 +244,8 @@ const OpportunityPrioritizer: React.FC<OpportunityPrioritizerProps> = ({
return ( return (
<div className="bg-white p-8 rounded-xl border border-slate-200 text-center"> <div className="bg-white p-8 rounded-xl border border-slate-200 text-center">
<AlertTriangle className="mx-auto mb-4 text-amber-500" size={48} /> <AlertTriangle className="mx-auto mb-4 text-amber-500" size={48} />
<h3 className="text-lg font-semibold text-slate-700">No hay oportunidades identificadas</h3> <h3 className="text-lg font-semibold text-slate-700">{t('opportunityPrioritizer.noOpportunitiesTitle')}</h3>
<p className="text-slate-500 mt-2">Los datos actuales no muestran oportunidades de automatización viables.</p> <p className="text-slate-500 mt-2">{t('opportunityPrioritizer.noOpportunitiesDescription')}</p>
</div> </div>
); );
} }
@@ -292,7 +286,7 @@ const OpportunityPrioritizer: React.FC<OpportunityPrioritizerProps> = ({
{summary.byTier.AUTOMATE.length} {summary.byTier.AUTOMATE.length}
</div> </div>
<div className="text-xs text-emerald-600"> <div className="text-xs text-emerald-600">
{(summary.byTier.AUTOMATE.reduce((s, o) => s + o.savings, 0) / 1000).toFixed(0)}K {t('opportunityPrioritizer.inMonths', { count: '3-6' })} {(summary.byTier.AUTOMATE.reduce((s, o) => s + o.savings, 0) / 1000).toFixed(0)}K {t('opportunityPrioritizer.inMonths', { months: '3-6' })}
</div> </div>
</div> </div>
@@ -305,7 +299,7 @@ const OpportunityPrioritizer: React.FC<OpportunityPrioritizerProps> = ({
{summary.byTier.ASSIST.length} {summary.byTier.ASSIST.length}
</div> </div>
<div className="text-xs text-blue-600"> <div className="text-xs text-blue-600">
{(summary.byTier.ASSIST.reduce((s, o) => s + o.savings, 0) / 1000).toFixed(0)}K {t('opportunityPrioritizer.inMonths', { count: '6-9' })} {(summary.byTier.ASSIST.reduce((s, o) => s + o.savings, 0) / 1000).toFixed(0)}K {t('opportunityPrioritizer.inMonths', { months: '6-9' })}
</div> </div>
</div> </div>
@@ -318,7 +312,7 @@ const OpportunityPrioritizer: React.FC<OpportunityPrioritizerProps> = ({
{summary.byTier.AUGMENT.length} {summary.byTier.AUGMENT.length}
</div> </div>
<div className="text-xs text-amber-600"> <div className="text-xs text-amber-600">
{(summary.byTier.AUGMENT.reduce((s, o) => s + o.savings, 0) / 1000).toFixed(0)}K {t('opportunityPrioritizer.inMonths', { count: '9-12' })} {(summary.byTier.AUGMENT.reduce((s, o) => s + o.savings, 0) / 1000).toFixed(0)}K {t('opportunityPrioritizer.inMonths', { months: '9-12' })}
</div> </div>
</div> </div>
</div> </div>
@@ -345,7 +339,7 @@ const OpportunityPrioritizer: React.FC<OpportunityPrioritizerProps> = ({
{topOpportunity.name.replace(/^[^\w\s]+\s*/, '')} {topOpportunity.name.replace(/^[^\w\s]+\s*/, '')}
</h3> </h3>
<span className={`text-sm font-medium ${TIER_CONFIG[topOpportunity.tier].color}`}> <span className={`text-sm font-medium ${TIER_CONFIG[topOpportunity.tier].color}`}>
{t(`opportunityPrioritizer.tierLabels.${topOpportunity.tier.toLowerCase()}`)} {TIER_CONFIG[topOpportunity.tier].description} {t(TIER_CONFIG[topOpportunity.tier].labelKey)} {t(TIER_CONFIG[topOpportunity.tier].descriptionKey)}
</span> </span>
</div> </div>
</div> </div>
@@ -371,7 +365,7 @@ const OpportunityPrioritizer: React.FC<OpportunityPrioritizerProps> = ({
</div> </div>
</div> </div>
<div className="bg-slate-50 rounded-lg p-3"> <div className="bg-slate-50 rounded-lg p-3">
<div className="text-xs text-slate-500 mb-1">Agentic Score</div> <div className="text-xs text-slate-500 mb-1">{t('opportunityPrioritizer.agenticScore')}</div>
<div className="text-xl font-bold text-slate-700"> <div className="text-xl font-bold text-slate-700">
{topOpportunity.agenticScore.toFixed(1)}/10 {topOpportunity.agenticScore.toFixed(1)}/10
</div> </div>
@@ -382,13 +376,13 @@ const OpportunityPrioritizer: React.FC<OpportunityPrioritizerProps> = ({
<div className="mb-4"> <div className="mb-4">
<h4 className="text-sm font-semibold text-slate-700 mb-2 flex items-center gap-2"> <h4 className="text-sm font-semibold text-slate-700 mb-2 flex items-center gap-2">
<Info size={14} /> <Info size={14} />
¿Por qué es la prioridad #1? {t('opportunityPrioritizer.whyPriority1')}
</h4> </h4>
<ul className="space-y-1"> <ul className="space-y-1">
{topOpportunity.whyPrioritized.slice(0, 4).map((reason, i) => ( {topOpportunity.whyPrioritized.slice(0, 4).map((reason, i) => (
<li key={i} className="flex items-center gap-2 text-sm text-slate-600"> <li key={i} className="flex items-center gap-2 text-sm text-slate-600">
<CheckCircle2 size={14} className="text-emerald-500 flex-shrink-0" /> <CheckCircle2 size={14} className="text-emerald-500 flex-shrink-0" />
{reason} {t(`opportunityPrioritizer.${reason.key}`, reason.params)}
</li> </li>
))} ))}
</ul> </ul>
@@ -399,7 +393,7 @@ const OpportunityPrioritizer: React.FC<OpportunityPrioritizerProps> = ({
<div className="lg:w-80 bg-emerald-50 rounded-lg p-4 border border-emerald-200"> <div className="lg:w-80 bg-emerald-50 rounded-lg p-4 border border-emerald-200">
<h4 className="text-sm font-semibold text-emerald-800 mb-3 flex items-center gap-2"> <h4 className="text-sm font-semibold text-emerald-800 mb-3 flex items-center gap-2">
<ArrowRight size={14} /> <ArrowRight size={14} />
t("opportunityPrioritizer.nextSteps") {t('opportunityPrioritizer.nextSteps')}
</h4> </h4>
<ol className="space-y-2"> <ol className="space-y-2">
{topOpportunity.nextSteps.map((step, i) => ( {topOpportunity.nextSteps.map((step, i) => (
@@ -407,12 +401,12 @@ const OpportunityPrioritizer: React.FC<OpportunityPrioritizerProps> = ({
<span className="bg-emerald-600 text-white w-5 h-5 rounded-full flex items-center justify-center text-xs flex-shrink-0 mt-0.5"> <span className="bg-emerald-600 text-white w-5 h-5 rounded-full flex items-center justify-center text-xs flex-shrink-0 mt-0.5">
{i + 1} {i + 1}
</span> </span>
{step} {t(`opportunityPrioritizer.${step}`)}
</li> </li>
))} ))}
</ol> </ol>
<button className="mt-4 w-full bg-emerald-600 hover:bg-emerald-700 text-white font-medium py-2 px-4 rounded-lg transition-colors flex items-center justify-center gap-2"> <button className="mt-4 w-full bg-emerald-600 hover:bg-emerald-700 text-white font-medium py-2 px-4 rounded-lg transition-colors flex items-center justify-center gap-2">
Ver Detalle Completo {t('opportunityPrioritizer.viewCompleteDetail')}
<ChevronRight size={16} /> <ChevronRight size={16} />
</button> </button>
</div> </div>
@@ -462,7 +456,7 @@ const OpportunityPrioritizer: React.FC<OpportunityPrioritizerProps> = ({
{opp.name.replace(/^[^\w\s]+\s*/, '')} {opp.name.replace(/^[^\w\s]+\s*/, '')}
</h4> </h4>
<span className={`text-xs ${TIER_CONFIG[opp.tier].color}`}> <span className={`text-xs ${TIER_CONFIG[opp.tier].color}`}>
{t(`opportunityPrioritizer.tierLabels.${opp.tier.toLowerCase()}`)} {t(`opportunityPrioritizer.timelines.${opp.tier.toLowerCase()}`)} {t(TIER_CONFIG[opp.tier].labelKey)} {t(TIER_CONFIG[opp.tier].timelineKey)}
</span> </span>
</div> </div>
@@ -496,8 +490,8 @@ const OpportunityPrioritizer: React.FC<OpportunityPrioritizerProps> = ({
/> />
</div> </div>
<div className="flex justify-between text-[10px] text-slate-400 mt-0.5"> <div className="flex justify-between text-[10px] text-slate-400 mt-0.5">
<span>Valor</span> <span>{t('opportunityPrioritizer.value')}</span>
<span>Esfuerzo</span> <span>{t('opportunityPrioritizer.effort')}</span>
</div> </div>
</div> </div>
@@ -525,12 +519,12 @@ const OpportunityPrioritizer: React.FC<OpportunityPrioritizerProps> = ({
<div className="grid grid-cols-1 md:grid-cols-2 gap-4"> <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{/* Why prioritized */} {/* Why prioritized */}
<div> <div>
<h5 className="text-sm font-semibold text-slate-700 mb-2">¿Por qué esta posición?</h5> <h5 className="text-sm font-semibold text-slate-700 mb-2">{t('opportunityPrioritizer.whyThisPosition')}</h5>
<ul className="space-y-1"> <ul className="space-y-1">
{opp.whyPrioritized.map((reason, i) => ( {opp.whyPrioritized.map((reason, i) => (
<li key={i} className="flex items-center gap-2 text-sm text-slate-600"> <li key={i} className="flex items-center gap-2 text-sm text-slate-600">
<CheckCircle2 size={12} className="text-emerald-500 flex-shrink-0" /> <CheckCircle2 size={12} className="text-emerald-500 flex-shrink-0" />
{reason} {t(`opportunityPrioritizer.${reason.key}`, reason.params)}
</li> </li>
))} ))}
</ul> </ul>
@@ -538,7 +532,7 @@ const OpportunityPrioritizer: React.FC<OpportunityPrioritizerProps> = ({
{/* Metrics */} {/* Metrics */}
<div> <div>
<h5 className="text-sm font-semibold text-slate-700 mb-2">Métricas Clave</h5> <h5 className="text-sm font-semibold text-slate-700 mb-2">{t('opportunityPrioritizer.keyMetrics')}</h5>
<div className="grid grid-cols-2 gap-2"> <div className="grid grid-cols-2 gap-2">
<div className="bg-white rounded p-2 border border-slate-200"> <div className="bg-white rounded p-2 border border-slate-200">
<div className="text-xs text-slate-500">CV AHT</div> <div className="text-xs text-slate-500">CV AHT</div>
@@ -553,12 +547,12 @@ const OpportunityPrioritizer: React.FC<OpportunityPrioritizerProps> = ({
<div className="font-semibold text-slate-700">{opp.fcr_rate.toFixed(1)}%</div> <div className="font-semibold text-slate-700">{opp.fcr_rate.toFixed(1)}%</div>
</div> </div>
<div className="bg-white rounded p-2 border border-slate-200"> <div className="bg-white rounded p-2 border border-slate-200">
<div className="text-xs text-slate-500">Riesgo</div> <div className="text-xs text-slate-500">{t('roadmap.risk')}</div>
<div className={`font-semibold ${ <div className={`font-semibold ${
opp.riskLevel === 'low' ? 'text-emerald-600' : opp.riskLevel === 'low' ? 'text-emerald-600' :
opp.riskLevel === 'medium' ? 'text-amber-600' : 'text-red-600' opp.riskLevel === 'medium' ? 'text-amber-600' : 'text-red-600'
}`}> }`}>
{opp.riskLevel === 'low' ? 'Bajo' : opp.riskLevel === 'medium' ? 'Medio' : 'Alto'} {t(`roadmap.risk${opp.riskLevel.charAt(0).toUpperCase() + opp.riskLevel.slice(1)}`)}
</div> </div>
</div> </div>
</div> </div>
@@ -571,7 +565,7 @@ const OpportunityPrioritizer: React.FC<OpportunityPrioritizerProps> = ({
<div className="flex flex-wrap gap-2"> <div className="flex flex-wrap gap-2">
{opp.nextSteps.map((step, i) => ( {opp.nextSteps.map((step, i) => (
<span key={i} className="bg-white border border-slate-200 rounded-full px-3 py-1 text-xs text-slate-600"> <span key={i} className="bg-white border border-slate-200 rounded-full px-3 py-1 text-xs text-slate-600">
{i + 1}. {step} {i + 1}. {t(`opportunityPrioritizer.${step}`)}
</span> </span>
))} ))}
</div> </div>
@@ -593,12 +587,12 @@ const OpportunityPrioritizer: React.FC<OpportunityPrioritizerProps> = ({
{showAllOpportunities ? ( {showAllOpportunities ? (
<> <>
<ChevronDown size={16} className="rotate-180" /> <ChevronDown size={16} className="rotate-180" />
Mostrar menos {t('opportunityPrioritizer.showLess')}
</> </>
) : ( ) : (
<> <>
<ChevronDown size={16} /> <ChevronDown size={16} />
Ver {enrichedOpportunities.length - 5} oportunidades más {t('opportunityPrioritizer.viewMore', { count: enrichedOpportunities.length - 5 })}
</> </>
)} )}
</button> </button>
@@ -611,9 +605,7 @@ const OpportunityPrioritizer: React.FC<OpportunityPrioritizerProps> = ({
<div className="flex items-start gap-2"> <div className="flex items-start gap-2">
<Info size={14} className="flex-shrink-0 mt-0.5" /> <Info size={14} className="flex-shrink-0 mt-0.5" />
<div> <div>
<strong>{t('opportunityPrioritizer.methodology')}</strong> Las oportunidades se ordenan por potencial de ahorro TCO (volumen × tasa de contención × diferencial CPI). <strong>{t('opportunityPrioritizer.methodology')}</strong> {t('opportunityPrioritizer.methodologyDescription')}
La clasificación de tier (AUTOMATE/ASSIST/AUGMENT) se basa en el Agentic Readiness Score considerando predictibilidad (CV AHT),
resolutividad (FCR + Transfer), volumen, calidad de datos y simplicidad del proceso.
</div> </div>
</div> </div>
</div> </div>

View File

@@ -1558,10 +1558,10 @@ function AgenticReadinessHeader({
{/* Footer con totales */} {/* Footer con totales */}
<div className="mt-3 pt-3 flex items-center justify-between text-xs" style={{ borderTop: `1px solid ${COLORS.light}`, color: COLORS.medium }}> <div className="mt-3 pt-3 flex items-center justify-between text-xs" style={{ borderTop: `1px solid ${COLORS.light}`, color: COLORS.medium }}>
<span> <span>
Total: <strong style={{ color: COLORS.dark }}>{formatVolume(totalVolume)}</strong> interacciones Total: <strong style={{ color: COLORS.dark }}>{formatVolume(totalVolume)}</strong> {t('agenticReadiness.summary.interactions')}
</span> </span>
<span> <span>
<strong style={{ color: COLORS.dark }}>{totalQueues}</strong> colas analizadas <strong style={{ color: COLORS.dark }}>{totalQueues}</strong> {t('agenticReadiness.summary.queuesAnalyzed')}
</span> </span>
</div> </div>
</div> </div>
@@ -2565,7 +2565,7 @@ function TierQueueSection({
{/* Footer */} {/* Footer */}
<div className="px-5 py-3 bg-gray-50 border-t border-gray-200 text-xs text-gray-500"> <div className="px-5 py-3 bg-gray-50 border-t border-gray-200 text-xs text-gray-500">
Click en un skill para ver el detalle de colas individuales {t('agenticReadiness.table.clickToExpand')}
</div> </div>
</div> </div>
); );
@@ -2618,9 +2618,9 @@ function HumanOnlyByReasonSection({ drilldownData, redFlagConfigs, t }: { drilld
const flagConfig = redFlagConfigs.find(c => c.id === reasonId); const flagConfig = redFlagConfigs.find(c => c.id === reasonId);
return { return {
reasonId, reasonId,
reason: flagConfig?.label || 'Sin Red Flags específicos', reason: flagConfig?.label || t('agenticReadiness.redFlagsActions.noSpecificFlags'),
description: flagConfig?.description || 'Colas que no cumplen criterios de automatización', description: flagConfig?.description || t('agenticReadiness.redFlagsActions.noFlagsDesc'),
action: flagConfig ? getActionForFlag(flagConfig.id) : 'Revisar manualmente', action: flagConfig ? getActionForFlag(flagConfig.id) : t('agenticReadiness.redFlagsActions.reviewManually'),
queues, queues,
totalVolume: queues.reduce((s, q) => s + q.volume, 0), totalVolume: queues.reduce((s, q) => s + q.volume, 0),
queueCount: queues.length queueCount: queues.length
@@ -2643,11 +2643,11 @@ function HumanOnlyByReasonSection({ drilldownData, redFlagConfigs, t }: { drilld
function getActionForFlag(flagId: string): string { function getActionForFlag(flagId: string): string {
switch (flagId) { switch (flagId) {
case 'cv_high': return 'Estandarizar procesos y scripts'; case 'cv_high': return t('agenticReadiness.redFlagsActions.standardizeProcesses');
case 'transfer_high': return 'Simplificar flujo, capacitar agentes'; case 'transfer_high': return t('agenticReadiness.redFlagsActions.simplifyFlow');
case 'volume_low': return 'Consolidar con colas similares'; case 'volume_low': return t('agenticReadiness.redFlagsActions.consolidate');
case 'valid_low': return 'Mejorar captura de datos'; case 'valid_low': return t('agenticReadiness.redFlagsActions.improveDataCapture');
default: return 'Revisar manualmente'; default: return t('agenticReadiness.redFlagsActions.reviewManually');
} }
} }
@@ -3020,16 +3020,16 @@ function HumanOnlyRedFlagsSection({ drilldownData, redFlagConfigs }: { drilldown
let action = ''; let action = '';
switch (config.id) { switch (config.id) {
case 'cv_high': case 'cv_high':
action = 'Estandarizar procesos'; action = t('agenticReadiness.redFlagsActions.standardizeProcesses');
break; break;
case 'transfer_high': case 'transfer_high':
action = 'Simplificar flujo / capacitar'; action = t('agenticReadiness.redFlagsActions.simplifyFlow');
break; break;
case 'volume_low': case 'volume_low':
action = 'Consolidar con similar'; action = t('agenticReadiness.redFlagsActions.consolidate');
break; break;
case 'valid_low': case 'valid_low':
action = 'Mejorar captura datos'; action = t('agenticReadiness.redFlagsActions.improveDataCapture');
break; break;
} }
@@ -3057,10 +3057,10 @@ function HumanOnlyRedFlagsSection({ drilldownData, redFlagConfigs }: { drilldown
<div> <div>
<h3 className="font-semibold text-gray-900 flex items-center gap-2"> <h3 className="font-semibold text-gray-900 flex items-center gap-2">
<AlertOctagon className="w-5 h-5 text-amber-500" /> <AlertOctagon className="w-5 h-5 text-amber-500" />
Skills con Red Flags {t('agenticReadiness.redFlagsActions.skillsWithRedFlags')}
</h3> </h3>
<p className="text-sm text-gray-500 mt-1"> <p className="text-sm text-gray-500 mt-1">
Colas que requieren intervención antes de automatizar {t('agenticReadiness.redFlagsActions.queuesRequireIntervention')}
</p> </p>
</div> </div>
<Badge <Badge
@@ -3654,7 +3654,7 @@ function RoadmapConnectionSection({ drilldownData }: { drilldownData: DrilldownD
<div className="flex items-center gap-2 pt-2"> <div className="flex items-center gap-2 pt-2">
<span className="text-lg">👉</span> <span className="text-lg">👉</span>
<span className="text-sm font-medium" style={{ color: COLORS.primary }}> <span className="text-sm font-medium" style={{ color: COLORS.primary }}>
Ver pestaña Roadmap para plan detallado {t('agenticReadiness.redFlagsActions.viewRoadmapTab')}
</span> </span>
</div> </div>
</div> </div>
@@ -3755,7 +3755,7 @@ export function AgenticReadinessTab({ data, onTabChange }: AgenticReadinessTabPr
onClick={() => onTabChange('roadmap')} onClick={() => onTabChange('roadmap')}
className="text-sm text-blue-600 hover:text-blue-800 hover:underline" className="text-sm text-blue-600 hover:text-blue-800 hover:underline"
> >
Ver pestaña Roadmap para plan detallado {t('agenticReadiness.redFlagsActions.viewRoadmapLink')}
</button> </button>
</div> </div>
)} )}

View File

@@ -1097,7 +1097,11 @@
"standardizeProcesses": "Standardize processes and scripts", "standardizeProcesses": "Standardize processes and scripts",
"simplifyFlow": "Simplify flow, train agents", "simplifyFlow": "Simplify flow, train agents",
"consolidate": "Consolidate with similar queues", "consolidate": "Consolidate with similar queues",
"improveDataCapture": "Improve data capture" "improveDataCapture": "Improve data capture",
"skillsWithRedFlags": "Skills with Red Flags",
"queuesRequireIntervention": "Queues that require intervention before automating",
"viewRoadmapTab": "View Roadmap tab for detailed plan",
"viewRoadmapLink": "View Roadmap tab for detailed plan →"
}, },
"factorsExtended": { "factorsExtended": {
"volumeMethodology": "Score = normalized log10(Volume). >5000 → 10, <100 → 2", "volumeMethodology": "Score = normalized log10(Volume). >5000 → 10, <100 → 2",
@@ -1849,12 +1853,46 @@
"tierLabels": { "tierLabels": {
"automate": "Automate", "automate": "Automate",
"assist": "Assist", "assist": "Assist",
"augment": "Augment" "augment": "Augment",
"human": "Human"
}, },
"timelines": { "timelines": {
"automate": "3-6 months", "automate": "3-6 months",
"assist": "6-9 months", "assist": "6-9 months",
"augment": "9-12 months" "augment": "9-12 months"
},
"tierDescriptions": {
"automate": "Full automation with AI agents",
"assist": "AI Copilot for human agents",
"augment": "Process standardization and improvement",
"humanOnly": "Requires human intervention"
},
"agenticScore": "Agentic Score",
"whyPriority1": "Why is this priority #1?",
"viewCompleteDetail": "View Complete Detail",
"showLess": "Show less",
"whyThisPosition": "Why this position?",
"keyMetrics": "Key Metrics",
"noOpportunitiesTitle": "No opportunities identified",
"noOpportunitiesDescription": "Current data doesn't show viable automation opportunities.",
"reasons": {
"highSavingsPotential": "High savings potential (€{{amount}}K/year)",
"highVolume": "High volume ({{volume}} interactions)",
"highlyPredictable": "Highly predictable and repetitive process",
"lowVariability": "Low variability in handling times",
"lowTransferRate": "Low transfer rate",
"highFeasibility": "High technical feasibility"
},
"steps": {
"automate1": "Define main conversational flows",
"automate2": "Identify necessary integrations (CRM, APIs)",
"automate3": "Create pilot with 10% of volume",
"assist1": "Map agent friction points",
"assist2": "Design contextual suggestions",
"assist3": "Pilot with selected team",
"augment1": "Analyze root cause of variability",
"augment2": "Standardize processes and scripts",
"augment3": "Train team on best practices"
} }
} }
} }

View File

@@ -1128,7 +1128,11 @@
"standardizeProcesses": "Estandarizar procesos y scripts", "standardizeProcesses": "Estandarizar procesos y scripts",
"simplifyFlow": "Simplificar flujo, capacitar agentes", "simplifyFlow": "Simplificar flujo, capacitar agentes",
"consolidate": "Consolidar con colas similares", "consolidate": "Consolidar con colas similares",
"improveDataCapture": "Mejorar captura de datos" "improveDataCapture": "Mejorar captura de datos",
"skillsWithRedFlags": "Skills con Red Flags",
"queuesRequireIntervention": "Colas que requieren intervención antes de automatizar",
"viewRoadmapTab": "Ver pestaña Roadmap para plan detallado",
"viewRoadmapLink": "Ver pestaña Roadmap para plan detallado →"
}, },
"factorsExtended": { "factorsExtended": {
"volumeMethodology": "Score = log10(Volumen) normalizado. >5000 → 10, <100 → 2", "volumeMethodology": "Score = log10(Volumen) normalizado. >5000 → 10, <100 → 2",
@@ -1833,12 +1837,46 @@
"tierLabels": { "tierLabels": {
"automate": "Automatizar", "automate": "Automatizar",
"assist": "Asistir", "assist": "Asistir",
"augment": "Aumentar" "augment": "Aumentar",
"human": "Humano"
}, },
"timelines": { "timelines": {
"automate": "3-6 meses", "automate": "3-6 meses",
"assist": "6-9 meses", "assist": "6-9 meses",
"augment": "9-12 meses" "augment": "9-12 meses"
},
"tierDescriptions": {
"automate": "Automatización completa con agentes IA",
"assist": "Copilot IA para agentes humanos",
"augment": "Estandarización y mejora de procesos",
"humanOnly": "Requiere intervención humana"
},
"agenticScore": "Puntuación Agéntica",
"whyPriority1": "¿Por qué es la prioridad #1?",
"viewCompleteDetail": "Ver Detalle Completo",
"showLess": "Mostrar menos",
"whyThisPosition": "¿Por qué esta posición?",
"keyMetrics": "Métricas Clave",
"noOpportunitiesTitle": "No hay oportunidades identificadas",
"noOpportunitiesDescription": "Los datos actuales no muestran oportunidades de automatización viables.",
"reasons": {
"highSavingsPotential": "Alto ahorro potencial (€{{amount}}K/año)",
"highVolume": "Alto volumen ({{volume}} interacciones)",
"highlyPredictable": "Proceso altamente predecible y repetitivo",
"lowVariability": "Baja variabilidad en tiempos de gestión",
"lowTransferRate": "Baja tasa de transferencias",
"highFeasibility": "Alta factibilidad técnica"
},
"steps": {
"automate1": "Definir flujos conversacionales principales",
"automate2": "Identificar integraciones necesarias (CRM, APIs)",
"automate3": "Crear piloto con 10% del volumen",
"assist1": "Mapear puntos de fricción del agente",
"assist2": "Diseñar sugerencias contextuales",
"assist3": "Piloto con equipo seleccionado",
"augment1": "Analizar causa raíz de variabilidad",
"augment2": "Estandarizar procesos y scripts",
"augment3": "Capacitar equipo en mejores prácticas"
} }
} }
} }