feat(i18n): translate hardcoded strings across print, public recipe, and recipe management UI
Wires dozens of components and server pages to next-intl instead of hardcoded English text, and adds a lightweight getMessages/formatMessage helper for server components (print pages, public recipe page, cook metadata) since next-intl/server isn't wired into this app's routing. Backfills missing en/fr message keys that existing code already referenced but fr.json lacked.
This commit is contained in:
@@ -44,6 +44,10 @@
|
||||
"pairingGenerateFailed": "Failed to generate \"{name}\"",
|
||||
"pairingSaveFailed": "Failed to save \"{name}\"",
|
||||
"pairingSuccess": "Recipe generated — review before publishing",
|
||||
"pairingBulkSuccess": "{count} recipes generated — find them in your library",
|
||||
"cookAction": "Cook",
|
||||
"adaptConstraintPlaceholder": "e.g. Make it vegan, lower the calories, use pantry staples only, gluten-free…",
|
||||
"photoImportFailed": "Failed to import recipe from photo.",
|
||||
"shoppingListCreateFailed": "Failed to create list",
|
||||
"shoppingListAddFailed": "Failed to add ingredients",
|
||||
"bulkDeleted": "{count, plural, one {1 recipe deleted} other {{count} recipes deleted}}",
|
||||
@@ -136,6 +140,60 @@
|
||||
"metric": "Metric",
|
||||
"imperial": "Imperial"
|
||||
},
|
||||
"print": {
|
||||
"footer": "Printed from Epicure",
|
||||
"day": "Day",
|
||||
"srv": " · {count} srv",
|
||||
"days": {
|
||||
"mon": "Monday",
|
||||
"tue": "Tuesday",
|
||||
"wed": "Wednesday",
|
||||
"thu": "Thursday",
|
||||
"fri": "Friday",
|
||||
"sat": "Saturday",
|
||||
"sun": "Sunday"
|
||||
}
|
||||
},
|
||||
"publicRecipe": {
|
||||
"publicRecipeBy": "Public recipe by",
|
||||
"viewInLibrary": "View in your library",
|
||||
"signUpFree": "Sign up free",
|
||||
"logIn": "Log in",
|
||||
"wantToSave": "Want to save this recipe?",
|
||||
"wantToSaveDescription": "Create a free account to save recipes, scale servings, and build your own library.",
|
||||
"getStartedFree": "Get started free"
|
||||
},
|
||||
"substitute": {
|
||||
"fetchError": "Couldn't fetch substitutes.",
|
||||
"titleFor": "Substitute for {ingredient}",
|
||||
"substitutesFor": "Substitutes for",
|
||||
"finding": "Finding substitutes…",
|
||||
"noneFound": "No substitutions found."
|
||||
},
|
||||
"recipeChat": {
|
||||
"sorry": "Sorry, I couldn't answer that.",
|
||||
"error": "Something went wrong. Please try again.",
|
||||
"suggestion1": "Can I substitute any ingredients?",
|
||||
"suggestion2": "How do I know when it's done?",
|
||||
"suggestion3": "Can I make this ahead of time?",
|
||||
"suggestion4": "What can I serve with this?",
|
||||
"ariaLabel": "Ask AI about this recipe",
|
||||
"title": "Ask about this recipe",
|
||||
"intro": "Ask anything about this recipe — ingredients, techniques, substitutions, timing…",
|
||||
"inputPlaceholder": "Ask a question…"
|
||||
},
|
||||
"servingScaler": {
|
||||
"servings": "Servings",
|
||||
"reset": "Reset",
|
||||
"aiScale": "AI Scale",
|
||||
"scaling": "Scaling…",
|
||||
"aiScaledNote": "AI-scaled quantities shown below"
|
||||
},
|
||||
"explore": {
|
||||
"searchPlaceholder": "Search public recipes…",
|
||||
"maxMinutes": "Max minutes",
|
||||
"aiSearchPlaceholder": "e.g. quick weeknight dinners, Italian comfort food…"
|
||||
},
|
||||
"common": {
|
||||
"loading": "Loading…",
|
||||
"error": "Something went wrong",
|
||||
@@ -220,7 +278,8 @@
|
||||
"createFirst": "Create your first recipe",
|
||||
"resultSingular": "result",
|
||||
"resultPlural": "results",
|
||||
"for": "for"
|
||||
"for": "for",
|
||||
"filterByTag": "Filter by tag…"
|
||||
},
|
||||
"recipeForm": {
|
||||
"titleLabel": "Title *",
|
||||
@@ -244,6 +303,9 @@
|
||||
"ingredient": "Ingredient",
|
||||
"note": "Note",
|
||||
"addIngredient": "Add ingredient",
|
||||
"setCover": "Set as cover",
|
||||
"removePhoto": "Remove",
|
||||
"expand": "Expand",
|
||||
"steps": "Steps",
|
||||
"stepPlaceholder": "Step {n}…",
|
||||
"timerSeconds": "Timer (s)",
|
||||
@@ -277,6 +339,11 @@
|
||||
"noRecipes": "No recipes found",
|
||||
"addFailed": "Failed to add",
|
||||
"addedToPantry": "{count, plural, one {1 item added to pantry} other {{count} items added to pantry}}",
|
||||
"moveToPantryFailed": "Failed to move items to pantry",
|
||||
"aisleOther": "Other",
|
||||
"listEmptyState": "This list is empty.",
|
||||
"checkedCount": "{checked}/{total} checked",
|
||||
"moveToPantry": "Move {count} to pantry",
|
||||
"listCreated": "List created",
|
||||
"days": {
|
||||
"mon": "Mon",
|
||||
@@ -326,7 +393,21 @@
|
||||
"empty": "No shopping lists yet",
|
||||
"listEmpty": "Empty",
|
||||
"generated": "Generated",
|
||||
"items": "{checked}/{total} items"
|
||||
"items": "{checked}/{total} items",
|
||||
"itemsChecked": "{checked}/{total} items checked",
|
||||
"fromMealPlan": " · From meal plan",
|
||||
"addToList": "Add to list",
|
||||
"dialogTitle": "Add to shopping list",
|
||||
"dialogDescription": "Add the ingredients of <strong>{title}</strong> to a shopping list.",
|
||||
"scaledSuffix": "scaled)",
|
||||
"loadingLists": "Loading your lists…",
|
||||
"modeExisting": "Add to existing list",
|
||||
"modeNew": "Create new list",
|
||||
"listNamePlaceholder": "List name",
|
||||
"ingredientsWillBeAdded": "{count, plural, one {1 ingredient will be added.} other {{count} ingredients will be added.}}",
|
||||
"adding": "Adding…",
|
||||
"addIngredients": "Add ingredients",
|
||||
"addedCount": "{count} ingredients added to list"
|
||||
},
|
||||
"collections": {
|
||||
"title": "Collections",
|
||||
@@ -345,7 +426,9 @@
|
||||
"collectionCreated": "Collection created",
|
||||
"collectionForked": "Collection forked to your library",
|
||||
"inviteSent": "Invitation sent",
|
||||
"memberRemoved": "Member removed"
|
||||
"memberRemoved": "Member removed",
|
||||
"replyPlaceholder": "Reply…",
|
||||
"commentPlaceholder": "Share your thoughts…"
|
||||
},
|
||||
"cookingMode": {
|
||||
"cooking": "Cooking",
|
||||
@@ -363,6 +446,8 @@
|
||||
"enableVoice": "Enable voice control",
|
||||
"stopVoice": "Stop voice",
|
||||
"toggleIngredients": "Toggle ingredients",
|
||||
"pageTitle": "Cooking: {title}",
|
||||
"pageTitleFallback": "Cooking Mode",
|
||||
"shortcutsTitle": "Shortcuts & commands",
|
||||
"keyboardSection": "Keyboard",
|
||||
"voiceSection": "Voice commands",
|
||||
@@ -423,8 +508,16 @@
|
||||
"redeliveryFailed": "Failed to redeliver",
|
||||
"apiKeyCreateFailed": "Failed to create API key",
|
||||
"apiKeyRevokeFailed": "Failed to revoke API key",
|
||||
"apiKeyNamePlaceholder": "e.g. My app",
|
||||
"webhookUrlPlaceholder": "https://example.com/webhook",
|
||||
"webhookAdding": "Adding…",
|
||||
"webhookAddButton": "Add webhook",
|
||||
"modelDefaultPlaceholder": "Default",
|
||||
"modelNamePlaceholder": "e.g. llama3.2",
|
||||
"copyFailed": "Failed to copy to clipboard",
|
||||
"byokSaved": "{provider} key saved",
|
||||
"byokSaveFailed": "Failed to save key",
|
||||
"byokRemoved": "{provider} key removed",
|
||||
"byokRemoveFailed": "Failed to remove key",
|
||||
"modelSaved": "Model preferences saved",
|
||||
"modelSaveFailed": "Failed to save",
|
||||
|
||||
Reference in New Issue
Block a user