adaa837564
Manual: DELETE /api/v1/ai/chat-history (scoped by recipeId or scope=general, matching GET's scoping) plus a trash-icon button + confirm dialog in both chat panels' headers. Automatic: new internal cron endpoint (chat-cleanup), same shared-secret pattern as the existing leftover-reminders/weekly-digest crons, deletes any chat_messages older than 90 days. Wired into cron/crontab (daily, 03:00 UTC) and the Dockerfile's cron stage. Verified locally: cleared a real conversation through the actual UI and confirmed it didn't come back on reopen (not just cleared client-side); inserted a 100-day-old and a 5-day-old message directly, called the cron endpoint with the real shared-secret check, confirmed only the old one was deleted and the recent one survived; confirmed the endpoint 401s with no/wrong secret.
1231 lines
57 KiB
JSON
1231 lines
57 KiB
JSON
{
|
||
"nav": {
|
||
"menu": "Menu",
|
||
"recipes": "Recettes",
|
||
"explore": "Explorer",
|
||
"search": "Rechercher",
|
||
"feed": "Fil d'actualité",
|
||
"collections": "Collections",
|
||
"mealPlan": "Planning repas",
|
||
"nutrition": "Nutrition",
|
||
"pantry": "Garde-manger",
|
||
"shopping": "Courses",
|
||
"settings": "Paramètres",
|
||
"admin": "Admin",
|
||
"signOut": "Se déconnecter",
|
||
"apiKeys": "Clés API",
|
||
"webhooks": "Webhooks",
|
||
"language": "Langue",
|
||
"notifications": "Notifications",
|
||
"viewProfile": "Voir le profil",
|
||
"lightMode": "Mode clair",
|
||
"darkMode": "Mode sombre",
|
||
"systemMode": "Système"
|
||
},
|
||
"notifications": {
|
||
"title": "Notifications",
|
||
"empty": "Aucune notification pour l'instant.",
|
||
"markAllRead": "Tout marquer comme lu",
|
||
"viewAll": "Tout voir",
|
||
"loading": "Chargement…",
|
||
"loadMore": "Charger plus",
|
||
"loadFailed": "Échec du chargement des notifications. Vérifiez votre connexion et réessayez.",
|
||
"retry": "Réessayer",
|
||
"unread": "Non lu",
|
||
"follow": "{name} vous suit désormais",
|
||
"comment": "{name} a commenté votre recette",
|
||
"reply": "{name} a répondu à votre commentaire",
|
||
"reaction": "{name} a réagi à votre commentaire",
|
||
"rating": "{name} a noté votre recette",
|
||
"mention": "{name} vous a mentionné dans un commentaire",
|
||
"detail": {
|
||
"comment": "{name} a commenté votre recette « {title} »",
|
||
"rating": "{name} a noté votre recette « {title} » {stars} étoiles",
|
||
"leftoverExpiring": "Votre « {dish} » de « {title} » arrive à expiration — à manger vite !",
|
||
"shoppingListChecked": "{name} a coché « {item} » dans « {list} »",
|
||
"shoppingListItemsAdded": "{name} a ajouté {countLabel} à « {list} »"
|
||
},
|
||
"pushTitle": {
|
||
"follow": "Nouvel abonné",
|
||
"comment": "Nouveau commentaire",
|
||
"reply": "Nouvelle réponse",
|
||
"reaction": "Nouvelle réaction",
|
||
"rating": "Nouvelle note",
|
||
"mention": "Vous avez été mentionné",
|
||
"leftoverExpiring": "Restes bientôt périmés",
|
||
"shoppingListUpdate": "Mise à jour de la liste de courses"
|
||
}
|
||
},
|
||
"recipe": {
|
||
"byAuthor": "par {name}",
|
||
"source": "Source",
|
||
"importedFrom": "Importée depuis {host}",
|
||
"share": "Partager",
|
||
"shareLinkCopied": "Lien copié dans le presse-papiers",
|
||
"shareCopyFailed": "Échec de la copie du lien",
|
||
"shareNotPublicNotice": "Ce lien ne fonctionnera qu'une fois la recette définie sur Public — lien copié quand même.",
|
||
"print": "Imprimer",
|
||
"ingredients": "Ingrédients",
|
||
"instructions": "Instructions",
|
||
"photos": "Photos",
|
||
"batchCookBadge": "Batch cooking",
|
||
"batchCookPrep": "Préparation",
|
||
"batchCookDishesTitle": "Plats & conservation",
|
||
"batchCookFridgeDays": "Frigo : {days}j",
|
||
"batchCookFreezerFriendly": "Se congèle",
|
||
"batchCookDayOf": "Le jour J",
|
||
"batchCookMarkCooked": "Marquer comme cuisiné aujourd'hui",
|
||
"batchCookMarkSuccess": "Marqué comme cuisiné",
|
||
"batchCookMarkFailed": "Échec du marquage",
|
||
"batchCookExpiresOn": "Cuisiné — bon jusqu'au {date}",
|
||
"servings": "{count} portions",
|
||
"prep": "{mins}m prép.",
|
||
"cook": "{mins}m cuisson",
|
||
"total": "{mins}m total",
|
||
"edit": "Modifier",
|
||
"variations": "Variations",
|
||
"save": "Enregistrer",
|
||
"cancel": "Annuler",
|
||
"delete": "Supprimer",
|
||
"noIngredientsSteps": "Pas encore d'ingrédients ni d'étapes.",
|
||
"generateContent": "Générer avec l'IA",
|
||
"editManually": "Modifier manuellement",
|
||
"deleted": "Recette supprimée",
|
||
"deleteFailed": "Échec de la suppression",
|
||
"imported": "Recette importée ! Vérifiez avant de publier.",
|
||
"adapted": "Recette adaptée enregistrée comme brouillon",
|
||
"adaptFailed": "Échec de l'adaptation de la recette",
|
||
"adaptConstraintRequired": "Sélectionnez au moins un ingrédient à exclure ou ajoutez une contrainte",
|
||
"adaptTooltip": "Adapter",
|
||
"adaptTitle": "Adapter cette recette",
|
||
"adaptDescription": "Touchez les ingrédients pour les exclure. L'IA trouvera les meilleurs substituts tout en préservant le plat.",
|
||
"excludeIngredients": "Exclure des ingrédients",
|
||
"excludedCount": "{count} exclus",
|
||
"additionalConstraints": "Contraintes supplémentaires",
|
||
"optional": "facultatif",
|
||
"adapting": "Adaptation de la recette — cela peut prendre 20 à 30 secondes…",
|
||
"adaptingButton": "Adaptation…",
|
||
"adaptButton": "Adapter la recette",
|
||
"clearExclusions": "Effacer",
|
||
"adaptConstraintPlaceholder": "ex. Rendre végétalien, réduire les calories, utiliser seulement les produits du garde-manger, sans gluten…",
|
||
"variationsDirectionsPlaceholder": "ex. rendre végétalien, utiliser uniquement les produits du garde-manger, réduire le sucre…",
|
||
"historyRestoreFailed": "Échec de la restauration de la version",
|
||
"pairingMealFailed": "Échec de la suggestion d'accompagnements",
|
||
"pairingDrinkFailed": "Échec de la suggestion de boissons",
|
||
"pairingGenerateFailed": "Échec de la génération de « {name} »",
|
||
"pairingSaveFailed": "Échec de l'enregistrement de « {name} »",
|
||
"pairingSuccess": "Recette générée — vérifiez avant de publier",
|
||
"pairingBulkSuccess": "{count} recettes générées — retrouvez-les dans votre bibliothèque",
|
||
"pairingDialogTitle": "Compléter le repas",
|
||
"pairingDialogDescription": "Plats suggérés par l'IA qui accompagnent bien cette recette. Générez-en n'importe lequel comme nouvelle recette.",
|
||
"forkTooltip": "Copier cette recette",
|
||
"forked": "Recette copiée dans votre bibliothèque",
|
||
"forkFailed": "Échec de la copie de la recette",
|
||
"forkLimitReached": "Limite de recettes atteinte pour votre offre",
|
||
"forkedFrom": "Copiée depuis {title}",
|
||
"pairingFindingLabel": "Recherche des meilleurs accords…",
|
||
"pairingSuggestButton": "Suggérer des accompagnements",
|
||
"pairingRegenerate": "Régénérer",
|
||
"pairingGenerateButton": "Générer",
|
||
"pairingGeneratingButton": "Génération {current}/{total}…",
|
||
"pairingGeneratingLabel": "Génération de la recette {current} sur {total}…",
|
||
"pairingRoleStarter": "Entrée",
|
||
"pairingRoleSide": "Accompagnement",
|
||
"pairingRoleSalad": "Salade",
|
||
"pairingRoleBread": "Pain",
|
||
"pairingRoleDrink": "Boisson",
|
||
"pairingRoleDessert": "Dessert",
|
||
"pairingRoleSauce": "Sauce",
|
||
"drinksDialogTitle": "Accords boissons",
|
||
"drinksDialogDescription": "Boissons suggérées par l'IA qui accompagnent cette recette.",
|
||
"drinksSuggestButton": "Suggérer des boissons",
|
||
"drinksExamplesLabel": "ex.",
|
||
"drinksTypeWine": "Vin",
|
||
"drinksTypeBeer": "Bière",
|
||
"drinksTypeCocktail": "Cocktail",
|
||
"drinksTypeSpirit": "Spiritueux",
|
||
"drinksTypeNonAlcoholic": "Sans alcool",
|
||
"drinksTypeHot": "Chaud",
|
||
"cookAction": "Cuisiner",
|
||
"photoImportFailed": "Échec de l'importation de la recette depuis la photo.",
|
||
"importFromPhoto": "Importer depuis une photo",
|
||
"urlImportTitle": "Importer une recette depuis une URL",
|
||
"urlImportDescription": "Collez l'URL d'une recette et l'IA en extraira les ingrédients et les instructions.",
|
||
"urlImportLabel": "URL de la recette",
|
||
"urlImportButton": "Importer",
|
||
"urlImportingButton": "Importation…",
|
||
"urlImportFetchFailed": "Échec de l'importation de la recette",
|
||
"urlImportSaveFailed": "Échec de l'enregistrement de la recette importée",
|
||
"urlImportSuccess": "Recette importée ! Vérifiez-la avant de la publier.",
|
||
"diffTitleLabel": "Titre",
|
||
"diffDescriptionLabel": "Description",
|
||
"diffIngredientsLabel": "Ingrédients",
|
||
"diffStepsLabel": "Étapes",
|
||
"viewGrid": "Vue grille",
|
||
"viewList": "Vue liste",
|
||
"viewCompact": "Vue compacte",
|
||
"updatedLabel": "Mis à jour le {date}",
|
||
"addToCollection": "Ajouter à une collection",
|
||
"addToCollectionTitle": "Ajouter {count, plural, one {1 recette} other {{count} recettes}} à une collection",
|
||
"newCollectionOption": "Nouvelle collection…",
|
||
"newCollectionNamePlaceholder": "Nom de la collection",
|
||
"addToCollectionSuccess": "{count, plural, one {1 recette} other {{count} recettes}} ajoutée(s) à « {name} »",
|
||
"addToCollectionFailed": "Échec de l'ajout à la collection",
|
||
"createCollectionFailed": "Échec de la création de la collection",
|
||
"noCollectionsYet": "Vous n'avez pas encore de collection.",
|
||
"versionHistoryTitle": "Historique des versions",
|
||
"versionsLoading": "Chargement des versions...",
|
||
"versionsEmpty": "Aucune version pour l'instant. Les versions sont enregistrées automatiquement lorsque vous modifiez cette recette.",
|
||
"versionCompare": "Comparer",
|
||
"versionCompareWith": "Comparer v{version} avec la version actuelle",
|
||
"versionRestore": "Restaurer",
|
||
"versionRestored": "Recette restaurée à la version {version}",
|
||
"versionDetailLoading": "Chargement...",
|
||
"versionDetailSummary": "{ingredients, plural, one {1 ingrédient} other {{ingredients} ingrédients}}, {steps, plural, one {1 étape} other {{steps} étapes}}",
|
||
"analyzingPhoto": "Analyse de la photo…",
|
||
"pairMealTooltip": "Accorder un plat",
|
||
"historyTooltip": "Historique",
|
||
"translateTooltip": "Traduire",
|
||
"drinksTooltip": "Boissons",
|
||
"variationsTooltip": "Variations",
|
||
"viewPublicly": "Voir publiquement",
|
||
"shoppingListCreateFailed": "Échec de la création de la liste",
|
||
"shoppingListAddFailed": "Échec de l'ajout des ingrédients",
|
||
"bulkDeleted": "{count, plural, one {1 recette supprimée} other {{count} recettes supprimées}}",
|
||
"bulkVisibility": "{count, plural, one {1 recette définie sur {visibility}} other {{count} recettes définies sur {visibility}}}",
|
||
"bulkDeleteFailed": "Échec de la suppression",
|
||
"bulkUpdateFailed": "Échec de la mise à jour",
|
||
"bulkDeleteConfirmTitle": "{count, plural, one {Supprimer 1 recette ?} other {Supprimer {count} recettes ?}}",
|
||
"bulkDeleteConfirmDescription": "Cette action est irréversible.",
|
||
"deselectAll": "Tout désélectionner",
|
||
"selectAll": "Tout sélectionner",
|
||
"clickToSelect": "Cliquez sur les cartes pour sélectionner",
|
||
"selectedCount": "{count} sélectionnée(s)",
|
||
"select": "Sélectionner",
|
||
"visibilityMenuLabel": "Visibilité",
|
||
"makePublic": "Rendre publique",
|
||
"makeUnlisted": "Rendre non répertoriée",
|
||
"makePrivate": "Rendre privée",
|
||
"visibility": {
|
||
"private": "Privée",
|
||
"unlisted": "Non répertoriée",
|
||
"public": "Publique"
|
||
},
|
||
"difficulty": {
|
||
"easy": "Facile",
|
||
"medium": "Moyen",
|
||
"hard": "Difficile"
|
||
},
|
||
"dietary": {
|
||
"vegan": "Végétalien",
|
||
"vegetarian": "Végétarien",
|
||
"glutenFree": "Sans gluten",
|
||
"dairyFree": "Sans lactose",
|
||
"nutFree": "Sans noix",
|
||
"halal": "Halal",
|
||
"kosher": "Casher"
|
||
}
|
||
},
|
||
"ai": {
|
||
"generate": {
|
||
"title": "Générer une recette avec l'IA",
|
||
"description": "Décrivez ce que vous voulez cuisiner et l'IA créera une recette complète.",
|
||
"descriptionFull": "Décrivez un plat ou prenez une photo — l'IA construit la recette complète.",
|
||
"tabDescribe": "Décrire",
|
||
"tabPhoto": "Depuis une photo",
|
||
"surpriseMe": "Surprends-moi",
|
||
"prompt": "Que voulez-vous cuisiner ?",
|
||
"placeholder": "ex. Un risotto crémeux aux champignons et parmesan, 4 portions, niveau facile",
|
||
"language": "Langue de la recette",
|
||
"difficulty": "Difficulté",
|
||
"anyDifficulty": "Toutes",
|
||
"button": "Générer",
|
||
"generating": "Génération en cours…",
|
||
"success": "Recette générée ! Vérifiez et modifiez avant de publier.",
|
||
"error": "Échec de la génération de la recette",
|
||
"saveError": "Échec de l'enregistrement de la recette générée",
|
||
"uploadClick": "Cliquez pour importer",
|
||
"uploadDrag": "ou glissez une photo du plat",
|
||
"uploadFormats": "JPEG, PNG ou WebP · l'IA reconstituera la recette",
|
||
"analyzing": "Analyse en cours…",
|
||
"analyzePhoto": "Analyse de la photo du plat…",
|
||
"recognizeDish": "Reconnaître le plat",
|
||
"photoSuccess": "Recette reconnue ! Vérifiez et modifiez avant de publier.",
|
||
"photoError": "Échec de l'analyse de la photo",
|
||
"contentGenerated": "Ingrédients et étapes générés !",
|
||
"contentGenerateFailed": "Échec de la génération",
|
||
"contentSaveFailed": "Échec de l'enregistrement du contenu généré",
|
||
"generatingContent": "Génération du contenu de la recette…",
|
||
"photoAnalysisNote": "L'IA analysera ce plat et déduira les ingrédients, quantités et étapes de préparation."
|
||
},
|
||
"variations": {
|
||
"title": "Variations de recette par IA",
|
||
"description": "Générez des variations créatives de cette recette — adaptations diététiques, profils de saveurs, changements de techniques.",
|
||
"generate": "Générer 3 variations",
|
||
"generating": "Génération des variations…",
|
||
"regenerate": "Régénérer",
|
||
"apply": "Appliquer",
|
||
"applying": "Application…",
|
||
"ingredientChanges": "Changements d'ingrédients",
|
||
"stepChanges": "Changements d'étapes",
|
||
"success": "Variation créée — vérifiez et modifiez avant de publier.",
|
||
"error": "Échec de la génération des variations",
|
||
"saveError": "Échec de l'enregistrement de la variation",
|
||
"wait": "Cela peut prendre 20 à 30 secondes",
|
||
"directions": "Instructions",
|
||
"optional": "facultatif",
|
||
"stepLabel": "Étape {n}"
|
||
},
|
||
"translate": {
|
||
"title": "Traduire la recette",
|
||
"description": "Traduisez le titre, la description, les ingrédients et les étapes de cette recette dans une autre langue.",
|
||
"targetLanguage": "Langue cible",
|
||
"button": "Traduire",
|
||
"translating": "Traduction en cours…",
|
||
"success": "Traduction enregistrée comme nouveau brouillon.",
|
||
"error": "Échec de la traduction de la recette",
|
||
"saveError": "Échec de l'enregistrement de la recette traduite",
|
||
"wait": "Cela peut prendre 20 à 30 secondes"
|
||
}
|
||
},
|
||
"settings": {
|
||
"title": "Paramètres",
|
||
"subtitle": "Gérez votre compte, vos préférences et vos intégrations.",
|
||
"profile": "Profil",
|
||
"language": "Langue",
|
||
"units": "Unités",
|
||
"metric": "Métrique",
|
||
"imperial": "Impérial",
|
||
"security": "Sécurité",
|
||
"aiModels": "IA et modèles",
|
||
"notifications": "Notifications",
|
||
"nutrition": "Nutrition",
|
||
"apiKeys": "Clés API",
|
||
"webhooks": "Webhooks",
|
||
"byok": {
|
||
"title": "Vos clés API (BYOK)",
|
||
"description": "Utilisez vos propres clés API au lieu du quota partagé de l'application. Les clés sont chiffrées au repos."
|
||
},
|
||
"modelPrefs": {
|
||
"title": "Préférences de modèle",
|
||
"description": "Choisissez le modèle à utiliser pour chaque tâche. Par défaut, votre premier fournisseur configuré."
|
||
},
|
||
"apiKeysPage": {
|
||
"title": "Clés API",
|
||
"description": "Gérez les clés API pour un accès programmatique à l'API Epicure.",
|
||
"docsLink": "Voir la documentation de l'API"
|
||
},
|
||
"pushNotifications": {
|
||
"title": "Notifications push",
|
||
"description": "Soyez averti lorsqu'on commente vos recettes ou aime votre contenu."
|
||
},
|
||
"nutritionGoals": {
|
||
"title": "Objectifs nutritionnels quotidiens",
|
||
"description": "Définissez vos objectifs quotidiens. Ils apparaissent sous forme de barres de progression dans votre planning repas.",
|
||
"viewDiaryCta": "Voir le journal nutritionnel",
|
||
"caloriesLabel": "Calories (kcal/jour)",
|
||
"proteinLabel": "Protéines (g/jour)",
|
||
"carbsLabel": "Glucides (g/jour)",
|
||
"fatLabel": "Lipides (g/jour)",
|
||
"caloriesPlaceholder": "ex. 2000",
|
||
"proteinPlaceholder": "ex. 50",
|
||
"carbsPlaceholder": "ex. 250",
|
||
"fatPlaceholder": "ex. 70",
|
||
"saveButton": "Enregistrer les objectifs",
|
||
"saving": "Enregistrement...",
|
||
"saveSuccess": "Objectifs nutritionnels enregistrés",
|
||
"saveError": "Impossible d'enregistrer les objectifs nutritionnels"
|
||
},
|
||
"webhooksPage": {
|
||
"title": "Webhooks",
|
||
"description": "Recevez des appels HTTP lorsque des événements se produisent sur votre compte Epicure."
|
||
}
|
||
},
|
||
"print": {
|
||
"footer": "Imprimé depuis Epicure",
|
||
"day": "Jour",
|
||
"srv": " · {count} pers.",
|
||
"days": {
|
||
"mon": "Lundi",
|
||
"tue": "Mardi",
|
||
"wed": "Mercredi",
|
||
"thu": "Jeudi",
|
||
"fri": "Vendredi",
|
||
"sat": "Samedi",
|
||
"sun": "Dimanche"
|
||
}
|
||
},
|
||
"publicShoppingList": {
|
||
"sharedList": "Liste de courses partagée",
|
||
"wantYourOwn": "Envie de vos propres listes de courses ?"
|
||
},
|
||
"publicRecipe": {
|
||
"publicRecipeBy": "Recette publique par",
|
||
"viewInLibrary": "Voir dans votre bibliothèque",
|
||
"signUpFree": "S'inscrire gratuitement",
|
||
"logIn": "Se connecter",
|
||
"wantToSave": "Envie de sauvegarder cette recette ?",
|
||
"wantToSaveDescription": "Créez un compte gratuit pour sauvegarder des recettes, ajuster les portions et construire votre propre bibliothèque.",
|
||
"getStartedFree": "Commencer gratuitement"
|
||
},
|
||
"substitute": {
|
||
"fetchError": "Impossible de récupérer les substituts.",
|
||
"titleFor": "Substitut pour {ingredient}",
|
||
"substitutesFor": "Substituts pour",
|
||
"finding": "Recherche de substituts…",
|
||
"noneFound": "Aucune substitution trouvée."
|
||
},
|
||
"recipeChat": {
|
||
"sorry": "Désolé, je n'ai pas pu répondre à cela.",
|
||
"error": "Une erreur s'est produite. Veuillez réessayer.",
|
||
"suggestion1": "Puis-je substituer des ingrédients ?",
|
||
"suggestion2": "Comment savoir quand c'est prêt ?",
|
||
"suggestion3": "Puis-je préparer cela à l'avance ?",
|
||
"suggestion4": "Avec quoi puis-je servir ce plat ?",
|
||
"ariaLabel": "Demander à l'IA à propos de cette recette",
|
||
"title": "Poser une question sur cette recette",
|
||
"intro": "Demandez n'importe quoi sur cette recette — ingrédients, techniques, substitutions, minutage…",
|
||
"inputPlaceholder": "Posez une question…",
|
||
"send": "Envoyer le message"
|
||
},
|
||
"chatHistory": {
|
||
"searchAriaLabel": "Rechercher dans l'historique",
|
||
"searchPlaceholder": "Rechercher une question passée…",
|
||
"searching": "Recherche…",
|
||
"noResults": "Aucun message correspondant",
|
||
"close": "Fermer",
|
||
"clearAriaLabel": "Effacer l'historique",
|
||
"clearConfirmTitle": "Effacer cette conversation ?",
|
||
"clearConfirmDescription": "Cela supprime l'historique enregistré de cette conversation. Cette action est irréversible.",
|
||
"clearCancel": "Annuler",
|
||
"clearConfirm": "Effacer l'historique",
|
||
"cleared": "Historique effacé",
|
||
"clearFailed": "Échec de l'effacement de l'historique"
|
||
},
|
||
"cookingChat": {
|
||
"sorry": "Désolé, je n'ai pas pu répondre à cela.",
|
||
"error": "Une erreur s'est produite. Veuillez réessayer.",
|
||
"suggestion1": "Comment savoir si l'huile est assez chaude ?",
|
||
"suggestion2": "Quel est un bon substitut au lait fermenté ?",
|
||
"suggestion3": "Combien de temps puis-je garder des restes au frigo ?",
|
||
"suggestion4": "Quelle est la différence entre mijoter et bouillir ?",
|
||
"ariaLabel": "Poser une question de cuisine",
|
||
"title": "Assistant culinaire",
|
||
"subtitle": "Posez n'importe quelle question de cuisine — pas liée à une recette précise",
|
||
"intro": "Demandez n'importe quoi sur la cuisine — techniques, substitutions, minutage, équipement…",
|
||
"inputPlaceholder": "Posez une question…",
|
||
"send": "Envoyer le message"
|
||
},
|
||
"servingScaler": {
|
||
"servings": "Portions",
|
||
"reset": "Réinitialiser",
|
||
"aiScale": "Ajuster avec l'IA",
|
||
"scaling": "Ajustement…",
|
||
"aiScaledNote": "Quantités ajustées par l'IA affichées ci-dessous",
|
||
"dismissAiScaling": "Ignorer l'ajustement IA"
|
||
},
|
||
"people": {
|
||
"title": "Trouver des personnes",
|
||
"subtitle": "Recherchez des cuisiniers à suivre par nom ou nom d'utilisateur.",
|
||
"searchPlaceholder": "Rechercher par nom ou nom d'utilisateur…",
|
||
"searching": "Recherche…",
|
||
"noneFound": "Personne trouvé."
|
||
},
|
||
"messages": {
|
||
"loading": "Chargement…",
|
||
"noMessagesYet": "Aucun message pour l'instant. Dites bonjour !",
|
||
"sendFailed": "Échec de l'envoi",
|
||
"placeholder": "Écrire un message…",
|
||
"noConversationsYet": "Aucune conversation pour l'instant. Visitez un profil pour dire bonjour.",
|
||
"unknownUser": "Inconnu",
|
||
"noMessagesPreview": "Aucun message pour l'instant",
|
||
"selectConversation": "Sélectionnez une conversation",
|
||
"messageButton": "Message",
|
||
"startConversationFailed": "Échec du démarrage de la conversation",
|
||
"title": "Messages",
|
||
"loadOlder": "Charger les messages précédents",
|
||
"loadingOlder": "Chargement…",
|
||
"send": "Envoyer le message"
|
||
},
|
||
"nutritionPanel": {
|
||
"estimateButton": "Estimer les valeurs nutritionnelles",
|
||
"reEstimateButton": "Réestimer",
|
||
"estimating": "Estimation…",
|
||
"estimatingNutrition": "Estimation des valeurs nutritionnelles…",
|
||
"title": "Valeurs nutritionnelles par portion",
|
||
"estimateFailed": "Échec de l'estimation nutritionnelle",
|
||
"error": "Une erreur s'est produite",
|
||
"protein": "Protéines",
|
||
"carbs": "Glucides",
|
||
"fat": "Lipides",
|
||
"fiber": "Fibres",
|
||
"sodium": "Sodium"
|
||
},
|
||
"nutritionDiary": {
|
||
"title": "Journal nutritionnel",
|
||
"subtitle": "Votre apport nutritionnel quotidien, calculé à partir de ce que vous avez cuisiné.",
|
||
"dateLabel": "Date",
|
||
"today": "Aujourd'hui",
|
||
"loading": "Chargement…",
|
||
"loadError": "Impossible de charger votre journal nutritionnel. Veuillez réessayer.",
|
||
"goalNotSet": "Vous n'avez pas encore défini d'objectifs nutritionnels quotidiens.",
|
||
"setGoalsCta": "Définir les objectifs",
|
||
"calories": "Calories",
|
||
"protein": "Protéines",
|
||
"carbs": "Glucides",
|
||
"fat": "Lipides",
|
||
"fiber": "Fibres",
|
||
"sodium": "Sodium",
|
||
"entriesTitle": "Recettes cuisinées",
|
||
"noEntries": "Rien n'est enregistré pour ce jour. Marquez une recette comme « cuisinée » pour la voir ici.",
|
||
"servingsLabel": "{count, plural, one {1 portion} other {{count} portions}}",
|
||
"nutritionUnknownBadge": "Nutrition inconnue",
|
||
"unknownNote": "{count, plural, one {1 entrée n'a pas de données nutritionnelles et n'est pas incluse dans les totaux ci-dessus.} other {{count} entrées n'ont pas de données nutritionnelles et ne sont pas incluses dans les totaux ci-dessus.}}"
|
||
},
|
||
"explore": {
|
||
"title": "Explorer",
|
||
"tabRecipes": "Recettes",
|
||
"tabPeople": "Personnes",
|
||
"searchPlaceholder": "Rechercher des recettes publiques…",
|
||
"maxMinutes": "Minutes max",
|
||
"aiSearchPlaceholder": "ex. dîners rapides en semaine, cuisine réconfortante italienne…",
|
||
"anyDifficulty": "Toute difficulté",
|
||
"resultsFoundSingular": "{count} recette trouvée",
|
||
"resultsFoundPlural": "{count} recettes trouvées",
|
||
"noResultsTitle": "Aucune recette trouvée pour « {query} »",
|
||
"noResultsHint": "Essayez d'autres mots-clés ou retirez des filtres",
|
||
"loadMore": "Charger plus",
|
||
"recipeIdeas": "Idées de recettes",
|
||
"recipeIdeasHint": "Dites à l'IA ce dont vous avez envie, ou laissez-la vous surprendre.",
|
||
"generating": "Génération…",
|
||
"getIdeas": "Obtenir des idées",
|
||
"surpriseMe": "Surprenez-moi",
|
||
"generateFullRecipe": "Générer la recette complète",
|
||
"trendingThisWeek": "Tendances cette semaine",
|
||
"noTrending": "Aucune recette tendance pour l'instant. Soyez le premier à en partager une !",
|
||
"recentlyAdded": "Récemment ajoutées",
|
||
"noRecent": "Aucune recette publique pour l'instant."
|
||
},
|
||
"common": {
|
||
"loading": "Chargement…",
|
||
"error": "Une erreur s'est produite",
|
||
"save": "Enregistrer",
|
||
"saved": "Enregistré",
|
||
"saveFailed": "Échec de l'enregistrement",
|
||
"exportMarkdown": "Exporter en Markdown",
|
||
"copyMarkdown": "Copier en Markdown",
|
||
"downloadMarkdown": "Télécharger en Markdown",
|
||
"copiedToClipboard": "Copié dans le presse-papiers",
|
||
"copyFailed": "Échec de la copie dans le presse-papiers",
|
||
"print": "Imprimer",
|
||
"share": "Partager",
|
||
"deleteFailed": "Échec de la suppression",
|
||
"updateFailed": "Échec de la mise à jour",
|
||
"deleted": "Supprimé",
|
||
"cancel": "Annuler",
|
||
"delete": "Supprimer",
|
||
"confirm": "Confirmer",
|
||
"back": "Retour",
|
||
"difficulty": "Difficulté",
|
||
"anyDifficulty": "Toutes",
|
||
"editManually": "Modifier manuellement",
|
||
"surpriseMe": "Surprends-moi",
|
||
"generatingContent": "Génération du contenu de la recette…",
|
||
"decrease": "Diminuer",
|
||
"increase": "Augmenter"
|
||
},
|
||
"auth": {
|
||
"signIn": "Se connecter",
|
||
"signInTitle": "Connectez-vous à votre bibliothèque de recettes",
|
||
"signInLoading": "Connexion en cours…",
|
||
"signUp": "S'inscrire",
|
||
"signUpTitle": "Créer un compte",
|
||
"signUpSubtitle": "Commencez à construire votre bibliothèque de recettes",
|
||
"signUpLoading": "Création du compte…",
|
||
"continueWithGoogle": "Continuer avec Google",
|
||
"continueWithGithub": "Continuer avec GitHub",
|
||
"continueWithDiscord": "Continuer avec Discord",
|
||
"continueWithAuthentik": "Continuer avec Authentik",
|
||
"email": "E-mail",
|
||
"emailPlaceholder": "vous@exemple.fr",
|
||
"password": "Mot de passe",
|
||
"name": "Nom",
|
||
"namePlaceholder": "Votre nom",
|
||
"forgotPassword": "Mot de passe oublié ?",
|
||
"forgotPasswordTitle": "Mot de passe oublié",
|
||
"forgotPasswordSent": "Vérifiez vos e-mails",
|
||
"forgotPasswordDescription": "Saisissez votre e-mail et nous vous enverrons un lien de réinitialisation.",
|
||
"forgotPasswordSentDescription": "Si un compte existe pour cet e-mail, vous recevrez un lien sous peu.",
|
||
"sendResetLink": "Envoyer le lien",
|
||
"sendingLink": "Envoi en cours…",
|
||
"resetPasswordTitle": "Réinitialiser le mot de passe",
|
||
"resetPasswordDescription": "Saisissez un nouveau mot de passe pour votre compte.",
|
||
"newPassword": "Nouveau mot de passe",
|
||
"confirmPassword": "Confirmer le mot de passe",
|
||
"updatePassword": "Mettre à jour le mot de passe",
|
||
"updatingPassword": "Mise à jour…",
|
||
"invalidToken": "Jeton de réinitialisation invalide ou manquant.",
|
||
"noAccount": "Pas de compte ? S'inscrire",
|
||
"alreadyHaveAccount": "Déjà un compte ? Se connecter",
|
||
"backToSignIn": "Retour à la connexion",
|
||
"emailNotVerified": "E-mail non vérifié",
|
||
"checkInboxVerification": "Vérifiez votre boîte de réception pour l'e-mail de vérification.",
|
||
"resendVerification": "Renvoyer l'e-mail de vérification",
|
||
"resendingSending": "Envoi en cours…",
|
||
"or": "ou"
|
||
},
|
||
"batchCooking": {
|
||
"title": "Batch cooking",
|
||
"subtitle": "Cuisinez une fois, mangez bien toute la semaine",
|
||
"empty": "Aucune session de batch cooking pour l'instant",
|
||
"newSession": "Nouvelle session de batch cooking",
|
||
"dishCount": "{count, plural, one {# plat} other {# plats}}",
|
||
"wizardTitle": "Planifier une session de batch cooking",
|
||
"wizardDescription": "Choisissez combien de repas couvrir — on génère une liste de courses partagée et une seule session de préparation pour tout.",
|
||
"describe": "Décrivez ce que vous recherchez",
|
||
"describePlaceholder": "ex. saveurs méditerranéennes, utiliser la courge du garde-manger, adapté aux enfants…",
|
||
"dinners": "Dîners",
|
||
"lunches": "Déjeuners",
|
||
"servingsPerMeal": "Portions par repas",
|
||
"dietaryPrefs": "Préférences alimentaires",
|
||
"dietaryPrefsPlaceholder": "ex : végétarien, sans crustacés",
|
||
"anyDifficulty": "Peu importe",
|
||
"generate": "Générer",
|
||
"generating": "Génération…",
|
||
"generateSuccess": "Session de batch cooking créée",
|
||
"generateFailed": "Échec de la génération"
|
||
},
|
||
"recipes": {
|
||
"title": "Recettes",
|
||
"subtitle": "Votre bibliothèque personnelle de recettes",
|
||
"new": "Nouvelle recette",
|
||
"newTitle": "Nouvelle recette",
|
||
"newSubtitle": "Créez votre recette depuis zéro",
|
||
"importUrl": "Importer une URL",
|
||
"generate": "Générer",
|
||
"batchCooking": "Batch cooking",
|
||
"search": "Rechercher des recettes…",
|
||
"noRecipes": "Aucune recette pour l'instant",
|
||
"noMatch": "Aucune recette ne correspond",
|
||
"clearSearch": "Effacer la recherche",
|
||
"createFirst": "Créer votre première recette",
|
||
"resultSingular": "{count} recette",
|
||
"resultPlural": "{count} recettes",
|
||
"for": "pour",
|
||
"filterByTag": "Filtrer par tag…",
|
||
"sortRecentlyUpdated": "Mise à jour récemment",
|
||
"sortOldestUpdated": "Mise à jour la plus ancienne",
|
||
"sortNewestFirst": "Plus récentes",
|
||
"sortOldestFirst": "Plus anciennes",
|
||
"sortTitleAZ": "Titre A–Z",
|
||
"sortTitleZA": "Titre Z–A",
|
||
"sort": "Trier",
|
||
"sortBy": "Trier par",
|
||
"filter": "Filtrer",
|
||
"all": "Toutes",
|
||
"anyDifficulty": "Toute difficulté",
|
||
"visibilityLabel": "Visibilité",
|
||
"difficultyLabel": "Difficulté",
|
||
"tagLabel": "Tag",
|
||
"batchCookLabel": "Batch cooking",
|
||
"batchCookOnly": "Batch cooking uniquement",
|
||
"batchCookExclude": "Masquer le batch cooking",
|
||
"clearFilters": "Effacer les filtres",
|
||
"tabMine": "Mes recettes",
|
||
"tabFavorites": "Favoris",
|
||
"favoritesCount": "{count} recette favorite",
|
||
"favoritesCountPlural": "{count} recettes favorites",
|
||
"favoritesEmpty": "Aucune recette favorite pour l'instant — touchez le cœur sur une recette pour l'enregistrer ici.",
|
||
"favoritesEmptyTitle": "Aucun favori pour l'instant",
|
||
"exploreRecipes": "Explorer les recettes",
|
||
"emptyStateDescription": "Créez la vôtre, importez-la depuis une URL, ou laissez l'IA en générer une pour commencer."
|
||
},
|
||
"recipeNotes": {
|
||
"title": "Vos notes personnelles",
|
||
"visibilityHint": "Visible uniquement par vous — jamais partagé avec l'auteur de la recette ou quiconque d'autre.",
|
||
"placeholder": "ex. : j'ai mis moins de sel que ce que la recette indique, très bon avec du riz à la place des pâtes…",
|
||
"save": "Enregistrer",
|
||
"saving": "Enregistrement…",
|
||
"saved": "Note enregistrée",
|
||
"saveFailed": "Échec de l'enregistrement de la note"
|
||
},
|
||
"recipeForm": {
|
||
"titleLabel": "Titre *",
|
||
"titleRequired": "Le titre est requis",
|
||
"titlePlaceholder": "Ma super recette",
|
||
"descriptionLabel": "Description",
|
||
"descriptionPlaceholder": "Ce qui rend cette recette spéciale…",
|
||
"servings": "Portions",
|
||
"prepMins": "Prép. (min)",
|
||
"cookMins": "Cuisson (min)",
|
||
"difficulty": "Difficulté",
|
||
"visibilityMenuLabel": "Visibilité",
|
||
"dietaryTags": "Tags alimentaires",
|
||
"photos": "Photos",
|
||
"ingredients": "Ingrédients",
|
||
"amount": "Quantité",
|
||
"unit": "Unité",
|
||
"ingredient": "Ingrédient",
|
||
"note": "Note",
|
||
"addIngredient": "Ajouter un ingrédient",
|
||
"setCover": "Définir comme couverture",
|
||
"removePhoto": "Supprimer",
|
||
"expand": "Développer",
|
||
"steps": "Étapes",
|
||
"stepPlaceholder": "Étape {n}…",
|
||
"timerSeconds": "Minuteur (s)",
|
||
"addStep": "Ajouter une étape",
|
||
"saving": "Enregistrement…",
|
||
"saveChanges": "Enregistrer les modifications",
|
||
"createRecipe": "Créer la recette",
|
||
"updateSuccess": "Recette mise à jour",
|
||
"createSuccess": "Recette créée",
|
||
"saveError": "Échec de l'enregistrement de la recette",
|
||
"ingredientsRequired": "Ajoutez au moins un ingrédient",
|
||
"stepsRequired": "Ajoutez au moins une étape",
|
||
"discardChangesTitle": "Abandonner les modifications ?",
|
||
"discardChangesDescription": "Vous avez des modifications non enregistrées. Si vous quittez maintenant, elles seront perdues.",
|
||
"keepEditing": "Continuer l'édition",
|
||
"discardChanges": "Abandonner",
|
||
"batchCookToggle": "Ceci est une recette de batch cooking",
|
||
"batchCookToggleHelp": "Divisez cette recette en plusieurs plats cuisinés ensemble, chacun avec ses propres consignes de conservation et de réchauffage.",
|
||
"dishes": "Plats",
|
||
"addDish": "Ajouter un plat",
|
||
"dishName": "Nom du plat",
|
||
"dishDescription": "Description",
|
||
"fridgeDays": "Frigo (jours)",
|
||
"freezerFriendly": "Se congèle bien",
|
||
"freezerNote": "Note de congélation",
|
||
"dayOfInstructions": "Consignes le jour J",
|
||
"dishesRequired": "Ajoutez au moins un plat",
|
||
"dayOfInstructionsRequired": "Chaque plat nécessite des consignes pour le jour J",
|
||
"appliesTo": "Concerne",
|
||
"sharedPrep": "Préparation commune"
|
||
},
|
||
"canCook": {
|
||
"title": "Que puis-je cuisiner ?",
|
||
"subtitle": "Recettes réalisables avec votre garde-manger",
|
||
"emptyPantry": "Votre garde-manger est vide",
|
||
"addPantryItems": "Ajouter des articles",
|
||
"readyToCook": "Prêt à cuisiner",
|
||
"almostThere": "Presque là (70–99 %)",
|
||
"partialMatches": "Correspondances partielles",
|
||
"noMatches": "Aucune correspondance trouvée",
|
||
"missing": "Manquant",
|
||
"ingredientProgress": "{matched}/{total} ingrédients",
|
||
"useItUp": "À utiliser vite"
|
||
},
|
||
"mealPlan": {
|
||
"title": "Planning repas",
|
||
"shoppingLists": "Listes de courses",
|
||
"print": "Imprimer",
|
||
"shareTitle": "Partager le planning de cette semaine",
|
||
"shareDescription": "Invitez des membres du foyer à voir ou modifier le planning repas de cette semaine.",
|
||
"sharedWithYou": "Partagé avec vous",
|
||
"sharedPlanOf": "Planning de {name}",
|
||
"weekOf": "Semaine du {date}",
|
||
"sharedMealPlanTitle": "Planning repas de {name}",
|
||
"batchCookBadge": "Batch cooking",
|
||
"batchCooking": "Batch cooking",
|
||
"pickDishTitle": "Quel plat de \"{recipe}\" ?",
|
||
"pickDishDescription": "C'est une session de batch cooking — choisissez le plat précis pour ce créneau.",
|
||
"back": "Retour",
|
||
"addTo": "Ajouter à {day} – {meal}",
|
||
"searchRecipes": "Rechercher des recettes…",
|
||
"servings": "Portions",
|
||
"servingsAbbrev": "{count} pers.",
|
||
"difficulty": "Difficulté",
|
||
"noRecipes": "Aucune recette trouvée",
|
||
"addFailed": "Échec de l'ajout",
|
||
"addedToPantry": "{count, plural, one {1 article ajouté au garde-manger} other {{count} articles ajoutés au garde-manger}}",
|
||
"moveToPantryFailed": "Échec du déplacement des articles vers le garde-manger",
|
||
"aisleOther": "Autre",
|
||
"listEmptyState": "Cette liste est vide.",
|
||
"checkedCount": "{checked}/{total} cochés",
|
||
"searchItemsPlaceholder": "Rechercher des articles…",
|
||
"sortByCategory": "Par catégorie",
|
||
"sortByAlpha": "Alphabétique",
|
||
"sortByUnchecked": "Non cochés d'abord",
|
||
"noSearchResults": "Aucun article ne correspond à votre recherche.",
|
||
"autoCategorize": "Catégoriser automatiquement",
|
||
"autoCategorizeSuccess": "{count, plural, one {1 article catégorisé} other {{count} articles catégorisés}}",
|
||
"autoCategorizeNoneFound": "Impossible de deviner une catégorie pour les articles restants",
|
||
"removeItemConfirmTitle": "Supprimer l'article ?",
|
||
"removeItemConfirmDescription": "Supprimer « {name} » de cette liste ?",
|
||
"moveToPantry": "Déplacer {count} vers le garde-manger",
|
||
"listCreated": "Liste créée",
|
||
"days": {
|
||
"mon": "Lun",
|
||
"tue": "Mar",
|
||
"wed": "Mer",
|
||
"thu": "Jeu",
|
||
"fri": "Ven",
|
||
"sat": "Sam",
|
||
"sun": "Dim"
|
||
},
|
||
"meals": {
|
||
"breakfast": "Petit-déjeuner",
|
||
"lunch": "Déjeuner",
|
||
"dinner": "Dîner",
|
||
"snack": "Collation"
|
||
},
|
||
"generateWithAi": "Générer avec l'IA",
|
||
"aiModalDescription": "L'IA va générer une semaine complète de repas et créer des recettes brouillons.",
|
||
"dietaryPrefs": "Préférences alimentaires",
|
||
"dietaryPrefsPlaceholder": "ex. végétarien, sans gluten, low-carb…",
|
||
"aiPantryNote": "Les articles de votre garde-manger seront pris en compte.",
|
||
"generating": "Génération…",
|
||
"generate": "Générer",
|
||
"cancel": "Annuler",
|
||
"aiGenerated": "Plan de repas généré !",
|
||
"includePantryItems": "Inclure les articles du garde-manger",
|
||
"pantryMode": "Mode garde-manger — maximiser ce que vous avez",
|
||
"pantryModeDescription": "Préférer les repas utilisant plusieurs ingrédients du garde-manger et limiter les achats supplémentaires.",
|
||
"targetNutritionGoals": "Viser mes objectifs nutritionnels",
|
||
"targetNutritionGoalsDescription": "Inciter l'IA à viser vos objectifs quotidiens de calories et de macronutriments sur l'ensemble des repas de la journée.",
|
||
"removeFailed": "Échec de la suppression",
|
||
"generationFailed": "Échec de la génération",
|
||
"anyDifficulty": "Toute",
|
||
"aiPhaseAnalyzing": "Analyse de vos préférences…",
|
||
"aiPhasePlanning": "Planification du petit-déjeuner, déjeuner et dîner…",
|
||
"aiPhaseSelecting": "Sélection des recettes pour chaque jour…",
|
||
"aiPhaseBalancing": "Équilibrage nutritionnel de la semaine…",
|
||
"aiPhaseFinalizing": "Finalisation de votre planning repas…",
|
||
"newList": "Nouvelle liste",
|
||
"newListTitle": "Nouvelle liste de courses",
|
||
"listNameLabel": "Nom",
|
||
"listNamePlaceholder": "Courses de la semaine",
|
||
"generateFromWeek": "Générer depuis une semaine du planning (facultatif)",
|
||
"generateFromWeekHint": "Sélectionne le lundi de la semaine choisie",
|
||
"generateFromThisWeek": "Ajouter à la liste de courses",
|
||
"generateFromThisWeekHint": "Fusionne les ingrédients de toutes les recettes de cette semaine, additionne les quantités identiques et signale ce que vous avez déjà au garde-manger.",
|
||
"shoppingListWeekName": "Courses pour {week}",
|
||
"listCreateFailed": "Échec de la création",
|
||
"listCreating": "Création…",
|
||
"listCreate": "Créer",
|
||
"pickRecipe": "Choisir une recette",
|
||
"addEntry": "+ Ajouter",
|
||
"removeEntry": "Retirer le repas",
|
||
"markCooked": "Marquer comme cuisiné",
|
||
"markCookedSuccess": "Marqué comme cuisiné",
|
||
"markCookedFailed": "Échec du marquage comme cuisiné"
|
||
},
|
||
"pantry": {
|
||
"title": "Garde-manger",
|
||
"subtitle": "Suivez ce que vous avez en stock",
|
||
"canCook": "Que puis-je cuisiner ?",
|
||
"expiringSoonSuggestionsTitle": "À utiliser bientôt",
|
||
"seeAll": "Tout voir",
|
||
"expiringLeftoversTitle": "Restes bientôt périmés",
|
||
"expiringToday": "À manger aujourd'hui",
|
||
"expiringInDays": "{days}j restants",
|
||
"itemNamePlaceholder": "Nom de l'article",
|
||
"qtyPlaceholder": "Qté",
|
||
"unitPlaceholder": "Unité",
|
||
"add": "Ajouter",
|
||
"addFailed": "Échec de l'ajout",
|
||
"removeFailed": "Échec de la suppression",
|
||
"removeConfirmTitle": "Retirer cet article ?",
|
||
"removeConfirmDescription": "Retirer « {name} » du garde-manger ?",
|
||
"empty": "Aucun article dans le garde-manger.",
|
||
"emptyDescription": "Ajoutez des articles manuellement, ou scannez un code-barres / une photo pour aller plus vite.",
|
||
"expired": "Expiré",
|
||
"expiresInDays": "Expire dans {days}j",
|
||
"expiresOn": "Expire le {date}",
|
||
"printItemCountSingular": "{count} article",
|
||
"printItemCountPlural": "{count} articles",
|
||
"noItems": "Aucun article dans le garde-manger.",
|
||
"colItem": "Article",
|
||
"colQuantity": "Quantité",
|
||
"colExpires": "Expire",
|
||
"expiredDaysAgo": "Expiré il y a {days}j",
|
||
"scan": "Scanner",
|
||
"scanTitle": "Ajouter par scan",
|
||
"scanDescription": "Scannez un code-barres ou prenez une photo pour ajouter rapidement des articles.",
|
||
"scanBarcodeOption": "Scanner un code-barres",
|
||
"scanPhotoOption": "Prendre/importer une photo",
|
||
"scanBarcodeTitle": "Scanner un code-barres",
|
||
"scanBarcodeDescription": "Pointez votre caméra vers un code-barres.",
|
||
"scanConfirmTitle": "Confirmer l'article",
|
||
"scanConfirmDescription": "Vérifiez et modifiez avant d'ajouter au garde-manger.",
|
||
"scanAnalyzingTitle": "Analyse de la photo",
|
||
"scanAnalyzingDescription": "Identification des articles dans votre photo…",
|
||
"scanBack": "Retour",
|
||
"scanAddToPantry": "Ajouter au garde-manger",
|
||
"scanAdded": "Ajouté au garde-manger",
|
||
"scanLookupFailed": "Échec de la recherche du code-barres",
|
||
"scanNotFound": "Produit introuvable. Essayez un scan photo.",
|
||
"scanPhotoFailed": "Échec du scan photo",
|
||
"scanNoItemsFound": "Aucun article reconnu sur cette photo",
|
||
"cameraError": "Impossible d'accéder à la caméra"
|
||
},
|
||
"feed": {
|
||
"title": "Fil d'actualité",
|
||
"followEmpty": "Suivez des chefs pour voir leurs recettes ici.",
|
||
"followEmptyDescription": "Votre fil d'abonnements se remplit dès que vous suivez quelques personnes.",
|
||
"findPeople": "Trouver des personnes à suivre",
|
||
"noNew": "Aucune nouvelle recette de vos abonnements.",
|
||
"following": "Abonnements",
|
||
"trending": "Tendances",
|
||
"trendingEmpty": "Aucune recette tendance cette semaine.",
|
||
"forYou": "Pour vous",
|
||
"forYouEmpty": "Ajoutez des favoris ou notez des recettes pour des suggestions personnalisées.",
|
||
"loading": "Chargement…",
|
||
"loadMore": "Charger plus",
|
||
"loadFailed": "Échec du chargement des recettes. Vérifiez votre connexion et réessayez.",
|
||
"retry": "Réessayer"
|
||
},
|
||
"shoppingLists": {
|
||
"title": "Listes de courses",
|
||
"subtitle": "Planifiez vos courses",
|
||
"empty": "Aucune liste de courses",
|
||
"emptyDescription": "Générez-en une depuis un planning repas, ou créez-en une de zéro.",
|
||
"listEmpty": "Vide",
|
||
"generated": "Générée",
|
||
"shareTitle": "Partager la liste de courses",
|
||
"shareDescription": "Invitez des membres du foyer à voir ou modifier cette liste.",
|
||
"sharedWithYou": "Partagées avec vous",
|
||
"sendToGroceryDelivery": "Envoyer à un service de livraison",
|
||
"copyAsText": "Copier la liste en texte",
|
||
"sendToInstacart": "Envoyer à Instacart",
|
||
"copiedToClipboard": "Liste copiée dans le presse-papiers",
|
||
"exportBuildFailed": "Impossible de générer l'export",
|
||
"instacartNotConfigured": "Instacart n'est pas encore configuré",
|
||
"alreadyInPantry": "Déjà au garde-manger",
|
||
"items": "{checked}/{total} articles",
|
||
"itemsChecked": "{checked}/{total} articles cochés",
|
||
"fromMealPlan": " · Depuis le planning repas",
|
||
"itemCount": "{count} article",
|
||
"itemCountPlural": "{count} articles",
|
||
"addToList": "Ajouter à la liste",
|
||
"dialogTitle": "Ajouter à la liste de courses",
|
||
"dialogDescription": "Ajouter les ingrédients de <strong>{title}</strong> à une liste de courses.",
|
||
"scaledSuffix": "ajustée)",
|
||
"loadingLists": "Chargement de vos listes…",
|
||
"modeExisting": "Ajouter à une liste existante",
|
||
"modeNew": "Créer une nouvelle liste",
|
||
"listNamePlaceholder": "Nom de la liste",
|
||
"ingredientsWillBeAdded": "{count, plural, one {1 ingrédient sera ajouté.} other {{count} ingrédients seront ajoutés.}}",
|
||
"adding": "Ajout…",
|
||
"addIngredients": "Ajouter les ingrédients",
|
||
"addedCount": "{count} ingrédients ajoutés à la liste",
|
||
"actionsMenuLabel": "Actions de la liste",
|
||
"rename": "Renommer",
|
||
"renameListTitle": "Renommer la liste",
|
||
"renameListLabel": "Nom de la liste",
|
||
"renaming": "Enregistrement…",
|
||
"listRenamed": "Liste renommée",
|
||
"listRenameFailed": "Échec du renommage de la liste",
|
||
"deleteListConfirmTitle": "Supprimer la liste ?",
|
||
"deleteListConfirmDescription": "Cette action est irréversible. La liste et tous ses articles seront définitivement supprimés.",
|
||
"listDeleted": "Liste supprimée",
|
||
"listDeleteFailed": "Échec de la suppression de la liste",
|
||
"changeCategory": "Changer de catégorie",
|
||
"deleteItem": "Supprimer l'article",
|
||
"aisleOther": "Autre",
|
||
"newCategoryPlaceholder": "Nouvelle catégorie…",
|
||
"addCategory": "Ajouter",
|
||
"categories": {
|
||
"produce": "Fruits & légumes",
|
||
"dairyEggs": "Produits laitiers & œufs",
|
||
"meatSeafood": "Viande & poisson",
|
||
"bakery": "Boulangerie",
|
||
"frozen": "Surgelés",
|
||
"pantry": "Épicerie",
|
||
"spicesCondiments": "Épices & condiments",
|
||
"beverages": "Boissons"
|
||
}
|
||
},
|
||
"collections": {
|
||
"title": "Collections",
|
||
"subtitle": "Organisez vos recettes favorites en collections",
|
||
"empty": "Aucune collection pour l'instant",
|
||
"emptyDescription": "Regroupez vos recettes par thème, occasion, ou comme bon vous semble.",
|
||
"emptyCollection": "Aucune recette dans cette collection pour l'instant.",
|
||
"public": "Publique",
|
||
"recipeCount": "{count} recette",
|
||
"recipeCountPlural": "{count} recettes",
|
||
"discoverTitle": "Découvrir",
|
||
"discoverSubtitle": "Collections publiques tendances et récemment partagées",
|
||
"myCollectionsLink": "Mes collections",
|
||
"trendingThisWeek": "Tendance cette semaine",
|
||
"recentlyAdded": "Récemment ajoutées",
|
||
"noTrending": "Aucune collection tendance pour l'instant",
|
||
"noRecent": "Aucune collection publique pour l'instant",
|
||
"exportPdf": "Exporter en PDF",
|
||
"shareTitle": "Partager la collection",
|
||
"shareDescription": "Invitez des personnes à voir ou modifier cette collection.",
|
||
"new": "Nouvelle collection",
|
||
"newTitle": "Nouvelle collection",
|
||
"nameLabel": "Nom",
|
||
"namePlaceholder": "Dîners du week-end",
|
||
"descriptionLabel": "Description",
|
||
"descriptionPlaceholder": "Facultatif…",
|
||
"makePublic": "Rendre publique",
|
||
"creating": "Création…",
|
||
"create": "Créer",
|
||
"createFailed": "Échec de la création",
|
||
"forking": "Duplication…",
|
||
"forkCollection": "Dupliquer la collection",
|
||
"forkFailed": "Échec de la duplication"
|
||
},
|
||
"shareDialog": {
|
||
"invite": "Inviter",
|
||
"emailPlaceholder": "Adresse e-mail",
|
||
"owner": "Propriétaire",
|
||
"viewer": "Lecteur",
|
||
"editor": "Éditeur",
|
||
"loadingMembers": "Chargement des membres…",
|
||
"noMembers": "Aucun membre pour l'instant.",
|
||
"invitationSent": "Invitation envoyée",
|
||
"alreadyMember": "Déjà membre",
|
||
"userNotFound": "Utilisateur introuvable",
|
||
"inviteFailed": "Impossible d'inviter cet utilisateur",
|
||
"loadMembersFailed": "Impossible de charger les membres",
|
||
"memberRemoved": "Membre retiré",
|
||
"removeMemberFailed": "Impossible de retirer le membre",
|
||
"enterEmail": "Saisissez une adresse e-mail",
|
||
"publicLinkTitle": "Lien public",
|
||
"publicLinkDescription": "Toute personne disposant du lien peut voir cette liste.",
|
||
"publicLinkToggleFailed": "Impossible de mettre à jour le lien public",
|
||
"copyLink": "Copier le lien",
|
||
"linkCopied": "Lien copié",
|
||
"copyLinkFailed": "Impossible de copier le lien"
|
||
},
|
||
"social": {
|
||
"followed": "Abonné",
|
||
"unfollowed": "Désabonné",
|
||
"commentFailed": "Échec de la publication du commentaire",
|
||
"deleted": "Supprimé",
|
||
"ratingSaved": "Note enregistrée",
|
||
"collectionCreated": "Collection créée",
|
||
"collectionForked": "Collection dupliquée dans votre bibliothèque",
|
||
"inviteSent": "Invitation envoyée",
|
||
"memberRemoved": "Membre supprimé",
|
||
"replyPlaceholder": "Répondre…",
|
||
"commentPlaceholder": "Partagez vos impressions…",
|
||
"commentsTitle": "Commentaires",
|
||
"noCommentsYet": "Aucun commentaire pour l'instant. Soyez le premier !",
|
||
"deleteCommentTitle": "Supprimer le commentaire ?",
|
||
"deleteCommentDescription": "Cette action est irréversible.",
|
||
"blockConfirmTitle": "Bloquer @{username} ?",
|
||
"blockConfirmDescription": "Cette personne ne pourra plus vous suivre ni commenter vos recettes.",
|
||
"blockConfirmAction": "Bloquer",
|
||
"loadMoreComments": "Charger plus de commentaires",
|
||
"loadingMoreComments": "Chargement…",
|
||
"postButton": "Publier",
|
||
"postingButton": "Publication…",
|
||
"replyButton": "Répondre",
|
||
"reportButton": "Signaler",
|
||
"ratingFailed": "Échec de la notation",
|
||
"cookedItPrompt": "Vous l'avez cuisiné ? Notez-la et partagez une photo",
|
||
"reviewTextPlaceholder": "Comment était le résultat ?",
|
||
"reviewPhotoAdd": "Ajouter une photo",
|
||
"reviewPhotoUploading": "Envoi…",
|
||
"reviewPhotoFailed": "Échec de l'envoi de la photo",
|
||
"reviewSubmit": "Publier l'avis",
|
||
"reviewSubmitting": "Publication…",
|
||
"reviewsTitle": "{count, plural, one {# avis} other {# avis}}",
|
||
"justNow": "à l'instant",
|
||
"minutesAgo": "il y a {mins} min",
|
||
"hoursAgo": "il y a {hours} h",
|
||
"daysAgo": "il y a {days} j",
|
||
"signInToReact": "Connectez-vous pour réagir aux commentaires",
|
||
"reactionFailed": "Échec de la mise à jour de la réaction",
|
||
"addReaction": "Ajouter la réaction {type}",
|
||
"removeReaction": "Retirer la réaction {type}",
|
||
"favoriteAdd": "Favoris",
|
||
"favoriteRemove": "Retirer des favoris"
|
||
},
|
||
"cookingMode": {
|
||
"cooking": "En cuisine",
|
||
"stepOf": "Étape {current} sur {total}",
|
||
"batchPrepLabel": "Préparation",
|
||
"ingredients": "Ingrédients",
|
||
"startTimer": "Démarrer le minuteur",
|
||
"timerDone": "Terminé",
|
||
"pause": "Pause",
|
||
"reset": "Réinitialiser",
|
||
"previous": "Précédent",
|
||
"next": "Suivant",
|
||
"finish": "Terminé !",
|
||
"voiceNotSupported": "Commandes vocales non supportées dans ce navigateur",
|
||
"voiceError": "Erreur vocale — réessayez",
|
||
"enableVoice": "Activer les commandes vocales",
|
||
"stopVoice": "Désactiver les commandes vocales",
|
||
"toggleIngredients": "Afficher les ingrédients",
|
||
"pageTitle": "Cuisiner : {title}",
|
||
"pageTitleFallback": "Mode cuisine",
|
||
"shortcutsTitle": "Raccourcis et commandes",
|
||
"keyboardSection": "Clavier",
|
||
"voiceSection": "Commandes vocales",
|
||
"enableMicFirst": "Activez le micro via le bouton micro d'abord.",
|
||
"stepRepeatPrefix": "Étape {n} : ",
|
||
"shortcuts": {
|
||
"nextStep": "Étape suivante",
|
||
"prevStep": "Étape précédente",
|
||
"startTimer": "Démarrer le minuteur",
|
||
"toggleHelp": "Afficher/masquer ce panneau",
|
||
"exitMode": "Quitter le mode cuisine"
|
||
},
|
||
"voiceLabels": {
|
||
"nextCmd": "suivant / continuer",
|
||
"prevCmd": "précédent / retour",
|
||
"timerCmd": "minuteur / démarrer",
|
||
"stopCmd": "arrêter / pause",
|
||
"resetCmd": "réinitialiser",
|
||
"repeatCmd": "répéter / encore",
|
||
"nextLabel": "Étape suivante",
|
||
"prevLabel": "Étape précédente",
|
||
"timerLabel": "Démarrer le minuteur",
|
||
"stopLabel": "Mettre en pause",
|
||
"resetLabel": "Réinitialiser le minuteur",
|
||
"repeatLabel": "Relire l'étape"
|
||
}
|
||
},
|
||
"settingsForm": {
|
||
"notificationCategories": {
|
||
"title": "Catégories de notifications",
|
||
"description": "Choisissez les notifications push que vous souhaitez recevoir.",
|
||
"follow": "Nouveaux abonnés",
|
||
"comment": "Commentaires sur vos recettes",
|
||
"reply": "Réponses à vos commentaires",
|
||
"reaction": "Réactions à vos commentaires",
|
||
"rating": "Notes sur vos recettes",
|
||
"mention": "Mentions dans les commentaires",
|
||
"leftoverExpiring": "Restes bientôt périmés",
|
||
"shoppingList": "Mises à jour des listes de courses partagées"
|
||
},
|
||
"profile": "Profil",
|
||
"changePhoto": "Changer la photo",
|
||
"removePhoto": "Supprimer la photo",
|
||
"avatarUploadSuccess": "Photo de profil mise à jour",
|
||
"avatarUploadFailed": "Échec de la mise à jour de la photo de profil",
|
||
"avatarRemoved": "Photo de profil supprimée",
|
||
"displayName": "Nom d'affichage",
|
||
"email": "E-mail",
|
||
"emailReadOnly": "L'e-mail ne peut pas être modifié ici.",
|
||
"saving": "Enregistrement…",
|
||
"title": "Paramètres",
|
||
"subtitle": "Gérez votre compte et vos préférences",
|
||
"language": "Langue",
|
||
"languageDescription": "Choisissez la langue de l'application et du contenu généré par l'IA.",
|
||
"changeEmail": "Changer l'e-mail",
|
||
"newEmail": "Nouvelle adresse e-mail",
|
||
"changeEmailDescription": "Un lien de vérification sera envoyé à votre nouvelle adresse avant que la modification soit prise en compte.",
|
||
"sendVerification": "Envoyer la vérification",
|
||
"sendingVerification": "Envoi…",
|
||
"emailChangeSent": "E-mail de vérification envoyé. Vérifiez votre boîte de réception.",
|
||
"emailChangeFailed": "Échec de l'envoi de l'e-mail de vérification.",
|
||
"changePassword": "Changer le mot de passe",
|
||
"currentPassword": "Mot de passe actuel",
|
||
"newPassword": "Nouveau mot de passe",
|
||
"confirmPassword": "Confirmer le nouveau mot de passe",
|
||
"passwordMismatch": "Les mots de passe ne correspondent pas.",
|
||
"changingPassword": "Modification…",
|
||
"changePasswordButton": "Changer le mot de passe",
|
||
"passwordChanged": "Mot de passe modifié avec succès.",
|
||
"passwordChangeFailed": "Échec de la modification du mot de passe.",
|
||
"downloadData": "Télécharger mes données",
|
||
"downloadDataDescription": "Obtenez un export JSON de toutes les données personnelles qu'Epicure détient sur vous — votre profil, vos recettes, votre activité et vos paramètres.",
|
||
"downloadDataButton": "Télécharger mes données",
|
||
"webhookCreateFailed": "Échec de la création du webhook",
|
||
"webhookDeleteFailed": "Échec de la suppression du webhook",
|
||
"webhookUpdateFailed": "Échec de la mise à jour du webhook",
|
||
"webhookUrlPlaceholder": "https://exemple.fr/webhook",
|
||
"webhookAdding": "Ajout…",
|
||
"webhookAddButton": "Ajouter un webhook",
|
||
"webhookDocsLink": "Voir la doc webhook et l'intégration Zapier →",
|
||
"endpointUrlLabel": "URL de destination",
|
||
"eventsLabel": "Événements",
|
||
"eventsHint": "Sélectionnez les événements qui déclenchent ce webhook. Laissez tout décoché pour recevoir tous les événements.",
|
||
"secretRevealNotice": "Enregistrez ce secret de signature — il ne sera plus affiché.",
|
||
"secretUsageHint": "Utilisez-le pour vérifier l'en-tête X-Epicure-Signature des requêtes entrantes.",
|
||
"noWebhooks": "Aucun webhook pour l'instant.",
|
||
"addedOn": "Ajouté le {date}",
|
||
"active": "Actif",
|
||
"inactive": "Inactif",
|
||
"allEvents": "Tous les événements",
|
||
"deliveries": "Livraisons",
|
||
"disable": "Désactiver",
|
||
"enable": "Activer",
|
||
"noDeliveriesYet": "Aucune livraison pour l'instant.",
|
||
"redeliverySuccess": "Renvoi mis en file d'attente",
|
||
"redeliveryFailed": "Échec du renvoi",
|
||
"apiKeyCreateFailed": "Échec de la création de la clé API",
|
||
"apiKeyRevokeFailed": "Échec de la révocation de la clé API",
|
||
"apiKeyNamePlaceholder": "ex. Mon application",
|
||
"apiKeyNameLabel": "Nom de la clé",
|
||
"apiKeyCreating": "Création…",
|
||
"apiKeyCreate": "Créer",
|
||
"apiKeyRevealNotice": "Enregistrez cette clé — elle ne sera plus affichée.",
|
||
"copy": "Copier",
|
||
"copied": "Copié !",
|
||
"dismiss": "Ignorer",
|
||
"noApiKeys": "Aucune clé API pour l'instant.",
|
||
"createdOn": "Créée le {date}",
|
||
"lastUsedOn": "Utilisée le {date}",
|
||
"neverUsed": "Jamais utilisée",
|
||
"revoke": "Révoquer",
|
||
"apiKeyScopeFull": "Accès complet",
|
||
"apiKeyScopeRead": "Lecture seule",
|
||
"apiKeyScopeHelp": "Les clés en lecture seule ne peuvent faire que des requêtes GET — elles ne peuvent rien créer, modifier ou supprimer.",
|
||
"copyFailed": "Échec de la copie dans le presse-papiers",
|
||
"byokSaved": "Clé {provider} enregistrée",
|
||
"byokSaveFailed": "Échec de l'enregistrement de la clé",
|
||
"byokRemoved": "Clé {provider} supprimée",
|
||
"byokRemoveFailed": "Échec de la suppression de la clé",
|
||
"byokConfigured": "Configurée",
|
||
"byokOllamaHint": "Définie via la variable d'environnement OLLAMA_BASE_URL",
|
||
"byokSaving": "Enregistrement…",
|
||
"byokSave": "Enregistrer",
|
||
"byokFooter": "Vos clés sont chiffrées au repos. Une fois définies, elles remplacent les clés par défaut de l'application pour votre compte.",
|
||
"modelSaved": "Préférences de modèle enregistrées",
|
||
"modelSaveFailed": "Échec de l'enregistrement",
|
||
"useCaseText": "Génération de texte",
|
||
"useCaseTextDesc": "Génération de recettes, variations, traductions, adaptation",
|
||
"useCaseVision": "Vision / import photo",
|
||
"useCaseVisionDesc": "Reconnaissance de plats, import de recette depuis une photo",
|
||
"useCaseMealPlan": "Planning repas",
|
||
"useCaseMealPlanDesc": "Génération du planning repas hebdomadaire",
|
||
"providerLabel": "Fournisseur",
|
||
"modelLabel": "Modèle",
|
||
"defaultAuto": "Par défaut (auto)",
|
||
"modelDefault": "Par défaut",
|
||
"modelSaving": "Enregistrement…",
|
||
"saveModelPrefs": "Enregistrer les préférences de modèle",
|
||
"modelDefaultPlaceholder": "Par défaut",
|
||
"modelNamePlaceholder": "ex. llama3.2",
|
||
"userUpdated": "Utilisateur mis à jour avec succès",
|
||
"userUpdateFailed": "Échec de l'enregistrement",
|
||
"adminSettingsSaved": "Paramètres enregistrés",
|
||
"adminSettingsFailed": "Échec de l'enregistrement des paramètres",
|
||
"nutritionGoalsSaved": "Objectifs nutritionnels enregistrés",
|
||
"bio": "Bio",
|
||
"publicBio": "Bio publique",
|
||
"publicBioDescription": "Affichée sur votre profil public.",
|
||
"publicBioPlaceholder": "Parlez de vous aux autres cuisiniers…",
|
||
"privateBio": "Contexte IA (privé)",
|
||
"privateBioDescription": "Jamais visible publiquement. Injecté dans les prompts IA pour personnaliser les suggestions — ajoutez vos préférences alimentaires, équipements, niveau de cuisine, allergies, etc.",
|
||
"privateBioPlaceholder": "ex. Je suis végétarien, j'ai un robot pâtissier et une friteuse à air, niveau intermédiaire, allergique aux fruits à coque, je préfère les saveurs méditerranéennes…",
|
||
"privateAccount": "Compte privé",
|
||
"privateAccountDescription": "Une fois activé, votre profil et vos recettes n'apparaîtront plus dans la recherche ni dans les découvertes (Explorer, Tendances, Pour vous). Les personnes qui vous suivent déjà continueront de voir vos recettes."
|
||
},
|
||
"profilePage": {
|
||
"tabRecipes": "Recettes",
|
||
"tabHistory": "Historique de cuisine",
|
||
"tabPhotos": "Photos",
|
||
"statTotalCooked": "Total de fois cuisinées",
|
||
"statStreak": "Série en cours",
|
||
"statLastCooked": "Dernière cuisson",
|
||
"streakDays": "{count, plural, one {# jour} other {# jours}}",
|
||
"noneYet": "Aucune pour le moment",
|
||
"recentActivity": "Activité récente",
|
||
"noHistoryYet": "Aucun historique de cuisine pour le moment.",
|
||
"noPhotosYet": "Aucune photo pour le moment.",
|
||
"previous": "Précédent",
|
||
"next": "Suivant",
|
||
"pageOf": "Page {page} sur {total}"
|
||
}
|
||
}
|