i18n(app-svep) + i18n-vakt: hela mobil-UI:t översatt + CI-vakt mot regress

- Svepte 51 hårdkodade strängar -> t() över konto, sök/bläddra, sparade recept,
  kök, planera, skanna, byt måltid, inköp, minne, cooking, api-fel (+ locLabel/
  kategorier via nycklar). 47 nya nycklar, översatta till alla 12 språk.
- NY: apps/mobile/scripts/i18n-check.mjs (i18n:check) – fäller bygget om ett språk
  saknar en nyckel, en använd nyckel saknas, eller det finns hårdkodad UI-text.
  Wire:ad i CI (.github/workflows/ci.yml) efter typecheck. => 'lägg till språk'
  blir: kör vakten, den listar exakt vad som fattas. Aldrig mer leta för hand.
- Prettier-fixade 5 filer från tidigare leveranser så format:check blir grön.
- submit-recipe fri-text-payload + firebase dev-stubs markerade // i18n-ignore.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Claude
2026-08-21 01:50:08 +00:00
parent cadaa1a41f
commit 2d59a3e636
36 changed files with 1123 additions and 288 deletions
+47
View File
@@ -51,6 +51,53 @@
"common.add": "Ajouter",
"common.back": "Retour",
"common.cancel": "Annuler",
"common.remove": "Supprimer",
"common.all": "Tous",
"auth.tagline": "Moins de gaspillage, moins de stress, plus d'argent dans votre portefeuille",
"auth.passwordMin8": "Le mot de passe doit contenir au moins 8 caractères.",
"auth.passwordMismatch": "Les mots de passe ne correspondent pas.",
"auth.repeatPassword": "Confirmer le mot de passe",
"plan.swapDish": "Changer de plat",
"scan.maxTitle": "Terminé",
"scan.maxBody": "Max {max} photos pour ce scan analyse en cours.",
"scan.photoTaken": "Photo {count} prise",
"scan.multiAngleHint": "N'hésitez pas à prendre plusieurs angles du même emplacement l'application liste chaque article une seule fois. Chaque photo compte comme un scan.",
"scan.takeAnother": "En prendre une autre",
"scan.analyzeCount": "Analyser ({count})",
"scan.tips.merge": "Réfrigérateur/congélateur/garde-manger : prenez plusieurs photos dans le même scan l'application fusionne les doublons.",
"cooking.timerHint": "Durée approximative de l'étape utilisez le minuteur de votre téléphone.",
"kitchen.deleteConfirm": "Supprimer les articles sélectionnés de {label} ?",
"kitchen.scopeSearch": "la recherche",
"kitchen.scopeAll": "tout le stock",
"kitchen.scopeSelection": "la sélection",
"kitchen.searchPlaceholder": "Rechercher un article…",
"kitchen.clearList": "Vider la liste",
"kitchen.empty": "Aucun article à afficher. Scannez ou ajoutez des articles.",
"kitchen.pastBefore": "à consommer avant",
"memory.trainingNote": "La mémoire personnelle n'est jamais utilisée comme données d'entraînement sans consentement distinct.",
"recipe.source": "Source : {name}",
"recipes.sub.bread": "Pain",
"recipes.sub.bun": "Brioches",
"recipes.sub.pie": "Tartes",
"recipes.sub.cake": "Gâteaux",
"recipes.sub.cookie": "Biscuits",
"recipes.searchPlaceholder": "Rechercher une recette…",
"recipes.emptyCategory": "Aucune recette dans cette catégorie pour l'instant elles apparaîtront à mesure que le catalogue s'agrandit.",
"savedRecipes.searchPlaceholder": "Rechercher parmi vos recettes enregistrées",
"savedRecipes.empty": "Vous n'avez pas encore de recettes enregistrées. Appuyez sur ☆ Enregistrer sur une recette pour la retrouver ici.",
"savedRecipes.emptySearch": "Aucune recette enregistrée ne correspond à votre recherche.",
"shopping.removeConfirm": "Supprimer l'article de la liste ?",
"swap.addTitle": "Ajouter un repas",
"swap.swapTitle": "Remplacer le repas",
"swap.chooseFor": "Choisissez un plat pour {meal} ou recherchez n'importe quel plat.",
"swap.chooseOther": "Choisissez un autre plat pour {meal} ou recherchez n'importe quel plat.",
"swap.mealLunch": "le déjeuner",
"swap.mealBreakfast": "le petit-déjeuner",
"swap.mealDinner": "le dîner",
"swap.searchPlaceholder": "Rechercher parmi toutes les recettes …",
"swap.showingResults": "Affichage des résultats pour ”{query}”.",
"swap.clearHint": "Videz le champ de recherche et lancez une recherche vide pour revoir les suggestions.",
"errors.uploadTimeout": "L'envoi a pris trop de temps vérifiez votre réseau et réessayez.",
"common.done": "Terminé",
"common.error": "Un problème est survenu. Réessayez.",
"common.estimate": "Estimation",