Add English language support with i18n implementation

Implemented comprehensive internationalization (i18n) for both frontend and backend:

Frontend:
- Added react-i18next configuration with Spanish (default) and English
- Created translation files (locales/es.json, locales/en.json)
- Refactored core components to use i18n: LoginPage, DashboardHeader, DataUploader
- Created LanguageSelector component with toggle between ES/EN
- Updated API client to send Accept-Language header

Backend:
- Created i18n module with translation dictionary for error messages
- Updated security.py to return localized authentication errors
- Updated api/analysis.py to return localized validation errors
- Implemented language detection from Accept-Language header

Spanish remains the default language ensuring backward compatibility.
Users can switch between languages using the language selector in the dashboard header.

https://claude.ai/code/session_1N9VX
This commit is contained in:
Claude
2026-02-06 17:46:01 +00:00
parent 9457d3d02f
commit f719d181c0
15 changed files with 768 additions and 58 deletions

207
frontend/locales/es.json Normal file
View File

@@ -0,0 +1,207 @@
{
"common": {
"or": "O",
"loading": "Cargando...",
"error": "Error",
"success": "Éxito",
"cancel": "Cancelar",
"confirm": "Confirmar",
"close": "Cerrar",
"save": "Guardar",
"delete": "Eliminar",
"edit": "Editar",
"view": "Ver",
"back": "Volver",
"next": "Siguiente",
"previous": "Anterior",
"search": "Buscar",
"filter": "Filtrar",
"export": "Exportar",
"import": "Importar"
},
"auth": {
"login": "Iniciar sesión",
"logout": "Cerrar sesión",
"loginTitle": "Inicia sesión para acceder al análisis",
"username": "Usuario",
"password": "Contraseña",
"enterButton": "Entrar",
"enteringButton": "Entrando…",
"sessionInfo": "La sesión permanecerá activa durante 1 hora.",
"sessionExpired": "Sesión caducada o credenciales incorrectas. Vuelve a iniciar sesión.",
"loginRequired": "Debes iniciar sesión para analizar datos.",
"credentialsRequired": "Introduce usuario y contraseña",
"sessionStarted": "Sesión iniciada"
},
"upload": {
"title": "Sube tus Datos y Ejecuta el Análisis",
"uploadFile": "Subir Archivo",
"clickToUpload": "Haz clic para subir un fichero",
"dragAndDrop": "o arrastra y suelta aquí",
"fileTypes": "CSV, XLSX, o XLS",
"googleSheetPlaceholder": "Pega la URL de tu Google Sheet aquí",
"invalidFileType": "Tipo de archivo no válido. Sube un CSV o Excel.",
"pleaseUploadFile": "Por favor, sube un archivo o introduce una URL de Google Sheet.",
"generateSyntheticData": "Generar Datos Sintéticos",
"syntheticDataGenerated": "Datos Sintéticos Generados!",
"dataReceived": "Datos Recibidos!",
"noDataPrompt": "¿No tienes datos a mano? Genera un set de datos de ejemplo.",
"processingData": "Procesando...",
"analyzingData": "Analizando...",
"generating": "Generando...",
"readyToAnalyze": "¡Listo para analizar!",
"dataProcessed": "Datos Procesados",
"recordsAnalyzed": "Registros analizados",
"monthsHistory": "Meses de histórico",
"sourceSystem": "Sistema origen",
"highConfidence": "Confianza: Alta",
"mediumConfidence": "Confianza: Media",
"lowConfidence": "Confianza: Baja",
"subtitle": "Usa una de las siguientes opciones para enviarnos tus datos para el análisis."
},
"stepper": {
"step1": "Paso 1",
"step2": "Paso 2",
"step3": "Paso 3",
"selectTier": "Seleccionar Tier",
"uploadData": "Subir Datos",
"viewResults": "Ver Resultados"
},
"tiers": {
"gold": {
"name": "Análisis GOLD",
"description": "5 dimensiones completas con Agentic Readiness avanzado",
"features": [
"5 dimensiones: Volumetría, Eficiencia, Efectividad, Complejidad, Agentic Readiness",
"IA Generativa: Insights personalizados por OpenAI",
"Roadmap de transformación: Fases AUTOMATE, ASSIST, AUGMENT",
"Matriz de priorización con niveles de madurez",
"Benchmarking avanzado contra industria",
"Informes exportables en PDF"
]
},
"silver": {
"name": "Análisis SILVER",
"description": "4 dimensiones core con métricas operativas",
"features": [
"4 dimensiones: Volumetría, Eficiencia, Efectividad, Economía",
"Análisis sin IA generativa",
"Roadmap simplificado",
"Benchmark básico",
"Matriz de oportunidades"
]
},
"express": {
"name": "Análisis EXPRESS",
"description": "Diagnóstico rápido de volumetría y eficiencia",
"features": [
"2 dimensiones: Volumetría, Eficiencia",
"Análisis instantáneo",
"Sin IA ni roadmap",
"Ideal para pruebas rápidas"
]
}
},
"dashboard": {
"title": "Dashboard de Diagnóstico",
"viewDashboard": "Ver Dashboard de Diagnóstico",
"generateAnalysis": "Generar Análisis",
"analyzing": "Analizando...",
"analysisComplete": "¡Análisis completado!",
"dataLoadedFromCache": "¡Datos cargados desde caché!",
"reloadPage": "Recargar Página"
},
"tabs": {
"executive": "Resumen",
"dimensions": "Dimensiones",
"agenticReadiness": "Agentic Readiness",
"roadmap": "Roadmap",
"law10": "Ley 10/2025"
},
"dimensions": {
"volumetry": "Volumetría & Distribución",
"operationalPerformance": "Eficiencia Operativa",
"effectiveness": "Efectividad & Resolución",
"complexity": "Complejidad & Predictibilidad",
"economy": "Economía & Costes",
"agenticReadiness": "Agentic Readiness"
},
"healthStatus": {
"excellent": "EXCELENTE",
"excellentDesc": "Top quartile, modelo a seguir",
"good": "BUENO",
"goodDesc": "Por encima de benchmarks, desempeño sólido",
"medium": "MEDIO",
"mediumDesc": "Dentro de rango esperado",
"low": "BAJO",
"lowDesc": "Requiere mejora, por debajo de benchmarks",
"critical": "CRÍTICO",
"criticalDesc": "Necesita intervención inmediata"
},
"benchmark": {
"title": "Benchmark Industria (P50)",
"aboveBenchmark": "Por encima de benchmarks, desempeño sólido",
"belowBenchmark": "Requiere mejora, por debajo de benchmarks",
"withinRange": "Dentro de rango esperado"
},
"roadmap": {
"wave1": "Wave 1: AUTOMATE",
"wave2": "Wave 2: ASSIST",
"wave3": "Wave 3: AUGMENT",
"quickWins": "Quick Wins (0-6 meses)",
"buildCapability": "Build Capability (6-12 meses)",
"transform": "Transform (12-18 meses)",
"automate": "Automatizar",
"duration3to6": "3-6 meses",
"duration6to12": "6-12 meses",
"duration12to18": "12-18 meses"
},
"opportunities": {
"viewCriticalActions": "Ver Acciones Críticas",
"explorImprovements": "Explorar Mejoras",
"inGoodState": "En buen estado",
"prioritize": "Priorizar",
"optimize": "Optimizar",
"maintain": "Mantener"
},
"agenticReadiness": {
"score": "Agentic Readiness Score",
"confidence": "Confianza",
"readyForCopilot": "Listo para Copilot",
"readyForCopilotDesc": "Procesos con predictibilidad y simplicidad suficientes para asistencia IA (sugerencias en tiempo real, autocompletado).",
"optimizeFirst": "Optimizar primero",
"optimizeFirstDesc": "Estandarizar procesos y reducir variabilidad antes de implementar asistencia IA.",
"requiresHumanManagement": "Requiere gestión humana",
"requiresHumanManagementDesc": "Procesos complejos o variables que necesitan intervención humana antes de considerar automatización."
},
"economicModel": {
"title": "Modelo Económico",
"costPerInteraction": "Coste por interacción (CPI) por canal",
"totalCost": "Coste Total",
"avgCost": "Coste Promedio",
"costBreakdown": "Desglose de Costes",
"enterCostPerHour": "Por favor, introduce el coste por hora del agente.",
"noCostConfig": "Sin configuración de costes"
},
"charts": {
"volumeByDayAndHour": "Volumen por día de la semana y hora",
"ahtDistributionBySkill": "Distribución de AHT por skill",
"resolutionFunnelBySkill": "Funnel de resolución (P50) por skill",
"csatDistribution": "Distribución de CSAT"
},
"errors": {
"renderError": "Error de Renderizado",
"componentError": "Este componente encontró un error y no pudo renderizarse correctamente.",
"viewTechnicalDetails": "Ver detalles técnicos",
"errorInComponent": "Error en {{componentName}}",
"somethingWentWrong": "Algo salió mal",
"tryAgain": "Intentar de nuevo"
},
"methodology": {
"title": "Metodología",
"description": "Conoce cómo calculamos las métricas",
"close": "Cerrar",
"appliedBadge": "Metodología de Transformación de Datos aplicada",
"appliedBadgeShort": "Metodología"
}
}