From cbe074f43c531efc70d65c9212b2149228ae6817 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 6 Feb 2026 19:43:01 +0000 Subject: [PATCH] refactor: implement i18n in RoadmapTab and Law10Tab (phase 5) Refactored two major tab components to use react-i18next: RoadmapTab (2,719 lines): - Opportunity bubble chart with all quadrants and methodology - Wave cards with risk levels and strategic recommendations - Tier classification (TIER 1-4) with distribution analysis - Economic impact and feasibility axis labels - 100+ translation keys for visualization and strategy content Law10Tab (1,533 lines): - Spanish regulatory compliance (Ley 10/2025) analysis - All 12 requirements with status evaluations - Time coverage, response speed, resolution quality sections - Compliance messages and action recommendations - 80+ translation keys for regulatory content Added comprehensive translation keys to es.json and en.json: - roadmap section: 100+ keys - law10 section: 80+ keys Build verified successfully. https://claude.ai/code/session_4f888c33-8937-4db8-8a9d-ddc9ac51a725 --- frontend/components/tabs/Law10Tab.tsx | 394 ++++++++++---------- frontend/components/tabs/RoadmapTab.tsx | 225 ++++++------ frontend/locales/en.json | 463 +++++++++++++++++++++++- frontend/locales/es.json | 463 +++++++++++++++++++++++- 4 files changed, 1230 insertions(+), 315 deletions(-) diff --git a/frontend/components/tabs/Law10Tab.tsx b/frontend/components/tabs/Law10Tab.tsx index 9c8d5c3..89a89e2 100644 --- a/frontend/components/tabs/Law10Tab.tsx +++ b/frontend/components/tabs/Law10Tab.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { useTranslation } from 'react-i18next'; import { Scale, Clock, @@ -65,7 +66,7 @@ const LAW_10_2025 = { // FUNCIONES DE EVALUACION DE COMPLIANCE // ============================================ -function evaluateLaw07Compliance(data: AnalysisData): ComplianceResult { +function evaluateLaw07Compliance(data: AnalysisData, t: (key: string, options?: any) => string): ComplianceResult { // Evaluar cobertura horaria basado en off_hours_pct const volumetryDim = data.dimensions.find(d => d.name === 'volumetry_distribution'); const offHoursPct = volumetryDim?.distribution_data?.off_hours_pct ?? null; @@ -74,39 +75,39 @@ function evaluateLaw07Compliance(data: AnalysisData): ComplianceResult { return { status: 'SIN_DATOS', score: 0, - gap: 'Sin datos de distribucion horaria', - details: ['No se encontraron datos de distribucion horaria en el analisis'], + gap: t('law10.compliance.law07.noData'), + details: [t('law10.compliance.law07.noDataDetails')], }; } const details: string[] = []; - details.push(`${offHoursPct.toFixed(1)}% de interacciones fuera de horario laboral`); + details.push(t('law10.compliance.law07.offHoursPercent', { percent: offHoursPct.toFixed(1) })); if (offHoursPct < 5) { return { status: 'CUMPLE', score: 100, gap: '-', - details: [...details, 'Cobertura horaria adecuada'], + details: [...details, t('law10.compliance.law07.adequateCoverage')], }; } else if (offHoursPct <= 15) { return { status: 'PARCIAL', score: Math.round(100 - ((offHoursPct - 5) / 10) * 50), - gap: `${(offHoursPct - 5).toFixed(1)}pp sobre optimo`, - details: [...details, 'Cobertura horaria mejorable - considerar ampliar horarios'], + gap: t('law10.compliance.law07.gapOverOptimal', { gap: (offHoursPct - 5).toFixed(1) }), + details: [...details, t('law10.compliance.law07.improvableCoverage')], }; } else { return { status: 'NO_CUMPLE', score: Math.max(0, Math.round(50 - ((offHoursPct - 15) / 10) * 50)), - gap: `${(offHoursPct - 15).toFixed(1)}pp sobre limite`, - details: [...details, 'Cobertura horaria insuficiente - requiere accion inmediata'], + gap: t('law10.compliance.law07.gapOverLimit', { gap: (offHoursPct - 15).toFixed(1) }), + details: [...details, t('law10.compliance.law07.insufficientCoverage')], }; } } -function evaluateLaw01Compliance(data: AnalysisData): ComplianceResult { +function evaluateLaw01Compliance(data: AnalysisData, t: (key: string, options?: any) => string): ComplianceResult { // Evaluar tiempo de espera (hold_time) vs limite de 180 segundos const totalVolume = data.heatmapData.reduce((sum, h) => sum + h.volume, 0); @@ -114,8 +115,8 @@ function evaluateLaw01Compliance(data: AnalysisData): ComplianceResult { return { status: 'SIN_DATOS', score: 0, - gap: 'Sin datos de tiempos de espera', - details: ['No se encontraron datos de hold_time en el analisis'], + gap: t('law10.compliance.law01.noData'), + details: [t('law10.compliance.law01.noDataDetails')], }; } @@ -135,35 +136,35 @@ function evaluateLaw01Compliance(data: AnalysisData): ComplianceResult { const pctDentroLimite = (volDentroLimite / totalVolume) * 100; const details: string[] = []; - details.push(`Tiempo de espera promedio: ${Math.round(avgHoldTime)}s (limite: 180s)`); - details.push(`${pctDentroLimite.toFixed(1)}% de interacciones dentro del limite`); - details.push(`${colasExceden.length} de ${data.heatmapData.length} colas exceden el limite`); + details.push(t('law10.compliance.law01.avgHoldTime', { time: Math.round(avgHoldTime) })); + details.push(t('law10.compliance.law01.withinLimit', { percent: pctDentroLimite.toFixed(1) })); + details.push(t('law10.compliance.law01.queuesExceedLimit', { count: colasExceden.length, total: data.heatmapData.length })); if (avgHoldTime < 180 && pctColasExceden < 10) { return { status: 'CUMPLE', score: 100, - gap: `-${Math.round(180 - avgHoldTime)}s`, + gap: t('law10.compliance.law01.gapNegative', { gap: Math.round(180 - avgHoldTime) }), details, }; } else if (avgHoldTime < 180) { return { status: 'PARCIAL', score: Math.round(90 - pctColasExceden), - gap: `${colasExceden.length} colas fuera`, + gap: t('law10.compliance.law01.queuesOutside', { count: colasExceden.length }), details, }; } else { return { status: 'NO_CUMPLE', score: Math.max(0, Math.round(50 - ((avgHoldTime - 180) / 60) * 25)), - gap: `+${Math.round(avgHoldTime - 180)}s`, + gap: t('law10.compliance.law01.gapPositive', { gap: Math.round(avgHoldTime - 180) }), details, }; } } -function evaluateLaw02Compliance(data: AnalysisData): ComplianceResult { +function evaluateLaw02Compliance(data: AnalysisData, t: (key: string, options?: any) => string): ComplianceResult { // Evaluar FCR y tasa de transferencia const totalVolume = data.heatmapData.reduce((sum, h) => sum + h.volume, 0); @@ -171,8 +172,8 @@ function evaluateLaw02Compliance(data: AnalysisData): ComplianceResult { return { status: 'SIN_DATOS', score: 0, - gap: 'Sin datos de resolucion', - details: ['No se encontraron datos de FCR o transferencias'], + gap: t('law10.compliance.law02.noData'), + details: [t('law10.compliance.law02.noDataDetails')], }; } @@ -187,13 +188,13 @@ function evaluateLaw02Compliance(data: AnalysisData): ComplianceResult { ) / totalVolume; const details: string[] = []; - details.push(`FCR Tecnico: ${avgFCR.toFixed(1)}% (objetivo: >75%)`); - details.push(`Tasa de transferencia: ${avgTransfer.toFixed(1)}% (objetivo: <15%)`); + details.push(t('law10.compliance.law02.fcrTechnical', { fcr: avgFCR.toFixed(1) })); + details.push(t('law10.compliance.law02.transferRate', { rate: avgTransfer.toFixed(1) })); // Colas con alto transfer const colasAltoTransfer = data.heatmapData.filter(h => h.metrics.transfer_rate > 25); if (colasAltoTransfer.length > 0) { - details.push(`${colasAltoTransfer.length} colas con transfer >25%`); + details.push(t('law10.compliance.law02.highTransferQueues', { count: colasAltoTransfer.length })); } const cumpleFCR = avgFCR >= 75; @@ -205,7 +206,7 @@ function evaluateLaw02Compliance(data: AnalysisData): ComplianceResult { return { status: 'CUMPLE', score: 100, - gap: '-', + gap: t('law10.compliance.law02.gapDash'), details, }; } else if (parcialFCR && parcialTransfer) { @@ -213,31 +214,33 @@ function evaluateLaw02Compliance(data: AnalysisData): ComplianceResult { (Math.min(avgFCR, 75) / 75 * 50) + (Math.max(0, 25 - avgTransfer) / 25 * 50) ); + const fcrGap = avgFCR < 75 ? t('law10.compliance.law02.gapNegative', { gap: (75 - avgFCR).toFixed(0) }) : t('law10.compliance.law02.gapOk'); + const transferGap = avgTransfer > 15 ? t('law10.compliance.law02.gapPositive', { gap: (avgTransfer - 15).toFixed(0) }) : t('law10.compliance.law02.gapOk'); return { status: 'PARCIAL', score, - gap: `FCR ${avgFCR < 75 ? `-${(75 - avgFCR).toFixed(0)}pp` : 'OK'}, Transfer ${avgTransfer > 15 ? `+${(avgTransfer - 15).toFixed(0)}pp` : 'OK'}`, + gap: t('law10.compliance.law02.gapFcr', { fcrGap, transferGap }), details, }; } else { return { status: 'NO_CUMPLE', score: Math.max(0, Math.round((avgFCR / 75 * 30) + ((30 - avgTransfer) / 30 * 20))), - gap: `FCR -${(75 - avgFCR).toFixed(0)}pp, Transfer +${(avgTransfer - 15).toFixed(0)}pp`, + gap: `FCR ${t('law10.compliance.law02.gapNegative', { gap: (75 - avgFCR).toFixed(0) })}, Transfer ${t('law10.compliance.law02.gapPositive', { gap: (avgTransfer - 15).toFixed(0) })}`, details, }; } } -function evaluateLaw09Compliance(_data: AnalysisData): ComplianceResult { +function evaluateLaw09Compliance(_data: AnalysisData, t: (key: string, options?: any) => string): ComplianceResult { // Los datos de idioma no estan disponibles en el modelo actual return { status: 'SIN_DATOS', score: 0, - gap: 'Requiere datos', + gap: t('law10.compliance.law09.noData'), details: [ - 'No se dispone de datos de idioma en las interacciones', - 'Para evaluar este requisito se necesita el campo "language" en el CSV', + t('law10.compliance.law09.noLanguageData'), + t('law10.compliance.law09.needsLanguageField'), ], }; } @@ -273,12 +276,12 @@ function getStatusBadgeVariant(status: ComplianceStatus): 'success' | 'warning' } } -function getStatusLabel(status: ComplianceStatus): string { +function getStatusLabel(status: ComplianceStatus, t: (key: string) => string): string { switch (status) { - case 'CUMPLE': return 'Cumple'; - case 'PARCIAL': return 'Parcial'; - case 'NO_CUMPLE': return 'No Cumple'; - default: return 'Sin Datos'; + case 'CUMPLE': return t('law10.status.CUMPLE'); + case 'PARCIAL': return t('law10.status.PARCIAL'); + case 'NO_CUMPLE': return t('law10.status.NO_CUMPLE'); + default: return t('law10.status.SIN_DATOS'); } } @@ -288,6 +291,7 @@ function Law10HeaderCountdown({ }: { complianceResults: { law07: ComplianceResult; law01: ComplianceResult; law02: ComplianceResult; law09: ComplianceResult }; }) { + const { t } = useTranslation(); const now = new Date(); const deadline = LAW_10_2025.deadline; const diffTime = deadline.getTime() - now.getTime(); @@ -314,18 +318,14 @@ function Law10HeaderCountdown({
-

Sobre este Analisis

-

Ley 10/2025 de Atencion al Cliente

+

{t('law10.header.aboutThisAnalysis')}

+

{t('law10.header.lawTitle')}

{/* Descripcion */}
-

- Este modulo conecta tus metricas operacionales actuales con los requisitos de la - Ley 10/2025. No mide compliance directamente (requeriria datos adicionales), pero SI - identifica patrones que impactan en tu capacidad de cumplir con la normativa. -

+

{/* Metricas de estado */} @@ -334,9 +334,9 @@ function Law10HeaderCountdown({
-

Deadline de cumplimiento

-

28 Diciembre 2026

-

{diffDays} dias restantes

+

{t('law10.header.complianceDeadline')}

+

{t('law10.header.december282026')}

+

{t('law10.header.daysRemaining', { days: diffDays })}

@@ -344,9 +344,9 @@ function Law10HeaderCountdown({
-

Requisitos evaluados

-

{cumplidos} de {total} cumplen

-

Basado en datos disponibles

+

{t('law10.header.requirementsEvaluated')}

+

{t('law10.header.requirementsMet', { met: cumplidos, total })}

+

{t('law10.header.basedOnData')}

@@ -354,18 +354,18 @@ function Law10HeaderCountdown({
-

Estado general

+

{t('law10.header.overallStatus')}

- {getStatusLabel(overallStatus)} + {getStatusLabel(overallStatus, t)}

- {overallStatus === 'CUMPLE' ? 'Buen estado' : - overallStatus === 'PARCIAL' ? 'Requiere atencion' : 'Accion urgente'} + {overallStatus === 'CUMPLE' ? t('law10.header.goodState') : + overallStatus === 'PARCIAL' ? t('law10.header.requiresAttention') : t('law10.header.urgentAction')}

@@ -376,6 +376,7 @@ function Law10HeaderCountdown({ // Seccion: Cobertura Horaria (LAW-07) function TimeCoverageSection({ data, result }: { data: AnalysisData; result: ComplianceResult }) { + const { t } = useTranslation(); const volumetryDim = data.dimensions.find(d => d.name === 'volumetry_distribution'); const hourlyData = volumetryDim?.distribution_data?.hourly || []; const dailyData = volumetryDim?.distribution_data?.daily || []; @@ -447,13 +448,13 @@ function TimeCoverageSection({ data, result }: { data: AnalysisData; result: Com
-

Cobertura Temporal: Disponibilidad del Servicio

-

Relacionado con Art. 14 - Servicios basicos 24/7

+

{t('law10.timeCoverage.title')}

+

{t('law10.timeCoverage.article')}

- +
@@ -461,12 +462,12 @@ function TimeCoverageSection({ data, result }: { data: AnalysisData; result: Com

- LO QUE SABEMOS + {t('law10.timeCoverage.whatWeKnow')}

{/* Heatmap 24x7 */}
-

HEATMAP VOLUMETRICO 24x7

+

{t('law10.timeCoverage.heatmap247')}

{/* Header de horas */}
@@ -500,32 +501,32 @@ function TimeCoverageSection({ data, result }: { data: AnalysisData; result: Com {/* Leyenda */}
- Intensidad: - ▁ Bajo - ▄ Medio - █ Alto + {t('law10.timeCoverage.intensity')} + ▁ {t('law10.timeCoverage.intensityLow')} + ▄ {t('law10.timeCoverage.intensityMedium')} + █ {t('law10.timeCoverage.intensityHigh')}
{/* Hallazgos operacionales */}
-

Hallazgos operacionales:

+

{t('law10.timeCoverage.operationalFindings')}

  • - Horario detectado: L-V 08:00-22:00, S-D horario reducido +
  • - Volumen nocturno (22:00-08:00): {formatNumber(nightVolume)} interacciones ({nightPct.toFixed(1)}%) +
  • - Volumen madrugada (00:00-06:00): {formatNumber(earlyMorningVolume)} interacciones ({earlyMorningPct.toFixed(1)}%) +
  • - Pico maximo: {maxHourIndex}:00-{maxHourIndex + 1}:00 ({maxHourPct.toFixed(1)}% del volumen diario) +
@@ -535,25 +536,25 @@ function TimeCoverageSection({ data, result }: { data: AnalysisData; result: Com

- IMPLICACION LEY 10/2025 + {t('law10.timeCoverage.lawImplication')}

- Transporte aereo = Servicio basico
- → Art. 14 requiere atencion 24/7 para incidencias + {t('law10.timeCoverage.basicServiceRequirement')}
+ {t('law10.timeCoverage.article14Requirement')}

-

Gap identificado:

+

{t('law10.timeCoverage.gapIdentified')}

  • - {nightPct.toFixed(1)}% de tus clientes contactan fuera del horario actual +
  • - Si estas son incidencias (equipaje perdido, cambios urgentes), NO cumples Art. 14 +
@@ -564,32 +565,32 @@ function TimeCoverageSection({ data, result }: { data: AnalysisData; result: Com

- ACCION SUGERIDA + {t('law10.timeCoverage.suggestedAction')}

-

1. Clasificar volumen nocturno por tipo:

+

{t('law10.timeCoverage.classifyNightVolume')}

    -
  • • ¿Que % son incidencias criticas? → Requiere 24/7
  • -
  • • ¿Que % son consultas generales? → Pueden esperar
  • +
  • • {t('law10.timeCoverage.criticalIncidents')}
  • +
  • • {t('law10.timeCoverage.generalQueries')}
-

2. Opciones de cobertura:

+

{t('law10.timeCoverage.coverageOptions')}

- A) Chatbot IA + agente on-call - ~65K/año + {t('law10.timeCoverage.optionAChatbot')} + {t('law10.timeCoverage.costPerYear', { cost: '65K' })}
- B) Redirigir a call center 24/7 externo - ~95K/año + {t('law10.timeCoverage.optionBExternal')} + {t('law10.timeCoverage.costPerYear', { cost: '95K' })}
- C) Agentes nocturnos (3 turnos) - ~180K/año + {t('law10.timeCoverage.optionCNight')} + {t('law10.timeCoverage.costPerYear', { cost: '180K' })}
@@ -601,6 +602,7 @@ function TimeCoverageSection({ data, result }: { data: AnalysisData; result: Com // Seccion: Velocidad de Respuesta (LAW-01) function ResponseSpeedSection({ data, result }: { data: AnalysisData; result: ComplianceResult }) { + const { t } = useTranslation(); const totalVolume = data.heatmapData.reduce((sum, h) => sum + h.volume, 0); const volumetryDim = data.dimensions.find(d => d.name === 'volumetry_distribution'); const hourlyData = volumetryDim?.distribution_data?.hourly || []; @@ -677,13 +679,13 @@ function ResponseSpeedSection({ data, result }: { data: AnalysisData; result: Co
-

Velocidad de Atencion: Eficiencia Operativa

-

Relacionado con Art. 8.2 - 95% llamadas <3min

+

{t('law10.responseSpeed.title')}

+

{t('law10.responseSpeed.article')}

- +
@@ -691,22 +693,22 @@ function ResponseSpeedSection({ data, result }: { data: AnalysisData; result: Co

- LO QUE SABEMOS + {t('law10.responseSpeed.whatWeKnow')}

{/* Metricas principales */}

{abandonRate.toFixed(1)}%

-

Tasa abandono

+

{t('law10.responseSpeed.abandonmentRate')}

{Math.round(ahtP50)}s

-

AHT P50 ({Math.floor(ahtP50 / 60)}m {Math.round(ahtP50 % 60)}s)

+

{t('law10.responseSpeed.ahtP50', { min: Math.floor(ahtP50 / 60), sec: Math.round(ahtP50 % 60) })}

{Math.round(ahtP90)}s

-

AHT P90 ({Math.floor(ahtP90 / 60)}m {Math.round(ahtP90 % 60)}s)

+

{t('law10.responseSpeed.ahtP90', { min: Math.floor(ahtP90 / 60), sec: Math.round(ahtP90 % 60) })}

2 ? 'text-amber-600' : 'text-gray-900' )}>{ahtRatio.toFixed(1)}

-

Ratio P90/P50 {ahtRatio > 2 && '(elevado)'}

+

{t('law10.responseSpeed.ratioP90P50', { elevated: ahtRatio > 2 ? t('law10.responseSpeed.elevated') : '' })}

{/* Grafico de abandonos por hora */}
-

DISTRIBUCION DE ABANDONOS POR HORA

+

{t('law10.responseSpeed.abandonmentByHour')}

{hourlyAbandonment.map((h, idx) => (
24:00
- Abandono: - ▁ <8% - ▃ 8-15% - █ >20% + {t('law10.responseSpeed.abandonmentLegend')} + + +
{/* Patrones observados */}
-

Patrones observados:

+

{t('law10.responseSpeed.patternsObserved')}

  • - Mayor abandono: {maxAbandonHour.hour}:00-{maxAbandonHour.hour + 2}:00 ({maxAbandonHour.abandonRate.toFixed(1)}% vs {abandonRate.toFixed(1)}% media) +
  • - AHT mas alto: Lunes 09:00-11:00 ({Math.round(ahtP50 * 1.18)}s vs {Math.round(ahtP50)}s P50) +
  • - Menor abandono: {minAbandonHour.hour}:00-{minAbandonHour.hour + 2}:00 ({minAbandonHour.abandonRate.toFixed(1)}%) +
@@ -775,54 +777,47 @@ function ResponseSpeedSection({ data, result }: { data: AnalysisData; result: Co

- IMPLICACION LEY 10/2025 + {t('law10.responseSpeed.lawImplication')}

-

- Art. 8.2 requiere: "95% de llamadas atendidas en <3 minutos" -

+

- LIMITACION DE DATOS + {t('law10.responseSpeed.dataLimitation')}

- Tu CDR actual NO incluye ASA (tiempo en cola antes de responder), - por lo que NO podemos medir este requisito directamente. + {t('law10.responseSpeed.noAsaData')}

-

PERO SI sabemos:

+

{t('law10.responseSpeed.butWeKnow')}

  • - {abandonRate.toFixed(1)}% de clientes abandonan → Probablemente esperaron mucho +
  • - Alta variabilidad AHT (P90/P50={ahtRatio.toFixed(1)}) → Cola impredecible + {t('law10.responseSpeed.highVariability', { ratio: ahtRatio.toFixed(1) })}
  • - Picos de abandono coinciden con picos de volumen + {t('law10.responseSpeed.peaksCoincide')}
-

Estimacion conservadora (±10% margen error):

-

- → ~{estimatedFastResponse.toFixed(0)}% de llamadas probablemente atendidas "rapido" -

+

{t('law10.responseSpeed.conservativeEstimate')}

+

0 ? 'text-red-600' : 'text-emerald-600' - )}> - → Gap vs 95% requerido: {gapVs95 > 0 ? '-' : '+'}{Math.abs(gapVs95).toFixed(0)} puntos porcentuales -

+ )} dangerouslySetInnerHTML={{ __html: t('law10.responseSpeed.gapVs95', { operator: gapVs95 > 0 ? '-' : '+', gap: Math.abs(gapVs95).toFixed(0) }) }} />
@@ -831,32 +826,32 @@ function ResponseSpeedSection({ data, result }: { data: AnalysisData; result: Co

- ACCION SUGERIDA + {t('law10.responseSpeed.suggestedAction')}

-

1. CORTO PLAZO: Reducir AHT para aumentar capacidad

+

{t('law10.responseSpeed.shortTerm')}

    -
  • • Tu Dimension 2 (Eficiencia) ya identifica:
  • -
  • - AHT elevado ({Math.round(ahtP50)}s vs 380s benchmark)
  • -
  • - Oportunidad Copilot IA: -18% AHT proyectado
  • -
  • • Beneficio dual: ↓ AHT = ↑ capacidad = ↓ cola = ↑ ASA
  • +
  • • {t('law10.responseSpeed.dimension2Identifies')}
  • +
  • {t('law10.responseSpeed.highAht', { aht: Math.round(ahtP50) })}
  • +
  • {t('law10.responseSpeed.copilotOpportunity')}
  • +
  • • {t('law10.responseSpeed.dualBenefit')}
-

2. MEDIO PLAZO: Implementar tracking ASA real

+

{t('law10.responseSpeed.mediumTerm')}

- Configuracion en plataforma + {t('law10.responseSpeed.platformConfig')} 5-8K
- Timeline implementacion - 4-6 semanas + {t('law10.responseSpeed.implementationTimeline')} + {t('law10.responseSpeed.implementationWeeks')}
-

Beneficio: Medicion precisa para auditoria ENAC

+

{t('law10.responseSpeed.benefit')}

@@ -867,6 +862,7 @@ function ResponseSpeedSection({ data, result }: { data: AnalysisData; result: Co // Seccion: Calidad de Resolucion (LAW-02) function ResolutionQualitySection({ data, result }: { data: AnalysisData; result: ComplianceResult }) { + const { t } = useTranslation(); const totalVolume = data.heatmapData.reduce((sum, h) => sum + h.volume, 0); // FCR Tecnico y Real @@ -925,13 +921,13 @@ function ResolutionQualitySection({ data, result }: { data: AnalysisData; result
-

Calidad de Resolucion: Efectividad

-

Relacionado con Art. 17 - Resolucion en 15 dias

+

{t('law10.resolutionQuality.title')}

+

{t('law10.resolutionQuality.article')}

- +
@@ -939,7 +935,7 @@ function ResolutionQualitySection({ data, result }: { data: AnalysisData; result

- LO QUE SABEMOS + {t('law10.resolutionQuality.whatWeKnow')}

{/* Metricas principales */} @@ -952,21 +948,21 @@ function ResolutionQualitySection({ data, result }: { data: AnalysisData; result 'text-2xl font-bold', avgFCRReal >= 60 ? 'text-gray-900' : 'text-red-600' )}>{avgFCRReal.toFixed(0)}%

-

FCR Real (fcr_real_flag)

+

{t('law10.resolutionQuality.fcrReal')}

{recontactRate7d.toFixed(0)}%

-

Tasa recontacto 7 dias

+

{t('law10.resolutionQuality.recontactRate7d')}

{repeatCallsPct.toFixed(0)}%

-

Llamadas repetidas

+

{t('law10.resolutionQuality.repeatCalls')}

{/* Grafico FCR por skill */}
-

FCR POR SKILL/QUEUE

+

{t('law10.resolutionQuality.fcrBySkill')}

{skillFCRData.slice(0, 8).map((s, idx) => (
@@ -994,22 +990,22 @@ function ResolutionQualitySection({ data, result }: { data: AnalysisData; result ))}
- FCR: - ▁ <45% - ▃ 45-65% - █ >75% + {t('law10.resolutionQuality.fcrLegend')} + + +
{/* Top skills con FCR bajo */} {lowFCRSkills.length > 0 && (
-

Top skills con FCR bajo:

+

{t('law10.resolutionQuality.topLowFcr')}

    {lowFCRSkills.map((s, idx) => (
  • {idx + 1}. - {s.skill}: {s.fcrReal.toFixed(0)}% FCR + {s.skill}: {t('law10.resolutionQuality.fcrValue', { fcr: s.fcrReal.toFixed(0) })}
  • ))}
@@ -1021,48 +1017,44 @@ function ResolutionQualitySection({ data, result }: { data: AnalysisData; result

- IMPLICACION LEY 10/2025 + {t('law10.resolutionQuality.lawImplication')}

-

- Art. 17 requiere: "Resolucion de reclamaciones ≤15 dias" -

+

- LIMITACION DE DATOS + {t('law10.resolutionQuality.dataLimitation')}

- Tu CDR solo registra interacciones individuales, NO casos multi-touch - ni tiempo total de resolucion. + {t('law10.resolutionQuality.noCaseTracking')}

-

PERO SI sabemos:

+

{t('law10.resolutionQuality.butWeKnow')}

  • - {recontactRate7d.toFixed(0)}% de casos requieren multiples contactos +
  • - FCR {avgFCRReal.toFixed(0)}% = {recontactRate7d.toFixed(0)}% NO resuelto en primera interaccion + {t('law10.resolutionQuality.fcrGap', { fcr: avgFCRReal.toFixed(0), gap: recontactRate7d.toFixed(0) })}
  • - Esto sugiere procesos complejos o informacion fragmentada + {t('law10.resolutionQuality.complexProcesses')}
-

Senal de alerta:

+

{t('law10.resolutionQuality.alertSignal')}

- Si los clientes recontactan multiples veces por el mismo tema, es probable - que el tiempo TOTAL de resolucion supere los 15 dias requeridos por ley. + {t('law10.resolutionQuality.resolutionTimeRisk')}

@@ -1072,30 +1064,30 @@ function ResolutionQualitySection({ data, result }: { data: AnalysisData; result

- ACCION SUGERIDA + {t('law10.resolutionQuality.suggestedAction')}

-

1. DIAGNOSTICO: Implementar sistema de casos/tickets

+

{t('law10.resolutionQuality.diagnosis')}

    -
  • • Registrar fecha apertura + cierre
  • -
  • • Vincular multiples interacciones al mismo caso
  • -
  • • Tipologia: consulta / reclamacion / incidencia
  • +
  • • {t('law10.resolutionQuality.registerOpenClose')}
  • +
  • • {t('law10.resolutionQuality.linkInteractions')}
  • +
  • • {t('law10.resolutionQuality.typology')}
- Inversion CRM/Ticketing + {t('law10.resolutionQuality.crmInvestment')} 15-25K
-

2. MEJORA OPERATIVA: Aumentar FCR

+

{t('law10.resolutionQuality.operationalImprovement')}

    -
  • • Tu Dimension 3 (Efectividad) ya identifica:
  • -
  • - Root causes: info fragmentada, falta empowerment
  • -
  • - Solucion: Knowledge base + decision trees
  • -
  • • Beneficio: ↑ FCR = ↓ recontactos = ↓ tiempo total
  • +
  • • {t('law10.resolutionQuality.dimension3Identifies')}
  • +
  • {t('law10.resolutionQuality.rootCauses')}
  • +
  • {t('law10.resolutionQuality.solution')}
  • +
  • • {t('law10.resolutionQuality.fcrBenefit')}
@@ -1112,86 +1104,88 @@ function Law10SummaryRoadmap({ complianceResults: { law07: ComplianceResult; law01: ComplianceResult; law02: ComplianceResult; law09: ComplianceResult }; data: AnalysisData; }) { + const { t } = useTranslation(); + // Resultado por defecto para requisitos sin datos const sinDatos: ComplianceResult = { status: 'SIN_DATOS', score: 0, - gap: 'Requiere datos', - details: ['No se dispone de datos para evaluar este requisito'], + gap: t('law10.common.requiredData'), + details: [t('law10.common.noData')], }; // Todos los requisitos de la Ley 10/2025 con descripciones const allRequirements = [ { id: 'LAW-01', - name: 'Tiempo de Espera', - description: 'Tiempo maximo de espera de 3 minutos para atencion telefonica', + name: t('law10.summary.requirements.LAW-01.name'), + description: t('law10.summary.requirements.LAW-01.description'), result: complianceResults.law01, }, { id: 'LAW-02', - name: 'Resolucion Efectiva', - description: 'Resolucion en primera contacto sin transferencias innecesarias', + name: t('law10.summary.requirements.LAW-02.name'), + description: t('law10.summary.requirements.LAW-02.description'), result: complianceResults.law02, }, { id: 'LAW-03', - name: 'Acceso a Agente Humano', - description: 'Derecho a hablar con un agente humano en cualquier momento', + name: t('law10.summary.requirements.LAW-03.name'), + description: t('law10.summary.requirements.LAW-03.description'), result: sinDatos, }, { id: 'LAW-04', - name: 'Grabacion de Llamadas', - description: 'Notificacion previa de grabacion y acceso a la misma', + name: t('law10.summary.requirements.LAW-04.name'), + description: t('law10.summary.requirements.LAW-04.description'), result: sinDatos, }, { id: 'LAW-05', - name: 'Accesibilidad', - description: 'Canales accesibles para personas con discapacidad', + name: t('law10.summary.requirements.LAW-05.name'), + description: t('law10.summary.requirements.LAW-05.description'), result: sinDatos, }, { id: 'LAW-06', - name: 'Confirmacion Escrita', - description: 'Confirmacion por escrito de reclamaciones y gestiones', + name: t('law10.summary.requirements.LAW-06.name'), + description: t('law10.summary.requirements.LAW-06.description'), result: sinDatos, }, { id: 'LAW-07', - name: 'Cobertura Horaria', - description: 'Atencion 24/7 para servicios esenciales o horario ampliado', + name: t('law10.summary.requirements.LAW-07.name'), + description: t('law10.summary.requirements.LAW-07.description'), result: complianceResults.law07, }, { id: 'LAW-08', - name: 'Formacion de Agentes', - description: 'Personal cualificado y formado en atencion al cliente', + name: t('law10.summary.requirements.LAW-08.name'), + description: t('law10.summary.requirements.LAW-08.description'), result: sinDatos, }, { id: 'LAW-09', - name: 'Idiomas Cooficiales', - description: 'Atencion en catalan, euskera, gallego y valenciano', + name: t('law10.summary.requirements.LAW-09.name'), + description: t('law10.summary.requirements.LAW-09.description'), result: complianceResults.law09, }, { id: 'LAW-10', - name: 'Plazos de Resolucion', - description: 'Resolucion de reclamaciones en maximo 15 dias habiles', + name: t('law10.summary.requirements.LAW-10.name'), + description: t('law10.summary.requirements.LAW-10.description'), result: sinDatos, }, { id: 'LAW-11', - name: 'Gratuidad del Servicio', - description: 'Atencion telefonica sin coste adicional (numeros 900)', + name: t('law10.summary.requirements.LAW-11.name'), + description: t('law10.summary.requirements.LAW-11.description'), result: sinDatos, }, { id: 'LAW-12', - name: 'Trazabilidad', - description: 'Numero de referencia para seguimiento de gestiones', + name: t('law10.summary.requirements.LAW-12.name'), + description: t('law10.summary.requirements.LAW-12.description'), result: sinDatos, }, ]; @@ -1496,12 +1490,14 @@ function DataMaturitySummary({ data }: { data: AnalysisData }) { // ============================================ export function Law10Tab({ data }: Law10TabProps) { + const { t } = useTranslation(); + // Evaluar compliance para cada requisito const complianceResults = { - law07: evaluateLaw07Compliance(data), - law01: evaluateLaw01Compliance(data), - law02: evaluateLaw02Compliance(data), - law09: evaluateLaw09Compliance(data), + law07: evaluateLaw07Compliance(data, t), + law01: evaluateLaw01Compliance(data, t), + law02: evaluateLaw02Compliance(data, t), + law09: evaluateLaw09Compliance(data, t), }; return ( diff --git a/frontend/components/tabs/RoadmapTab.tsx b/frontend/components/tabs/RoadmapTab.tsx index 75cf5ca..669010c 100644 --- a/frontend/components/tabs/RoadmapTab.tsx +++ b/frontend/components/tabs/RoadmapTab.tsx @@ -5,6 +5,7 @@ import { ArrowRight, Info, Users, Target, Zap, Shield, ChevronDown, ChevronUp, BookOpen, Bot, Settings, Rocket, AlertCircle } from 'lucide-react'; +import { useTranslation } from 'react-i18next'; import { RoadmapPhase } from '../../types'; import type { AnalysisData, RoadmapInitiative, HeatmapDataPoint, DrilldownDataPoint, OriginalQueueMetrics, AgenticTier } from '../../types'; import { @@ -450,6 +451,8 @@ function OpportunityBubbleChart({ heatmapData: HeatmapDataPoint[]; drilldownData?: DrilldownDataPoint[] }) { + const { t } = useTranslation(); + // v3.5: Usar drilldownData si está disponible para tener info de Tier por cola let chartData: BubbleDataPoint[] = []; @@ -517,10 +520,10 @@ function OpportunityBubbleChart({

- Mapa de Oportunidades por Tier + {t('roadmap.opportunityMapTitle')}

- Factibilidad (Score) vs Impacto Económico (Ahorro TCO) • Tamaño = Volumen • Color = Tier + {t('roadmap.opportunityMapSubtitle')}

@@ -529,12 +532,12 @@ function OpportunityBubbleChart({
{/* Y-axis label */}
- IMPACTO ECONÓMICO (Ahorro TCO €/año) + {t('roadmap.economicImpactAxis')}
{/* X-axis label */}
- FACTIBILIDAD (Agentic Readiness Score 0-10) + {t('roadmap.feasibilityAxis')}
{/* Chart area */} @@ -553,7 +556,7 @@ function OpportunityBubbleChart({ style={{ left: `${(7.5 / 10) * 100}%` }} > - Tier AUTOMATE ≥7.5 + {t('roadmap.tierAutomateThreshold')}
@@ -566,27 +569,27 @@ function OpportunityBubbleChart({ {/* Quadrant labels - basados en Score (X) y Ahorro (Y) */} {/* Top-right: High Score + High Savings = QUICK WINS */}
-
🎯 QUICK WINS
-
Score ≥7.5 + Ahorro alto
-
→ Prioridad 1
+
🎯 {t('roadmap.quadrantQuickWins')}
+
{t('roadmap.quadrantQuickWinsDesc')}
+
{t('roadmap.quadrantQuickWinsPriority')}
{/* Top-left: Low Score + High Savings = OPTIMIZE */}
-
⚙️ OPTIMIZE
-
Score <7.5 + Ahorro alto
-
→ Wave 1 primero
+
⚙️ {t('roadmap.quadrantOptimize')}
+
{t('roadmap.quadrantOptimizeDesc')}
+
{t('roadmap.quadrantOptimizePriority')}
{/* Bottom-right: High Score + Low Savings = STRATEGIC */}
-
📊 STRATEGIC
-
Score ≥7.5 + Ahorro bajo
-
→ Evaluar ROI
+
📊 {t('roadmap.quadrantStrategic')}
+
{t('roadmap.quadrantStrategicDesc')}
+
{t('roadmap.quadrantStrategicPriority')}
{/* Bottom-left: Low Score + Low Savings = DEFER */}
-
📋 DEFER
-
Score <7.5 + Ahorro bajo
-
→ Backlog
+
📋 {t('roadmap.quadrantDefer')}
+
{t('roadmap.quadrantDeferDesc')}
+
{t('roadmap.quadrantDeferPriority')}
{/* Bubbles */} @@ -629,19 +632,19 @@ function OpportunityBubbleChart({
{item.name}
- Score: + {t('roadmap.tooltipScore')} {item.feasibility.toFixed(1)}/10
- Volumen: - {item.volume.toLocaleString()}/mes + {t('roadmap.tooltipVolume')} + {item.volume.toLocaleString()}{t('roadmap.perMonth')}
- Ahorro TCO: - {formatCurrency(item.economicImpact)}/año + {t('roadmap.tooltipSavingsTco')} + {formatCurrency(item.economicImpact)}{t('roadmap.perYear')}
- Tier: + {t('roadmap.tooltipTier')}

- Interpretación: Las burbujas en el cuadrante superior derecho (Score alto + Ahorro alto) - son Quick Wins para automatización. El tamaño indica volumen de interacciones. + {t('roadmap.interpretation')} {t('roadmap.opportunityMapInterpretation')}

- Tamaño: Volumen + {t('roadmap.bubbleSize')} {t('roadmap.volume')}
@@ -735,29 +737,29 @@ function OpportunityBubbleChart({

- Metodología de Cálculo + {t('roadmap.methodologyTitle')}

{/* Ejes */}
-
📊 Eje X: FACTIBILIDAD (Score 0-10)
+
📊 {t('roadmap.axisXFactibility')}

- Score Agentic Readiness calculado con 5 factores ponderados: + {t('roadmap.axisXFactibilityDesc')}

    -
  • Predictibilidad (30%): basado en CV AHT
  • -
  • Resolutividad (25%): FCR (60%) + Transfer (40%)
  • -
  • Volumen (25%): escala logarítmica del volumen
  • -
  • Calidad Datos (10%): % registros válidos
  • -
  • Simplicidad (10%): basado en AHT
  • +
  • {t('roadmap.factorPredictability')}: {t('roadmap.factorPredictabilityDesc')}
  • +
  • {t('roadmap.factorResolution')}: {t('roadmap.factorResolutionDesc')}
  • +
  • {t('roadmap.factorVolumeWeight')}: {t('roadmap.factorVolumeDesc')}
  • +
  • {t('roadmap.factorDataQuality')}: {t('roadmap.factorDataQualityDesc')}
  • +
  • {t('roadmap.factorSimplicity')}: {t('roadmap.factorSimplicityDesc')}
-
💰 Eje Y: IMPACTO ECONÓMICO (€/año)
+
💰 {t('roadmap.axisYEconomicImpact')}

- Ahorro TCO calculado según tier con CPI diferencial: + {t('roadmap.axisYEconomicImpactDesc')}

@@ -778,49 +780,49 @@ function OpportunityBubbleChart({ {/* Fórmulas por Tier */}

-
🧮 Fórmulas de Ahorro por Tier
+
🧮 {t('roadmap.savingsFormulas')}
-

AUTOMATE (Score ≥ 7.5)

+

{t('roadmap.formulaAutomate')}

- Ahorro = Vol × 12 × 70% × (€2.33 - €0.15) + {t('roadmap.formulaAutomateCalc')}

-

= Vol × 12 × 0.70 × €2.18

+

{t('roadmap.formulaAutomateResult')}

-

ASSIST (Score ≥ 5.5)

+

{t('roadmap.formulaAssist')}

- Ahorro = Vol × 12 × 30% × (€2.33 - €1.50) + {t('roadmap.formulaAssistCalc')}

-

= Vol × 12 × 0.30 × €0.83

+

{t('roadmap.formulaAssistResult')}

-

AUGMENT (Score ≥ 3.5)

+

{t('roadmap.formulaAugment')}

- Ahorro = Vol × 12 × 15% × (€2.33 - €2.00) + {t('roadmap.formulaAugmentCalc')}

-

= Vol × 12 × 0.15 × €0.33

+

{t('roadmap.formulaAugmentResult')}

-

HUMAN-ONLY (Score < 3.5 o Red Flags)

+

{t('roadmap.formulaHumanOnly')}

- Ahorro = €0 + {t('roadmap.formulaHumanOnlyCalc')}

-

Requiere estandarización previa

+

{t('roadmap.formulaHumanOnlyRequires')}

@@ -828,7 +830,7 @@ function OpportunityBubbleChart({ {/* Clasificación de Tier */}
-
🏷️ Criterios de Clasificación de Tier
+
🏷️ {t('roadmap.tierClassificationCriteria')}

AUTOMATE

@@ -871,9 +873,7 @@ function OpportunityBubbleChart({ {/* Nota metodológica */}

- Nota: El tamaño de las burbujas representa el volumen de interacciones. - Las colas clasificadas como HUMAN-ONLY no aparecen en el gráfico (ahorro = €0). - Los ahorros son proyecciones basadas en benchmarks de industria y deben validarse con pilotos. + {t('roadmap.methodologicalNote')} {t('roadmap.methodologicalNoteText')}

@@ -954,6 +954,7 @@ function WaveCard({ exitCriteria?: WaveExitCriteria; priorityQueues?: PriorityQueue[]; }) { + const { t } = useTranslation(); const [expanded, setExpanded] = React.useState(false); const margenAnual = wave.ahorroAnual - wave.costoRecurrenteAnual; @@ -990,7 +991,7 @@ function WaveCard({

{wave.titulo}

{wave.esCondicional && ( - Condicional + {t('roadmap.conditional')} )}
@@ -998,7 +999,7 @@ function WaveCard({
- {riesgoIcons[wave.riesgo]} Riesgo {wave.riesgo} + {riesgoIcons[wave.riesgo]} {t('roadmap.risk')} {t(`roadmap.risk${wave.riesgo.charAt(0).toUpperCase() + wave.riesgo.slice(1)}`)}
@@ -1056,7 +1057,7 @@ function WaveCard({ {/* Por qué es necesario */}
-

🎯 Por qué es necesario:

+

🎯 {t('roadmap.whyNecessary')}

{wave.porQueNecesario}

@@ -1169,7 +1170,7 @@ function WaveCard({ onClick={() => setExpanded(!expanded)} className="w-full text-sm text-gray-500 hover:text-gray-700 flex items-center justify-center gap-1 py-2 border-t border-gray-100" > - {expanded ? 'Ocultar detalles' : 'Ver iniciativas y criterios'} + {expanded ? t('roadmap.hideDetails') : t('roadmap.viewInitiatives')} {expanded ? : } @@ -1678,6 +1679,8 @@ function RoadmapTimeline({ waves }: { waves: WaveData[] }) { // ========== COMPONENTE PRINCIPAL: ROADMAP TAB ========== export function RoadmapTab({ data }: RoadmapTabProps) { + const { t } = useTranslation(); + // Analizar datos de heatmap para determinar skills listos const heatmapData = data.heatmapData || []; @@ -2266,10 +2269,10 @@ export function RoadmapTab({ data }: RoadmapTabProps) {

- Clasificación por Potencial de Automatización + {t('roadmap.classificationByAutomationTier')}

- {totalQueues} colas clasificadas en 4 Tiers según su preparación para IA • {totalVolume.toLocaleString()} interacciones/mes + {t('roadmap.queuesClassifiedDescription', { count: totalQueues, volume: totalVolume.toLocaleString() })}

@@ -2283,20 +2286,20 @@ export function RoadmapTab({ data }: RoadmapTabProps) {
-

TIER 1

+

{t('roadmap.tier1')}

AUTOMATE

{tierCounts.AUTOMATE.length}

- {tierVolumes.AUTOMATE.toLocaleString()} int/mes + {tierVolumes.AUTOMATE.toLocaleString()} {t('roadmap.intPerMonth')}

- ({Math.round((tierVolumes.AUTOMATE / totalVolume) * 100)}% volumen) + {t('roadmap.volumePercentage', { pct: Math.round((tierVolumes.AUTOMATE / totalVolume) * 100) })}

- {formatCurrency(potentialSavings.AUTOMATE)}/año + {formatCurrency(potentialSavings.AUTOMATE)}{t('roadmap.perYear')}

@@ -2308,20 +2311,20 @@ export function RoadmapTab({ data }: RoadmapTabProps) {
-

TIER 2

+

{t('roadmap.tier2')}

ASSIST

{tierCounts.ASSIST.length}

- {tierVolumes.ASSIST.toLocaleString()} int/mes + {tierVolumes.ASSIST.toLocaleString()} {t('roadmap.intPerMonth')}

- ({Math.round((tierVolumes.ASSIST / totalVolume) * 100)}% volumen) + {t('roadmap.volumePercentage', { pct: Math.round((tierVolumes.ASSIST / totalVolume) * 100) })}

- {formatCurrency(potentialSavings.ASSIST)}/año + {formatCurrency(potentialSavings.ASSIST)}{t('roadmap.perYear')}

@@ -2333,20 +2336,20 @@ export function RoadmapTab({ data }: RoadmapTabProps) {
-

TIER 3

+

{t('roadmap.tier3')}

AUGMENT

{tierCounts.AUGMENT.length}

- {tierVolumes.AUGMENT.toLocaleString()} int/mes + {tierVolumes.AUGMENT.toLocaleString()} {t('roadmap.intPerMonth')}

- ({Math.round((tierVolumes.AUGMENT / totalVolume) * 100)}% volumen) + {t('roadmap.volumePercentage', { pct: Math.round((tierVolumes.AUGMENT / totalVolume) * 100) })}

- {formatCurrency(potentialSavings.AUGMENT)}/año + {formatCurrency(potentialSavings.AUGMENT)}{t('roadmap.perYear')}

@@ -2358,20 +2361,20 @@ export function RoadmapTab({ data }: RoadmapTabProps) {
-

TIER 4

+

{t('roadmap.tier4')}

HUMAN-ONLY

{tierCounts['HUMAN-ONLY'].length}

- {tierVolumes['HUMAN-ONLY'].toLocaleString()} int/mes + {tierVolumes['HUMAN-ONLY'].toLocaleString()} {t('roadmap.intPerMonth')}

- ({Math.round((tierVolumes['HUMAN-ONLY'] / totalVolume) * 100)}% volumen) + {t('roadmap.volumePercentage', { pct: Math.round((tierVolumes['HUMAN-ONLY'] / totalVolume) * 100) })}

- €0/año (Red flags) + {t('roadmap.noSavingsRedFlags')}

@@ -2379,7 +2382,7 @@ export function RoadmapTab({ data }: RoadmapTabProps) { {/* Barra de distribución visual */}
-

Distribución del volumen por tier:

+

{t('roadmap.volumeDistributionByTier')}

{tierVolumes.AUTOMATE > 0 && (
{/* Explicación */}
-

¿Qué significa Foundation?

+

{t('roadmap.whatIsFoundation')}

- La operación actual no tiene colas listas para automatizar directamente. - Foundation es la fase de preparación: estandarizar procesos, reducir variabilidad - y mejorar la calidad de datos para que la automatización posterior sea efectiva. + {t('roadmap.foundationExplanation')}

- {tierCounts.ASSIST.length} colas ASSIST ({Math.round(assistPct)}% del volumen) - pueden elevarse a Tier AUTOMATE tras completar Wave 1-2. + {t('roadmap.assistQueuesCanElevate', { count: tierCounts.ASSIST.length, pct: Math.round(assistPct) })}

-

Inversión

+

{t('roadmap.investment')}

{formatCurrency(wave1Setup + wave2Setup)}

-

Timeline

-

6-9 meses

+

{t('roadmap.timeline')}

+

6-9 {t('roadmap.months', { count: 6 }).toLowerCase()}

-

Ahorro habilitado

-

{formatCurrency(potentialSavings.ASSIST)}/año

+

{t('roadmap.enabledSavings')}

+

{formatCurrency(potentialSavings.ASSIST)}{t('roadmap.perYear')}

- Criterios para pasar a automatización: CV ≤90% · Transfer ≤30% · AHT -15% + {t('roadmap.criteriaForAutomation')} {t('roadmap.criteriaForAutomationValues')}
)} @@ -2581,51 +2581,48 @@ export function RoadmapTab({ data }: RoadmapTabProps) { <> {/* Explicación */}
-

¿Por qué estandarización primero?

+

{t('roadmap.whyStandardizationFirst')}

- Se han detectado "red flags" operativos críticos (alta variabilidad, muchas transferencias) - que harían fracasar cualquier proyecto de automatización. Invertir en IA ahora sería - malgastar recursos. Primero hay que estabilizar la operación. + {t('roadmap.standardizationExplanation')}

- {Math.round(humanOnlyPct + augmentPct)}% del volumen presenta red flags (CV >75%, Transfer >20%). - Wave 1 es una inversión habilitadora sin retorno directo inmediato. + {t('roadmap.volumeWithRedFlags', { pct: Math.round(humanOnlyPct + augmentPct) })}

-

Inversión Wave 1

+

{t('roadmap.investmentWave1')}

{formatCurrency(wave1Setup)}

-

Timeline

-

3-4 meses

+

{t('roadmap.timeline')}

+

3-4 {t('roadmap.months', { count: 3 }).toLowerCase()}

-

Ahorro directo

-

€0 (habilitador)

+

{t('roadmap.directSavings')}

+

{t('roadmap.enablingNoDirectSavings')}

- Objetivo: Reducir red flags en las {Math.min(10, tierCounts['HUMAN-ONLY'].length + tierCounts.AUGMENT.length)} colas principales. Reevaluar tras completar. + {t('roadmap.objective')} {t('roadmap.objectiveReduceRedFlags', { count: Math.min(10, tierCounts['HUMAN-ONLY'].length + tierCounts.AUGMENT.length) })}
)} {/* Siguiente paso */}
-

Siguiente paso recomendado:

+

{t('roadmap.nextRecommendedStep')}

{recType === 'DUAL' && ( - <>Iniciar piloto de automatización con las {pilotQueues.length} colas AUTOMATE, mientras se ejecuta Wave 1 (Foundation) en paralelo para preparar el resto. + t('roadmap.nextStepDual', { count: pilotQueues.length }) )} {recType === 'FOUNDATION' && ( - <>Comenzar Wave 1 focalizando en las {Math.min(10, tierCounts['HUMAN-ONLY'].length)} colas de mayor volumen. Medir progreso mensual en CV y Transfer. + t('roadmap.nextStepFoundation', { count: Math.min(10, tierCounts['HUMAN-ONLY'].length) }) )} {recType === 'STANDARDIZATION' && ( - <>Realizar workshop de diagnóstico operacional para identificar las causas raíz de los red flags antes de planificar inversiones. + t('roadmap.nextStepStandardization') )}

@@ -2653,13 +2650,13 @@ export function RoadmapTab({ data }: RoadmapTabProps) {
-

Detalle por Wave

-

Iniciativas, criterios de entrada/salida, inversión por fase

+

{t('roadmap.waveDetail')}

+

{t('roadmap.waveDetailDescription')}

- {waveDetailExpanded ? 'Ocultar detalle' : 'Ver detalle'} + {waveDetailExpanded ? t('roadmap.hideDetail') : t('roadmap.viewDetail')} {waveDetailExpanded ? ( @@ -2678,7 +2675,7 @@ export function RoadmapTab({ data }: RoadmapTabProps) { onClick={() => setShowAllWaves(!showAllWaves)} className="text-xs text-blue-600 hover:text-blue-800 font-medium flex items-center gap-1" > - {showAllWaves ? 'Colapsar todas' : 'Expandir todas'} + {showAllWaves ? t('roadmap.collapseAll') : t('roadmap.expandAll')} {showAllWaves ? : }
diff --git a/frontend/locales/en.json b/frontend/locales/en.json index 0461a4f..63468b4 100644 --- a/frontend/locales/en.json +++ b/frontend/locales/en.json @@ -390,7 +390,149 @@ "foundationFirst": "Foundation First", "foundationFirstDesc": "Prepare the operation before automating", "standardization": "Standardization", - "standardizationDesc": "Resolve critical operational issues before investing in AI" + "standardizationDesc": "Resolve critical operational issues before investing in AI", + "opportunityMapTitle": "Opportunity Map by Tier", + "opportunityMapSubtitle": "Feasibility (Score) vs Economic Impact (TCO Savings) • Size = Volume • Color = Tier", + "economicImpactAxis": "ECONOMIC IMPACT (TCO Savings €/year)", + "feasibilityAxis": "FEASIBILITY (Agentic Readiness Score 0-10)", + "tierAutomateThreshold": "AUTOMATE Tier ≥7.5", + "quadrantQuickWins": "QUICK WINS", + "quadrantQuickWinsDesc": "Score ≥7.5 + High savings", + "quadrantQuickWinsPriority": "→ Priority 1", + "quadrantOptimize": "OPTIMIZE", + "quadrantOptimizeDesc": "Score <7.5 + High savings", + "quadrantOptimizePriority": "→ Wave 1 first", + "quadrantStrategic": "STRATEGIC", + "quadrantStrategicDesc": "Score ≥7.5 + Low savings", + "quadrantStrategicPriority": "→ Evaluate ROI", + "quadrantDefer": "DEFER", + "quadrantDeferDesc": "Score <7.5 + Low savings", + "quadrantDeferPriority": "→ Backlog", + "tooltipScore": "Score:", + "tooltipVolume": "Volume:", + "tooltipSavingsTco": "TCO Savings:", + "tooltipTier": "Tier:", + "perMonth": "/month", + "perYear": "/year", + "interpretation": "Interpretation:", + "opportunityMapInterpretation": "Bubbles in the upper right quadrant (High Score + High Savings) are Quick Wins for automation. Size indicates interaction volume.", + "bubbleSize": "Size:", + "volume": "Volume", + "methodologyTitle": "Calculation Methodology", + "axisXFactibility": "X Axis: FEASIBILITY (Score 0-10)", + "axisXFactibilityDesc": "Agentic Readiness Score calculated with 5 weighted factors:", + "factorPredictability": "Predictability (30%)", + "factorPredictabilityDesc": "based on CV AHT", + "factorResolution": "Resolution (25%)", + "factorResolutionDesc": "FCR (60%) + Transfer (40%)", + "factorVolumeWeight": "Volume (25%)", + "factorVolumeDesc": "logarithmic volume scale", + "factorDataQuality": "Data Quality (10%)", + "factorDataQualityDesc": "% valid records", + "factorSimplicity": "Simplicity (10%)", + "factorSimplicityDesc": "based on AHT", + "axisYEconomicImpact": "Y Axis: ECONOMIC IMPACT (€/year)", + "axisYEconomicImpactDesc": "TCO savings calculated by tier with differential CPI:", + "cpiHuman": "Human CPI", + "cpiBot": "Bot CPI", + "cpiAssist": "Assist CPI", + "cpiAugment": "Augment CPI", + "savingsFormulas": "Savings Formulas by Tier", + "formulaAutomate": "AUTOMATE (Score ≥ 7.5)", + "formulaAutomateCalc": "Savings = Vol × 12 × 70% × (€2.33 - €0.15)", + "formulaAutomateResult": "= Vol × 12 × 0.70 × €2.18", + "formulaAssist": "ASSIST (Score ≥ 5.5)", + "formulaAssistCalc": "Savings = Vol × 12 × 30% × (€2.33 - €1.50)", + "formulaAssistResult": "= Vol × 12 × 0.30 × €0.83", + "formulaAugment": "AUGMENT (Score ≥ 3.5)", + "formulaAugmentCalc": "Savings = Vol × 12 × 15% × (€2.33 - €2.00)", + "formulaAugmentResult": "= Vol × 12 × 0.15 × €0.33", + "formulaHumanOnly": "HUMAN-ONLY (Score < 3.5 or Red Flags)", + "formulaHumanOnlyCalc": "Savings = €0", + "formulaHumanOnlyRequires": "Requires prior standardization", + "tierClassificationCriteria": "Tier Classification Criteria", + "tierCriteriaCV": "CV", + "tierCriteriaTransfer": "Transfer", + "tierCriteriaFCR": "FCR", + "tierCriteriaNoRedFlags": "No red flags", + "tierCriteriaRequiresOptimization": "Requires optimization", + "tierCriteriaOr": "or", + "tierCriteriaVolume": "Vol", + "tierCriteriaValid": "Valid", + "methodologicalNote": "Note:", + "methodologicalNoteText": "Bubble size represents interaction volume. Queues classified as HUMAN-ONLY don't appear in the chart (savings = €0). Savings are projections based on industry benchmarks and should be validated with pilots.", + "hideDetails": "Hide details", + "viewInitiatives": "View initiatives and criteria", + "conditional": "Conditional", + "risk": "Risk", + "riskLow": "Low", + "riskMedium": "Medium", + "riskHigh": "High", + "whyNecessary": "Why is it necessary?", + "targetSkills": "Target skills", + "initiatives": "Initiatives", + "setup": "Setup", + "recurring": "Recurring", + "kpiTarget": "KPI Target", + "successCriteria": "Success criteria", + "riskDescription": "Risk description", + "provider": "Provider", + "entryCriteria": "Entry criteria", + "fromTier": "From Tier:", + "scoreRange": "Score Range:", + "requiredMetrics": "Required metrics:", + "exitCriteria": "Exit criteria", + "toTier": "To Tier:", + "scoreTarget": "Target score:", + "kpiTargets": "Target KPIs:", + "priorityQueues": "Priority queues", + "currentScore": "Current score", + "currentTier": "Current tier", + "potentialSavings": "Potential savings", + "redFlags": "Red Flags", + "classificationByAutomationTier": "Classification by Automation Potential", + "queuesClassifiedDescription": "{{count}} queues classified into 4 Tiers by AI readiness • {{volume}} interactions/month", + "tier1": "TIER 1", + "tier2": "TIER 2", + "tier3": "TIER 3", + "tier4": "TIER 4", + "intPerMonth": "int/month", + "volumePercentage": "({{pct}}% volume)", + "noSavingsRedFlags": "€0/year (Red flags)", + "volumeDistributionByTier": "Volume distribution by tier:", + "strategicRecommendation": "Our Recommendation:", + "dualStrategyLabel": "Our Recommendation: Dual Strategy", + "dualStrategySublabel": "Execute two work streams in parallel to maximize impact", + "foundationFirstLabel": "Our Recommendation: Foundation First", + "foundationFirstSublabel": "Prepare the operation before automating", + "standardizationLabel": "Our Recommendation: Standardization", + "standardizationSublabel": "Resolve critical operational issues before investing in AI", + "whatIsFoundation": "What does Foundation mean?", + "foundationExplanation": "The current operation has no queues ready for direct automation. Foundation is the preparation phase: standardize processes, reduce variability, and improve data quality so subsequent automation is effective.", + "assistQueuesCanElevate": "{{count}} ASSIST queues ({{pct}}% of volume) can be elevated to AUTOMATE Tier after completing Wave 1-2.", + "investment": "Investment", + "timeline": "Timeline", + "enabledSavings": "Enabled savings", + "criteriaForAutomation": "Criteria for automation:", + "criteriaForAutomationValues": "CV ≤90% · Transfer ≤30% · AHT -15%", + "whyStandardizationFirst": "Why standardization first?", + "standardizationExplanation": "Critical operational \"red flags\" (high variability, many transfers) have been detected that would cause any automation project to fail. Investing in AI now would be wasting resources. The operation must be stabilized first.", + "volumeWithRedFlags": "{{pct}}% of volume has red flags (CV >75%, Transfer >20%). Wave 1 is an enabling investment with no immediate direct return.", + "investmentWave1": "Wave 1 Investment", + "directSavings": "Direct savings", + "enablingNoDirectSavings": "€0 (enabler)", + "objective": "Objective:", + "objectiveReduceRedFlags": "Reduce red flags in the top {{count}} queues. Reassess after completion.", + "nextRecommendedStep": "Next recommended step:", + "nextStepDual": "Launch automation pilot with the {{count}} AUTOMATE queues, while executing Wave 1 (Foundation) in parallel to prepare the rest.", + "nextStepFoundation": "Start Wave 1 focusing on the top {{count}} queues by volume. Measure monthly progress in CV and Transfer.", + "nextStepStandardization": "Conduct operational diagnostic workshop to identify root causes of red flags before planning investments.", + "waveDetail": "Wave Detail", + "waveDetailDescription": "Initiatives, entry/exit criteria, investment by phase", + "hideDetail": "Hide detail", + "viewDetail": "View detail", + "collapseAll": "Collapse all", + "expandAll": "Expand all" }, "opportunities": { "viewCriticalActions": "View Critical Actions", @@ -852,5 +994,324 @@ "november": "November", "december": "December" } + }, + "law10": { + "constants": { + "requirements": { + "LAW_07": { + "name": "Time Coverage" + }, + "LAW_01": { + "name": "Response Speed" + }, + "LAW_02": { + "name": "Resolution Quality" + }, + "LAW_09": { + "name": "Language Coverage" + } + } + }, + "status": { + "CUMPLE": "Complies", + "PARCIAL": "Partial", + "NO_CUMPLE": "Does Not Comply", + "SIN_DATOS": "No Data" + }, + "compliance": { + "law07": { + "noData": "No time distribution data", + "noDataDetails": "No time distribution data found in the analysis", + "offHoursPercent": "{{percent}}% of interactions outside business hours", + "adequateCoverage": "Adequate time coverage", + "improvableCoverage": "Time coverage can be improved - consider extending hours", + "insufficientCoverage": "Insufficient time coverage - requires immediate action", + "gapOverOptimal": "{{gap}}pp over optimal", + "gapOverLimit": "{{gap}}pp over limit" + }, + "law01": { + "noData": "No wait time data", + "noDataDetails": "No hold_time data found in the analysis", + "avgHoldTime": "Average wait time: {{time}}s (limit: 180s)", + "withinLimit": "{{percent}}% of interactions within limit", + "queuesExceedLimit": "{{count}} of {{total}} queues exceed the limit", + "gapNegative": "-{{gap}}s", + "queuesOutside": "{{count}} queues outside", + "gapPositive": "+{{gap}}s" + }, + "law02": { + "noData": "No resolution data", + "noDataDetails": "No FCR or transfer data found", + "fcrTechnical": "Technical FCR: {{fcr}}% (target: >75%)", + "transferRate": "Transfer rate: {{rate}}% (target: <15%)", + "highTransferQueues": "{{count}} queues with transfer >25%", + "gapDash": "-", + "gapFcr": "FCR {{fcrGap}}, Transfer {{transferGap}}", + "gapOk": "OK", + "gapPositive": "+{{gap}}pp", + "gapNegative": "-{{gap}}pp" + }, + "law09": { + "noData": "Requires data", + "noLanguageData": "No language data available in interactions", + "needsLanguageField": "To evaluate this requirement, the \"language\" field is needed in the CSV" + } + }, + "header": { + "aboutThisAnalysis": "About this Analysis", + "lawTitle": "Law 10/2025 on Customer Service", + "description": "This module connects your current operational metrics with Law 10/2025 requirements. It doesn't measure compliance directly (would require additional data), but DOES identify patterns that impact your ability to comply with regulations.", + "complianceDeadline": "Compliance deadline", + "december282026": "December 28, 2026", + "daysRemaining": "{{days}} days remaining", + "requirementsEvaluated": "Requirements evaluated", + "requirementsMet": "{{met}} of {{total}} comply", + "basedOnData": "Based on available data", + "overallStatus": "Overall status", + "goodState": "Good state", + "requiresAttention": "Requires attention", + "urgentAction": "Urgent action" + }, + "timeCoverage": { + "title": "Temporal Coverage: Service Availability", + "article": "Related to Art. 14 - 24/7 basic services", + "whatWeKnow": "WHAT WE KNOW", + "heatmap247": "24x7 VOLUMETRIC HEATMAP", + "intensity": "Intensity:", + "intensityLow": "Low", + "intensityMedium": "Medium", + "intensityHigh": "High", + "operationalFindings": "Operational findings:", + "detectedSchedule": "Detected schedule: M-F 08:00-22:00, Sat-Sun reduced hours", + "nightVolume": "Night volume (22:00-08:00): {{volume}} interactions ({{percent}}%)", + "earlyMorningVolume": "Early morning volume (00:00-06:00): {{volume}} interactions ({{percent}}%)", + "peakHour": "Peak hour: {{hour}}:00-{{hourEnd}}:00 ({{percent}}% of daily volume)", + "lawImplication": "LAW 10/2025 IMPLICATION", + "basicServiceRequirement": "Air transport = Basic service", + "article14Requirement": "→ Art. 14 requires 24/7 attention for incidents", + "gapIdentified": "Gap identified:", + "clientsOutsideHours": "{{percent}}% of your clients contact outside current hours", + "complianceIssue": "If these are incidents (lost luggage, urgent changes), you DON'T comply with Art. 14", + "suggestedAction": "SUGGESTED ACTION", + "classifyNightVolume": "1. Classify night volume by type:", + "criticalIncidents": "What % are critical incidents? → Requires 24/7", + "generalQueries": "What % are general queries? → Can wait", + "coverageOptions": "2. Coverage options:", + "optionAChatbot": "A) AI Chatbot + on-call agent", + "optionBExternal": "B) Redirect to external 24/7 call center", + "optionCNight": "C) Night shift agents (3 shifts)", + "costPerYear": "~{{cost}}/year" + }, + "responseSpeed": { + "title": "Response Speed: Operational Efficiency", + "article": "Related to Art. 8.2 - 95% calls <3min", + "whatWeKnow": "WHAT WE KNOW", + "abandonmentRate": "Abandonment rate", + "ahtP50": "AHT P50 ({{min}}m {{sec}}s)", + "ahtP90": "AHT P90 ({{min}}m {{sec}}s)", + "ratioP90P50": "P90/P50 Ratio {{elevated}}", + "elevated": "(elevated)", + "abandonmentByHour": "ABANDONMENT DISTRIBUTION BY HOUR", + "abandonmentLegend": "Abandonment:", + "abandonmentLow": "<8%", + "abandonmentMedium": "8-15%", + "abandonmentHigh": ">20%", + "patternsObserved": "Patterns observed:", + "maxAbandonment": "Highest abandonment: {{hourStart}}:00-{{hourEnd}}:00 ({{rate}}% vs {{avg}}% average)", + "highestAht": "Highest AHT: Monday 09:00-11:00 ({{high}}s vs {{p50}}s P50)", + "minAbandonment": "Lowest abandonment: {{hourStart}}:00-{{hourEnd}}:00 ({{rate}}%)", + "lawImplication": "LAW 10/2025 IMPLICATION", + "article82Requirement": "Art. 8.2 requires: \"95% of calls answered in <3 minutes\"", + "dataLimitation": "DATA LIMITATION", + "noAsaData": "Your current CDR does NOT include ASA (queue time before answer), so we CANNOT measure this requirement directly.", + "butWeKnow": "BUT WE DO know:", + "customersAbandon": "{{rate}}% of customers abandon → They likely waited too long", + "highVariability": "High AHT variability (P90/P50={{ratio}}) → Unpredictable queue", + "peaksCoincide": "Abandonment peaks coincide with volume peaks", + "conservativeEstimate": "Conservative estimate (±10% margin of error):", + "likelyFastResponse": "→ ~{{percent}}% of calls likely answered \"quickly\"", + "gapVs95": "→ Gap vs required 95%: {{operator}}{{gap}} percentage points", + "suggestedAction": "SUGGESTED ACTION", + "shortTerm": "1. SHORT TERM: Reduce AHT to increase capacity", + "dimension2Identifies": "Your Dimension 2 (Efficiency) already identifies:", + "highAht": "- High AHT ({{aht}}s vs 380s benchmark)", + "copilotOpportunity": "- AI Copilot opportunity: -18% projected AHT", + "dualBenefit": "Dual benefit: ↓ AHT = ↑ capacity = ↓ queue = ↑ ASA", + "mediumTerm": "2. MEDIUM TERM: Implement real ASA tracking", + "platformConfig": "Platform configuration", + "implementationTimeline": "Implementation timeline", + "implementationWeeks": "4-6 weeks", + "benefit": "Benefit: Precise measurement for ENAC audit" + }, + "resolutionQuality": { + "title": "Resolution Quality: Effectiveness", + "article": "Related to Art. 17 - Resolution in 15 days", + "whatWeKnow": "WHAT WE KNOW", + "fcrReal": "Real FCR (fcr_real_flag)", + "recontactRate7d": "7-day recontact rate", + "repeatCalls": "Repeat calls", + "fcrBySkill": "FCR BY SKILL/QUEUE", + "fcrLegend": "FCR:", + "fcrLow": "<45%", + "fcrMedium": "45-65%", + "fcrHigh": ">75%", + "topLowFcr": "Top skills with low FCR:", + "fcrValue": "{{fcr}}% FCR", + "lawImplication": "LAW 10/2025 IMPLICATION", + "article17Requirement": "Art. 17 requires: \"Resolution of complaints ≤15 days\"", + "dataLimitation": "DATA LIMITATION", + "noCaseTracking": "Your CDR only records individual interactions, NOT multi-touch cases or total resolution time.", + "butWeKnow": "BUT WE DO know:", + "multipleContactsRequired": "{{percent}}% of cases require multiple contacts", + "fcrGap": "FCR {{fcr}}% = {{gap}}% NOT resolved at first contact", + "complexProcesses": "This suggests complex processes or fragmented information", + "alertSignal": "Warning signal:", + "resolutionTimeRisk": "If customers recontact multiple times for the same issue, TOTAL resolution time likely exceeds the 15 days required by law.", + "suggestedAction": "SUGGESTED ACTION", + "diagnosis": "1. DIAGNOSIS: Implement case/ticket system", + "registerOpenClose": "Register open + close dates", + "linkInteractions": "Link multiple interactions to same case", + "typology": "Typology: query / complaint / incident", + "crmInvestment": "CRM/Ticketing investment", + "operationalImprovement": "2. OPERATIONAL IMPROVEMENT: Increase FCR", + "dimension3Identifies": "Your Dimension 3 (Effectiveness) already identifies:", + "rootCauses": "- Root causes: fragmented info, lack of empowerment", + "solution": "- Solution: Knowledge base + decision trees", + "fcrBenefit": "Benefit: ↑ FCR = ↓ recontacts = ↓ total time" + }, + "summary": { + "title": "Compliance Summary - All Requirements", + "requirementColumn": "Requirement", + "descriptionColumn": "Description", + "statusColumn": "Status", + "scoreColumn": "Score", + "gapColumn": "Gap", + "requirements": { + "LAW-01": { + "name": "Wait Time", + "description": "Maximum wait time of 3 minutes for phone service" + }, + "LAW-02": { + "name": "Effective Resolution", + "description": "First contact resolution without unnecessary transfers" + }, + "LAW-03": { + "name": "Human Agent Access", + "description": "Right to speak with a human agent at any time" + }, + "LAW-04": { + "name": "Call Recording", + "description": "Prior notification of recording and access to it" + }, + "LAW-05": { + "name": "Accessibility", + "description": "Accessible channels for people with disabilities" + }, + "LAW-06": { + "name": "Written Confirmation", + "description": "Written confirmation of complaints and procedures" + }, + "LAW-07": { + "name": "Time Coverage", + "description": "24/7 service for essential services or extended hours" + }, + "LAW-08": { + "name": "Agent Training", + "description": "Qualified personnel trained in customer service" + }, + "LAW-09": { + "name": "Co-official Languages", + "description": "Service in Catalan, Basque, Galician and Valencian" + }, + "LAW-10": { + "name": "Resolution Timeframes", + "description": "Complaint resolution in maximum 15 business days" + }, + "LAW-11": { + "name": "Free Service", + "description": "Phone service at no additional cost (900 numbers)" + }, + "LAW-12": { + "name": "Traceability", + "description": "Reference number for procedure tracking" + } + }, + "legend": { + "complies": "Complies: Requirement met", + "partial": "Partial: Requires improvements", + "notComplies": "Does Not Comply: Urgent action", + "noData": "No Data: Fields not available in CSV" + }, + "investment": { + "nonComplianceCost": "Cost of non-compliance", + "upTo100k": "Up to 100K", + "potentialFines": "Potential fines/violation", + "recommendedInvestment": "Recommended investment", + "basedOnOperation": "Based on your operation", + "complianceRoi": "Compliance ROI", + "avoidSanctionsAndImprove": "Avoid sanctions + improve CX", + "highRoi": "High", + "percentOfAnnualCost": "~5% annual cost" + } + }, + "dataMaturity": { + "title": "Summary: Data Maturity for Compliance", + "currentLevel": "Your current instrumentation level:", + "dataAvailable": "DATA AVAILABLE (3/10)", + "dataEstimable": "ESTIMABLE DATA (2/10)", + "dataNotAvailable": "NOT AVAILABLE (5/10)", + "availableData": { + "temporalCoverage": "24/7 temporal coverage", + "geographicDistribution": "Geographic distribution", + "resolutionQuality": "Resolution quality proxy" + }, + "estimableData": { + "asaProxy": "ASA <3min via abandonment proxy", + "languagesViaCountry": "Co-official languages via country" + }, + "missingData": { + "caseResolutionTime": "Case resolution time", + "refundTime": "Improper charges <5 days", + "supervisorTransfer": "Transfer to supervisor", + "incidentInfo": "Incident info <2h", + "enacAudit": "ENAC audit", + "externalContract": "requires external contracting" + }, + "suggestedInvestment": "SUGGESTED INVESTMENT FOR FULL COMPLIANCE", + "phase1": "Phase 1 - Instrumentation (Q1 2026)", + "phase2": "Phase 2 - Operations (Q2-Q3 2026)", + "phase1Items": { + "asaTracking": "Real ASA tracking", + "ticketingSystem": "Ticketing/case system", + "languageEnrichment": "Language enrichment", + "subtotal": "Subtotal:" + }, + "phase2Items": { + "coverage247": "24/7 coverage (chatbot + on-call)", + "aiCopilot": "AI Copilot (reduce AHT)", + "enacAuditor": "ENAC Auditor", + "subtotalYear1": "Year 1 subtotal:", + "perYear": "/year", + "perMonth": "/month" + }, + "totals": { + "totalInvestment": "Total Investment", + "percentAnnualCost": "~5% annual cost", + "riskAvoided": "Risk Avoided", + "potentialSanctions": "potential sanctions", + "complianceRoi": "Compliance ROI" + }, + "article": "Art. {{number}}", + "articlePartial": "Art. {{number}} partial", + "articleIndirect": "Art. {{number}} indirect", + "errorMargin": "±{{margin}}%", + "noDetail": "no detail" + }, + "common": { + "noData": "No data", + "requiredData": "Requires data", + "score": "Score", + "gap": "Gap" + } } } \ No newline at end of file diff --git a/frontend/locales/es.json b/frontend/locales/es.json index 3f8147d..b6cf7a0 100644 --- a/frontend/locales/es.json +++ b/frontend/locales/es.json @@ -390,7 +390,149 @@ "foundationFirst": "Foundation First", "foundationFirstDesc": "Preparar la operación antes de automatizar", "standardization": "Estandarización", - "standardizationDesc": "Resolver problemas operativos críticos antes de invertir en IA" + "standardizationDesc": "Resolver problemas operativos críticos antes de invertir en IA", + "opportunityMapTitle": "Mapa de Oportunidades por Tier", + "opportunityMapSubtitle": "Factibilidad (Score) vs Impacto Económico (Ahorro TCO) • Tamaño = Volumen • Color = Tier", + "economicImpactAxis": "IMPACTO ECONÓMICO (Ahorro TCO €/año)", + "feasibilityAxis": "FACTIBILIDAD (Agentic Readiness Score 0-10)", + "tierAutomateThreshold": "Tier AUTOMATE ≥7.5", + "quadrantQuickWins": "QUICK WINS", + "quadrantQuickWinsDesc": "Score ≥7.5 + Ahorro alto", + "quadrantQuickWinsPriority": "→ Prioridad 1", + "quadrantOptimize": "OPTIMIZE", + "quadrantOptimizeDesc": "Score <7.5 + Ahorro alto", + "quadrantOptimizePriority": "→ Wave 1 primero", + "quadrantStrategic": "STRATEGIC", + "quadrantStrategicDesc": "Score ≥7.5 + Ahorro bajo", + "quadrantStrategicPriority": "→ Evaluar ROI", + "quadrantDefer": "DEFER", + "quadrantDeferDesc": "Score <7.5 + Ahorro bajo", + "quadrantDeferPriority": "→ Backlog", + "tooltipScore": "Score:", + "tooltipVolume": "Volumen:", + "tooltipSavingsTco": "Ahorro TCO:", + "tooltipTier": "Tier:", + "perMonth": "/mes", + "perYear": "/año", + "interpretation": "Interpretación:", + "opportunityMapInterpretation": "Las burbujas en el cuadrante superior derecho (Score alto + Ahorro alto) son Quick Wins para automatización. El tamaño indica volumen de interacciones.", + "bubbleSize": "Tamaño:", + "volume": "Volumen", + "methodologyTitle": "Metodología de Cálculo", + "axisXFactibility": "Eje X: FACTIBILIDAD (Score 0-10)", + "axisXFactibilityDesc": "Score Agentic Readiness calculado con 5 factores ponderados:", + "factorPredictability": "Predictibilidad (30%)", + "factorPredictabilityDesc": "basado en CV AHT", + "factorResolution": "Resolutividad (25%)", + "factorResolutionDesc": "FCR (60%) + Transfer (40%)", + "factorVolumeWeight": "Volumen (25%)", + "factorVolumeDesc": "escala logarítmica del volumen", + "factorDataQuality": "Calidad Datos (10%)", + "factorDataQualityDesc": "% registros válidos", + "factorSimplicity": "Simplicidad (10%)", + "factorSimplicityDesc": "basado en AHT", + "axisYEconomicImpact": "Eje Y: IMPACTO ECONÓMICO (€/año)", + "axisYEconomicImpactDesc": "Ahorro TCO calculado según tier con CPI diferencial:", + "cpiHuman": "CPI Humano", + "cpiBot": "CPI Bot", + "cpiAssist": "CPI Assist", + "cpiAugment": "CPI Augment", + "savingsFormulas": "Fórmulas de Ahorro por Tier", + "formulaAutomate": "AUTOMATE (Score ≥ 7.5)", + "formulaAutomateCalc": "Ahorro = Vol × 12 × 70% × (€2.33 - €0.15)", + "formulaAutomateResult": "= Vol × 12 × 0.70 × €2.18", + "formulaAssist": "ASSIST (Score ≥ 5.5)", + "formulaAssistCalc": "Ahorro = Vol × 12 × 30% × (€2.33 - €1.50)", + "formulaAssistResult": "= Vol × 12 × 0.30 × €0.83", + "formulaAugment": "AUGMENT (Score ≥ 3.5)", + "formulaAugmentCalc": "Ahorro = Vol × 12 × 15% × (€2.33 - €2.00)", + "formulaAugmentResult": "= Vol × 12 × 0.15 × €0.33", + "formulaHumanOnly": "HUMAN-ONLY (Score < 3.5 o Red Flags)", + "formulaHumanOnlyCalc": "Ahorro = €0", + "formulaHumanOnlyRequires": "Requiere estandarización previa", + "tierClassificationCriteria": "Criterios de Clasificación de Tier", + "tierCriteriaCV": "CV", + "tierCriteriaTransfer": "Transfer", + "tierCriteriaFCR": "FCR", + "tierCriteriaNoRedFlags": "Sin red flags", + "tierCriteriaRequiresOptimization": "Requiere optimización", + "tierCriteriaOr": "o", + "tierCriteriaVolume": "Vol", + "tierCriteriaValid": "Valid", + "methodologicalNote": "Nota:", + "methodologicalNoteText": "El tamaño de las burbujas representa el volumen de interacciones. Las colas clasificadas como HUMAN-ONLY no aparecen en el gráfico (ahorro = €0). Los ahorros son proyecciones basadas en benchmarks de industria y deben validarse con pilotos.", + "hideDetails": "Ocultar detalles", + "viewInitiatives": "Ver iniciativas y criterios", + "conditional": "Condicional", + "risk": "Riesgo", + "riskLow": "Bajo", + "riskMedium": "Medio", + "riskHigh": "Alto", + "whyNecessary": "¿Por qué es necesario?", + "targetSkills": "Skills objetivo", + "initiatives": "Iniciativas", + "setup": "Setup", + "recurring": "Recurrente", + "kpiTarget": "KPI Objetivo", + "successCriteria": "Criterios de éxito", + "riskDescription": "Descripción del riesgo", + "provider": "Proveedor", + "entryCriteria": "Criterios de entrada", + "fromTier": "Desde Tier:", + "scoreRange": "Rango Score:", + "requiredMetrics": "Métricas requeridas:", + "exitCriteria": "Criterios de salida", + "toTier": "Hacia Tier:", + "scoreTarget": "Score objetivo:", + "kpiTargets": "KPIs objetivo:", + "priorityQueues": "Colas prioritarias", + "currentScore": "Score actual", + "currentTier": "Tier actual", + "potentialSavings": "Ahorro potencial", + "redFlags": "Red Flags", + "classificationByAutomationTier": "Clasificación por Potencial de Automatización", + "queuesClassifiedDescription": "{{count}} colas clasificadas en 4 Tiers según su preparación para IA • {{volume}} interacciones/mes", + "tier1": "TIER 1", + "tier2": "TIER 2", + "tier3": "TIER 3", + "tier4": "TIER 4", + "intPerMonth": "int/mes", + "volumePercentage": "({{pct}}% volumen)", + "noSavingsRedFlags": "€0/año (Red flags)", + "volumeDistributionByTier": "Distribución del volumen por tier:", + "strategicRecommendation": "Nuestra Recomendación:", + "dualStrategyLabel": "Nuestra Recomendación: Estrategia Dual", + "dualStrategySublabel": "Ejecutar dos líneas de trabajo en paralelo para maximizar el impacto", + "foundationFirstLabel": "Nuestra Recomendación: Foundation First", + "foundationFirstSublabel": "Preparar la operación antes de automatizar", + "standardizationLabel": "Nuestra Recomendación: Estandarización", + "standardizationSublabel": "Resolver problemas operativos críticos antes de invertir en IA", + "whatIsFoundation": "¿Qué significa Foundation?", + "foundationExplanation": "La operación actual no tiene colas listas para automatizar directamente. Foundation es la fase de preparación: estandarizar procesos, reducir variabilidad y mejorar la calidad de datos para que la automatización posterior sea efectiva.", + "assistQueuesCanElevate": "{{count}} colas ASSIST ({{pct}}% del volumen) pueden elevarse a Tier AUTOMATE tras completar Wave 1-2.", + "investment": "Inversión", + "timeline": "Timeline", + "enabledSavings": "Ahorro habilitado", + "criteriaForAutomation": "Criterios para pasar a automatización:", + "criteriaForAutomationValues": "CV ≤90% · Transfer ≤30% · AHT -15%", + "whyStandardizationFirst": "¿Por qué estandarización primero?", + "standardizationExplanation": "Se han detectado \"red flags\" operativos críticos (alta variabilidad, muchas transferencias) que harían fracasar cualquier proyecto de automatización. Invertir en IA ahora sería malgastar recursos. Primero hay que estabilizar la operación.", + "volumeWithRedFlags": "{{pct}}% del volumen presenta red flags (CV >75%, Transfer >20%). Wave 1 es una inversión habilitadora sin retorno directo inmediato.", + "investmentWave1": "Inversión Wave 1", + "directSavings": "Ahorro directo", + "enablingNoDirectSavings": "€0 (habilitador)", + "objective": "Objetivo:", + "objectiveReduceRedFlags": "Reducir red flags en las {{count}} colas principales. Reevaluar tras completar.", + "nextRecommendedStep": "Siguiente paso recomendado:", + "nextStepDual": "Iniciar piloto de automatización con las {{count}} colas AUTOMATE, mientras se ejecuta Wave 1 (Foundation) en paralelo para preparar el resto.", + "nextStepFoundation": "Comenzar Wave 1 focalizando en las {{count}} colas de mayor volumen. Medir progreso mensual en CV y Transfer.", + "nextStepStandardization": "Realizar workshop de diagnóstico operacional para identificar las causas raíz de los red flags antes de planificar inversiones.", + "waveDetail": "Detalle por Wave", + "waveDetailDescription": "Iniciativas, criterios de entrada/salida, inversión por fase", + "hideDetail": "Ocultar detalle", + "viewDetail": "Ver detalle", + "collapseAll": "Colapsar todas", + "expandAll": "Expandir todas" }, "opportunities": { "viewCriticalActions": "Ver Acciones Críticas", @@ -852,5 +994,324 @@ "november": "Noviembre", "december": "Diciembre" } + }, + "law10": { + "constants": { + "requirements": { + "LAW_07": { + "name": "Cobertura Horaria" + }, + "LAW_01": { + "name": "Velocidad de Respuesta" + }, + "LAW_02": { + "name": "Calidad de Resolucion" + }, + "LAW_09": { + "name": "Cobertura Linguistica" + } + } + }, + "status": { + "CUMPLE": "Cumple", + "PARCIAL": "Parcial", + "NO_CUMPLE": "No Cumple", + "SIN_DATOS": "Sin Datos" + }, + "compliance": { + "law07": { + "noData": "Sin datos de distribucion horaria", + "noDataDetails": "No se encontraron datos de distribucion horaria en el analisis", + "offHoursPercent": "{{percent}}% de interacciones fuera de horario laboral", + "adequateCoverage": "Cobertura horaria adecuada", + "improvableCoverage": "Cobertura horaria mejorable - considerar ampliar horarios", + "insufficientCoverage": "Cobertura horaria insuficiente - requiere accion inmediata", + "gapOverOptimal": "{{gap}}pp sobre optimo", + "gapOverLimit": "{{gap}}pp sobre limite" + }, + "law01": { + "noData": "Sin datos de tiempos de espera", + "noDataDetails": "No se encontraron datos de hold_time en el analisis", + "avgHoldTime": "Tiempo de espera promedio: {{time}}s (limite: 180s)", + "withinLimit": "{{percent}}% de interacciones dentro del limite", + "queuesExceedLimit": "{{count}} de {{total}} colas exceden el limite", + "gapNegative": "-{{gap}}s", + "queuesOutside": "{{count}} colas fuera", + "gapPositive": "+{{gap}}s" + }, + "law02": { + "noData": "Sin datos de resolucion", + "noDataDetails": "No se encontraron datos de FCR o transferencias", + "fcrTechnical": "FCR Tecnico: {{fcr}}% (objetivo: >75%)", + "transferRate": "Tasa de transferencia: {{rate}}% (objetivo: <15%)", + "highTransferQueues": "{{count}} colas con transfer >25%", + "gapDash": "-", + "gapFcr": "FCR {{fcrGap}}, Transfer {{transferGap}}", + "gapOk": "OK", + "gapPositive": "+{{gap}}pp", + "gapNegative": "-{{gap}}pp" + }, + "law09": { + "noData": "Requiere datos", + "noLanguageData": "No se dispone de datos de idioma en las interacciones", + "needsLanguageField": "Para evaluar este requisito se necesita el campo \"language\" en el CSV" + } + }, + "header": { + "aboutThisAnalysis": "Sobre este Analisis", + "lawTitle": "Ley 10/2025 de Atencion al Cliente", + "description": "Este modulo conecta tus metricas operacionales actuales con los requisitos de la Ley 10/2025. No mide compliance directamente (requeriria datos adicionales), pero SI identifica patrones que impactan en tu capacidad de cumplir con la normativa.", + "complianceDeadline": "Deadline de cumplimiento", + "december282026": "28 Diciembre 2026", + "daysRemaining": "{{days}} dias restantes", + "requirementsEvaluated": "Requisitos evaluados", + "requirementsMet": "{{met}} de {{total}} cumplen", + "basedOnData": "Basado en datos disponibles", + "overallStatus": "Estado general", + "goodState": "Buen estado", + "requiresAttention": "Requiere atencion", + "urgentAction": "Accion urgente" + }, + "timeCoverage": { + "title": "Cobertura Temporal: Disponibilidad del Servicio", + "article": "Relacionado con Art. 14 - Servicios basicos 24/7", + "whatWeKnow": "LO QUE SABEMOS", + "heatmap247": "HEATMAP VOLUMETRICO 24x7", + "intensity": "Intensidad:", + "intensityLow": "Bajo", + "intensityMedium": "Medio", + "intensityHigh": "Alto", + "operationalFindings": "Hallazgos operacionales:", + "detectedSchedule": "Horario detectado: L-V 08:00-22:00, S-D horario reducido", + "nightVolume": "Volumen nocturno (22:00-08:00): {{volume}} interacciones ({{percent}}%)", + "earlyMorningVolume": "Volumen madrugada (00:00-06:00): {{volume}} interacciones ({{percent}}%)", + "peakHour": "Pico maximo: {{hour}}:00-{{hourEnd}}:00 ({{percent}}% del volumen diario)", + "lawImplication": "IMPLICACION LEY 10/2025", + "basicServiceRequirement": "Transporte aereo = Servicio basico", + "article14Requirement": "→ Art. 14 requiere atencion 24/7 para incidencias", + "gapIdentified": "Gap identificado:", + "clientsOutsideHours": "{{percent}}% de tus clientes contactan fuera del horario actual", + "complianceIssue": "Si estas son incidencias (equipaje perdido, cambios urgentes), NO cumples Art. 14", + "suggestedAction": "ACCION SUGERIDA", + "classifyNightVolume": "1. Clasificar volumen nocturno por tipo:", + "criticalIncidents": "¿Que % son incidencias criticas? → Requiere 24/7", + "generalQueries": "¿Que % son consultas generales? → Pueden esperar", + "coverageOptions": "2. Opciones de cobertura:", + "optionAChatbot": "A) Chatbot IA + agente on-call", + "optionBExternal": "B) Redirigir a call center 24/7 externo", + "optionCNight": "C) Agentes nocturnos (3 turnos)", + "costPerYear": "~{{cost}}/año" + }, + "responseSpeed": { + "title": "Velocidad de Atencion: Eficiencia Operativa", + "article": "Relacionado con Art. 8.2 - 95% llamadas <3min", + "whatWeKnow": "LO QUE SABEMOS", + "abandonmentRate": "Tasa abandono", + "ahtP50": "AHT P50 ({{min}}m {{sec}}s)", + "ahtP90": "AHT P90 ({{min}}m {{sec}}s)", + "ratioP90P50": "Ratio P90/P50 {{elevated}}", + "elevated": "(elevado)", + "abandonmentByHour": "DISTRIBUCION DE ABANDONOS POR HORA", + "abandonmentLegend": "Abandono:", + "abandonmentLow": "<8%", + "abandonmentMedium": "8-15%", + "abandonmentHigh": ">20%", + "patternsObserved": "Patrones observados:", + "maxAbandonment": "Mayor abandono: {{hourStart}}:00-{{hourEnd}}:00 ({{rate}}% vs {{avg}}% media)", + "highestAht": "AHT mas alto: Lunes 09:00-11:00 ({{high}}s vs {{p50}}s P50)", + "minAbandonment": "Menor abandono: {{hourStart}}:00-{{hourEnd}}:00 ({{rate}}%)", + "lawImplication": "IMPLICACION LEY 10/2025", + "article82Requirement": "Art. 8.2 requiere: \"95% de llamadas atendidas en <3 minutos\"", + "dataLimitation": "LIMITACION DE DATOS", + "noAsaData": "Tu CDR actual NO incluye ASA (tiempo en cola antes de responder), por lo que NO podemos medir este requisito directamente.", + "butWeKnow": "PERO SI sabemos:", + "customersAbandon": "{{rate}}% de clientes abandonan → Probablemente esperaron mucho", + "highVariability": "Alta variabilidad AHT (P90/P50={{ratio}}) → Cola impredecible", + "peaksCoincide": "Picos de abandono coinciden con picos de volumen", + "conservativeEstimate": "Estimacion conservadora (±10% margen error):", + "likelyFastResponse": "→ ~{{percent}}% de llamadas probablemente atendidas \"rapido\"", + "gapVs95": "→ Gap vs 95% requerido: {{operator}}{{gap}} puntos porcentuales", + "suggestedAction": "ACCION SUGERIDA", + "shortTerm": "1. CORTO PLAZO: Reducir AHT para aumentar capacidad", + "dimension2Identifies": "Tu Dimension 2 (Eficiencia) ya identifica:", + "highAht": "- AHT elevado ({{aht}}s vs 380s benchmark)", + "copilotOpportunity": "- Oportunidad Copilot IA: -18% AHT proyectado", + "dualBenefit": "Beneficio dual: ↓ AHT = ↑ capacidad = ↓ cola = ↑ ASA", + "mediumTerm": "2. MEDIO PLAZO: Implementar tracking ASA real", + "platformConfig": "Configuracion en plataforma", + "implementationTimeline": "Timeline implementacion", + "implementationWeeks": "4-6 semanas", + "benefit": "Beneficio: Medicion precisa para auditoria ENAC" + }, + "resolutionQuality": { + "title": "Calidad de Resolucion: Efectividad", + "article": "Relacionado con Art. 17 - Resolucion en 15 dias", + "whatWeKnow": "LO QUE SABEMOS", + "fcrReal": "FCR Real (fcr_real_flag)", + "recontactRate7d": "Tasa recontacto 7 dias", + "repeatCalls": "Llamadas repetidas", + "fcrBySkill": "FCR POR SKILL/QUEUE", + "fcrLegend": "FCR:", + "fcrLow": "<45%", + "fcrMedium": "45-65%", + "fcrHigh": ">75%", + "topLowFcr": "Top skills con FCR bajo:", + "fcrValue": "{{fcr}}% FCR", + "lawImplication": "IMPLICACION LEY 10/2025", + "article17Requirement": "Art. 17 requiere: \"Resolucion de reclamaciones ≤15 dias\"", + "dataLimitation": "LIMITACION DE DATOS", + "noCaseTracking": "Tu CDR solo registra interacciones individuales, NO casos multi-touch ni tiempo total de resolucion.", + "butWeKnow": "PERO SI sabemos:", + "multipleContactsRequired": "{{percent}}% de casos requieren multiples contactos", + "fcrGap": "FCR {{fcr}}% = {{gap}}% NO resuelto en primera interaccion", + "complexProcesses": "Esto sugiere procesos complejos o informacion fragmentada", + "alertSignal": "Senal de alerta:", + "resolutionTimeRisk": "Si los clientes recontactan multiples veces por el mismo tema, es probable que el tiempo TOTAL de resolucion supere los 15 dias requeridos por ley.", + "suggestedAction": "ACCION SUGERIDA", + "diagnosis": "1. DIAGNOSTICO: Implementar sistema de casos/tickets", + "registerOpenClose": "Registrar fecha apertura + cierre", + "linkInteractions": "Vincular multiples interacciones al mismo caso", + "typology": "Tipologia: consulta / reclamacion / incidencia", + "crmInvestment": "Inversion CRM/Ticketing", + "operationalImprovement": "2. MEJORA OPERATIVA: Aumentar FCR", + "dimension3Identifies": "Tu Dimension 3 (Efectividad) ya identifica:", + "rootCauses": "- Root causes: info fragmentada, falta empowerment", + "solution": "- Solucion: Knowledge base + decision trees", + "fcrBenefit": "Beneficio: ↑ FCR = ↓ recontactos = ↓ tiempo total" + }, + "summary": { + "title": "Resumen de Cumplimiento - Todos los Requisitos", + "requirementColumn": "Requisito", + "descriptionColumn": "Descripcion", + "statusColumn": "Estado", + "scoreColumn": "Score", + "gapColumn": "Gap", + "requirements": { + "LAW-01": { + "name": "Tiempo de Espera", + "description": "Tiempo maximo de espera de 3 minutos para atencion telefonica" + }, + "LAW-02": { + "name": "Resolucion Efectiva", + "description": "Resolucion en primera contacto sin transferencias innecesarias" + }, + "LAW-03": { + "name": "Acceso a Agente Humano", + "description": "Derecho a hablar con un agente humano en cualquier momento" + }, + "LAW-04": { + "name": "Grabacion de Llamadas", + "description": "Notificacion previa de grabacion y acceso a la misma" + }, + "LAW-05": { + "name": "Accesibilidad", + "description": "Canales accesibles para personas con discapacidad" + }, + "LAW-06": { + "name": "Confirmacion Escrita", + "description": "Confirmacion por escrito de reclamaciones y gestiones" + }, + "LAW-07": { + "name": "Cobertura Horaria", + "description": "Atencion 24/7 para servicios esenciales o horario ampliado" + }, + "LAW-08": { + "name": "Formacion de Agentes", + "description": "Personal cualificado y formado en atencion al cliente" + }, + "LAW-09": { + "name": "Idiomas Cooficiales", + "description": "Atencion en catalan, euskera, gallego y valenciano" + }, + "LAW-10": { + "name": "Plazos de Resolucion", + "description": "Resolucion de reclamaciones en maximo 15 dias habiles" + }, + "LAW-11": { + "name": "Gratuidad del Servicio", + "description": "Atencion telefonica sin coste adicional (numeros 900)" + }, + "LAW-12": { + "name": "Trazabilidad", + "description": "Numero de referencia para seguimiento de gestiones" + } + }, + "legend": { + "complies": "Cumple: Requisito satisfecho", + "partial": "Parcial: Requiere mejoras", + "notComplies": "No Cumple: Accion urgente", + "noData": "Sin Datos: Campos no disponibles en CSV" + }, + "investment": { + "nonComplianceCost": "Coste de no cumplimiento", + "upTo100k": "Hasta 100K", + "potentialFines": "Multas potenciales/infraccion", + "recommendedInvestment": "Inversion recomendada", + "basedOnOperation": "Basada en tu operacion", + "complianceRoi": "ROI de cumplimiento", + "avoidSanctionsAndImprove": "Evitar sanciones + mejora CX", + "highRoi": "Alto", + "percentOfAnnualCost": "~5% coste anual" + } + }, + "dataMaturity": { + "title": "Resumen: Madurez de Datos para Compliance", + "currentLevel": "Tu nivel actual de instrumentacion:", + "dataAvailable": "DATOS DISPONIBLES (3/10)", + "dataEstimable": "DATOS ESTIMABLES (2/10)", + "dataNotAvailable": "NO DISPONIBLES (5/10)", + "availableData": { + "temporalCoverage": "Cobertura temporal 24/7", + "geographicDistribution": "Distribucion geografica", + "resolutionQuality": "Calidad resolucion proxy" + }, + "estimableData": { + "asaProxy": "ASA <3min via proxy abandono", + "languagesViaCountry": "Lenguas cooficiales via pais" + }, + "missingData": { + "caseResolutionTime": "Tiempo resolucion casos", + "refundTime": "Cobros indebidos <5 dias", + "supervisorTransfer": "Transfer a supervisor", + "incidentInfo": "Info incidencias <2h", + "enacAudit": "Auditoria ENAC", + "externalContract": "requiere contratacion externa" + }, + "suggestedInvestment": "INVERSION SUGERIDA PARA COMPLIANCE COMPLETO", + "phase1": "Fase 1 - Instrumentacion (Q1 2026)", + "phase2": "Fase 2 - Operaciones (Q2-Q3 2026)", + "phase1Items": { + "asaTracking": "Tracking ASA real", + "ticketingSystem": "Sistema ticketing/casos", + "languageEnrichment": "Enriquecimiento lenguas", + "subtotal": "Subtotal:" + }, + "phase2Items": { + "coverage247": "Cobertura 24/7 (chatbot + on-call)", + "aiCopilot": "Copilot IA (reducir AHT)", + "enacAuditor": "Auditor ENAC", + "subtotalYear1": "Subtotal año 1:", + "perYear": "/año", + "perMonth": "/mes" + }, + "totals": { + "totalInvestment": "Inversion Total", + "percentAnnualCost": "~5% coste anual", + "riskAvoided": "Riesgo Evitado", + "potentialSanctions": "sanciones potenciales", + "complianceRoi": "ROI Compliance" + }, + "article": "Art. {{number}}", + "articlePartial": "Art. {{number}} parcial", + "articleIndirect": "Art. {{number}} indirecto", + "errorMargin": "±{{margin}}%", + "noDetail": "sin detalle" + }, + "common": { + "noData": "Sin datos", + "requiredData": "Requiere datos", + "score": "Score", + "gap": "Gap" + } } } \ No newline at end of file