screentinker/frontend/js/i18n/fr.js
ScreenTinker 8e7a093150 i18n: extract all strings, add 6 language translations, restructure i18n module
Session 1 of 2 of the i18n rollout.

- Split i18n module into per-language files under frontend/js/i18n/ so a
  translator can edit one language without touching the others.
- Add Portuguese (pt) and seed Hindi (hi). Hindi is intentionally a skeleton
  -- 0 keys, full English fallback -- because we have an active Indian user
  and would rather ship "no Hindi" than ship machine-quality Hindi that
  could read as unprofessional or get formality/gender register wrong.
- 183 keys, 100% parity across en/es/fr/de/pt; native review still
  recommended before publicizing as "fully supported".
- Add t(key, vars) variable substitution and tn(keyBase, n, vars) plural
  helper for _one/_other key pairs.
- setLanguage() now triggers a CustomEvent + HashChangeEvent so the
  existing hash router naturally re-renders the current view, plus a
  subscriber pattern for nav labels rendered once outside the router.
- Wire t() into 3 high-traffic views end-to-end: dashboard, login,
  content-library. Sidebar nav labels in app.js update on language change.
- The remaining 16 views still ship with hardcoded English; they will be
  wired in session 2. The t() lookup is robust against unwired views, so
  the dashboard works in 5 languages while clicking into e.g. Schedule
  still shows English. No regressions.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 19:25:22 -05:00

198 lines
10 KiB
JavaScript

// French translations. Reviewed for UI register (informal vous-vouvoiement is
// standard for software UIs in France; tu would feel underdressed for a B2B tool).
// Native review recommended before publicizing as fully supported.
export default {
// Nav
'nav.displays': 'Écrans',
'nav.content': 'Contenu',
'nav.playlists': 'Listes de lecture',
'nav.layouts': 'Mises en page',
'nav.widgets': 'Widgets',
'nav.schedule': 'Calendrier',
'nav.walls': 'Murs vidéo',
'nav.reports': 'Rapports',
'nav.kiosk': 'Kiosque',
'nav.designer': 'Concepteur',
'nav.activity': 'Activité',
'nav.teams': 'Équipes',
'nav.help': 'Aide',
'nav.settings': 'Paramètres',
'nav.subscription': 'Abonnement',
'nav.admin': 'Admin',
// Common
'common.save': 'Enregistrer',
'common.cancel': 'Annuler',
'common.delete': 'Supprimer',
'common.edit': 'Modifier',
'common.done': 'Terminé',
'common.loading': 'Chargement...',
'common.connected': 'Connecté',
'common.disconnected': 'Déconnecté',
'common.never': 'Jamais',
'common.just_now': 'À l\'instant',
'common.minutes_ago': 'il y a {n}m',
'common.hours_ago': 'il y a {n}h',
'common.days_ago': 'il y a {n}j',
'common.unknown': 'Inconnu',
// Auth
'auth.sign_in': 'Se connecter',
'auth.sign_out': 'Se déconnecter',
'auth.create_account': 'Créer un compte',
'auth.create_admin_account': 'Créer un compte administrateur',
'auth.email': 'E-mail',
'auth.password': 'Mot de passe',
'auth.name': 'Nom',
'auth.placeholder_email': 'vous@exemple.com',
'auth.placeholder_password': '••••••••',
'auth.placeholder_name': 'Votre nom',
'auth.placeholder_register_password': 'Au moins 6 caractères',
'auth.subtitle_setup': 'Créez votre compte administrateur pour commencer',
'auth.subtitle_signin': 'Connectez-vous pour gérer vos écrans',
'auth.trial_notice': 'Les nouveaux comptes obtiennent un essai Pro gratuit de 14 jours',
'auth.divider_or': 'OU',
'auth.signin_google': 'Se connecter avec Google',
'auth.signin_microsoft': 'Se connecter avec Microsoft',
'auth.back_to_signin': 'Retour à la connexion',
'auth.support_access': 'Accès au support',
'auth.support_token_placeholder': 'Collez le jeton de support',
'auth.support_authenticate': 'Authentifier avec le jeton de support',
'auth.terms': 'Conditions d\'utilisation',
'auth.privacy': 'Politique de confidentialité',
'auth.error_email_password_required': 'E-mail et mot de passe requis',
'auth.error_password_min_6': 'Le mot de passe doit comporter au moins 6 caractères',
'auth.error_login_failed': 'Échec de la connexion',
'auth.error_registration_failed': 'Échec de l\'inscription',
'auth.error_paste_support_token': 'Collez un jeton de support',
'auth.error_support_failed': 'Échec de la connexion de support',
'auth.error_google_failed': 'Échec de la connexion Google',
'auth.error_microsoft_failed': 'Échec de la connexion Microsoft',
// Dashboard
'dashboard.title': 'Écrans',
'dashboard.subtitle': 'Gérez vos écrans distants',
'dashboard.help_tip': 'Vos écrans appariés. Vert = en ligne, rouge = hors ligne. Cliquez sur un écran pour gérer sa liste de lecture, voir la télémétrie ou utiliser le contrôle à distance.',
'dashboard.add': 'Ajouter un écran',
'dashboard.create_group': '+ Groupe',
'dashboard.search': 'Rechercher des écrans...',
'dashboard.all_status': 'Tous les statuts',
'dashboard.online': 'En ligne',
'dashboard.offline': 'Hors ligne',
'dashboard.awaiting_pairing': 'En attente d\'appairage',
'dashboard.no_preview': 'Aperçu indisponible',
'dashboard.total_displays': 'Écrans totaux',
'dashboard.ungrouped': 'Sans groupe',
'dashboard.no_displays': 'Aucun écran pour le moment',
'dashboard.no_displays_desc': 'Installez l\'application ScreenTinker sur votre TV et appariez-la avec le bouton ci-dessus.',
'dashboard.failed_to_load': 'Échec du chargement des écrans',
'dashboard.unknown_playlist': 'Liste de lecture inconnue',
'dashboard.mixed_playlists': 'Listes mixtes',
'dashboard.playlist_label': 'Liste : {name}',
'dashboard.devices_count_one': '{n} appareil',
'dashboard.devices_count_other': '{n} appareils',
'dashboard.online_count': '{n} en ligne',
'dashboard.set_playlist_placeholder': 'Définir la liste...',
'dashboard.send_command_placeholder': 'Envoyer une commande...',
'dashboard.manage': 'Gérer',
'dashboard.manage_tooltip': 'Ajouter/retirer des appareils',
'dashboard.delete_group_tooltip': 'Supprimer le groupe',
'dashboard.no_devices_in_group': 'Aucun appareil dans ce groupe. Cliquez sur Gérer pour en ajouter.',
'dashboard.manage_group_subtitle': 'Cochez les appareils à ajouter à ce groupe',
'dashboard.draft_suffix': '(brouillon)',
'dashboard.cmd.screen_on': 'Allumer l\'écran',
'dashboard.cmd.screen_off': 'Éteindre l\'écran',
'dashboard.cmd.restart_app': 'Redémarrer l\'app',
'dashboard.cmd.check_update': 'Vérifier la mise à jour',
'dashboard.cmd.reboot': 'Redémarrer',
'dashboard.cmd.shutdown': 'Arrêter',
'dashboard.prompt_group_name': 'Nom du groupe :',
'dashboard.error_pairing_code': 'Saisissez un code d\'appairage valide à 6 chiffres',
'dashboard.confirm_add_to_group': '{name} est déjà dans : {groups}\n\nL\'ajouter aussi à « {target} » ?',
'dashboard.confirm_assign_playlist': 'Attribuer la liste « {playlist} » à tous les appareils de « {group} » ?',
'dashboard.confirm_destructive_command': '{cmd} les {n} appareils de « {group} » ?\n\nCette action est irréversible.',
'dashboard.confirm_delete_group': 'Supprimer ce groupe ? Les appareils ne seront pas affectés.',
'dashboard.toast.display_paired': 'Écran appairé avec succès !',
'dashboard.toast.group_created': 'Groupe créé',
'dashboard.toast.group_deleted': 'Groupe supprimé',
'dashboard.toast.already_in_group': '{name} est déjà dans {group}',
'dashboard.toast.moved_device': '{name} déplacé vers {group}',
'dashboard.toast.removed_device_one': '{name} retiré de 1 groupe',
'dashboard.toast.removed_device_other': '{name} retiré de {n} groupes',
'dashboard.toast.playlist_assigned_one': 'Liste attribuée à 1 appareil',
'dashboard.toast.playlist_assigned_other': 'Liste attribuée à {n} appareils',
'dashboard.toast.command_sent': '{cmd} envoyé à {sent}/{total} appareils',
'dashboard.toast.command_sent_with_offline': '{cmd} envoyé à {sent}/{total} appareils ({offline} hors ligne)',
// Content library
'content.title': 'Bibliothèque de contenu',
'content.subtitle': 'Téléversez et gérez vos fichiers multimédias',
'content.help_tip': 'Téléversez des vidéos et des images ici. Sélectionnez plusieurs fichiers pour un envoi groupé. Utilisez l\'URL distante pour diffuser depuis des sources externes. Cliquez sur une miniature pour prévisualiser.',
'content.drop': 'Déposez les fichiers ici ou cliquez pour téléverser',
'content.upload_hint': 'Prend en charge MP4, WebM, AVI, MKV, JPEG, PNG, GIF, WebP',
'content.upload_progress': 'Téléversement...',
'content.upload_progress_named': 'Téléversement de {name}...',
'content.upload_progress_named_pct': 'Téléversement de {name}... {pct}%',
'content.remote_url': 'URL distante',
'content.remote_desc': 'Diffusez directement depuis une URL. Économise la bande passante locale.',
'content.remote_url_placeholder': 'https://exemple.com/video.mp4',
'content.remote_name_placeholder': 'Nom à afficher (facultatif)',
'content.remote_add_btn': 'Ajouter une URL distante',
'content.youtube': 'YouTube',
'content.youtube_desc': 'Intégrez une vidéo YouTube sur vos écrans.',
'content.youtube_url_placeholder': 'https://youtube.com/watch?v=...',
'content.youtube_name_placeholder': 'Nom à afficher (facultatif)',
'content.youtube_add_btn': 'Ajouter une vidéo YouTube',
'content.search_placeholder': 'Rechercher du contenu...',
'content.new_folder_btn': '+ Nouveau dossier',
'content.breadcrumb_root': 'Tout le contenu',
'content.rename_btn': 'Renommer',
'content.delete_folder_btn': 'Supprimer le dossier',
'content.prompt_folder_name': 'Nom du dossier :',
'content.prompt_rename_folder': 'Renommer le dossier :',
'content.confirm_delete_folder': 'Supprimer ce dossier ? Le contenu retournera à la racine. Les sous-dossiers seront aussi supprimés.',
'content.empty_folder_title': 'Ce dossier est vide',
'content.empty_folder_desc': 'Glissez du contenu ici ou utilisez l\'action Déplacer.',
'content.no_content': 'Pas encore de contenu',
'content.no_content_desc': 'Téléversez des vidéos et des images pour commencer.',
'content.failed_to_load': 'Échec du chargement du contenu',
'content.type_youtube': 'YouTube',
'content.type_remote': 'URL distante',
'content.type_remote_short': 'Distant',
'content.type_video': 'Vidéo',
'content.type_image': 'Image',
'content.btn_edit': 'Modifier',
'content.btn_delete': 'Supprimer',
'content.btn_confirm_delete': 'Confirmer la suppression ?',
'content.btn_deleting': 'Suppression...',
'content.edit_modal_title': 'Modifier le contenu',
'content.label_filename': 'Nom du fichier / Affichage',
'content.label_remote_url_field': 'URL distante',
'content.label_mime_type': 'Type MIME',
'content.label_folder': 'Dossier',
'content.label_replace_file': 'Remplacer le fichier',
'content.replace_file_hint': 'Laissez vide pour conserver le fichier actuel',
'content.folder_root_option': '— Racine —',
'content.save_changes': 'Enregistrer les modifications',
'content.mime.video_mp4': 'Vidéo (MP4)',
'content.mime.video_webm': 'Vidéo (WebM)',
'content.mime.image_jpeg': 'Image (JPEG)',
'content.mime.image_png': 'Image (PNG)',
'content.mime.image_gif': 'Image (GIF)',
'content.mime.image_webp': 'Image (WebP)',
'content.error_enter_url': 'Saisissez une URL',
'content.error_enter_youtube_url': 'Saisissez une URL YouTube',
'content.error_update_failed': 'Échec de la mise à jour',
'content.toast.remote_added': 'Contenu distant ajouté',
'content.toast.youtube_added': 'Vidéo YouTube ajoutée',
'content.toast.deleted': 'Contenu supprimé',
'content.toast.updated': 'Contenu mis à jour',
'content.toast.uploaded_named': '{name} téléversé avec succès',
'content.toast.upload_failed_named': 'Échec du téléversement de {name} : {error}',
'content.toast.folder_created_named': 'Dossier « {name} » créé',
'content.toast.folder_renamed': 'Dossier renommé',
'content.toast.folder_deleted': 'Dossier supprimé',
'content.toast.moved': 'Déplacé',
'content.toast.moved_to_root': 'Déplacé à la racine',
};