fix: varied gradient+icon placeholders for recipes without a cover photo (v0.50.2)
Replaces the single flat emoji-on-muted-bg fallback (same 🍽️/🍹 everywhere) with a deterministic gradient + food/drink icon per recipe id — pulled from a small curated palette/icon pool via a string hash, so it's stable across re-renders but visually varied across a grid of photo-less recipes. New shared lib/recipe-placeholder.ts + components/recipe/recipe-cover- placeholder.tsx, applied everywhere the old inline emoji fallback lived: recipe-grid-card.tsx, recipe-card.tsx, recipes-grid.tsx, and the public profile page's recipe grid. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
import {
|
||||
Soup, Salad, Pizza, Sandwich, IceCream, Cookie, Beef, Fish, Cherry,
|
||||
Carrot, Egg, Drumstick, Croissant, Donut, Cake, ChefHat,
|
||||
Coffee, Wine, Beer, GlassWater, Martini, CupSoda,
|
||||
type LucideIcon,
|
||||
} from "lucide-react";
|
||||
|
||||
const GRADIENTS = [
|
||||
"from-orange-200 to-rose-200 dark:from-orange-950 dark:to-rose-950",
|
||||
"from-amber-200 to-lime-200 dark:from-amber-950 dark:to-lime-950",
|
||||
"from-sky-200 to-indigo-200 dark:from-sky-950 dark:to-indigo-950",
|
||||
"from-emerald-200 to-teal-200 dark:from-emerald-950 dark:to-teal-950",
|
||||
"from-fuchsia-200 to-purple-200 dark:from-fuchsia-950 dark:to-purple-950",
|
||||
"from-yellow-200 to-orange-200 dark:from-yellow-950 dark:to-orange-950",
|
||||
"from-rose-200 to-pink-200 dark:from-rose-950 dark:to-pink-950",
|
||||
"from-teal-200 to-cyan-200 dark:from-teal-950 dark:to-cyan-950",
|
||||
];
|
||||
|
||||
const DISH_ICONS: LucideIcon[] = [
|
||||
ChefHat, Soup, Salad, Pizza, Sandwich, IceCream, Cookie, Beef, Fish,
|
||||
Cherry, Carrot, Egg, Drumstick, Croissant, Donut, Cake,
|
||||
];
|
||||
|
||||
const DRINK_ICONS: LucideIcon[] = [Coffee, Wine, Beer, GlassWater, Martini, CupSoda];
|
||||
|
||||
/** Small, fast, deterministic string hash (djb2) — same recipe always gets the same placeholder. */
|
||||
function hashString(s: string): number {
|
||||
let hash = 5381;
|
||||
for (let i = 0; i < s.length; i++) {
|
||||
hash = (hash * 33) ^ s.charCodeAt(i);
|
||||
}
|
||||
return hash >>> 0;
|
||||
}
|
||||
|
||||
export function getRecipePlaceholder(recipe: { id: string; recipeType?: "dish" | "drink" }): {
|
||||
gradient: string;
|
||||
Icon: LucideIcon;
|
||||
} {
|
||||
const hash = hashString(recipe.id);
|
||||
const icons = recipe.recipeType === "drink" ? DRINK_ICONS : DISH_ICONS;
|
||||
return {
|
||||
gradient: GRADIENTS[hash % GRADIENTS.length]!,
|
||||
// Different modulus base than gradient's so icon/color pairing doesn't
|
||||
// repeat in lockstep across ids that happen to share a gradient.
|
||||
Icon: icons[Math.floor(hash / GRADIENTS.length) % icons.length]!,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user