fix(i18n): translate remaining recipe card/detail strings, localize AI responses

Recipe cards, the recipe detail page, and meal planner still rendered raw
"{n} servings"/"{n}m cook"/"{n} srv" text and untranslated difficulty labels
outside the earlier i18n pass. Also wires the user's locale into AI features
that previously always answered in English regardless of app language:
recipe chat, ingredient substitution, recipe ideas, and generate-from-idea.
The recipe-language picker in the AI generate dialog now defaults to the
user's locale instead of always defaulting to English.
This commit is contained in:
Arnaud
2026-07-02 08:25:51 +02:00
parent 01fdbb880b
commit 2154512e54
15 changed files with 64 additions and 24 deletions
+6 -6
View File
@@ -28,7 +28,7 @@ import { CommentsSection } from "@/components/social/comments-section";
import { getPublicUrl } from "@/lib/storage";
import { cn } from "@/lib/utils";
import { RecipeChatPanel } from "@/components/recipe/recipe-chat-panel";
import { getMessages } from "@/lib/i18n/server";
import { getMessages, formatMessage } from "@/lib/i18n/server";
type Params = { params: Promise<{ id: string }> };
@@ -175,26 +175,26 @@ export default async function RecipePage({ params }: Params) {
<div className="flex flex-wrap items-center gap-3 text-sm">
{recipe.difficulty && (
<Badge variant={DIFFICULTY_COLOR[recipe.difficulty]}>{recipe.difficulty}</Badge>
<Badge variant={DIFFICULTY_COLOR[recipe.difficulty]}>{m.recipe.difficulty[recipe.difficulty]}</Badge>
)}
<span className="flex items-center gap-1 text-muted-foreground">
<Users className="h-4 w-4" />
{recipe.baseServings} servings
{formatMessage(m.recipe.servings, { count: recipe.baseServings })}
</span>
{recipe.prepMins && (
<span className="flex items-center gap-1 text-muted-foreground">
<Clock className="h-4 w-4" />
{recipe.prepMins}m prep
{formatMessage(m.recipe.prep, { mins: recipe.prepMins })}
</span>
)}
{recipe.cookMins && (
<span className="flex items-center gap-1 text-muted-foreground">
<ChefHat className="h-4 w-4" />
{recipe.cookMins}m cook
{formatMessage(m.recipe.cook, { mins: recipe.cookMins })}
</span>
)}
{totalMins > 0 && recipe.prepMins && recipe.cookMins && (
<span className="text-muted-foreground">({totalMins}m total)</span>
<span className="text-muted-foreground">({formatMessage(m.recipe.total, { mins: totalMins })})</span>
)}
<span className="flex items-center gap-1 text-muted-foreground ml-auto">
<VisibilityIcon className="h-4 w-4" />