feat: custom recipe cover color/icon + mute auto placeholder palette (v0.51.0)
Two changes to the no-photo cover placeholder shipped last version: 1. Muted the gradient palette (100/40-opacity tints instead of solid -200/ -950 stops) — the original was too saturated next to real cover photos in the same grid, per feedback. 2. New coverIcon/coverColor columns on recipes (nullable text, migration 0048, additive-only) let the author pin a specific color+icon from the recipe editor instead of the automatic per-id pick. getRecipePlaceholder now checks these first, falling back to the deterministic hash pick when unset — existing recipes are unaffected until edited. Wired coverIcon/coverColor through every explicit-column recipe select that feeds a grid card (explore trending/recent, search, feed, for-you) — the relational-query call sites (recipes page, collections, profile pages) already return all columns and needed no changes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -61,6 +61,8 @@ export default async function ExplorePage({
|
||||
isBatchCook: recipes.isBatchCook,
|
||||
sourceUrl: recipes.sourceUrl,
|
||||
recipeType: recipes.recipeType,
|
||||
coverIcon: recipes.coverIcon,
|
||||
coverColor: recipes.coverColor,
|
||||
};
|
||||
|
||||
// Trending: public recipes ordered by favorite count in last 7 days
|
||||
|
||||
@@ -60,6 +60,8 @@ export default async function EditRecipePage({ params }: Params) {
|
||||
isCover: photo.isCover,
|
||||
preview: getPublicUrl(photo.storageKey),
|
||||
})),
|
||||
coverIcon: recipe.coverIcon,
|
||||
coverColor: recipe.coverColor,
|
||||
isBatchCook: recipe.isBatchCook,
|
||||
// Only pre-fill the manual-nutrition editor with existing values when
|
||||
// they were actually manually entered — AI-estimated data shouldn't
|
||||
|
||||
@@ -51,6 +51,8 @@ export async function GET(req: NextRequest) {
|
||||
isBatchCook: recipes.isBatchCook,
|
||||
sourceUrl: recipes.sourceUrl,
|
||||
recipeType: recipes.recipeType,
|
||||
coverIcon: recipes.coverIcon,
|
||||
coverColor: recipes.coverColor,
|
||||
})
|
||||
.from(recipes)
|
||||
.innerJoin(users, eq(recipes.authorId, users.id))
|
||||
|
||||
@@ -41,6 +41,8 @@ export async function GET(req: NextRequest) {
|
||||
isBatchCook: recipes.isBatchCook,
|
||||
sourceUrl: recipes.sourceUrl,
|
||||
recipeType: recipes.recipeType,
|
||||
coverIcon: recipes.coverIcon,
|
||||
coverColor: recipes.coverColor,
|
||||
createdAt: recipes.createdAt,
|
||||
updatedAt: recipes.updatedAt,
|
||||
authorId: recipes.authorId,
|
||||
|
||||
@@ -47,6 +47,8 @@ const UpdateRecipeSchema = z.object({
|
||||
key: z.string().min(1).max(500),
|
||||
isCover: z.boolean().default(false),
|
||||
})).max(20).optional(),
|
||||
coverIcon: z.string().max(50).nullable().optional(),
|
||||
coverColor: z.string().max(50).nullable().optional(),
|
||||
isBatchCook: z.boolean().optional(),
|
||||
dishes: z.array(z.object({
|
||||
name: z.string().min(1).max(100),
|
||||
@@ -169,6 +171,8 @@ export async function PUT(req: NextRequest, { params }: Params) {
|
||||
if (data.tags !== undefined) updates.tags = data.tags;
|
||||
if (data.dietaryTags !== undefined) updates.dietaryTags = data.dietaryTags;
|
||||
if (data.isBatchCook !== undefined) updates.isBatchCook = data.isBatchCook;
|
||||
if (data.coverIcon !== undefined) updates.coverIcon = data.coverIcon;
|
||||
if (data.coverColor !== undefined) updates.coverColor = data.coverColor;
|
||||
if (data.nutrition !== undefined) {
|
||||
updates.nutritionData = data.nutrition ? { perServing: data.nutrition } : null;
|
||||
updates.nutritionManual = !!data.nutrition;
|
||||
|
||||
@@ -51,6 +51,8 @@ const CreateRecipeSchema = z.object({
|
||||
key: z.string().min(1).max(500),
|
||||
isCover: z.boolean().default(false),
|
||||
})).max(20).default([]),
|
||||
coverIcon: z.string().max(50).nullable().optional(),
|
||||
coverColor: z.string().max(50).nullable().optional(),
|
||||
isBatchCook: z.boolean().default(false),
|
||||
dishes: z.array(z.object({
|
||||
name: z.string().min(1).max(100),
|
||||
@@ -142,6 +144,8 @@ export async function POST(req: NextRequest) {
|
||||
aiGenerated: data.aiGenerated ?? false,
|
||||
language: data.language,
|
||||
sourceUrl: data.sourceUrl,
|
||||
coverIcon: data.coverIcon ?? null,
|
||||
coverColor: data.coverColor ?? null,
|
||||
isBatchCook: data.isBatchCook,
|
||||
nutritionData: data.nutrition ? { perServing: data.nutrition } : undefined,
|
||||
nutritionManual: !!data.nutrition,
|
||||
|
||||
@@ -137,6 +137,8 @@ export async function GET(req: NextRequest) {
|
||||
isBatchCook: recipes.isBatchCook,
|
||||
sourceUrl: recipes.sourceUrl,
|
||||
recipeType: recipes.recipeType,
|
||||
coverIcon: recipes.coverIcon,
|
||||
coverColor: recipes.coverColor,
|
||||
authorId: recipes.authorId,
|
||||
authorName: users.name,
|
||||
createdAt: recipes.createdAt,
|
||||
|
||||
Reference in New Issue
Block a user