Files
TREK/shared/src/i18n/fr/settings.ts
T
Maurice 247433fb2a feat(costs): rework Budget into Costs — Splitwise-style, multi-currency, mobile (#1106)
* fix(journey): authorize reads of the journey share link

GET /api/journeys/:id/share-link now requires journey access (canAccessJourney),
matching the create/delete share-link routes and the get_journey_share_link MCP
tool. Returns no link when the caller lacks access to the journey.

* feat(costs): rework Budget into Costs — Splitwise-style, multi-currency, mobile

Renames the Budget addon to "Costs" (UI only) and reworks it into a Tricount/
Splitwise-style cost tracker: multiple payers per expense, equal split across
chosen members, settle-up with persisted history + undo, 12 fixed categories,
per-expense currency with live FX conversion to a user-set display currency
(Settings -> Display), and locale-correct money formatting. Adds a desktop and a
dedicated mobile layout. A migration backfills existing budget items (single
payer, split members, currency). Closes #551 (per-expense currency).

Also switches the app font to self-hosted Poppins (Geist for secondary subtext),
replacing the Google Fonts CDN dependency.

* fix(costs): neutral dashboard dark palette + liquid glass, full page width, entry-count badge

- Dark mode used a warm oklch palette that read brownish; switch to the
  neutral zinc tokens used by the dashboard (#121215 bg, #f4f4f5 ink) and add a
  subtle backdrop-blur glass on cards.
- Costs now uses the full available page width on desktop instead of a 1280px cap.
- Render the expense count next to the Expenses title as a badge.
- Adapt budget/journey unit tests to the new payer-based settlement model and the
  Costs rename (category default 'other', Costs tab/CostsPanel).

* fix(costs): drop the entry-count badge, always show row edit/delete actions

Removes the count badge next to the Expenses title and makes the per-row
edit/delete actions permanently visible (no longer hover-only) on desktop too.

* feat(costs): currency-native money formatting, custom select/date, rename addon to Costs

- Format every amount in its own currency convention (symbol position, grouping
  and decimal separators) regardless of app language, via a currency->locale map
  (EUR -> '12,00 €', USD -> '$12.00', JPY -> '¥12', ...). Previously Intl used the
  app locale, so EUR showed the symbol in front under an English UI.
- Use TREK's CustomSelect (searchable, with symbols) and CustomDatePicker in the
  add/edit expense modal instead of the native <select>/<input type=date>.
- Rename the 'Budget Planner' add-on to 'Costs' in the admin list (display only;
  id/tables/permissions/MCP stay 'budget') via seed + a migration for existing DBs.

* feat(auth): configurable session duration via SESSION_DURATION

Adds a SESSION_DURATION env var (ms-style strings: 1h, 7d, 30d, ...) controlling
how long a session stays valid before re-login. It drives both the trek_session
JWT exp claim and the cookie maxAge from one source, so they never drift. Invalid
values warn at startup and fall back to the default (24h — unchanged). The MFA
challenge token and MCP OAuth tokens keep their own TTL.

Implements the request from discussion #946. Documented in the env-var wiki page,
.env.example and docker-compose.yml.
2026-06-05 01:38:25 +02:00

307 lines
18 KiB
TypeScript

import type { TranslationStrings } from '../types';
const settings: TranslationStrings = {
'settings.title': 'Paramètres',
'settings.subtitle': 'Configurez vos paramètres personnels',
'settings.tabs.display': 'Affichage',
'settings.tabs.map': 'Carte',
'settings.tabs.notifications': 'Notifications',
'settings.tabs.integrations': 'Intégrations',
'settings.tabs.account': 'Compte',
'settings.tabs.offline': 'Offline',
'settings.tabs.about': 'À propos',
'settings.map': 'Carte',
'settings.mapTemplate': 'Modèle de carte',
'settings.mapTemplatePlaceholder.select': 'Sélectionner un modèle…',
'settings.mapDefaultHint': 'Laissez vide pour OpenStreetMap (par défaut)',
'settings.mapTemplatePlaceholder':
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
'settings.mapHint': "Modèle d'URL pour les tuiles de carte",
'settings.mapProvider': 'Fournisseur de carte',
'settings.mapProviderHint':
'Affecte les cartes Trip Planner et Journey. Atlas utilise toujours Leaflet.',
'settings.mapLeafletSubtitle': 'Classique 2D, toutes tuiles raster',
'settings.mapMapboxSubtitle': 'Tuiles vectorielles, bâtiments 3D & terrain',
'settings.mapExperimental': 'Expérimental',
'settings.mapMapboxToken': "Jeton d'accès Mapbox",
'settings.mapMapboxTokenHint': 'Jeton public (pk.*) depuis',
'settings.mapMapboxTokenLink': "mapbox.com → Jetons d'accès",
'settings.mapStyle': 'Style de carte',
'settings.mapStylePlaceholder': 'Sélectionner un style Mapbox',
'settings.mapStyleHint': 'Preset ou votre propre URL mapbox://styles/USER/ID',
'settings.map3dBuildings': 'Bâtiments 3D & terrain',
'settings.map3dHint':
'Inclinaison + extrusions 3D réelles des bâtiments — fonctionne avec tous les styles, y compris satellite.',
'settings.mapHighQuality': 'Mode haute qualité',
'settings.mapHighQualityHint':
'Anticrénelage + projection globe pour des bords plus nets et une vue réaliste du monde.',
'settings.mapHighQualityWarning':
'Peut affecter les performances sur les appareils moins puissants.',
'settings.mapTipLabel': 'Astuce :',
'settings.mapTip':
'Clic droit et glisser pour pivoter/incliner la carte. Clic milieu pour ajouter un lieu (le clic droit est réservé à la rotation).',
'settings.latitude': 'Latitude',
'settings.longitude': 'Longitude',
'settings.saveMap': 'Enregistrer la carte',
'settings.apiKeys': 'Clés API',
'settings.mapsKey': 'Clé API Google Maps',
'settings.mapsKeyHint':
"Pour la recherche de lieux. Nécessite l'API Places (New). Obtenez-la sur console.cloud.google.com",
'settings.weatherKey': 'Clé API OpenWeatherMap',
'settings.weatherKeyHint':
'Pour les données météo. Gratuit sur openweathermap.org/api',
'settings.keyPlaceholder': 'Saisir la clé…',
'settings.configured': 'Configuré',
'settings.saveKeys': 'Enregistrer les clés',
'settings.display': 'Affichage',
'settings.colorMode': 'Mode de couleur',
'settings.light': 'Clair',
'settings.dark': 'Sombre',
'settings.auto': 'Auto',
'settings.language': 'Langue',
'settings.temperature': 'Unité de température',
'settings.timeFormat': "Format de l'heure",
'settings.blurBookingCodes': 'Masquer les codes de réservation',
'settings.notifications': 'Notifications',
'settings.notifyTripInvite': 'Invitations de voyage',
'settings.notifyBookingChange': 'Modifications de réservation',
'settings.notifyTripReminder': 'Rappels de voyage',
'settings.notifyTodoDue': 'Tâche à échéance',
'settings.notifyVacayInvite': 'Invitations de fusion Vacay',
'settings.notifyPhotosShared': 'Photos partagées (Immich)',
'settings.notifyCollabMessage': 'Messages de chat (Collab)',
'settings.notifyPackingTagged': 'Liste de bagages : attributions',
'settings.notifyWebhook': 'Notifications webhook',
'settings.notificationsDisabled':
"Les notifications ne sont pas configurées. Demandez à un administrateur d'activer les notifications par e-mail ou webhook.",
'settings.notificationsActive': 'Canal actif',
'settings.notificationsManagedByAdmin':
'Les événements de notification sont configurés par votre administrateur.',
'settings.on': 'Activé',
'settings.off': 'Désactivé',
'settings.mcp.title': 'Configuration MCP',
'settings.mcp.endpoint': 'Point de terminaison MCP',
'settings.mcp.clientConfig': 'Configuration du client',
'settings.mcp.clientConfigHint':
'Remplacez <your_token> par un token API de la liste ci-dessous. Le chemin vers npx devra peut-être être ajusté selon votre système (ex. C:\\PROGRA~1\\nodejs\\npx.cmd sous Windows).',
'settings.mcp.clientConfigHintOAuth':
"Remplacez <your_client_id> et <your_client_secret> par les identifiants affichés dans le client OAuth 2.1 créé ci-dessus. mcp-remote ouvrira votre navigateur pour finaliser l'autorisation lors de la première connexion. Le chemin vers npx devra peut-être être ajusté selon votre système (ex. C:\\PROGRA~1\\nodejs\\npx.cmd sous Windows).",
'settings.mcp.copy': 'Copier',
'settings.mcp.copied': 'Copié !',
'settings.mcp.apiTokens': 'Tokens API',
'settings.mcp.createToken': 'Créer un token',
'settings.mcp.noTokens':
"Aucun token pour l'instant. Créez-en un pour connecter des clients MCP.",
'settings.mcp.tokenCreatedAt': 'Créé',
'settings.mcp.tokenUsedAt': 'Utilisé',
'settings.mcp.deleteTokenTitle': 'Supprimer le token',
'settings.mcp.deleteTokenMessage':
"Ce token cessera de fonctionner immédiatement. Tout client MCP l'utilisant perdra l'accès.",
'settings.mcp.modal.createTitle': 'Créer un token API',
'settings.mcp.modal.tokenName': 'Nom du token',
'settings.mcp.modal.tokenNamePlaceholder':
'ex. Claude Desktop, Ordinateur pro',
'settings.mcp.modal.creating': 'Création…',
'settings.mcp.modal.create': 'Créer le token',
'settings.mcp.modal.createdTitle': 'Token créé',
'settings.mcp.modal.createdWarning':
"Ce token ne sera affiché qu'une seule fois. Copiez-le et conservez-le maintenant — il ne pourra pas être récupéré.",
'settings.mcp.modal.done': 'Terminé',
'settings.mcp.toast.created': 'Token créé',
'settings.mcp.toast.createError': 'Impossible de créer le token',
'settings.mcp.toast.deleted': 'Token supprimé',
'settings.mcp.toast.deleteError': 'Impossible de supprimer le token',
'settings.mcp.apiTokensDeprecated':
'Les tokens API sont dépréciés et seront supprimés dans une prochaine version. Veuillez utiliser les clients OAuth 2.1 à la place.',
'settings.oauth.clients': 'Clients OAuth 2.1',
'settings.oauth.clientsHint':
'Enregistrez des clients OAuth 2.1 pour permettre à des applications MCP tierces (Claude Web, Cursor, etc.) de se connecter sans tokens statiques.',
'settings.oauth.createClient': 'Nouveau client',
'settings.oauth.noClients': 'Aucun client OAuth enregistré.',
'settings.oauth.clientId': 'ID client',
'settings.oauth.clientSecret': 'Secret client',
'settings.oauth.deleteClient': 'Supprimer le client',
'settings.oauth.deleteClientMessage':
"Ce client et toutes les sessions actives seront définitivement supprimés. Toute application l'utilisant perdra immédiatement l'accès.",
'settings.oauth.rotateSecret': 'Renouveler le secret',
'settings.oauth.rotateSecretMessage':
'Un nouveau secret client sera généré et toutes les sessions existantes seront immédiatement invalidées. Mettez à jour votre application avant de fermer cette fenêtre.',
'settings.oauth.rotateSecretConfirm': 'Renouveler',
'settings.oauth.rotateSecretConfirming': 'Renouvellement…',
'settings.oauth.rotateSecretDoneTitle': 'Nouveau secret généré',
'settings.oauth.rotateSecretDoneWarning':
"Ce secret n'est affiché qu'une seule fois. Copiez-le maintenant et mettez à jour votre application — toutes les sessions précédentes ont été invalidées.",
'settings.oauth.activeSessions': 'Sessions OAuth actives',
'settings.oauth.sessionScopes': 'Portées',
'settings.oauth.sessionExpires': 'Expire',
'settings.oauth.revoke': 'Révoquer',
'settings.oauth.revokeSession': 'Révoquer la session',
'settings.oauth.revokeSessionMessage':
"Cela révoquera immédiatement l'accès pour cette session OAuth.",
'settings.oauth.modal.createTitle': 'Enregistrer un client OAuth',
'settings.oauth.modal.presets': 'Préréglages rapides',
'settings.oauth.modal.clientName': "Nom de l'application",
'settings.oauth.modal.clientNamePlaceholder': 'ex. Claude Web, Mon app MCP',
'settings.oauth.modal.redirectUris': 'URIs de redirection',
'settings.oauth.modal.redirectUrisPlaceholder':
'https://your-app.com/callback\nhttps://your-app.com/auth',
'settings.oauth.modal.redirectUrisHint':
'Une URI par ligne. HTTPS requis (localhost exempté). Correspondance exacte.',
'settings.oauth.modal.scopes': 'Portées autorisées',
'settings.oauth.modal.scopesHint':
"list_trips et get_trip_summary sont toujours disponibles — aucune portée requise. Ils permettent à l'IA de découvrir les IDs de voyage nécessaires.",
'settings.oauth.modal.selectAll': 'Tout sélectionner',
'settings.oauth.modal.deselectAll': 'Tout désélectionner',
'settings.oauth.modal.creating': 'Enregistrement…',
'settings.oauth.modal.create': 'Enregistrer le client',
'settings.oauth.modal.createdTitle': 'Client enregistré',
'settings.oauth.modal.createdWarning':
"Le secret client n'est affiché qu'une seule fois. Copiez-le maintenant — il ne peut pas être récupéré.",
'settings.oauth.toast.createError':
"Impossible d'enregistrer le client OAuth",
'settings.oauth.toast.deleted': 'Client OAuth supprimé',
'settings.oauth.toast.deleteError': 'Impossible de supprimer le client OAuth',
'settings.oauth.toast.revoked': 'Session révoquée',
'settings.oauth.toast.revokeError': 'Impossible de révoquer la session',
'settings.oauth.toast.rotateError':
'Impossible de renouveler le secret client',
'settings.oauth.modal.machineClient':
'Client machine (sans connexion navigateur)',
'settings.oauth.modal.machineClientHint':
'Utilise le grant client_credentials — aucune URI de redirection requise. Le token est émis directement via client_id + client_secret et agit en votre nom dans les portées sélectionnées.',
'settings.oauth.modal.machineClientUsage':
'Obtenir un token : POST /oauth/token avec grant_type=client_credentials, client_id et client_secret. Sans navigateur, sans token de rafraîchissement.',
'settings.oauth.badge.machine': 'machine',
'settings.account': 'Compte',
'settings.about': 'À propos',
'settings.about.reportBug': 'Signaler un bug',
'settings.about.reportBugHint': 'Un problème ? Faites-le nous savoir',
'settings.about.featureRequest': 'Proposer une fonctionnalité',
'settings.about.featureRequestHint': 'Suggérez une nouvelle fonctionnalité',
'settings.about.wikiHint': 'Documentation et guides',
'settings.about.supporters.badge': 'Soutiens Mensuels',
'settings.about.supporters.title': 'Compagnons de voyage pour TREK',
'settings.about.supporters.subtitle':
"Pendant que tu planifies ton prochain itinéraire, ces personnes aident à planifier l'avenir de TREK. Leur contribution mensuelle va directement au développement et aux heures réellement passées — pour que TREK reste Open Source.",
'settings.about.supporters.since': 'soutien depuis {date}',
'settings.about.supporters.tierEmpty': 'Sois le premier',
'settings.about.supporter.tier.noReturnTicket': 'No Return Ticket',
'settings.about.supporter.tier.lostLuggageVip': 'Lost Luggage VIP',
'settings.about.supporter.tier.businessClassDreamer':
'Business Class Dreamer',
'settings.about.supporter.tier.budgetTraveller': 'Budget Traveller',
'settings.about.supporter.tier.hostelBunkmate': 'Hostel Bunkmate',
'settings.about.description':
'TREK est un planificateur de voyage auto-hébergé qui vous aide à organiser vos voyages de la première idée au dernier souvenir. Planification journalière, budget, listes de bagages, photos et bien plus — le tout au même endroit, sur votre propre serveur.',
'settings.about.madeWith': 'Fait avec',
'settings.about.madeBy':
'par Maurice et une communauté open-source grandissante.',
'settings.username': "Nom d'utilisateur",
'settings.email': 'E-mail',
'settings.role': 'Rôle',
'settings.roleAdmin': 'Administrateur',
'settings.oidcLinked': 'Lié avec',
'settings.changePassword': 'Changer le mot de passe',
'settings.mustChangePassword':
'Vous devez changer votre mot de passe avant de continuer. Veuillez définir un nouveau mot de passe ci-dessous.',
'settings.currentPassword': 'Mot de passe actuel',
'settings.currentPasswordRequired': 'Le mot de passe actuel est requis',
'settings.newPassword': 'Nouveau mot de passe',
'settings.confirmPassword': 'Confirmer le nouveau mot de passe',
'settings.updatePassword': 'Mettre à jour le mot de passe',
'settings.passwordRequired':
'Veuillez saisir le mot de passe actuel et le nouveau',
'settings.passwordTooShort':
'Le mot de passe doit comporter au moins 8 caractères',
'settings.passwordMismatch': 'Les mots de passe ne correspondent pas',
'settings.passwordWeak':
'Le mot de passe doit contenir des majuscules, des minuscules, un chiffre et un caractère spécial',
'settings.passwordChanged': 'Mot de passe modifié avec succès',
'settings.deleteAccount': 'Supprimer le compte',
'settings.deleteAccountTitle': 'Supprimer votre compte ?',
'settings.deleteAccountWarning':
'Votre compte ainsi que tous vos voyages, lieux et fichiers seront définitivement supprimés. Cette action est irréversible.',
'settings.deleteAccountConfirm': 'Supprimer définitivement',
'settings.deleteBlockedTitle': 'Suppression impossible',
'settings.deleteBlockedMessage':
"Vous êtes le seul administrateur. Promouvez un autre utilisateur en tant qu'administrateur avant de supprimer votre compte.",
'settings.roleUser': 'Utilisateur',
'settings.saveProfile': 'Enregistrer le profil',
'settings.mfa.title': 'Authentification à deux facteurs (2FA)',
'settings.mfa.description':
"Ajoute une étape supplémentaire lors de la connexion. Utilisez une application d'authentification (Google Authenticator, Authy, etc.).",
'settings.mfa.requiredByPolicy':
"Votre administrateur exige l'authentification à deux facteurs. Configurez une application d'authentification ci-dessous avant de continuer.",
'settings.mfa.backupTitle': 'Codes de secours',
'settings.mfa.backupDescription':
"Utilisez ces codes à usage unique si vous perdez l'accès à votre application d'authentification.",
'settings.mfa.backupWarning':
"Enregistrez ces codes maintenant. Chaque code n'est utilisable qu'une seule fois.",
'settings.mfa.backupCopy': 'Copier les codes',
'settings.mfa.backupDownload': 'Télécharger TXT',
'settings.mfa.backupPrint': 'Imprimer / PDF',
'settings.mfa.backupCopied': 'Codes de secours copiés',
'settings.mfa.enabled': '2FA est activé sur votre compte.',
'settings.mfa.disabled': "2FA n'est pas activé.",
'settings.mfa.setup': "Configurer l'authentificateur",
'settings.mfa.scanQr':
'Scannez ce code QR avec votre application ou entrez la clé manuellement.',
'settings.mfa.secretLabel': 'Clé secrète (saisie manuelle)',
'settings.mfa.codePlaceholder': 'Code à 6 chiffres',
'settings.mfa.enable': 'Activer 2FA',
'settings.mfa.cancelSetup': 'Annuler',
'settings.mfa.disableTitle': 'Désactiver 2FA',
'settings.mfa.disableHint':
'Entrez votre mot de passe et un code actuel de votre authentificateur.',
'settings.mfa.disable': 'Désactiver 2FA',
'settings.mfa.toastEnabled': 'Authentification à deux facteurs activée',
'settings.mfa.toastDisabled': 'Authentification à deux facteurs désactivée',
'settings.mfa.demoBlocked': 'Non disponible en mode démo',
'settings.toast.mapSaved': 'Paramètres de carte enregistrés',
'settings.toast.keysSaved': 'Clés API enregistrées',
'settings.toast.displaySaved': "Paramètres d'affichage enregistrés",
'settings.toast.profileSaved': 'Profil enregistré',
'settings.uploadAvatar': 'Importer une photo de profil',
'settings.removeAvatar': 'Supprimer la photo de profil',
'settings.avatarUploaded': 'Photo de profil mise à jour',
'settings.avatarRemoved': 'Photo de profil supprimée',
'settings.avatarError': "Échec de l'import",
'settings.bookingLabels': 'Étiquettes des itinéraires',
'settings.bookingLabelsHint':
"Affiche les noms des gares / aéroports sur la carte. Si désactivé, seule l'icône est affichée.",
'settings.notifyVersionAvailable': 'Nouvelle version disponible',
'settings.notificationPreferences.noChannels':
"Aucun canal de notification n'est configuré. Demandez à un administrateur de configurer les notifications par e-mail ou webhook.",
'settings.webhookUrl.label': 'URL du webhook',
'settings.webhookUrl.placeholder': 'https://discord.com/api/webhooks/...',
'settings.webhookUrl.hint':
'Entrez votre URL de webhook Discord, Slack ou personnalisée pour recevoir des notifications.',
'settings.webhookUrl.saved': 'URL du webhook enregistrée',
'settings.webhookUrl.test': 'Tester',
'settings.webhookUrl.testSuccess': 'Webhook de test envoyé avec succès',
'settings.webhookUrl.testFailed': 'Échec du webhook de test',
'settings.ntfyUrl.topicLabel': 'Sujet Ntfy',
'settings.ntfyUrl.topicPlaceholder': 'my-trek-alerts',
'settings.ntfyUrl.serverLabel': 'URL du serveur Ntfy (optionnel)',
'settings.ntfyUrl.serverPlaceholder': 'https://ntfy.sh',
'settings.ntfyUrl.hint':
'Entrez votre sujet Ntfy pour recevoir des notifications push. Laissez le serveur vide pour utiliser la valeur par défaut configurée par votre administrateur.',
'settings.ntfyUrl.tokenLabel': "Jeton d'accès (optionnel)",
'settings.ntfyUrl.tokenHint':
'Requis pour les sujets protégés par mot de passe.',
'settings.ntfyUrl.saved': 'Paramètres Ntfy enregistrés',
'settings.ntfyUrl.test': 'Tester',
'settings.ntfyUrl.testSuccess':
'Notification de test Ntfy envoyée avec succès',
'settings.ntfyUrl.testFailed': 'Échec de la notification de test Ntfy',
'settings.ntfyUrl.tokenCleared': "Jeton d'accès effacé",
'settings.notificationPreferences.inapp': 'In-App',
'settings.notificationPreferences.webhook': 'Webhook',
'settings.notificationPreferences.email': 'Email',
'settings.notificationPreferences.ntfy': 'Ntfy',
"settings.currency": "Currency",
"settings.currencyHint": "All amounts in Costs are converted to and shown in this currency.",
};
export default settings;