Files
openccb/I18N_RESPONSIVIDAD_IMPLEMENTACION.md
T
Nurfog 2ff06ee7ae feat: i18n full support, responsive UI, multi-model AI config, and bug fixes
Major Features:
- Internationalization (i18n) with auto-detection for ES/EN/PT
- Mobile-first responsive design for Studio and Experience
- Multi-model AI configuration (llama3.2:3b, qwen3.5:9b, gpt-oss:latest)
- Course language configuration (auto-detect or fixed per course)

Backend Changes:
- shared/common: ModelType enum for intelligent model selection
- LMS: log_ai_usage function migration (fix chat tutor 500 error)
- LMS/CMS: course language config fields (language_setting, fixed_language)
- LMS: /courses/{id}/language-config endpoint for language detection

Frontend Changes:
- Experience: Enhanced i18n with browser language detection
- Experience: Audio recording with HTTPS check and error handling
- Studio: Memory game with unique pair IDs and debug logging
- Studio: Expanded translations (250+ keys for ES, EN, PT)
- Both: Language selector in headers (mobile responsive)

Documentation:
- AI_MODELS_CONFIG.md: Multi-model configuration guide
- RESPONSIVIDAD_GUIA.md: Mobile-first design patterns
- I18N_RESPONSIVIDAD_IMPLEMENTACION.md: Implementation details
- DEBUG_AUDIO_RECORDING.md: Audio troubleshooting guide
- DEBUG_MEMORY_GAME.md: Memory game debugging steps

Bug Fixes:
- Fix chat tutor 500 error (missing log_ai_usage function)
- Fix audio recording (HTTPS check, browser compatibility)
- Fix memory game pair IDs (unique ID generation)
- Fix HotspotBlock TypeScript errors

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-03-23 12:24:22 -03:00

10 KiB

Implementación de Internacionalización (i18n) y Responsividad

Resumen de la Implementación

Fecha: 20 de Marzo, 2026
Estado: Completado


🌍 Internacionalización (i18n)

Características Implementadas

  1. Detección Automática de Idioma

    • Detección del idioma del navegador al primer ingreso
    • Soporte para múltiples idiomas del navegador (navigator.languages)
    • Fallback a español si el idioma no está soportado
  2. Idiomas Soportados

    • 🇪🇸 Español (es)
    • 🇬🇧 Inglés (en)
    • 🇵🇹 Portugués (pt)
  3. Selector Manual de Idioma

    • Disponible en AppHeader (Experience) y Navbar (Studio)
    • Persistencia en localStorage
    • Cambio instantáneo sin recargar la página
  4. Configuración de Idioma por Curso

    • Modo Automático: Detecta el idioma del usuario
    • Modo Fijo: Usa siempre el idioma configurado en el curso
    • Ideal para cursos de idiomas (ej: curso de inglés siempre en inglés)

📱 Responsividad (Mobile-First)

Breakpoints Utilizados

Mobile:  < 640px   (default)
sm:      ≥ 640px
md:      ≥ 768px
lg:      ≥ 1024px
xl:      ≥ 1280px
2xl:     ≥ 1536px

Componentes Responsivos

AppHeader (Experience)

Mobile (< 768px):

  • Logo compacto
  • Íconos de notificación y tema
  • Botón de menú hamburguesa
  • Sidebar deslizante con navegación completa

Desktop (≥ 768px):

  • Logo completo
  • Navegación horizontal visible
  • Selector de idioma visible
  • Perfil de usuario visible

Navbar (Studio)

Mobile (< 768px):

  • Logo compacto
  • Dropdowns colapsados
  • Menú hamburguesa
  • Sidebar deslizante

Desktop (≥ 768px):

  • Logo completo
  • Dropdowns visibles
  • Información de usuario visible

🗂️ Archivos de Traducción

Experience (web/experience/src/lib/locales/)

Archivos:

  • es.json - Español (completo)
  • en.json - Inglés (completo)
  • pt.json - Portugués (completo)

Categorías:

  • common - Textos comunes (loading, error, save, cancel)
  • nav - Navegación (catalog, profile, signOut)
  • course - Cursos (modules, lessons, progress)
  • lesson - Lecciones (summary, transcription, complete)
  • auth - Autenticación (login, register, password)
  • dashboard - Dashboard (welcome, stats)
  • profile - Perfil (edit, avatar, settings)
  • gamification - Gamificación (level, xp, badges)
  • grading - Calificaciones (grade, score, feedback)
  • quiz - Cuestionarios (start, submit, attempts)
  • forum - Foros (discussions, threads, replies)
  • payments - Pagos (purchase, payment method)
  • accessibility - Accesibilidad (contrast, text size)
  • language - Idiomas (select, course, interface)
  • errors - Errores (notFound, unauthorized)
  • dates - Fechas (today, yesterday, daysAgo)

Studio (web/studio/src/lib/locales/)

Archivos:

  • es.json - Español (completo - administración)
  • en.json - Inglés (básico - pendiente completar)
  • pt.json - Portugués (básico - pendiente completar)

Categorías Adicionales:

  • course - Gestión de cursos (create, edit, modules, lessons)
  • content - Tipos de contenido (video, audio, quiz, code)
  • ai - Funciones de IA (generate, model, tokens)
  • grading - Sistema de calificación (categories, weights)
  • students - Estudiantes (enrollments, progress)
  • analytics - Analíticas (overview, retention)
  • settings - Configuración (branding, integrations)
  • user - Usuario (profile, preferences)
  • validation - Validación de formularios

🗄️ Base de Datos

Migración: Course Language Configuration

Archivo: services/cms-service/migrations/20260320000002_add_course_language_config.sql

Campos Agregados a courses:

language_setting VARCHAR(20) DEFAULT 'auto'
  - 'auto': Detectar idioma del usuario
  - 'fixed': Usar idioma fijo

fixed_language VARCHAR(5) DEFAULT NULL
  - 'es': Español
  - 'en': Inglés
  - 'pt': Portugués
  - NULL: Cuando language_setting es 'auto'

Constraints:

chk_language_setting: language_setting IN ('auto', 'fixed')
chk_fixed_language: fixed_language IS NULL OR fixed_language IN ('es', 'en', 'pt')

Índice:

idx_courses_language: (language_setting, fixed_language)

🔌 Backend API

LMS Service (Port 3002)

Endpoint: Course Language Config

GET /courses/{id}/language-config
Authorization: Bearer {token}

Respuesta:

{
  "language_setting": "auto",
  "fixed_language": null
}

Ejemplos de Uso:

// Curso en modo automático (usa idioma del usuario)
{
  "language_setting": "auto",
  "fixed_language": null
}

// Curso de inglés (siempre en inglés)
{
  "language_setting": "fixed",
  "fixed_language": "en"
}

// Curso de español (siempre en español)
{
  "language_setting": "fixed",
  "fixed_language": "es"
}

⚙️ Contextos y Hooks

I18nContext (Experience y Studio)

Funciones:

interface I18nContextType {
    language: string;
    setLanguage: (lang: string) => void;
    t: (path: string) => string;
    detectBrowserLanguage: () => string;
}

Uso:

import { useTranslation } from '@/context/I18nContext';

function MyComponent() {
    const { language, setLanguage, t } = useTranslation();
    
    return (
        <div>
            <h1>{t('dashboard.welcome')}</h1>
            <select 
                value={language} 
                onChange={(e) => setLanguage(e.target.value)}
            >
                <option value="es">ES</option>
                <option value="en">EN</option>
                <option value="pt">PT</option>
            </select>
        </div>
    );
}

useCourseLanguage Hook (Experience)

Hook para idioma por curso:

import { useCourseLanguage } from '@/hooks/useCourseLanguage';

function CoursePage({ courseId }) {
    const { 
        courseLanguage, 
        isFixedLanguage, 
        isLoading 
    } = useCourseLanguage(courseId);
    
    if (isLoading) return <Loading />;
    
    return (
        <div>
            <p>Idioma del curso: {courseLanguage}</p>
            {isFixedLanguage() && (
                <p>Este curso usa idioma fijo</p>
            )}
        </div>
    );
}

Funciones:

  • courseLanguage: Idioma actual del curso
  • isFixedLanguage(): Boolean - ¿el curso tiene idioma fijo?
  • isLoading: Boolean - ¿cargando configuración?
  • refreshConfig(): Recargar configuración

useCourseLanguageSwitcher Hook (Experience)

Hook para cambiar idioma (solo si es permitido):

import { useCourseLanguageSwitcher } from '@/hooks/useCourseLanguage';

function LanguageSelector({ courseId }) {
    const { 
        currentLanguage, 
        canChangeLanguage, 
        changeLanguage,
        isFixed 
    } = useCourseLanguageSwitcher(courseId);
    
    return (
        <select 
            value={currentLanguage}
            onChange={(e) => changeLanguage(e.target.value)}
            disabled={!canChangeLanguage}
        >
            <option value="es">Español</option>
            <option value="en">English</option>
            <option value="pt">Português</option>
        </select>
    );
}

📋 Guía de Responsividad

Archivo: RESPONSIVIDAD_GUIA.md

Principios Mobile-First

  1. Diseñar primero para móvil
  2. Mejorar progresivamente para pantallas más grandes
  3. Usar clases responsivas de Tailwind

Patrones Comunes

Grid de Cursos

<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
  {courses.map(course => (
    <CourseCard key={course.id} course={course} />
  ))}
</div>

Tablas Responsivas

<div className="overflow-x-auto">
  <table className="min-w-full">
    {/* Tabla completa */}
  </table>
</div>

Tipografía Fluida

<h1 className="text-2xl sm:text-3xl md:text-4xl lg:text-5xl font-bold">
  Título Responsivo
</h1>

Espaciado Responsivo

<div className="px-4 md:px-6 lg:px-8 py-4 md:py-6 lg:py-8">
  {/* Contenido */}
</div>

🧪 Pruebas

Checklist de Responsividad

  • Navegación funciona en mobile
  • Menús desplegables accesibles
  • Formularios usables en pantallas pequeñas
  • Tablas con scroll horizontal
  • Imágenes se escalan correctamente
  • Texto legible sin zoom
  • Botones táctiles (mínimo 44x44px)
  • Sin overflow horizontal no intencional

Dispositivos de Prueba (Chrome DevTools)

  • iPhone SE (375x667)
  • iPhone 12 Pro (390x844)
  • iPad Air (820x1180)
  • iPad Pro (1024x1366)
  • Desktop (1920x1080)

🚀 Comandos Útiles

Ver Logs de i18n

# Experience
docker logs openccb-experience-1 | grep -i "language\|i18n"

# Studio
docker logs openccb-studio-1 | grep -i "language\|i18n"

Probar Detección de Idioma

// Console del navegador
console.log(navigator.languages);
console.log(navigator.language);
localStorage.removeItem('experience_language');
location.reload();

Ver Configuración de Curso

# SQL
SELECT id, title, language_setting, fixed_language 
FROM courses 
WHERE id = '{course-id}';

📝 Tareas Futuras (Opcionales)

  1. Completar traducciones de Studio

    • Agregar claves faltantes en en.json y pt.json
  2. Agregar más idiomas

    • Francés (fr)
    • Alemán (de)
    • Italiano (it)
  3. Traducción de contenido de cursos

    • Sistema de traducción de lecciones
    • Contenido multi-idioma por lección
  4. Mejoras de accesibilidad

    • Aumentar contraste
    • Texto de mayor tamaño
    • Navegación por teclado
  5. Optimización de rendimiento

    • Lazy loading de traducciones
    • Code splitting por idioma

📞 Referencias


Implementado por: Equipo de Desarrollo OpenCCB
Versión: 1.0
Última actualización: 2026-03-20