Recipe catalog v2: - Recipe gagne visibility (PERSONAL/HOUSE/PUBLIC), authorId, authorHouseId - Favoris par utilisateur (RecipeFavorite), régimes associés (RecipeDiet) - Aliments "pas aimés" par utilisateur (UserProfileDislikedIngredient), distinct des allergies médicales - API: GET /recipes?tab=favoris|perso|foyer|publique avec contrôle d'accès complet, POST/DELETE /recipes/:id/favorite, édition/suppression réservées à l'auteur (403 NOT_RECIPE_AUTHOR), GET/PATCH /profile/disliked-ingredients - Frontend: vue maître-détail (onglets + tableau + panneau détail), formulaire enrichi (visibilité, régimes), section préférences pour les aliments pas aimés Catalogue d'ingrédients de référence: - Extension du seed de 39 à ~430 ingrédients (viandes, poissons/fruits de mer, légumes, fruits, féculents, condiments/sauces, épices/herbes, pains à sandwich, cuisines italienne/asiatique/mexicaine/maghrébine, liquides et boissons de cuisine, bouillons/fonds) - Chaque ingrédient lié à ses allergènes UE (IngredientAllergy) — les 14 allergènes réglementaires restent tous couverts - Seeding optimisé en requêtes groupées (createMany/diff ciblé) plutôt qu'un upsert par ligne, pour garder resetDatabase() rapide en test Tests: 102 tests Mocha + 32 scénarios BDD, tous verts. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
25 lines
823 B
TypeScript
25 lines
823 B
TypeScript
import type { AllergyView } from "@batch-cooking/shared";
|
|
import "./recipes.scss";
|
|
|
|
/**
|
|
* A row of allergen pills — used both on {@link RecipeCard} (catalog list)
|
|
* and the recipe detail page, for a single ingredient's allergens as well
|
|
* as a recipe's aggregated set (`RecipeSummaryView.allergens`/
|
|
* `RecipeView.allergens`, already deduplicated server-side). Renders
|
|
* nothing for an empty list rather than an empty wrapper, so callers can
|
|
* mount it unconditionally.
|
|
*/
|
|
export function AllergenBadges({ allergens }: { allergens: AllergyView[] }) {
|
|
if (allergens.length === 0) {
|
|
return null;
|
|
}
|
|
return (
|
|
<ul className="allergen-badges">
|
|
{allergens.map((allergen) => (
|
|
<li key={allergen.id} className="allergen-badge">
|
|
{allergen.name}
|
|
</li>
|
|
))}
|
|
</ul>
|
|
);
|
|
}
|