diff --git a/dashboard/src/i18n/index.ts b/dashboard/src/i18n/index.ts
index dafb0703..74320f57 100644
--- a/dashboard/src/i18n/index.ts
+++ b/dashboard/src/i18n/index.ts
@@ -2,6 +2,7 @@ import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import en from './locales/en.json';
+import es from './locales/es.json';
import he from './locales/he.json';
import zhCN from './locales/zh-CN.json';
import zhHK from './locales/zh-HK.json';
@@ -10,13 +11,14 @@ import te from './locales/te.json';
import fr from './locales/fr.json';
import it from './locales/it.json';
-export const supportedLanguages = ['en', 'he', 'zh-CN', 'zh-HK', 'ar', 'te', 'fr', 'it'] as const;
+export const supportedLanguages = ['en', 'es', 'he', 'zh-CN', 'zh-HK', 'ar', 'te', 'fr', 'it'] as const;
export type SupportedLanguage = (typeof supportedLanguages)[number];
export const rtlLanguages: SupportedLanguage[] = ['he', 'ar'];
export const languageOptions: Array<{ value: SupportedLanguage; label: string; compactLabel: string }> = [
{ value: 'en', label: 'English', compactLabel: 'EN' },
+ { value: 'es', label: 'Español', compactLabel: 'ES' },
{ value: 'he', label: 'עברית', compactLabel: 'עברית' },
{ value: 'zh-CN', label: '简体中文', compactLabel: '简中' },
{ value: 'zh-HK', label: '繁體中文', compactLabel: '繁中' },
@@ -48,6 +50,7 @@ void i18n
.init({
resources: {
en: { translation: en },
+ es: { translation: es },
he: { translation: he },
'zh-CN': { translation: zhCN },
'zh-HK': { translation: zhHK },
diff --git a/dashboard/src/i18n/locales/es.json b/dashboard/src/i18n/locales/es.json
new file mode 100644
index 00000000..5ad73384
--- /dev/null
+++ b/dashboard/src/i18n/locales/es.json
@@ -0,0 +1,608 @@
+{
+ "common": {
+ "appName": "OpenWA",
+ "appSubtitle": "API de WhatsApp",
+ "loading": "Cargando...",
+ "save": "Guardar",
+ "cancel": "Cancelar",
+ "delete": "Eliminar",
+ "edit": "Editar",
+ "create": "Crear",
+ "close": "Cerrar",
+ "submit": "Enviar",
+ "confirm": "Confirmar",
+ "search": "Buscar",
+ "filter": "Filtrar",
+ "actions": "Acciones",
+ "status": "Estado",
+ "name": "Nombre",
+ "role": "Rol",
+ "type": "Tipo",
+ "url": "URL",
+ "port": "Puerto",
+ "host": "Host",
+ "username": "Usuario",
+ "password": "Contraseña",
+ "active": "Activo",
+ "inactive": "Inactivo",
+ "enabled": "Habilitado",
+ "disabled": "Deshabilitado",
+ "connected": "Conectado",
+ "disconnected": "Desconectado",
+ "never": "Nunca",
+ "justNow": "Ahora mismo",
+ "minAgo": "Hace {{count}} min",
+ "hoursAgo": "Hace {{count}} horas",
+ "optional": "opcional",
+ "language": "Idioma",
+ "english": "English",
+ "hebrew": "עברית",
+ "back": "Atrás",
+ "next": "Siguiente",
+ "previous": "Anterior",
+ "expand": "Expandir",
+ "collapse": "Colapsar",
+ "logout": "Cerrar sesión",
+ "refresh": "Actualizar",
+ "errorGeneric": "Ha ocurrido un error",
+ "unknownError": "Error desconocido",
+ "showApiKey": "Mostrar clave API",
+ "hideApiKey": "Ocultar clave API"
+ },
+ "theme": {
+ "light": "Claro",
+ "dark": "Oscuro",
+ "system": "Sistema",
+ "label": "Tema: {{value}}"
+ },
+ "nav": {
+ "dashboard": "Panel",
+ "sessions": "Sesiones",
+ "chats": "Chats",
+ "webhooks": "Webhooks",
+ "apiKeys": "Claves API",
+ "messageTester": "Probador de mensajes",
+ "infrastructure": "Infraestructura",
+ "plugins": "Plugins",
+ "logs": "Registros",
+ "templates": "Plantillas"
+ },
+ "chats": {
+ "subtitle": "Envía y responde mensajes de WhatsApp en tiempo real",
+ "noSessionsTitle": "Sin sesiones conectadas",
+ "noSessionsDesc": "Conecta primero una sesión de WhatsApp desde el menú <1>Sesiones1> para usar el chat.",
+ "sessionLabel": "Sesión de WhatsApp",
+ "noPhone": "Sin teléfono",
+ "searchPlaceholder": "Buscar chats...",
+ "loadingChats": "Cargando chats...",
+ "empty": "Sin chats",
+ "noMessageYet": "Aún sin mensajes",
+ "loadingMessages": "Cargando mensajes...",
+ "noMessagesInChat": "Aún no hay mensajes. ¡Envía el primero para empezar!",
+ "downloadDocument": "Descargar documento",
+ "actions": {
+ "reply": "Responder",
+ "react": "Reaccionar",
+ "delete": "Eliminar mensaje"
+ },
+ "replyingTo": "Respondiendo a {{name}}",
+ "you": "Tú",
+ "youPrefix": "Tú: ",
+ "yesterday": "Ayer",
+ "attachTitle": "Enviar archivo / imagen",
+ "emojiTitle": "Elegir emoji",
+ "captionPlaceholder": "Añadir un pie de foto...",
+ "messagePlaceholder": "Escribe un mensaje...",
+ "noPermission": "No tienes permiso para enviar mensajes",
+ "send": "Enviar",
+ "placeholderTitle": "Empieza a escribir",
+ "placeholderDesc": "Selecciona un chat activo de la barra lateral izquierda para leer y enviar mensajes de WhatsApp.",
+ "deleteConfirm": "¿Eliminar este mensaje para todos?",
+ "messageDeleted": "🚫 Este mensaje fue eliminado",
+ "errors": {
+ "loadSessions": "Error al cargar las sesiones",
+ "loadChats": "Error al cargar los chats",
+ "loadMessages": "Error al cargar los mensajes",
+ "markRead": "Error al marcar el chat como leído",
+ "send": "Error al enviar el mensaje",
+ "react": "Error al reaccionar al mensaje",
+ "delete": "Error al eliminar el mensaje"
+ }
+ },
+ "errorBoundary": {
+ "title": "Algo salió mal",
+ "description": "El panel encontró un error inesperado.",
+ "reload": "Recargar panel"
+ },
+ "login": {
+ "apiKey": "Clave API",
+ "apiKeyPlaceholder": "Introduce tu clave API",
+ "apiKeyRequired": "La clave API es obligatoria",
+ "connect": "Conectar",
+ "connecting": "Conectando...",
+ "invalidKey": "Clave API no válida",
+ "connectionError": "No se puede conectar al servidor. Por favor, inténtalo de nuevo.",
+ "help": "¿Necesitas ayuda?",
+ "viewDocs": "Ver documentación",
+ "footer": "Hecho con ❤️ por Yudhi Armyndharis y la comunidad OpenWA",
+ "version": "v{{version}} · {{date}}"
+ },
+ "dashboard": {
+ "title": "Panel",
+ "subtitle": "Resumen de tus sesiones de WhatsApp y actividad",
+ "stats": {
+ "activeSessions": "Sesiones activas",
+ "messagesToday": "Mensajes hoy",
+ "webhooksConfigured": "Webhooks configurados",
+ "apiCalls": "Llamadas API (24h)"
+ },
+ "sessionsOverview": "Resumen de sesiones",
+ "showingSessions": "Mostrando {{shown}} de {{total}} sesiones",
+ "columns": {
+ "sessionId": "ID de sesión",
+ "phone": "Número de teléfono",
+ "status": "Estado",
+ "lastActive": "Última actividad",
+ "actions": "Acciones"
+ },
+ "noSessions": "No se encontraron sesiones. Crea una para empezar.",
+ "view": "Ver",
+ "disconnect": "Desconectar",
+ "errorPrefix": "Error: {{message}}",
+ "loadError": "Error al cargar los datos"
+ },
+ "sessionStatus": {
+ "created": "Nueva",
+ "idle": "Inactiva",
+ "initializing": "Iniciando...",
+ "connecting": "Conectando...",
+ "qr_ready": "Escanear QR",
+ "ready": "Conectada",
+ "disconnected": "Desconectada"
+ },
+ "sessions": {
+ "title": "Sesiones",
+ "subtitle": "Gestiona tus sesiones de WhatsApp y conexiones por código QR",
+ "newSession": "Nueva sesión",
+ "searchPlaceholder": "Buscar sesiones...",
+ "filter": {
+ "all": "Todos los estados",
+ "active": "Activas (Conectadas)",
+ "inactive": "Inactivas",
+ "connecting": "Conectando"
+ },
+ "empty": {
+ "title": "No se encontraron sesiones",
+ "description": "Crea una nueva sesión para empezar"
+ },
+ "create": {
+ "title": "Crear nueva sesión",
+ "label": "Nombre de sesión",
+ "placeholder": "ej., bot-marketing",
+ "hint": "Usa solo letras minúsculas, números y guiones. Ejemplo: soporte-cliente, bot-1",
+ "invalidChars": "Caracteres no válidos. Solo se permiten letras minúsculas, números y guiones.",
+ "tooLong": "El nombre debe tener 50 caracteres o menos ({{length}}/50).",
+ "duplicate": "Ya existe una sesión con ese nombre.",
+ "successTitle": "Sesión creada",
+ "successDesc": "Sesión \"{{name}}\" creada correctamente",
+ "errorTitle": "Error al crear",
+ "errorDefault": "No se pudo crear la sesión"
+ },
+ "delete": {
+ "title": "Confirmar eliminación",
+ "message": "¿Seguro que quieres eliminar la sesión \"{{name}}\"?",
+ "warning": "Esta acción no se puede deshacer.",
+ "successTitle": "Sesión eliminada",
+ "successDescNamed": "Sesión \"{{name}}\" eliminada",
+ "successDescGeneric": "Sesión eliminada",
+ "errorTitle": "Error al eliminar",
+ "errorDefault": "No se pudo eliminar la sesión"
+ },
+ "qr": {
+ "title": "Escanear código QR",
+ "step1": "1. Abre WhatsApp en tu teléfono",
+ "step2": "2. Toca Menú → Dispositivos vinculados",
+ "step3": "3. Toca Vincular dispositivo y escanea este QR",
+ "autoRefresh": "El QR se actualiza automáticamente cada 5 segundos",
+ "generating": "Generando código QR...",
+ "unavailable": "El código QR aún no está disponible. Inténtalo en un momento.",
+ "preparing": "Preparando código QR...",
+ "showQr": "Mostrar QR",
+ "loading": "Cargando...",
+ "scanToConnect": "Escanea el código QR para conectar"
+ },
+ "details": {
+ "title": "Detalles de sesión",
+ "name": "Nombre",
+ "status": "Estado",
+ "sessionId": "ID de sesión",
+ "phone": "Número de teléfono",
+ "phoneNone": "No conectado",
+ "created": "Creado",
+ "lastActive": "Última actividad"
+ },
+ "actions": {
+ "view": "Ver",
+ "start": "Iniciar",
+ "stop": "Detener",
+ "reconnect": "Reconectar",
+ "delete": "Eliminar"
+ },
+ "toasts": {
+ "readyTitle": "Sesión lista",
+ "readyDesc": "La sesión de WhatsApp está conectada",
+ "disconnectedTitle": "Sesión desconectada",
+ "disconnectedDesc": "La sesión de WhatsApp se ha desconectado",
+ "failedTitle": "Sesión fallida",
+ "failedDesc": "La sesión de WhatsApp no pudo iniciarse. Abre la sesión para ver el motivo."
+ },
+ "card": {
+ "phone": "Teléfono",
+ "sessionId": "ID de sesión",
+ "lastActive": "Última actividad",
+ "error": "Error"
+ }
+ },
+ "webhooks": {
+ "title": "Webhooks",
+ "subtitle": "Configura callbacks HTTP para notificaciones de eventos en tiempo real",
+ "addWebhook": "Añadir webhook",
+ "createTitle": "Crear webhook",
+ "editTitle": "Editar webhook",
+ "deleteTitle": "Eliminar webhook",
+ "deleteConfirm": "¿Seguro que quieres eliminar este webhook?",
+ "selectSession": "Seleccionar sesión...",
+ "session": "Sesión",
+ "events": "Eventos",
+ "available": "Eventos disponibles",
+ "saveChanges": "Guardar cambios",
+ "columns": {
+ "url": "URL",
+ "events": "Eventos",
+ "session": "Sesión",
+ "status": "Estado",
+ "actions": "Acciones"
+ },
+ "empty": {
+ "title": "No hay webhooks configurados",
+ "description": "Añade un webhook para recibir notificaciones de eventos en tiempo real"
+ },
+ "toasts": {
+ "created": "Webhook creado correctamente",
+ "createFailed": "Error al crear el webhook: {{message}}",
+ "deleted": "Webhook eliminado correctamente",
+ "deleteFailed": "Error al eliminar el webhook: {{message}}",
+ "updated": "Webhook actualizado correctamente",
+ "updateFailed": "Error al actualizar el webhook: {{message}}",
+ "testOk": "Prueba de webhook exitosa. Estado: {{status}}",
+ "testFailed": "Prueba de webhook fallida: {{message}}",
+ "testError": "Error al probar el webhook: {{message}}"
+ },
+ "actions": {
+ "test": "Probar",
+ "edit": "Editar",
+ "delete": "Eliminar"
+ },
+ "eventDescriptions": {
+ "message.received": "Cuando se recibe un mensaje",
+ "message.sent": "Cuando se envía un mensaje",
+ "session.connected": "Cuando una sesión se conecta",
+ "session.disconnected": "Cuando una sesión se desconecta",
+ "session.qr": "Cuando se genera un código QR",
+ "all": "Todos los eventos"
+ }
+ },
+ "apiKeys": {
+ "title": "Claves API",
+ "subtitle": "Gestiona las claves API para autenticación y control de acceso",
+ "createBtn": "Crear clave API",
+ "modalTitle": "Crear clave API",
+ "createdTitle": "Clave API creada",
+ "createdHint": "Copia esta clave ahora. No podrás verla de nuevo.",
+ "namePlaceholder": "ej., Clave de producción",
+ "rolesTitle": "Referencia de roles",
+ "roles": {
+ "admin": "Administrador",
+ "operator": "Operador",
+ "viewer": "Lector"
+ },
+ "roleDescriptions": {
+ "admin": "Acceso completo a todos los recursos",
+ "operator": "Gestión de sesiones y mensajes",
+ "viewer": "Acceso de solo lectura"
+ },
+ "columns": {
+ "name": "Nombre",
+ "key": "Clave",
+ "role": "Rol",
+ "status": "Estado",
+ "lastUsed": "Último uso",
+ "actions": "Acciones"
+ },
+ "statuses": {
+ "active": "Activa",
+ "revoked": "Revocada"
+ },
+ "empty": {
+ "title": "No hay claves API creadas",
+ "description": "Crea una clave API para autenticar tus peticiones"
+ },
+ "confirm": {
+ "deleteTitle": "Eliminar clave API",
+ "revokeTitle": "Revocar clave API",
+ "deleteMessage": "¿Seguro que quieres eliminar permanentemente {{name}}? Esta acción no se puede deshacer.",
+ "revokeMessage": "¿Seguro que quieres revocar {{name}}? Dejará de funcionar.",
+ "delete": "Eliminar",
+ "revoke": "Revocar"
+ },
+ "actions": {
+ "copy": "Copiar",
+ "revoke": "Revocar",
+ "delete": "Eliminar"
+ }
+ },
+ "logs": {
+ "title": "Registros de auditoría",
+ "subtitle": "Rastrea y revisa todas las acciones de la API y eventos del sistema",
+ "exportCsv": "Exportar CSV",
+ "searchPlaceholder": "Buscar registros...",
+ "severity": {
+ "all": "Todas las severidades",
+ "info": "Info",
+ "warn": "Advertencia",
+ "error": "Error"
+ },
+ "columns": {
+ "timestamp": "Fecha/Hora",
+ "action": "Acción",
+ "session": "Sesión",
+ "apiKey": "Clave API",
+ "ip": "Dirección IP",
+ "severity": "Severidad"
+ },
+ "empty": {
+ "title": "No se encontraron registros",
+ "description": "Los registros de auditoría aparecerán aquí cuando se realicen acciones"
+ }
+ },
+ "messageTester": {
+ "title": "Probador de mensajes",
+ "subtitle": "Envía mensajes de prueba a través de la API",
+ "compose": "Enviar mensaje de prueba",
+ "responseTitle": "Respuesta de la API",
+ "session": "Sesión",
+ "noReadySessions": "Sin sesiones listas",
+ "sessionOptionPhoneNone": "Sin teléfono",
+ "recipientType": "Tipo de destinatario",
+ "personal": "Personal",
+ "group": "Grupo",
+ "selectGroup": "Seleccionar grupo",
+ "recipientPhone": "Número de teléfono del destinatario",
+ "loadingGroups": "Cargando grupos...",
+ "noGroupsFound": "No se encontraron grupos",
+ "selectGroupHint": "Selecciona un grupo de tu WhatsApp",
+ "phoneHint": "Usa formato internacional sin espacios",
+ "messageType": "Tipo de mensaje",
+ "types": {
+ "text": "Texto",
+ "image": "Imagen",
+ "video": "Vídeo",
+ "audio": "Audio",
+ "document": "Documento"
+ },
+ "messageContent": "Contenido del mensaje",
+ "messagePlaceholder": "Escribe tu mensaje aquí...",
+ "mediaUrl": "URL del medio",
+ "caption": "Pie de foto",
+ "filename": "Nombre de archivo",
+ "captionPlaceholder": "Escribe un pie de foto...",
+ "filenamePlaceholder": "documento.pdf",
+ "send": "Enviar mensaje",
+ "sending": "Enviando...",
+ "viewOnly": "Solo lectura",
+ "responseEmpty": "Envía un mensaje para ver la respuesta de la API",
+ "successLabel": "200 OK - Éxito",
+ "failedLabel": "400 - Fallido",
+ "response": {
+ "timestamp": "Fecha/Hora",
+ "messageId": "ID de mensaje",
+ "error": "Error"
+ },
+ "sendFailed": "Error al enviar el mensaje",
+ "notOnWhatsApp": "Este número no está registrado en WhatsApp"
+ },
+ "templates": {
+ "title": "Plantillas",
+ "subtitle": "Crea plantillas de mensaje reutilizables para cada sesión de WhatsApp",
+ "createTitle": "Crear plantilla",
+ "editTitle": "Editar plantilla",
+ "newTemplate": "Nueva plantilla",
+ "createTemplate": "Crear plantilla",
+ "saveChanges": "Guardar cambios",
+ "viewOnly": "Solo lectura",
+ "noSessions": "Sin sesiones",
+ "sessionHint": "Guardada en {{name}}",
+ "namePlaceholder": "ej., confirmacion-pedido",
+ "header": "Encabezado",
+ "headerPlaceholder": "Línea de introducción opcional",
+ "body": "Cuerpo",
+ "bodyPlaceholder": "Hola {{customer}}, tu pedido {{orderId}} está listo.",
+ "footer": "Pie",
+ "footerPlaceholder": "Línea de cierre opcional",
+ "previewTitle": "Vista previa",
+ "previewValuePlaceholder": "Valor de ejemplo",
+ "previewEmpty": "Empieza a escribir una plantilla para previsualizarla aquí.",
+ "noPlaceholders": "Usa marcadores {{nombre}} para probar sustituciones.",
+ "savedTitle": "Plantillas guardadas",
+ "count": "{{count}} en total",
+ "deleteTitle": "Eliminar plantilla",
+ "deleteConfirm": "¿Eliminar la plantilla \"{{name}}\"? Esta acción no se puede deshacer.",
+ "actions": {
+ "copyName": "Copiar nombre de plantilla"
+ },
+ "empty": {
+ "title": "No hay plantillas guardadas",
+ "description": "Crea una plantilla reutilizable para agilizar respuestas y notificaciones habituales.",
+ "noSessionsTitle": "No hay sesiones disponibles",
+ "noSessionsDesc": "Crea una sesión de WhatsApp antes de añadir plantillas."
+ },
+ "toasts": {
+ "created": "Plantilla creada correctamente",
+ "createFailed": "Error al crear la plantilla: {{message}}",
+ "updated": "Plantilla actualizada correctamente",
+ "updateFailed": "Error al actualizar la plantilla: {{message}}",
+ "deleted": "Plantilla eliminada correctamente",
+ "deleteFailed": "Error al eliminar la plantilla: {{message}}",
+ "copied": "Nombre de plantilla copiado"
+ }
+ },
+ "infrastructure": {
+ "title": "Infraestructura",
+ "subtitle": "Configura el servidor, base de datos, caché, almacenamiento y motor",
+ "saveConfig": "Guardar configuración",
+ "saving": "Guardando...",
+ "server": {
+ "title": "Configuración del servidor",
+ "production": "Producción",
+ "development": "Desarrollo",
+ "environment": "Entorno",
+ "domain": "Dominio",
+ "apiPort": "Puerto API",
+ "dashboardPort": "Puerto del panel",
+ "corsOrigins": "Orígenes CORS",
+ "corsPlaceholder": "* o varios orígenes separados por comas",
+ "publicApiUrl": "URL pública de la API (opcional)",
+ "publicDashboardUrl": "URL pública del panel (opcional)"
+ },
+ "webhook": {
+ "title": "Webhook y límite de velocidad",
+ "settings": "Configuración de webhook",
+ "timeout": "Tiempo de espera (ms)",
+ "maxRetries": "Máximo de reintentos",
+ "retryDelay": "Retardo entre reintentos (ms)",
+ "rateLimit": "Límite de velocidad",
+ "window": "Ventana de tiempo (segundos)",
+ "maxReq": "Máximo de peticiones por ventana"
+ },
+ "database": {
+ "title": "Configuración de la base de datos",
+ "sqlite": "SQLite",
+ "sqliteDesc": "Base de datos local en archivo",
+ "postgres": "PostgreSQL",
+ "postgresDesc": "Base de datos para producción",
+ "useBuiltIn": "Usar contenedor PostgreSQL integrado",
+ "builtInDesc": "OpenWA gestionará un contenedor PostgreSQL por ti",
+ "dbName": "Nombre de la base de datos",
+ "poolSize": "Tamaño del pool",
+ "ssl": "Conexión SSL",
+ "sslDesc": "Habilitar TLS/SSL para conexiones seguras a la base de datos",
+ "sslRejectUnauthorized": "Verificar certificado SSL",
+ "sslRejectUnauthorizedDesc": "Rechazar certificados autofirmados o no válidos. Desactívalo para Postgres gestionado con certificados autofirmados (Supabase, Heroku, Render, Railway).",
+ "migrationsTitle": "Migraciones de la base de datos",
+ "migrationsStatus": "El esquema se sincroniza automáticamente con TypeORM",
+ "migrationsHint": "Las migraciones se gestionan automáticamente. Usa la CLI para migraciones manuales."
+ },
+ "redis": {
+ "title": "Redis",
+ "enable": "Habilitar Redis",
+ "enableDesc": "Necesario para caché, almacenamiento de sesiones y colas BullMQ",
+ "useBuiltIn": "Usar contenedor Redis integrado",
+ "builtInDesc": "OpenWA gestionará un contenedor Redis por ti",
+ "queueTitle": "Habilitar sistema de colas BullMQ",
+ "queueDesc": "Usa colas de mensajes para entrega fiable de mensajes y webhooks",
+ "statsTitle": "Estadísticas de colas",
+ "messageQueue": "Cola de mensajes",
+ "webhookQueue": "Cola de webhooks",
+ "pending": "Pendiente",
+ "completed": "Completado",
+ "failed": "Fallido",
+ "clearFailed": "Limpiar trabajos fallidos",
+ "viewBullMq": "Ver panel BullMQ",
+ "disabledTitle": "Redis está deshabilitado",
+ "disabledDesc": "Habilita Redis para caché, almacenamiento de sesiones y colas de mensajes BullMQ.",
+ "passwordOptional": "(opcional)"
+ },
+ "storage": {
+ "title": "Configuración de almacenamiento",
+ "local": "Sistema de archivos local",
+ "localDesc": "Almacenar archivos multimedia localmente",
+ "s3": "Amazon S3",
+ "s3Desc": "Almacenamiento en la nube (compatible con S3)",
+ "useBuiltIn": "Usar contenedor MinIO integrado",
+ "builtInDesc": "OpenWA gestionará un contenedor MinIO (compatible con S3) por ti",
+ "storagePath": "Ruta de almacenamiento",
+ "bucket": "Nombre del bucket",
+ "region": "Región",
+ "accessKey": "Clave de acceso",
+ "secretKey": "Clave secreta",
+ "endpoint": "Endpoint personalizado (opcional)",
+ "endpointHint": "Para MinIO u otros servicios compatibles con S3"
+ },
+ "statusLabels": {
+ "connected": "Conectado",
+ "disconnected": "Desconectado",
+ "disabled": "Deshabilitado"
+ },
+ "restart": {
+ "idleTitle": "⚙️ Configuración guardada",
+ "restartingTitle": "🔄 Reiniciando servidor...",
+ "waitingTitle": "⏳ Por favor espera...",
+ "successTitle": "✅ Servidor listo",
+ "errorTitle": "❌ Error al reiniciar",
+ "idleDesc": "La configuración se ha guardado en .env.generated.
Es necesario reiniciar el servidor para aplicar los cambios.",
+ "later": "Reiniciar más tarde",
+ "now": "Reiniciar ahora",
+ "restartingMsg": "Reiniciando servidor... {{count}}s",
+ "checking": "Comprobando estado del servidor...",
+ "dontClose": "Por favor, no cierres esta ventana",
+ "successMsg": "¡El servidor volvió a estar en línea! La página se recargará automáticamente.",
+ "errorMsg": "El servidor no respondió tras 30 segundos. Revisa los logs de Docker y reinicia manualmente.",
+ "reload": "Recargar página"
+ },
+ "toasts": {
+ "saveFailed": "Error al guardar"
+ }
+ },
+ "plugins": {
+ "title": "Plugins",
+ "subtitle": "Gestiona motores, backends de almacenamiento y extensiones",
+ "refresh": "Actualizar",
+ "engineCard": "Motor de WhatsApp activo",
+ "running": "En ejecución",
+ "supportedFeatures": "Funciones compatibles:",
+ "builtIn": "Integrado",
+ "noDescription": "Sin descripción disponible",
+ "required": "Obligatorio",
+ "active": "Activo",
+ "activate": "Activar",
+ "enable": "Habilitar",
+ "disable": "Deshabilitar",
+ "healthCheck": "Comprobación de salud",
+ "configure": "Configurar",
+ "empty": {
+ "title": "No se encontraron plugins",
+ "description": "Instala plugins para ampliar la funcionalidad de OpenWA"
+ },
+ "config": {
+ "title": "Configurar {{name}}",
+ "restartNotice": "Los cambios requieren reiniciar el servidor para aplicarse",
+ "engineType": "Tipo de motor",
+ "headless": "Modo sin cabeza",
+ "headlessDesc": "Ejecutar el navegador sin interfaz visible (recomendado para producción)",
+ "sessionDataPath": "Ruta de datos de sesión",
+ "browserArgs": "Argumentos del navegador",
+ "noOptions": "No hay opciones de configuración disponibles para este plugin",
+ "save": "Guardar configuración"
+ },
+ "toasts": {
+ "errorTitle": "Error de plugin",
+ "errorDefault": "Error al activar/desactivar el plugin",
+ "healthOk": "Comprobación de salud superada",
+ "healthFail": "Comprobación de salud fallida",
+ "healthError": "Error en la comprobación de salud",
+ "savedTitle": "Configuración guardada",
+ "savedDesc": "Es necesario reiniciar el servidor para aplicar los cambios.",
+ "saveFailed": "Error al guardar"
+ }
+ }
+}