import type { IngredientView } from "@batch-cooking/shared"; /** * The display name for an ingredient line. * * A real catalog ingredient has no name in the database — its French label * lives in i18n under `catalog.ingredients.` — so it's resolved * through `t`. A **placeholder** (`IngredientView.isPlaceholder`, the * free text a user typed when the catalog fell short — see * `Ingredient.isPlaceholder` in schema.prisma) has its name stored on the * row as `displayName` and no i18n key at all, so it's shown verbatim. * * Every place that used to inline `t(\`catalog.ingredients.${ingredient.key}\`)` * goes through this instead, so a placeholder never renders as the raw, * missing translation key `catalog.ingredients.placeholder:`. * * `t` is passed in (rather than calling `useTranslation` here) so this * stays a plain function usable from non-component code and unit-testable * without mounting i18next — same split as `shopping-list.ts`. */ export function ingredientLabel( ingredient: Pick, t: (key: string) => string, ): string { return ingredient.displayName ?? t(`catalog.ingredients.${ingredient.key}`); }