Files
Epicure/apps/web/app/(app)/recipes/[id]/cook/page.tsx
T
Arnaud ba1614073b feat: adapt recipe surfaces for batch-cook sessions
- Recipes page action buttons reordered/restyled to push AI generation
  and batch cooking ahead of manual recipe creation.
- Recipe detail page hides meal/drink pairing (doesn't make sense for
  a multi-dish batch session).
- Print pages force light mode regardless of app theme (dark bg +
  hardcoded dark text was unreadable) and render sectioned steps +
  dishes/storage for batch-cook recipes.
- Markdown export mirrors the same sectioned structure.
- Cooking mode tags each step with which dish(es) it belongs to.
- Meal planner: mealPlanEntries.batchDishId lets a slot point at one
  specific dish within a batch session; picking a batch-cook recipe
  now prompts for which dish, and the grid shows the dish name.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-12 02:32:57 +02:00

54 lines
1.9 KiB
TypeScript

import { notFound } from "next/navigation";
import { headers } from "next/headers";
import { auth } from "@/lib/auth/server";
import { db, recipes, eq, and } from "@epicure/db";
import { CookingMode } from "@/components/cooking-mode/cooking-mode";
import { getMessages, formatMessage } from "@/lib/i18n/server";
type Params = { params: Promise<{ id: string }> };
export async function generateMetadata({ params }: Params) {
const { id } = await params;
const session = await auth.api.getSession({ headers: await headers() });
const m = getMessages((session?.user as { locale?: string } | undefined)?.locale);
const recipe = await db.query.recipes.findFirst({ where: eq(recipes.id, id) });
return { title: recipe ? formatMessage(m.cookingMode.pageTitle, { title: recipe.title }) : m.cookingMode.pageTitleFallback };
}
export default async function CookPage({ params }: Params) {
const { id } = await params;
const session = await auth.api.getSession({ headers: await headers() });
if (!session) return null;
const recipe = await db.query.recipes.findFirst({
where: and(eq(recipes.id, id), eq(recipes.authorId, session.user.id)),
with: {
steps: { orderBy: (t, { asc }) => asc(t.order) },
ingredients: { orderBy: (t, { asc }) => asc(t.order) },
},
});
if (!recipe || recipe.steps.length === 0) notFound();
const unitPref = (session.user as { unitPref?: string }).unitPref === "imperial" ? "imperial" : "metric";
return (
<CookingMode
recipeId={id}
recipeTitle={recipe.title}
unitPref={unitPref}
steps={recipe.steps.map((s) => ({
id: s.id,
instruction: s.instruction,
timerSeconds: s.timerSeconds,
appliesTo: recipe.isBatchCook ? s.appliesTo : undefined,
}))}
ingredients={recipe.ingredients.map((i) => ({
rawName: i.rawName,
quantity: i.quantity,
unit: i.unit,
}))}
/>
);
}