Files
Epicure/apps/web/app/(app)/recipes/[id]/cook/page.tsx
T
Arnaud 84d6cfeb07 feat(recipes): full recipe CRUD with photos, print, version history
List, detail, new, edit pages. Server-side pagination, dietary tags, difficulty.
Photo upload to S3-compatible storage. Version history. Multi-select grid with
bulk delete/visibility. Print view. Delete confirmation dialog.
2026-07-01 08:10:11 +02:00

47 lines
1.4 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";
type Params = { params: Promise<{ id: string }> };
export async function generateMetadata({ params }: Params) {
const { id } = await params;
const recipe = await db.query.recipes.findFirst({ where: eq(recipes.id, id) });
return { title: recipe ? `Cooking: ${recipe.title}` : "Cooking Mode" };
}
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();
return (
<CookingMode
recipeId={id}
recipeTitle={recipe.title}
steps={recipe.steps.map((s) => ({
id: s.id,
instruction: s.instruction,
timerSeconds: s.timerSeconds,
}))}
ingredients={recipe.ingredients.map((i) => ({
rawName: i.rawName,
quantity: i.quantity,
unit: i.unit,
}))}
/>
);
}