]> git.giorgioravera.it Git - network-manager.git/commitdiff
Added french and spanish translation
authorGiorgio Ravera <giorgio.ravera@gmail.com>
Wed, 5 Aug 2026 19:24:24 +0000 (21:24 +0200)
committerGiorgio Ravera <giorgio.ravera@gmail.com>
Wed, 5 Aug 2026 19:24:24 +0000 (21:24 +0200)
TODO.md
frontend/locales/es.json [new file with mode: 0644]
frontend/locales/fr.json [new file with mode: 0644]

diff --git a/TODO.md b/TODO.md
index 490eca0bcc999b1f02503206b3f7c3fcd9a42113..db15e49a99de3902a3dbf6ea3f20642af6229054 100644 (file)
--- a/TODO.md
+++ b/TODO.md
 - [ ] Session timeout
 - [ ] Protection against session hijacking
 - [ ] Global logout / session invalidation
+- [ ] Themes & Dark mode
 
 ---
 
diff --git a/frontend/locales/es.json b/frontend/locales/es.json
new file mode 100644 (file)
index 0000000..9360438
--- /dev/null
@@ -0,0 +1,307 @@
+{
+  "language": "es",
+  "translations": {
+
+    "app.name": "Administrador de Red",
+    "app.translation.error": "Error al cargar la traducción",
+    "app.modals.error": "Error al cargar los diálogos",
+    "app.action.error": "Error en la acción",
+    "app.restart": "Reiniciar",
+    "app.restart.description": "Reiniciar la aplicación",
+    "app.restart.confirm": "¿Reiniciar la aplicación?",
+    "app.restart.progress": "Reinicio de la aplicación en curso...",
+    "app.restart.error": "Error al reiniciar la aplicación",
+    "app.reconnect.waiting": "Esperando a que el servidor vuelva a estar en línea...",
+    "app.reconnect.success": "La aplicación ha vuelto a estar en línea",
+    "app.reconnect.timeout": "El servidor no volvió a estar en línea",
+    "app.restart.button": "Reiniciando...",
+
+    "auth.login": "Iniciar sesión",
+    "auth.logout": "Cerrar sesión",
+    "auth.username": "Nombre de usuario",
+    "auth.password": "Contraseña",
+    "auth.sign_in": "Acceder",
+    "auth.session_expired": "Sesión expirada",
+    "auth.invalid_credentials": "Nombre de usuario o contraseña no válidos",
+
+    "header.api_status": "Estado de la API",
+    "header.api_status_online": "API OK",
+    "header.api_status_offline": "API FUERA DE LÍNEA",
+
+    "dashboard.title": "Panel de Control",
+
+    "dns.title": "DNS",
+    "dns.card.title": "DNS (BIND)",
+    "dns.card.description": "Zonas, registros y configuración.",
+    "dns.config": "Configuración DNS",
+    "dns.reload": "Recargar DNS",
+    "dns.reload.description": "Recargar DNS (BIND)",
+    "dns.reload.ok": "DNS recargado correctamente",
+    "dns.reload.error": "Error al recargar DNS",
+    "dns.reload.progress": "Reiniciando DNS...",
+
+    "dhcp.title": "Concesiones DHCP",
+    "dhcp.card.title": "DHCP (Kea)",
+    "dhcp.card.description": "Pools, concesiones y reservas.",
+    "dhcp.page.title": "Concesiones DHCP",
+    "dhcp.leases": "Concesiones DHCP",
+    "dhcp.leases.search": "Buscar concesiones DHCP",
+    "dhcp.reload": "Recargar DHCP",
+    "dhcp.reload.description": "Recargar DHCP (Kea)",
+    "dhcp.lease.start": "Inicio",
+    "dhcp.lease.end": "Fin",
+    "dhcp.leases.empty": "No hay concesiones disponibles",
+    "dhcp.leases.static": "estática",
+    "dhcp.leases.static.description": "Concesión estática",
+    "dhcp.leases.active": "activa",
+    "dhcp.leases.active.description": "Concesión activa",
+    "dhcp.leases.expired": "caducada",
+    "dhcp.leases.expired.description": "Concesión caducada",
+    "dhcp.leases.released": "liberada",
+    "dhcp.leases.released.description": "Concesión liberada",
+    "dhcp.leases.declined": "rechazada",
+    "dhcp.leases.declined.description": "Concesión rechazada",
+    "dhcp.leases.add": "Agregar concesión estática",
+    "dhcp.leases.delete": "Eliminar concesión",
+    "dhcp.reload.ok": "DHCP recargado correctamente",
+    "dhcp.reload.error": "Error al recargar DHCP",
+    "dhcp.reload.progress": "Reiniciando DHCP...",
+    "dhcp.leases.deleted.ok": "Concesión eliminada correctamente",
+    "dhcp.leases.deleted.error": "Error al eliminar la concesión",
+    "dhcp.leases.list.error": "Error al cargar las concesiones",
+    "dhcp.leases.loaded.error": "Error al cargar la concesión",
+    "dhcp.leases.delete.invalid_id": "ID de concesión no válido para la eliminación",
+    "dhcp.leases.not.found": "Concesión no encontrada",
+
+    "hosts.title": "Hosts",
+    "hosts.card.title": "Hosts",
+    "hosts.card.description": "Inventario de IP/MAC.",
+    "hosts.page.title": "Lista de Hosts",
+    "hosts.add": "Agregar Host",
+    "hosts.edit": "Editar Host",
+    "hosts.delete": "Eliminar Host",
+    "hosts.search": "Buscar Host",
+    "hosts.hostname": "Nombre del Host",
+    "hosts.ipv4": "Dirección IPv4",
+    "hosts.placeholder.ipv4": "ej. 192.168.1.10",
+    "hosts.ipv6": "Dirección IPv6",
+    "hosts.placeholder.ipv6": "ej. fe80::1",
+    "hosts.mac": "Dirección MAC",
+    "hosts.placeholder.mac": "ej. AA:BB:CC:DD:EE:FF",
+    "hosts.ssl": "Certificado SSL",
+    "hosts.ssl.enabled": "Certificado SSL habilitado",
+    "hosts.visibility": "Visibilidad",
+    "hosts.visibility.local": "Local",
+    "hosts.visibility.local.description": "Solo local (registro A resuelto internamente)",
+    "hosts.visibility.global": "Global",
+    "hosts.visibility.global.description": "Interno y externo son idénticos",
+    "hosts.visibility.alias": "Alias",
+    "hosts.visibility.alias.description": "El nombre externo es un CNAME de external_name",
+    "hosts.empty": "No hay hosts disponibles.",
+    "hosts.created.ok": "Host creado correctamente",
+    "hosts.created.error": "Error al crear el host",
+    "hosts.updated.ok": "Host actualizado correctamente",
+    "hosts.updated.error": "Error al actualizar el host",
+    "hosts.deleted.ok": "Host eliminado correctamente",
+    "hosts.deleted.error": "Error al eliminar el host",
+    "hosts.delete.invalid_id": "ID de host no válido para la eliminación",
+    "hosts.list.error": "Error al cargar los hosts",
+    "hosts.loaded.error": "Error al cargar el host",
+    "hosts.not.found": "Host no encontrado",
+    "hosts.already.present": "Host ya existente",
+
+    "aliases.title": "Alias",
+    "aliases.card.title": "Alias",
+    "aliases.card.description": "Inventario de alias DNS.",
+    "aliases.page.title": "Lista de Alias",
+    "aliases.add": "Agregar Alias",
+    "aliases.edit": "Editar Alias",
+    "aliases.delete": "Eliminar Alias",
+    "aliases.search": "Buscar Alias",
+    "aliases.name": "Alias",
+    "aliases.target": "Destino",
+    "aliases.ssl": "Certificado SSL",
+    "aliases.ssl.enabled": "Certificado SSL habilitado",
+    "aliases.visibility": "Visibilidad",
+    "aliases.visibility.local": "Local",
+    "aliases.visibility.local.description": "Solo local (registro CNAME resuelto internamente)",
+    "aliases.visibility.global": "Global",
+    "aliases.visibility.global.description": "Interno y externo son idénticos",
+    "aliases.visibility.alias": "Alias",
+    "aliases.visibility.alias.description": "El nombre externo es un CNAME de external_name",
+    "aliases.empty": "No hay alias disponibles.",
+    "aliases.created.ok": "Alias creado correctamente",
+    "aliases.created.error": "Error al crear el alias",
+    "aliases.updated.ok": "Alias actualizado correctamente",
+    "aliases.updated.error": "Error al actualizar el alias",
+    "aliases.deleted.ok": "Alias eliminado correctamente",
+    "aliases.deleted.error": "Error al eliminar el alias",
+    "aliases.delete.invalid_id": "ID de alias no válido para la eliminación",
+    "aliases.list.error": "Error al cargar los alias",
+    "aliases.loaded.error": "Error al cargar el alias",
+    "aliases.not.found": "Alias no encontrado",
+    "aliases.already.present": "Alias ya existente",
+
+    "devices.title": "Dispositivos",
+    "devices.card.title": "Dispositivos",
+    "devices.card.description": "Estado de los dispositivos (Host + DHCP).",
+    "devices.page.title": "Lista de Dispositivos",
+    "devices.edit": "Editar Dispositivo",
+    "devices.delete": "Eliminar Dispositivo",
+    "devices.search": "Buscar Dispositivos",
+    "devices.active": "Activo",
+    "devices.active.description": "Dispositivo activo",
+    "devices.not.active.description": "Dispositivo no activo",
+    "devices.empty": "No hay dispositivos disponibles.",
+    "devices.created.ok": "Dispositivo creado correctamente",
+    "devices.created.error": "Error al crear el dispositivo",
+    "devices.updated.ok": "Dispositivo actualizado correctamente",
+    "devices.updated.error": "Error al actualizar el dispositivo",
+    "devices.deleted.ok": "Dispositivo eliminado correctamente",
+    "devices.deleted.error": "Error al eliminar el dispositivo",
+    "devices.edit.invalid_id": "ID de dispositivo no válido para la modificación",
+    "devices.delete.invalid_id": "ID de dispositivo no válido para la eliminación",
+    "devices.list.error": "Error al cargar los dispositivos",
+    "devices.loaded.error": "Error al cargar el dispositivo",
+    "devices.not.found": "Dispositivo no encontrado",
+    "devices.already.present": "Dispositivo ya existente",
+    "devices.unknown.type": "Tipo de dispositivo desconocido",
+
+    "certificates.title": "Certificados",
+    "certificates.card.title": "Certificados",
+    "certificates.card.description": "Certificados Let's Encrypt y renovaciones.",
+    "certificates.page.title": "Lista de Certificados",
+    "certificates.empty": "No hay certificados disponibles.",
+
+    "backup.title": "Copia de Seguridad",
+    "backup.card.title": "Copia de Seguridad y Restauración",
+    "backup.card.description": "Ejecución de copias de seguridad y gestión de archivos.",
+    "backup.modal.title": "Gestión de Copias de Seguridad",
+    "backup.create": "Crear copia de seguridad",
+    "backup.create.progress": "Creando...",
+    "backup.manage": "Gestión de Copias de Seguridad",
+    "backup.available": "Copias de seguridad disponibles",
+    "backup.name": "Nombre",
+    "backup.date": "Fecha",
+    "backup.size": "Tamaño",
+    "backup.actions": "Acciones",
+    "backup.loading": "Cargando copias de seguridad...",
+    "backup.restore": "Restaurar copia de seguridad",
+    "backup.restore.select": "Seleccione una copia de seguridad para restaurar.",
+    "backup.restore.progress": "Restaurando...",
+    "backup.upload": "Subir copia de seguridad",
+    "backup.upload.select": "Seleccione un archivo de copia de seguridad para subir.",
+    "backup.upload.file": "Subir archivo de copia de seguridad",
+    "backup.download.file": "Descargar archivo de copia de seguridad",
+    "backup.delete.file": "Eliminar archivo de copia de seguridad",
+    "backup.refresh": "Actualizar lista",
+    "backup.empty": "No hay copias de seguridad disponibles.",
+    "backup.create_ok": "Copia de seguridad completada correctamente",
+    "backup.create_partial": "Copia de seguridad completada parcialmente",
+    "backup.create_error": "Error al realizar la copia de seguridad",
+    "backup.restore_ok": "Restauración completada correctamente",
+    "backup.restore_partial": "Restauración completada parcialmente",
+    "backup.restore_error": "Error al realizar la restauración",
+    "backup.delete_ok": "Copia de seguridad eliminada correctamente",
+    "backup.delete_error": "Error al eliminar la copia de seguridad",
+    "backup.download_ok": "Copia de seguridad descargada correctamente",
+    "backup.download_error": "Error al descargar la copia de seguridad",
+    "backup.upload_ok": "Copia de seguridad subida correctamente",
+    "backup.upload_error": "Error al subir la copia de seguridad",
+    "backup.refresh_ok": "Lista de copias de seguridad actualizada correctamente",
+    "backup.refresh_error": "Error al actualizar la lista de copias de seguridad",
+    "backup.select": "Seleccione una copia de seguridad",
+    "backup.select_file": "Seleccione primero un archivo",
+    "backup.delete_confirm": "¿Eliminar la copia de seguridad \"{id}\"?",
+    "backup.not.found": "Copia de seguridad no encontrada",
+
+    "logs.title": "Registros",
+    "logs.card.title": "Registros",
+    "logs.card.description": "Eventos y registros de acceso.",
+    "logs.page.title": "Registros del Sistema",
+    "logs.view": "Ver",
+    "logs.live": "En vivo",
+    "logs.live.description": "Activar/Desactivar transmisión en vivo",
+    "logs.refresh": "Actualizar",
+    "logs.refresh.description": "Actualizar registros",
+    "logs.app": "Aplicación",
+    "logs.search": "Buscar registros",
+    "logs.filter": "Filtros",
+
+    "settings.title": "Configuración",
+    "settings.card.title": "Configuración",
+    "settings.card.description": "Configuración del sistema y variables.",
+    "settings.page.title": "Configuración",
+    "settings.edit": "Editar configuración",
+    "settings.reset": "Restaurar valor predeterminado",
+    "settings.reset.confirm": "¿Restaurar esta configuración a su valor predeterminado?",
+    "settings.search": "Buscar parámetro de configuración",
+    "settings.parameter": "Parámetro",
+    "settings.modal.parameter": "Parámetro de configuración",
+    "settings.value": "Valor",
+    "settings.enabled": "Habilitado",
+    "settings.current": "Actual",
+    "settings.admin": "Administrador",
+    "settings.admin.description": "Menú de administración",
+    "settings.empty": "No hay configuraciones disponibles",
+    "settings.updated.ok": "Configuración actualizada correctamente",
+    "settings.updated.error": "Error al actualizar la configuración",
+    "settings.restored.ok": "Configuración restaurada a los valores predeterminados correctamente",
+    "settings.restored.error": "Error al restaurar los valores predeterminados",
+    "settings.restored.invalid_id": "Clave de configuración no válida",
+    "settings.list.error": "Error al cargar las configuraciones",
+    "settings.loaded.error": "Error al cargar la configuración",
+    "settings.not.found": "Configuración no encontrada",
+    "settings.expand.disabled": "Deshabilitado durante la búsqueda",
+    "settings.expand.all": "Expandir todos los grupos",
+    "settings.collapse.all": "Contraer todos los grupos",
+
+    "health.title": "Estado",
+    "health.card.title": "Estado",
+    "health.card.description": "Estado de servicios y recursos.",
+    "health.modal.title": "Estado del Sistema",
+    "health.loading": "Cargando estado...",
+    "health.error": "Error al obtener el estado del sistema.",
+    "health.update.ok": "Estado de la API actualizado correctamente",
+    "health.update.error": "Error al actualizar el estado de la API",
+    "health.details_unavailable": "Detalles del estado no disponibles",
+    "health.updated_at": "Actualizado el",
+    "health.status": "Estado",
+    "health.status.healthy": "Saludable",
+    "health.status.degraded": "Degradado",
+    "health.status.unhealthy": "No saludable",
+    "health.status.unknown": "Desconocido",
+    "health.latency": "Latencia",
+    "health.db_status": "Estado de la BD",
+    "health.db_version": "Versión de la BD",
+    "health.db_tables": "Tablas de la BD",
+    "health.db_size": "Tamaño de la BD",
+
+    "common.close": "Cerrar",
+    "common.cancel": "Cancelar",
+    "common.confirm": "Confirmar",
+    "common.confirmation": "Confirmación",
+    "common.are_you_sure": "¿Está seguro?",
+    "common.description": "Descripción",
+    "common.options": "Opciones",
+    "common.state": "Estado",
+    "common.actions": "Acciones",
+    "common.loading": "Cargando...",
+    "common.search": "Buscar",
+    "common.search.placeholder": "Buscar...",
+    "common.expand": "Expandir",
+    "common.expand.description": "Expandir todos los grupos",
+    "common.collapse": "Contraer",
+    "common.collapse.description": "Contraer todos los grupos",
+
+    "validation.name.required": "El nombre del host es obligatorio",
+    "validation.ipv4.invalid": "Formato IPv4 no válido",
+    "validation.ipv6.invalid": "Formato IPv6 no válido",
+    "validation.mac.invalid": "Formato MAC no válido",
+    "validation.target.required": "El destino es obligatorio",
+    "validation.alias.required": "El alias es obligatorio",
+    "validation.config.required": "El valor de configuración es obligatorio",
+    "validation.config.invalid_number": "Valor numérico no válido",
+    "validation.config.invalid": "Valor de configuración no válido"
+  }
+}
diff --git a/frontend/locales/fr.json b/frontend/locales/fr.json
new file mode 100644 (file)
index 0000000..c80f6b0
--- /dev/null
@@ -0,0 +1,307 @@
+{
+  "language": "fr",
+  "translations": {
+
+    "app.name": "Gestionnaire Réseau",
+    "app.translation.error": "Erreur lors du chargement de la traduction",
+    "app.modals.error": "Erreur lors du chargement des fenêtres modales",
+    "app.action.error": "Erreur d'action",
+    "app.restart": "Redémarrer",
+    "app.restart.description": "Redémarrer l'application",
+    "app.restart.confirm": "Redémarrer l'application ?",
+    "app.restart.progress": "Redémarrage de l'application en cours...",
+    "app.restart.error": "Erreur lors du redémarrage de l'application",
+    "app.reconnect.waiting": "En attente du retour du serveur en ligne...",
+    "app.reconnect.success": "L'application est de nouveau en ligne",
+    "app.reconnect.timeout": "Le serveur n'est pas revenu en ligne",
+    "app.restart.button": "Redémarrage...",
+
+    "auth.login": "Connexion",
+    "auth.logout": "Déconnexion",
+    "auth.username": "Nom d'utilisateur",
+    "auth.password": "Mot de passe",
+    "auth.sign_in": "Se connecter",
+    "auth.session_expired": "Session expirée",
+    "auth.invalid_credentials": "Nom d'utilisateur ou mot de passe invalide",
+
+    "header.api_status": "État de l'API",
+    "header.api_status_online": "API OK",
+    "header.api_status_offline": "API HORS LIGNE",
+
+    "dashboard.title": "Tableau de bord",
+
+    "dns.title": "DNS",
+    "dns.card.title": "DNS (BIND)",
+    "dns.card.description": "Zones, enregistrements et configuration.",
+    "dns.config": "Configuration DNS",
+    "dns.reload": "Recharger le DNS",
+    "dns.reload.description": "Recharger le DNS (BIND)",
+    "dns.reload.ok": "DNS rechargé avec succès",
+    "dns.reload.error": "Erreur lors du rechargement du DNS",
+    "dns.reload.progress": "Redémarrage du DNS...",
+
+    "dhcp.title": "Baux DHCP",
+    "dhcp.card.title": "DHCP (Kea)",
+    "dhcp.card.description": "Plages, baux et réservations.",
+    "dhcp.page.title": "Baux DHCP",
+    "dhcp.leases": "Baux DHCP",
+    "dhcp.leases.search": "Rechercher des baux DHCP",
+    "dhcp.reload": "Recharger DHCP",
+    "dhcp.reload.description": "Recharger DHCP (Kea)",
+    "dhcp.lease.start": "Début",
+    "dhcp.lease.end": "Fin",
+    "dhcp.leases.empty": "Aucun bail disponible",
+    "dhcp.leases.static": "statique",
+    "dhcp.leases.static.description": "Bail statique",
+    "dhcp.leases.active": "actif",
+    "dhcp.leases.active.description": "Bail actif",
+    "dhcp.leases.expired": "expiré",
+    "dhcp.leases.expired.description": "Bail expiré",
+    "dhcp.leases.released": "libéré",
+    "dhcp.leases.released.description": "Bail libéré",
+    "dhcp.leases.declined": "refusé",
+    "dhcp.leases.declined.description": "Bail refusé",
+    "dhcp.leases.add": "Ajouter un bail statique",
+    "dhcp.leases.delete": "Supprimer le bail",
+    "dhcp.reload.ok": "DHCP rechargé avec succès",
+    "dhcp.reload.error": "Erreur lors du rechargement du DHCP",
+    "dhcp.reload.progress": "Redémarrage du DHCP...",
+    "dhcp.leases.deleted.ok": "Bail supprimé avec succès",
+    "dhcp.leases.deleted.error": "Échec de la suppression du bail",
+    "dhcp.leases.list.error": "Échec du chargement des baux",
+    "dhcp.leases.loaded.error": "Échec du chargement du bail",
+    "dhcp.leases.delete.invalid_id": "ID de bail invalide pour la suppression",
+    "dhcp.leases.not.found": "Bail introuvable",
+
+    "hosts.title": "Hôtes",
+    "hosts.card.title": "Hôtes",
+    "hosts.card.description": "Inventaire IP/MAC.",
+    "hosts.page.title": "Liste des hôtes",
+    "hosts.add": "Ajouter un hôte",
+    "hosts.edit": "Modifier l'hôte",
+    "hosts.delete": "Supprimer l'hôte",
+    "hosts.search": "Rechercher un hôte",
+    "hosts.hostname": "Nom d'hôte",
+    "hosts.ipv4": "Adresse IPv4",
+    "hosts.placeholder.ipv4": "ex. 192.168.1.10",
+    "hosts.ipv6": "Adresse IPv6",
+    "hosts.placeholder.ipv6": "ex. fe80::1",
+    "hosts.mac": "Adresse MAC",
+    "hosts.placeholder.mac": "ex. AA:BB:CC:DD:EE:FF",
+    "hosts.ssl": "Certificat SSL",
+    "hosts.ssl.enabled": "Certificat SSL activé",
+    "hosts.visibility": "Visibilité",
+    "hosts.visibility.local": "Local",
+    "hosts.visibility.local.description": "Local uniquement (enregistrement A résolu en interne)",
+    "hosts.visibility.global": "Global",
+    "hosts.visibility.global.description": "Les enregistrements internes et externes sont identiques",
+    "hosts.visibility.alias": "Alias",
+    "hosts.visibility.alias.description": "Le nom externe est un CNAME vers external_name",
+    "hosts.empty": "Aucun hôte disponible.",
+    "hosts.created.ok": "Hôte créé avec succès",
+    "hosts.created.error": "Échec de la création de l'hôte",
+    "hosts.updated.ok": "Hôte mis à jour avec succès",
+    "hosts.updated.error": "Échec de la mise à jour de l'hôte",
+    "hosts.deleted.ok": "Hôte supprimé avec succès",
+    "hosts.deleted.error": "Échec de la suppression de l'hôte",
+    "hosts.delete.invalid_id": "ID d'hôte invalide pour la suppression",
+    "hosts.list.error": "Échec du chargement des hôtes",
+    "hosts.loaded.error": "Échec du chargement de l'hôte",
+    "hosts.not.found": "Hôte introuvable",
+    "hosts.already.present": "Hôte déjà présent",
+
+    "aliases.title": "Alias",
+    "aliases.card.title": "Alias",
+    "aliases.card.description": "Inventaire des alias DNS.",
+    "aliases.page.title": "Liste des alias",
+    "aliases.add": "Ajouter un alias",
+    "aliases.edit": "Modifier l'alias",
+    "aliases.delete": "Supprimer l'alias",
+    "aliases.search": "Rechercher des alias",
+    "aliases.name": "Alias",
+    "aliases.target": "Cible",
+    "aliases.ssl": "Certificat SSL",
+    "aliases.ssl.enabled": "Certificat SSL activé",
+    "aliases.visibility": "Visibilité",
+    "aliases.visibility.local": "Local",
+    "aliases.visibility.local.description": "Local uniquement (enregistrement CNAME résolu en interne)",
+    "aliases.visibility.global": "Global",
+    "aliases.visibility.global.description": "Les enregistrements internes et externes sont identiques",
+    "aliases.visibility.alias": "Alias",
+    "aliases.visibility.alias.description": "Le nom externe est un CNAME vers external_name",
+    "aliases.empty": "Aucun alias disponible.",
+    "aliases.created.ok": "Alias créé avec succès",
+    "aliases.created.error": "Échec de la création de l'alias",
+    "aliases.updated.ok": "Alias mis à jour avec succès",
+    "aliases.updated.error": "Échec de la mise à jour de l'alias",
+    "aliases.deleted.ok": "Alias supprimé avec succès",
+    "aliases.deleted.error": "Échec de la suppression de l'alias",
+    "aliases.delete.invalid_id": "ID d'alias invalide pour la suppression",
+    "aliases.list.error": "Échec du chargement des alias",
+    "aliases.loaded.error": "Échec du chargement de l'alias",
+    "aliases.not.found": "Alias introuvable",
+    "aliases.already.present": "Alias déjà présent",
+
+    "devices.title": "Appareils",
+    "devices.card.title": "Appareils",
+    "devices.card.description": "État des appareils (Hôte + DHCP).",
+    "devices.page.title": "Liste des appareils",
+    "devices.edit": "Modifier l'appareil",
+    "devices.delete": "Supprimer l'appareil",
+    "devices.search": "Rechercher des appareils",
+    "devices.active": "Actif",
+    "devices.active.description": "Appareil actif",
+    "devices.not.active.description": "Appareil inactif",
+    "devices.empty": "Aucun appareil disponible.",
+    "devices.created.ok": "Appareil créé avec succès",
+    "devices.created.error": "Échec de la création de l'appareil",
+    "devices.updated.ok": "Appareil mis à jour avec succès",
+    "devices.updated.error": "Échec de la mise à jour de l'appareil",
+    "devices.deleted.ok": "Appareil supprimé avec succès",
+    "devices.deleted.error": "Échec de la suppression de l'appareil",
+    "devices.edit.invalid_id": "ID d'appareil invalide pour la modification",
+    "devices.delete.invalid_id": "ID d'appareil invalide pour la suppression",
+    "devices.list.error": "Échec du chargement des appareils",
+    "devices.loaded.error": "Échec du chargement de l'appareil",
+    "devices.not.found": "Appareil introuvable",
+    "devices.already.present": "Appareil déjà présent",
+    "devices.unknown.type": "Type d'appareil inconnu",
+
+    "certificates.title": "Certificats",
+    "certificates.card.title": "Certificats",
+    "certificates.card.description": "Certificats Let's Encrypt et renouvellements.",
+    "certificates.page.title": "Liste des certificats",
+    "certificates.empty": "Aucun certificat disponible.",
+
+    "backup.title": "Sauvegarde",
+    "backup.card.title": "Sauvegarde et restauration",
+    "backup.card.description": "Exécution des sauvegardes et gestion des archives.",
+    "backup.modal.title": "Gestion des sauvegardes",
+    "backup.create": "Créer une sauvegarde",
+    "backup.create.progress": "Création...",
+    "backup.manage": "Gestion des sauvegardes",
+    "backup.available": "Sauvegardes disponibles",
+    "backup.name": "Nom",
+    "backup.date": "Date",
+    "backup.size": "Taille",
+    "backup.actions": "Actions",
+    "backup.loading": "Chargement des sauvegardes...",
+    "backup.restore": "Restaurer une sauvegarde",
+    "backup.restore.select": "Sélectionnez une sauvegarde à restaurer.",
+    "backup.restore.progress": "Restauration...",
+    "backup.upload": "Téléverser une sauvegarde",
+    "backup.upload.select": "Sélectionnez un fichier de sauvegarde à téléverser.",
+    "backup.upload.file": "Téléverser un fichier de sauvegarde",
+    "backup.download.file": "Télécharger un fichier de sauvegarde",
+    "backup.delete.file": "Supprimer un fichier de sauvegarde",
+    "backup.refresh": "Actualiser la liste",
+    "backup.empty": "Aucune sauvegarde disponible.",
+    "backup.create_ok": "Sauvegarde effectuée avec succès",
+    "backup.create_partial": "Sauvegarde effectuée partiellement",
+    "backup.create_error": "Erreur lors de l'exécution de la sauvegarde",
+    "backup.restore_ok": "Restauration effectuée avec succès",
+    "backup.restore_partial": "Restauration effectuée partiellement",
+    "backup.restore_error": "Erreur lors de la restauration",
+    "backup.delete_ok": "Sauvegarde supprimée avec succès",
+    "backup.delete_error": "Erreur lors de la suppression de la sauvegarde",
+    "backup.download_ok": "Sauvegarde téléchargée avec succès",
+    "backup.download_error": "Erreur lors du téléchargement de la sauvegarde",
+    "backup.upload_ok": "Sauvegarde téléversée avec succès",
+    "backup.upload_error": "Erreur lors du téléversement de la sauvegarde",
+    "backup.refresh_ok": "Liste des sauvegardes actualisée avec succès",
+    "backup.refresh_error": "Erreur lors de l'actualisation de la liste des sauvegardes",
+    "backup.select": "Sélectionner une sauvegarde",
+    "backup.select_file": "Sélectionnez d'abord un fichier",
+    "backup.delete_confirm": "Supprimer la sauvegarde \"{id}\" ?",
+    "backup.not.found": "Sauvegarde introuvable",
+
+    "logs.title": "Journaux",
+    "logs.card.title": "Journaux",
+    "logs.card.description": "Événements et journaux d'accès.",
+    "logs.page.title": "Journaux système",
+    "logs.view": "Afficher",
+    "logs.live": "Temps réel",
+    "logs.live.description": "Activer/Désactiver le flux en direct",
+    "logs.refresh": "Actualiser",
+    "logs.refresh.description": "Actualiser les journaux",
+    "logs.app": "Application",
+    "logs.search": "Rechercher dans les journaux",
+    "logs.filter": "Filtres",
+
+    "settings.title": "Paramètres",
+    "settings.card.title": "Paramètres",
+    "settings.card.description": "Configuration système et variables.",
+    "settings.page.title": "Paramètres",
+    "settings.edit": "Modifier le paramètre",
+    "settings.reset": "Restaurer la valeur par défaut",
+    "settings.reset.confirm": "Restaurer ce paramètre à sa valeur par défaut ?",
+    "settings.search": "Rechercher un paramètre de configuration",
+    "settings.parameter": "Paramètre",
+    "settings.modal.parameter": "Paramètre de configuration",
+    "settings.value": "Valeur",
+    "settings.enabled": "Activé",
+    "settings.current": "Actuel",
+    "settings.admin": "Administrateur",
+    "settings.admin.description": "Menu administrateur",
+    "settings.empty": "Aucun paramètre disponible",
+    "settings.updated.ok": "Paramètre mis à jour avec succès",
+    "settings.updated.error": "Échec de la mise à jour du paramètre",
+    "settings.restored.ok": "Paramètre restauré à sa valeur par défaut avec succès",
+    "settings.restored.error": "Échec de la restauration des valeurs par défaut",
+    "settings.restored.invalid_id": "Clé de paramètre invalide",
+    "settings.list.error": "Échec du chargement des paramètres",
+    "settings.loaded.error": "Échec du chargement du paramètre",
+    "settings.not.found": "Paramètre introuvable",
+    "settings.expand.disabled": "Désactivé pendant la recherche",
+    "settings.expand.all": "Développer tous les groupes",
+    "settings.collapse.all": "Réduire tous les groupes",
+
+    "health.title": "État de santé",
+    "health.card.title": "État de santé",
+    "health.card.description": "État des services et des ressources.",
+    "health.modal.title": "État de santé",
+    "health.loading": "Chargement de l'état...",
+    "health.error": "Erreur lors de la récupération de l'état de santé.",
+    "health.update.ok": "État de l'API mis à jour avec succès",
+    "health.update.error": "Erreur lors de la mise à jour de l'état de l'API",
+    "health.details_unavailable": "Détails de l'état de santé non disponibles",
+    "health.updated_at": "Mis à jour le",
+    "health.status": "État",
+    "health.status.healthy": "Sain",
+    "health.status.degraded": "Dégradé",
+    "health.status.unhealthy": "Non sain",
+    "health.status.unknown": "Inconnu",
+    "health.latency": "Latence",
+    "health.db_status": "État de la base de données",
+    "health.db_version": "Version de la base de données",
+    "health.db_tables": "Tables de la base de données",
+    "health.db_size": "Taille de la base de données",
+
+    "common.close": "Fermer",
+    "common.cancel": "Annuler",
+    "common.confirm": "Confirmer",
+    "common.confirmation": "Confirmation",
+    "common.are_you_sure": "Êtes-vous sûr ?",
+    "common.description": "Description",
+    "common.options": "Options",
+    "common.state": "État",
+    "common.actions": "Actions",
+    "common.loading": "Chargement...",
+    "common.search": "Rechercher",
+    "common.search.placeholder": "Rechercher...",
+    "common.expand": "Développer",
+    "common.expand.description": "Développer tous les groupes",
+    "common.collapse": "Réduire",
+    "common.collapse.description": "Réduire tous les groupes",
+
+    "validation.name.required": "Le nom d'hôte est requis",
+    "validation.ipv4.invalid": "Format IPv4 invalide",
+    "validation.ipv6.invalid": "Format IPv6 invalide",
+    "validation.mac.invalid": "Format d'adresse MAC invalide",
+    "validation.target.required": "La cible est requise",
+    "validation.alias.required": "L'alias est requis",
+    "validation.config.required": "La valeur de configuration est requise",
+    "validation.config.invalid_number": "Valeur numérique invalide",
+    "validation.config.invalid": "Valeur de configuration invalide"
+  }
+}