feat: mark recipe as cooked (multi-cook history + backdate) and enable auto-deduct pantry on cook (v0.75.0)
Adds a general-purpose "mark cooked" dialog for any recipe (not just batch-cook dishes), with a date picker for backdating and a pantry-deduct checkbox defaulted on. Also flips the previously dead-in-the-UI deductFromPantry flag to true for the existing batch-cook and meal-planner cook actions. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -31,6 +31,7 @@ import { ServingScaler } from "@/components/recipe/serving-scaler";
|
||||
import { FavoriteButton } from "@/components/social/favorite-button";
|
||||
import { RatingStars } from "@/components/social/rating-stars";
|
||||
import { CookedItReview } from "@/components/social/cooked-it-review";
|
||||
import { MarkCookedSection } from "@/components/recipe/mark-cooked-section";
|
||||
import { RecipeNotes } from "@/components/recipe/recipe-notes";
|
||||
import { CommentsSection } from "@/components/social/comments-section";
|
||||
import { getPublicUrl } from "@/lib/storage";
|
||||
@@ -127,6 +128,12 @@ export default async function RecipePage({ params }: Params) {
|
||||
}
|
||||
}
|
||||
|
||||
// Non-batch cook log — batch-cook recipes track this per-dish instead
|
||||
// (dishCookedAtMap above), logged via BatchCookDishes, not this list.
|
||||
const plainCookLog = dishCookLog.filter((l) => !l.batchDishId);
|
||||
const cookCount = plainCookLog.length;
|
||||
const lastCookedAt = plainCookLog[0]?.cookedAt.toISOString() ?? null;
|
||||
|
||||
const avgScore = ratingData[0]?.avgScore ? parseFloat(ratingData[0].avgScore) : null;
|
||||
const ratingCount = ratingData[0]?.total ?? 0;
|
||||
const isFavorited = !!favoriteData;
|
||||
@@ -492,6 +499,18 @@ export default async function RecipePage({ params }: Params) {
|
||||
</>
|
||||
)}
|
||||
|
||||
{!recipe.isBatchCook && (
|
||||
<>
|
||||
<Separator />
|
||||
<MarkCookedSection
|
||||
recipeId={id}
|
||||
baseServings={recipe.baseServings}
|
||||
cookCount={cookCount}
|
||||
lastCookedAt={lastCookedAt}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
{recipe.visibility !== "private" && (
|
||||
<>
|
||||
<Separator />
|
||||
|
||||
@@ -10,6 +10,9 @@ const Schema = z.object({
|
||||
notes: z.string().max(2000).optional(),
|
||||
deductFromPantry: z.boolean().default(true),
|
||||
batchDishId: z.string().optional(),
|
||||
/** ISO date (YYYY-MM-DD) or full datetime — lets a user log a past cook,
|
||||
* not just "just now". Defaults to now when omitted. */
|
||||
cookedAt: z.string().optional(),
|
||||
});
|
||||
|
||||
export async function POST(req: NextRequest, { params }: Params) {
|
||||
@@ -44,6 +47,8 @@ export async function POST(req: NextRequest, { params }: Params) {
|
||||
isFirstBatchCook = !priorCook;
|
||||
}
|
||||
|
||||
const cookedAt = data.cookedAt ? new Date(data.cookedAt) : new Date();
|
||||
|
||||
await db.insert(cookingHistory).values({
|
||||
id: crypto.randomUUID(),
|
||||
userId,
|
||||
@@ -51,7 +56,7 @@ export async function POST(req: NextRequest, { params }: Params) {
|
||||
batchDishId: data.batchDishId,
|
||||
servings: data.servings,
|
||||
notes: data.notes,
|
||||
cookedAt: new Date(),
|
||||
cookedAt: isNaN(cookedAt.getTime()) ? new Date() : cookedAt,
|
||||
});
|
||||
|
||||
if (data.deductFromPantry && (!data.batchDishId || isFirstBatchCook)) {
|
||||
|
||||
Reference in New Issue
Block a user