This commit is contained in:
2026-08-17 21:20:45 +02:00
parent 321f11e817
commit 6fcdc74843
157 changed files with 2895 additions and 7544 deletions
+28 -19
View File
@@ -78,7 +78,7 @@ export const fr: MessageDict = {
"auth.login.failed": "Échec de la connexion",
"auth.login.passwordNotSet": "Ce compte a encore besoin d'un mot de passe. Ouvrez votre lien d'invitation, ou demandez à un administrateur d'en émettre un nouveau.",
"auth.login.setPasswordFirstTitle": "Définissez d'abord le mot de passe :",
"auth.login.setPasswordFirstBody": "utilisez le lien d'invitation de votre e-mail. Si le lien a été envoyé à une ancienne adresse (dérive d'e-mail), demandez à un administrateur de l'entreprise de renvoyer une invitation de définition de mot de passe à {email}.",
"auth.login.setPasswordFirstBody": "utilisez le lien d'invitation de votre e-mail. Si vous avez besoin d'un nouveau lien, demandez à un administrateur de l'entreprise de réémettre un lien de définition de mot de passe à {email}.",
"auth.login.yourEmail": "votre e-mail",
"auth.login.platformAdminsReissue": "Les administrateurs de la plateforme peuvent réémettre depuis",
"auth.login.adminUsersLink": "Admin → Utilisateurs",
@@ -144,9 +144,9 @@ export const fr: MessageDict = {
"auth.invite.acceptFailed": "Impossible d'accepter l'invitation",
"auth.invite.setPasswordFailed": "Impossible de définir le mot de passe",
"auth.invite.expired": "Cette invitation est invalide ou expirée. Demandez à votre administrateur d'envoyer une nouvelle invitation, puis ouvrez le nouveau lien (ou collez le nouveau jeton ci-dessous).",
"auth.invite.setPasswordExpired": "Ce lien de définition de mot de passe est invalide ou expiré. Demandez à un administrateur de l'entreprise ou de la plateforme de le réémettre, puis ouvrez le nouveau lien (ou collez le nouveau jeton ci-dessous).",
"auth.invite.setPasswordExpired": "Ce lien de définition de mot de passe est invalide ou expiré. Demandez à un administrateur de l'entreprise de réémettre un lien de définition de mot de passe vers cet e-mail, puis ouvrez le nouveau lien (ou collez le nouveau jeton ci-dessous).",
"auth.invite.emailMismatchDefault": "Vous êtes connecté avec un e-mail différent de celui de cette invitation.",
"auth.invite.expiredFooter": "Lien expiré ? Demandez à un administrateur de le réémettre — il n'y a pas d'API de renvoi en libre-service. Administrateurs de plateforme :",
"auth.invite.expiredFooter": "Lien expiré ? Demandez à un administrateur de l'entreprise de le réémettre — il n'y a pas d'API de renvoi en libre-service.",
"auth.invite.adminUsersLink": "Admin → Utilisateurs",
"auth.invite.doneTitle": "Vous faites partie de l'équipe",
"auth.invite.doneSetPasswordTitle": "Mot de passe enregistré",
@@ -163,7 +163,7 @@ export const fr: MessageDict = {
"auth.invite.switchAccountTitle": "Changer de compte :",
"auth.invite.switchAccountBody": "déconnectez-vous, puis terminez ce formulaire avec l'e-mail invité{emailSuffix}.",
"auth.invite.reissueTitle": "Chemin de réémission :",
"auth.invite.reissueBody": "si votre vrai e-mail de connexion a changé (dérive d'e-mail), demandez à un administrateur de l'entreprise de révoquer cette invitation et d'en envoyer une nouvelle à l'e-mail que vous utilisez pour vous connecter. Les administrateurs de la plateforme peuvent aussi réémettre des liens de définition de mot de passe depuis Admin → Utilisateurs.",
"auth.invite.reissueBody": "demandez à un administrateur de l'entreprise de réémettre un lien de définition de mot de passe vers cet e-mail, ou de révoquer cette invitation et d'en envoyer une nouvelle à l'e-mail que vous utilisez pour vous connecter.",
"locale.switcher": "Langue de l'interface",
"locale.menu": "Choisir la langue de l'interface",
"locale.label": "Langue du tableau de bord",
@@ -276,7 +276,7 @@ export const fr: MessageDict = {
"settings.table.lastUsed": "Dernière utilisation",
"dashboard.demoSandbox": "Bac à sable démo",
"dashboard.demoEmptyTitle": "Le bac à sable démo est vide",
"dashboard.demoEmptyHint": "Le bac à sable démo est vide — basculez vers A1 ou connectez un flux pour voir de vraies stats catalogue.",
"dashboard.demoEmptyHint": "Le bac à sable démo est vide connectez un flux pour voir de vraies stats catalogue.",
"dashboard.overviewTitle": "Vue d'ensemble",
"dashboard.quickLinks": "Liens rapides",
"dashboard.whatsNew": "Nouveautés",
@@ -319,7 +319,7 @@ export const fr: MessageDict = {
"dashboard.workflow.exportMap": "Mapper puis exporter",
"dashboard.workflowHint": "Catalogue entrant → enrichir / traiter → exporter ou pousser vers les boutiques. Passez à l’étape suivante pour {name}.",
"dashboard.overviewHint": "Totaux en direct pour {name}",
"dashboard.demoEmptyMessage": "Basculez vers A1 (ou une autre entreprise seedée) dans l'en-tête, ou connectez un flux ici pour remplir ce bac à sable.",
"dashboard.demoEmptyMessage": "Connectez un flux ici pour remplir ce bac à sable, ou basculez vers une autre entreprise dans l'en-tête.",
"dashboard.emptyTitle": "Importez un catalogue",
"dashboard.emptyMessage": "Catalogue entrant → enrichir / traiter → exporter ou pousser vers les boutiques. Commencez avec Premiers pas ci-dessous (ou connectez un flux / téléversez un CSV).",
"dashboard.connectFeedAnyway": "Connecter un flux quand même",
@@ -367,29 +367,29 @@ export const fr: MessageDict = {
"activation.focus.sync": "Ensuite : synchronisez un échantillon après l’enregistrement du mapping. Utilisez Sync sur un flux mappé — évitez les sources non mappées.",
"activation.focus.dismiss": "Fermer l’indication",
"activation.dismiss": "Masquer la checklist",
"hypercare.report.title": "Hypercare de bascule",
"hypercare.report.title": "Besoin d'aide après le transfert ?",
"hypercare.report.message": "Données manquantes ou incorrectes après la migration ? Signalez-le pour que nous corrigions votre espace de travail.",
"hypercare.report.cta": "Signaler des données manquantes ou incorrectes",
"hypercare.report.dismiss": "Ignorer",
"hypercare.report.adminTriage": "Ouvrir la file hypercare",
"etl.gaps.title": "What did not migrate",
"etl.gaps.message": "These areas were intentionally left empty or partial after the Descrybe platform cutover. Nothing is “broken” — recreate or reconnect as needed.",
"etl.gaps.title": "What still needs setup",
"etl.gaps.message": "Some items weren't copied when we moved your workspace. Nothing is broken — recreate or reconnect as needed.",
"etl.gaps.dismiss": "Dismiss",
"etl.gaps.apiKeys.title": "API keys",
"etl.gaps.apiKeys.body": "Legacy API key secrets were not migrated. Create a new key to restore API access — the secret is shown only once.",
"etl.gaps.apiKeys.body": "Previous API keys weren't copied. Create a new key to restore API access the secret is shown only once.",
"etl.gaps.apiKeys.cta": "Open API keys",
"etl.gaps.blobs.title": "File contents (blobs)",
"etl.gaps.blobs.body": "Upload records may exist as metadata only. File bytes were not copied — re-upload CSVs or resync object storage if you need the originals.",
"etl.gaps.blobs.countHint": "{count} file records are metadata-only (bytes were not migrated).",
"etl.gaps.blobs.title": "Uploaded files",
"etl.gaps.blobs.body": "File names may appear even when the file itself wasn't copied. Re-upload CSVs if you need the originals.",
"etl.gaps.blobs.countHint": "{count} files are listed without their contents (they weren't copied).",
"etl.gaps.blobs.cta": "Open Files",
"etl.gaps.jobs.title": "Processing history",
"etl.gaps.jobs.body": "Legacy job and task history was not backfilled for cutover. New jobs you start here will appear normally.",
"etl.gaps.jobs.emptyHint": "Optional jobs domain was not run — empty history is expected.",
"etl.gaps.jobs.migratedHint": "{count} jobs were tagged migrated from an optional backfill.",
"etl.gaps.jobs.body": "Earlier job history wasn't imported. New jobs you start here will appear normally.",
"etl.gaps.jobs.emptyHint": "Processing history wasn't imported — an empty list is expected.",
"etl.gaps.jobs.migratedHint": "{count} jobs were imported from the previous workspace.",
"etl.gaps.jobs.cta": "Open Processing",
"etl.gaps.woo.title": "Store credentials",
"etl.gaps.woo.body": "WooCommerce and Shopify secrets may need to be re-entered after cutover — that is a reconnect step, not a broken sync.",
"etl.gaps.woo.body": "WooCommerce and Shopify passwords may need to be re-entered after the move — reconnect your store; sync is not broken.",
"etl.gaps.woo.cta": "Open Stores",
"etl.gaps.settings.title": "Company settings",
"etl.gaps.settings.body": "Only language and merge-products settings were imported. Re-check other company preferences in Settings.",
@@ -3690,6 +3690,7 @@ export const fr: MessageDict = {
"processing.receipt.cancelledDesc": "La tâche qui vient de démarrer a été annulée.",
"processing.receipt.cancelFailed": "Impossible d'annuler la tâche de traitement",
"unsubscribe.title": "Se désabonner",
"unsubscribe.useEmailLink": "Utilisez le lien de desabonnement dans l'e-mail que nous vous avons envoye. Ouvrir cette page sans ce lien ne peut pas modifier vos preferences e-mail.",
"unsubscribe.me": "Me désabonner",
"unsubscribe.invalidLink": "Lien invalide",
"unsubscribe.failedShort": "Échec du désabonnement",
@@ -4727,6 +4728,10 @@ export const fr: MessageDict = {
"seo.terms.description": "Conditions d'utilisation de Descrybe : import de flux, enrichissement de catalogue, contenu assisté par IA, exports et synchronisation WooCommerce pour votre entreprise.",
"seo.features.title": "Fonctionnalités — Flux, enrichissement et export | Descrybe",
"seo.features.description": "Découvrez comment Descrybe importe les flux fournisseurs, mappe les champs à votre taxonomie, enrichit les données produit et diffuse les catalogues via flux d'export, WooCommerce ou API.",
"seo.contactSales.title": "Contacter les ventes | Descrybe",
"seo.contactSales.description": "Parlez-nous de votre catalogue et de vos besoins de capacite: nous preparerons une offre personnalisee payable en ligne.",
"seo.unsubscribe.title": "Se desabonner | Descrybe",
"seo.unsubscribe.description": "Arretez les e-mails marketing Descrybe via le lien de desabonnement du message que nous vous avons envoye.",
"pricing.page.eyebrow": "Tarifs",
"pricing.page.title": "Des offres simples pour des catalogues en croissance",
"pricing.page.lead": "Commencez gratuitement avec le mapping de flux et un nettoyage de base. Passez à un plan supérieur quand vous avez besoin de titres et descriptions IA, de plus de produits, d’exports ou de la sync WooCommerce — de Starter à Enterprise.",
@@ -4734,6 +4739,8 @@ export const fr: MessageDict = {
"pricing.page.subscribedMid": "ou comparez les offres dans",
"pricing.page.plansLink": "Offres",
"pricing.page.subscribedAfter": ".",
"pricing.page.guestSubscribedBefore": "Deja abonne?",
"pricing.page.guestSubscribedAfter": "pour gerer la facturation et comparer les offres.",
"legal.lastUpdated": "Dernière mise à jour : {date}",
"legal.backHome": "← Retour à l’accueil",
"legal.emailLabel": "E-mail :",
@@ -5065,7 +5072,7 @@ export const fr: MessageDict = {
"brand.uploadLogo": "Téléverser le logo",
"brand.clear": "Effacer",
"brand.field.logoUrl": "URL du logo",
"brand.placeholder.logoUrl": "https://… ou téléversé /api/brand/logo/files/…",
"brand.placeholder.logoUrl": "https://",
"brand.logoAlt": "Aperçu du logo de marque",
"brand.tipsTitle": "Conseils formule / aperçu",
"brand.saving": "Enregistrement…",
@@ -5226,6 +5233,8 @@ export const fr: MessageDict = {
"pricing.section.publicBefore": "Offres publiques : Free, Starter, Growth, Business et Enterprise. Créez un compte Free, puis passez à un plan supérieur sous",
"pricing.section.publicOr": "ou",
"pricing.section.publicAfter": "via Stripe Checkout. Enterprise reste géré par les ventes.",
"pricing.section.guestPublicBefore": "Offres publiques: Free, Starter, Plus, Growth, Business, Scale et Enterprise. Creez un compte Free, puis",
"pricing.section.guestPublicAfter": "pour passer a un plan superieur via Stripe Checkout. Enterprise reste gere par les ventes.",
"pricing.section.plansLink": "Offres",
"pricing.section.billingLink": "Facturation",
"pricing.section.capabilitiesTitle": "Ce pour quoi chaque offre est conçue",
@@ -5291,7 +5300,7 @@ export const fr: MessageDict = {
"pricing.calc.enterpriseTitle": "Sounds like Enterprise",
"pricing.calc.enterpriseBody": "Your feeds or catalog size exceed self-serve caps. Talk to sales for unlimited capacity and a managed AI grant or BYOK.",
"pricing.calc.ctaPlan": "Choose {name}",
"pricing.calc.disclaimer": "Estimates use list prices and ~2 credits per AI product enhance. Checkout prices come from Stripe. A1 and other client deals stay admin-only.",
"pricing.calc.disclaimer": "Estimates use list prices and ~2 credits per AI product enhance. Checkout prices come from Stripe. Custom client deals stay admin-only.",
"pricing.card.mostPopular": "Le plus populaire",
"pricing.card.custom": "Sur mesure",
"pricing.card.forever": "pour toujours",