import type { IngredientCategory, IngredientIcon as IngredientIconType, IngredientSubcategory, } from "@batch-cooking/shared"; import type { ReactNode } from "react"; // Generic pictograms for ingredients — one per `IngredientIcon` value // (schema.prisma), reused across the category chips, subcategory chips and // ingredient cards in `IngredientPicker`/`IngredientRow`. Replaces the // earlier per-ingredient emoji (437 different characters, one per // ingredient) with a small vocabulary grouped by *what kind of thing* an // ingredient is (a vegetable, a bottle of oil, a wedge of cheese…) rather // than a literal picture of each one — 437 unique, professional icons // isn't a realistic set to draw or license one-by-one, but ~20 generic // shapes reused across them is. // // Most of these (everything using `FilledIcon` below) are solid-fill // glyphs from foodiconpack.com's free "Common ingredient icons"/"Common // Utensils" collections, licensed CC BY 4.0 — see the in-app credits page // (`pages/CreditsPage.tsx`) for the required attribution. The three with // no good match in that pack (`BreadIcon`, `DoughIcon`, `SproutIcon`) stay // hand-drawn, using the stroke-based `Icon` wrapper that used to cover all // 22 — both wrappers render at the same on-screen size (sized entirely via // CSS, no width/height baked into either), so the mix reads as one set. function Icon({ children }: { children: ReactNode }) { return ( ); } /** Wrapper for the foodiconpack.com icons — solid-fill glyphs (2048×2048 source viewBox) rather than `Icon`'s stroke-only ones. `fill="currentColor"` on the root cascades to every child `` (none set their own), so these theme/recolor exactly like the hand-drawn set. */ function FilledIcon({ children }: { children: ReactNode }) { return ( ); } /** Carrot (foodiconpack.com, CC BY 4.0 — see the credits page) — root vegetables, leafy greens, and produce generally (`freshProduce`/`vegetables`). */ export function VegetableIcon() { return ( ); } /** Apple (foodiconpack.com, CC BY 4.0) — `freshProduce`/`fruits`. */ export function FruitIcon() { return ( ); } /** Basil sprig (foodiconpack.com, CC BY 4.0) — `freshProduce`/`freshHerbs`. */ export function HerbIcon() { return ( ); } /** Cut of beef (foodiconpack.com, CC BY 4.0) — `meatAndSeafood`/`meats`. */ export function MeatIcon() { return ( ); } /** Chicken (foodiconpack.com, CC BY 4.0) — `meatAndSeafood`/`poultry`. */ export function PoultryIcon() { return ( ); } /** Salmon (foodiconpack.com, CC BY 4.0) — `meatAndSeafood`/`fish`. */ export function FishIcon() { return ( ); } /** Shrimp (foodiconpack.com, CC BY 4.0) — `meatAndSeafood`/`shellfish`. */ export function ShellfishIcon() { return ( ); } /** Bowl of rice (foodiconpack.com, CC BY 4.0) — grains, pasta, rice, flour (`dryGoods`/`starches`, and flours under `cookingEssentials`/`bases`). */ export function GrainIcon() { return ( ); } /** Chickpeas (foodiconpack.com, CC BY 4.0) — `dryGoods`/`legumes`. */ export function LegumeIcon() { return ( ); } /** Almonds (foodiconpack.com, CC BY 4.0) — nuts, seeds, dried fruit (`dryGoods`/`nutsAndSeeds`). */ export function NutSeedIcon() { return ( ); } /** A loaf, scored on top — `bakery`/`breads`. */ export function BreadIcon() { return ( ); } /** Rolling pin — raw, uncooked pastry (`bakery`/`rawDough`). */ export function DoughIcon() { return ( ); } /** Milk carton (foodiconpack.com, CC BY 4.0) — `dairyAndCheese`/`dairy` (non-cheese items). */ export function MilkIcon() { return ( ); } /** Wedge of cheddar (foodiconpack.com, CC BY 4.0) — `dairyAndCheese`/`dairy` (cheese items). */ export function CheeseIcon() { return ( ); } /** Eggs (foodiconpack.com, CC BY 4.0) — `dairyAndCheese`/`eggs`. */ export function EggIcon() { return ( ); } /** A seedling — plant-based dairy/meat alternatives (`dairyAndCheese`/`plantBasedAlternatives`). */ export function SproutIcon() { return ( ); } /** Cinnamon sticks (foodiconpack.com, CC BY 4.0) — dried spices/herbs (`condimentsAndSpices`/`spices`). */ export function SpiceIcon() { return ( ); } /** Honey jar (foodiconpack.com, CC BY 4.0) — sauces, pickles, tinned/preserved goods (`condimentsAndSpices`/`sauces` and the `dryGoods`/`other` catch-all). */ export function JarIcon() { return ( ); } /** Oil bottle (foodiconpack.com, CC BY 4.0) — oils, vinegars (`condimentsAndSpices`/`seasonings`, the pourable subset). */ export function BottleIcon() { return ( ); } /** Glass (foodiconpack.com, CC BY 4.0) — juices, coffee/tea, cooking alcohols, water (`condimentsAndSpices`/`seasonings`'s drinkable subset). */ export function DrinkIcon() { return ( ); } /** Stockpot (foodiconpack.com, CC BY 4.0) — broths, stocks, water bases (`cookingEssentials`/`bases`'s liquid-base subset). */ export function StockPotIcon() { return ( ); } /** Sugar (foodiconpack.com, CC BY 4.0) — `cookingEssentials`/`sugars`. */ export function SugarIcon() { return ( ); } /** Every icon component, keyed by {@link IngredientIconType} — the single lookup `IngredientPicker`/`IngredientRow`/category chips render through. */ export const INGREDIENT_ICON_COMPONENTS: Record JSX.Element> = { VEGETABLE: VegetableIcon, FRUIT: FruitIcon, HERB: HerbIcon, MEAT: MeatIcon, POULTRY: PoultryIcon, FISH: FishIcon, SHELLFISH: ShellfishIcon, GRAIN: GrainIcon, LEGUME: LegumeIcon, NUT_SEED: NutSeedIcon, BREAD: BreadIcon, DOUGH: DoughIcon, MILK: MilkIcon, CHEESE: CheeseIcon, EGG: EggIcon, SPROUT: SproutIcon, SPICE: SpiceIcon, JAR: JarIcon, BOTTLE: BottleIcon, DRINK: DrinkIcon, STOCK_POT: StockPotIcon, SUGAR: SugarIcon, }; /** Renders the generic pictogram for one {@link IngredientIconType} — the actual component `IngredientPicker`'s cards and `IngredientRow` use, rather than importing {@link INGREDIENT_ICON_COMPONENTS} directly everywhere. */ export function IngredientTypeIcon({ icon }: { icon: IngredientIconType }) { const Component = INGREDIENT_ICON_COMPONENTS[icon]; return ; } /** * One representative {@link IngredientIconType} per {@link IngredientCategory} * aisle, for `IngredientPicker`'s top-level category chips — a category * mixes several icon types (e.g. "Aides culinaires" has flour, stock, and * sugar items), so this is a deliberate, illustrative pick rather than a * derived fact. */ export const CATEGORY_ICON: Record = { freshProduce: "VEGETABLE", meatAndSeafood: "MEAT", dryGoods: "GRAIN", bakery: "BREAD", dairyAndCheese: "CHEESE", condimentsAndSpices: "SPICE", cookingEssentials: "STOCK_POT", }; /** Renders {@link CATEGORY_ICON}'s pictogram for one category — used by the category chip row. */ export function CategoryIcon({ category }: { category: IngredientCategory }) { return ; } /** * One representative {@link IngredientIconType} per {@link IngredientSubcategory} * rack, for `IngredientPicker`'s second-tier subcategory chips. Most map * 1:1 onto their subcategory's dominant shape; a couple of heterogeneous * subcategories (`seasonings` mixes oils with juices and coffee, * `bases` mixes flour with stock and canned tomato) get one illustrative * pick rather than a derived fact, same reasoning as {@link CATEGORY_ICON}. */ export const SUBCATEGORY_ICON: Record = { vegetables: "VEGETABLE", fruits: "FRUIT", freshHerbs: "HERB", meats: "MEAT", poultry: "POULTRY", fish: "FISH", shellfish: "SHELLFISH", starches: "GRAIN", legumes: "LEGUME", nutsAndSeeds: "NUT_SEED", other: "JAR", breads: "BREAD", rawDough: "DOUGH", dairy: "MILK", eggs: "EGG", plantBasedAlternatives: "SPROUT", spices: "SPICE", sauces: "JAR", seasonings: "BOTTLE", bases: "STOCK_POT", thickeners: "JAR", sugars: "SUGAR", }; /** Renders {@link SUBCATEGORY_ICON}'s pictogram for one subcategory — used by the subcategory chip row. */ export function SubcategoryIcon({ subcategory }: { subcategory: IngredientSubcategory }) { return ; }