fix: mobile layout fixes, i18n coverage, and recipe share link
Mobile:
- Recipes search bar full-width on mobile instead of capped narrow
- Cook mode ingredients panel stacks above the step instead of
squeezing it into a narrow column
- Version history Compare/Restore buttons wrap onto their own row
- Recipe edit ingredient fields wrap instead of forcing horizontal
scroll on narrow viewports
i18n: translates remaining hardcoded strings across recipes
filter/sort, adapt-recipe and AI variations dialogs, the full
settings section (sidebar + 6 sub-pages + BYOK/model-prefs/
API-keys/webhooks managers), explore tab, collections (new/fork/
share dialogs), meal planning (planner, AI generation phases, new
shopping list, shared-plan view), photo import, recipe bulk-select
toolbar, and recipe action-button tooltips. Also fixes the recipes
page subtitle, which wasn't just unworded but missing its {count}
interpolation entirely — it always rendered as the bare word
"results" regardless of how many recipes existed.
Feature: adds a ShareRecipeButton that copies the public /r/{id}
link to the clipboard, with a notice when the recipe isn't Public
yet.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,7 @@ import { MealPlanner } from "@/components/meal-plan/meal-planner";
|
||||
import { ShareMealPlanButton } from "@/components/meal-plan/share-meal-plan-button";
|
||||
import { WeeklyNutritionBar } from "@/components/nutrition/weekly-nutrition-bar";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { getMessages, formatMessage } from "@/lib/i18n/server";
|
||||
|
||||
export const metadata: Metadata = { title: "Meal Plan" };
|
||||
|
||||
@@ -39,6 +40,7 @@ export default async function MealPlanPage({
|
||||
const { week } = await searchParams;
|
||||
const session = await auth.api.getSession({ headers: await headers() });
|
||||
if (!session) return null;
|
||||
const msgs = getMessages((session.user as { locale?: string }).locale);
|
||||
|
||||
const monday = getMonday(week);
|
||||
const weekStart = toDateStr(monday);
|
||||
@@ -83,18 +85,18 @@ export default async function MealPlanPage({
|
||||
<div className="space-y-6">
|
||||
<div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold tracking-tight">Meal Plan</h1>
|
||||
<h1 className="text-3xl font-bold tracking-tight">{msgs.mealPlan.title}</h1>
|
||||
<p className="text-muted-foreground mt-1">{label}</p>
|
||||
</div>
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<ShareMealPlanButton weekStart={weekStart} />
|
||||
<Link href="/shopping-lists" className={cn(buttonVariants({ variant: "outline", size: "sm" }))}>
|
||||
<ShoppingCart className="h-4 w-4" />
|
||||
Shopping lists
|
||||
{msgs.mealPlan.shoppingLists}
|
||||
</Link>
|
||||
<Link href={`/print/meal-plan?week=${weekStart}`} target="_blank" className={cn(buttonVariants({ variant: "outline", size: "sm" }))}>
|
||||
<Printer className="h-4 w-4" />
|
||||
Print
|
||||
{msgs.common.print}
|
||||
</Link>
|
||||
<Link href={`/meal-plan?week=${prevWeek}`} className={cn(buttonVariants({ variant: "outline", size: "sm" }))}>
|
||||
<ChevronLeft className="h-4 w-4" />
|
||||
@@ -110,17 +112,19 @@ export default async function MealPlanPage({
|
||||
|
||||
{sharedMemberships.length > 0 && (
|
||||
<div className="space-y-3">
|
||||
<h2 className="text-sm font-semibold text-muted-foreground">Shared with you</h2>
|
||||
<h2 className="text-sm font-semibold text-muted-foreground">{msgs.mealPlan.sharedWithYou}</h2>
|
||||
<div className="space-y-2 max-w-lg">
|
||||
{sharedMemberships.map((m) => (
|
||||
{sharedMemberships.map((membership) => (
|
||||
<Link
|
||||
key={m.id}
|
||||
href={`/meal-plan/shared/${m.mealPlan.id}`}
|
||||
key={membership.id}
|
||||
href={`/meal-plan/shared/${membership.mealPlan.id}`}
|
||||
className="flex items-center justify-between rounded-xl border p-4 hover:shadow-sm transition-shadow"
|
||||
>
|
||||
<div>
|
||||
<p className="font-medium">{`${m.mealPlan.user?.name ?? "Unknown"}'s plan`}</p>
|
||||
<p className="text-sm text-muted-foreground">Week of {m.mealPlan.weekStart} · {m.role}</p>
|
||||
<p className="font-medium">{formatMessage(msgs.mealPlan.sharedPlanOf, { name: membership.mealPlan.user?.name ?? "?" })}</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{formatMessage(msgs.mealPlan.weekOf, { date: membership.mealPlan.weekStart })} · {msgs.shareDialog[membership.role]}
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user