diff --git a/apps/web/src/features/planning/RecipePickerDialog.tsx b/apps/web/src/features/planning/RecipePickerDialog.tsx index 7cfcb3c..c59d15a 100644 --- a/apps/web/src/features/planning/RecipePickerDialog.tsx +++ b/apps/web/src/features/planning/RecipePickerDialog.tsx @@ -15,11 +15,9 @@ import { ApiError, apiClient } from "../../api/client"; import { CheckboxOption } from "../../components/ui/Checkbox"; import { Dialog } from "../../components/ui/Dialog"; import { errorMessageService } from "../../services/error-message.service"; -import { DietTagSelect } from "../recipes/DietTagSelect"; -import { IngredientPicker } from "../recipes/IngredientPicker"; +import { DietTagSelect } from "../recipes/badges/DietTagSelect"; +import { IngredientPicker } from "../recipes/ingredients/IngredientPicker"; import { RecipeDetailPanel, type RecipeDetailState } from "../recipes/RecipeDetailPanel"; -import { RecipeImportForm } from "../recipes/RecipeImportForm"; -import { RecipeSourcesPanel, type SourceItemSelection } from "../recipes/RecipeSourcesPanel"; import { RecipeTable } from "../recipes/RecipeTable"; import { isSourceTab, @@ -27,8 +25,13 @@ import { type RecipesPageTab, RecipeTabs, } from "../recipes/RecipeTabs"; -import { tryBuildCompleteImport } from "../recipes/recipe-import-draft"; -import { useEnabledSources } from "../recipes/useEnabledSources"; +import { RecipeImportForm } from "../recipes/sources/RecipeImportForm"; +import { + RecipeSourcesPanel, + type SourceItemSelection, +} from "../recipes/sources/RecipeSourcesPanel"; +import { tryBuildCompleteImport } from "../recipes/sources/recipe-import-draft"; +import { useEnabledSources } from "../recipes/sources/useEnabledSources"; import "./recipe-picker-dialog.scss"; /** Debounce for the search field — same value as `RecipesPage`'s. */ diff --git a/apps/web/src/features/profile/DislikedIngredientsField.tsx b/apps/web/src/features/profile/DislikedIngredientsField.tsx index 4139855..831fdc4 100644 --- a/apps/web/src/features/profile/DislikedIngredientsField.tsx +++ b/apps/web/src/features/profile/DislikedIngredientsField.tsx @@ -1,6 +1,6 @@ import type { IngredientView } from "@batch-cooking/shared"; import { useTranslation } from "react-i18next"; -import { IngredientPicker } from "../recipes/IngredientPicker"; +import { IngredientPicker } from "../recipes/ingredients/IngredientPicker"; // Reuses `IngredientPicker` verbatim (built for the recipe form's // ingredient picker, features/recipes/) rather than a second search+browse // field — same reference ingredient list, same category/search browsing, @@ -10,7 +10,7 @@ import { IngredientPicker } from "../recipes/IngredientPicker"; // recipes.scss — colocated there since it's the same "reference ingredient // picker" visual family, even though this field lives in the profile // feature). -import { IngredientTypeIcon } from "../recipes/ingredient-icons"; +import { IngredientTypeIcon } from "../recipes/ingredients/ingredient-icons"; import "../recipes/recipes.scss"; import "./profile-forms.scss"; diff --git a/apps/web/src/features/recipes/RecipeDetailPanel.tsx b/apps/web/src/features/recipes/RecipeDetailPanel.tsx index 2f3da78..065fec7 100644 --- a/apps/web/src/features/recipes/RecipeDetailPanel.tsx +++ b/apps/web/src/features/recipes/RecipeDetailPanel.tsx @@ -5,9 +5,9 @@ import { Link } from "react-router-dom"; import { ApiError, apiClient } from "../../api/client"; import { SourceLinkIcon } from "../../layouts/nav-icons"; import { errorMessageService } from "../../services/error-message.service"; -import { AllergenBadges } from "./AllergenBadges"; -import { FavoriteStarButton } from "./FavoriteStarButton"; -import { StepDescription } from "./StepDescription"; +import { AllergenBadges } from "./badges/AllergenBadges"; +import { FavoriteStarButton } from "./badges/FavoriteStarButton"; +import { StepDescription } from "./steps/StepDescription"; import "./recipes.scss"; /** diff --git a/apps/web/src/features/recipes/RecipeTable.tsx b/apps/web/src/features/recipes/RecipeTable.tsx index 588abda..290e2c2 100644 --- a/apps/web/src/features/recipes/RecipeTable.tsx +++ b/apps/web/src/features/recipes/RecipeTable.tsx @@ -1,7 +1,7 @@ import type { RecipeSummaryView } from "@batch-cooking/shared"; import { useTranslation } from "react-i18next"; -import { AllergenBadges } from "./AllergenBadges"; -import { DietBadges } from "./DietBadges"; +import { AllergenBadges } from "./badges/AllergenBadges"; +import { DietBadges } from "./badges/DietBadges"; import "./recipes.scss"; /** diff --git a/apps/web/src/features/recipes/AllergenBadges.tsx b/apps/web/src/features/recipes/badges/AllergenBadges.tsx similarity index 97% rename from apps/web/src/features/recipes/AllergenBadges.tsx rename to apps/web/src/features/recipes/badges/AllergenBadges.tsx index 31c8d26..3f76183 100644 --- a/apps/web/src/features/recipes/AllergenBadges.tsx +++ b/apps/web/src/features/recipes/badges/AllergenBadges.tsx @@ -1,6 +1,6 @@ import type { AllergyView } from "@batch-cooking/shared"; import { useTranslation } from "react-i18next"; -import "./recipes.scss"; +import "../recipes.scss"; /** * A row of allergen pills — used both on {@link RecipeCard} (catalog list) diff --git a/apps/web/src/features/recipes/DietBadges.tsx b/apps/web/src/features/recipes/badges/DietBadges.tsx similarity index 97% rename from apps/web/src/features/recipes/DietBadges.tsx rename to apps/web/src/features/recipes/badges/DietBadges.tsx index 7e44114..aef23ab 100644 --- a/apps/web/src/features/recipes/DietBadges.tsx +++ b/apps/web/src/features/recipes/badges/DietBadges.tsx @@ -1,6 +1,6 @@ import type { DietView } from "@batch-cooking/shared"; import { useTranslation } from "react-i18next"; -import "./recipes.scss"; +import "../recipes.scss"; /** * A row of diet-regime pills — the "associated regime" reminder tagged on a diff --git a/apps/web/src/features/recipes/DietTagSelect.tsx b/apps/web/src/features/recipes/badges/DietTagSelect.tsx similarity index 92% rename from apps/web/src/features/recipes/DietTagSelect.tsx rename to apps/web/src/features/recipes/badges/DietTagSelect.tsx index 584a7dc..8e06e02 100644 --- a/apps/web/src/features/recipes/DietTagSelect.tsx +++ b/apps/web/src/features/recipes/badges/DietTagSelect.tsx @@ -1,7 +1,7 @@ import type { DietView } from "@batch-cooking/shared"; import { useTranslation } from "react-i18next"; -import { CheckboxOption } from "../../components/ui/Checkbox"; -import "./recipes.scss"; +import { CheckboxOption } from "../../../components/ui/Checkbox"; +import "../recipes.scss"; /** * Multi-select (checkbox grid, same pattern as `AllergySelect`) for the diff --git a/apps/web/src/features/recipes/FavoriteStarButton.tsx b/apps/web/src/features/recipes/badges/FavoriteStarButton.tsx similarity index 92% rename from apps/web/src/features/recipes/FavoriteStarButton.tsx rename to apps/web/src/features/recipes/badges/FavoriteStarButton.tsx index 638fc1d..643c1d4 100644 --- a/apps/web/src/features/recipes/FavoriteStarButton.tsx +++ b/apps/web/src/features/recipes/badges/FavoriteStarButton.tsx @@ -1,8 +1,8 @@ import { useState } from "react"; import { useTranslation } from "react-i18next"; -import { apiClient } from "../../api/client"; -import { FavoriteIcon } from "../../layouts/nav-icons"; -import "./recipes.scss"; +import { apiClient } from "../../../api/client"; +import { FavoriteIcon } from "../../../layouts/nav-icons"; +import "../recipes.scss"; /** * Star toggle for a recipe's favorite status — the overlay button on diff --git a/apps/web/src/features/recipes/ReproducibleBadge.tsx b/apps/web/src/features/recipes/badges/ReproducibleBadge.tsx similarity index 98% rename from apps/web/src/features/recipes/ReproducibleBadge.tsx rename to apps/web/src/features/recipes/badges/ReproducibleBadge.tsx index 678e5f9..2b1548f 100644 --- a/apps/web/src/features/recipes/ReproducibleBadge.tsx +++ b/apps/web/src/features/recipes/badges/ReproducibleBadge.tsx @@ -1,5 +1,5 @@ import { useTranslation } from "react-i18next"; -import "./recipes.scss"; +import "../recipes.scss"; /** * Single "faisable maison" pill for an ingredient flagged diff --git a/apps/web/src/features/recipes/IngredientPicker.tsx b/apps/web/src/features/recipes/ingredients/IngredientPicker.tsx similarity index 96% rename from apps/web/src/features/recipes/IngredientPicker.tsx rename to apps/web/src/features/recipes/ingredients/IngredientPicker.tsx index b12450e..4b45305 100644 --- a/apps/web/src/features/recipes/IngredientPicker.tsx +++ b/apps/web/src/features/recipes/ingredients/IngredientPicker.tsx @@ -7,13 +7,13 @@ import { } from "@batch-cooking/shared"; import { useState } from "react"; import { useTranslation } from "react-i18next"; -import { CheckboxOption } from "../../components/ui/Checkbox"; -import { SettingsIcon } from "../../layouts/nav-icons"; -import { AllergenBadges } from "./AllergenBadges"; -import { DietBadges } from "./DietBadges"; +import { CheckboxOption } from "../../../components/ui/Checkbox"; +import { SettingsIcon } from "../../../layouts/nav-icons"; +import { AllergenBadges } from "../badges/AllergenBadges"; +import { DietBadges } from "../badges/DietBadges"; +import { ReproducibleBadge } from "../badges/ReproducibleBadge"; import { CategoryIcon, IngredientTypeIcon, SubcategoryIcon } from "./ingredient-icons"; -import { ReproducibleBadge } from "./ReproducibleBadge"; -import "./recipes.scss"; +import "../recipes.scss"; /** "No filter at this level" — a UI-only pseudo-value, never sent to/received from the API (see {@link INGREDIENT_CATEGORIES}/{@link INGREDIENT_CATEGORY_SUBCATEGORIES} for the real, closed sets). */ const ALL = "ALL" as const; diff --git a/apps/web/src/features/recipes/IngredientRow.tsx b/apps/web/src/features/recipes/ingredients/IngredientRow.tsx similarity index 95% rename from apps/web/src/features/recipes/IngredientRow.tsx rename to apps/web/src/features/recipes/ingredients/IngredientRow.tsx index d73e752..82c1c7f 100644 --- a/apps/web/src/features/recipes/IngredientRow.tsx +++ b/apps/web/src/features/recipes/ingredients/IngredientRow.tsx @@ -1,10 +1,10 @@ import type { IngredientView, UnitView } from "@batch-cooking/shared"; import { useTranslation } from "react-i18next"; -import { AllergenBadges } from "./AllergenBadges"; -import { DietBadges } from "./DietBadges"; +import { AllergenBadges } from "../badges/AllergenBadges"; +import { DietBadges } from "../badges/DietBadges"; +import { ReproducibleBadge } from "../badges/ReproducibleBadge"; import { IngredientTypeIcon } from "./ingredient-icons"; -import { ReproducibleBadge } from "./ReproducibleBadge"; -import "./recipes.scss"; +import "../recipes.scss"; /** One selected ingredient line in the recipe form — the ingredient itself (picked via `IngredientPicker`) plus its quantity/unit for this recipe. Quantity is kept as a raw string while editing (not parsed to a number until submit) so an in-progress/invalid value doesn't fight the input; `unit` picks from `unitsCatalog` (a closed reference list, see `Unit` in schema.prisma) rather than free text. */ export function IngredientRow({ diff --git a/apps/web/src/features/recipes/ingredient-icons.tsx b/apps/web/src/features/recipes/ingredients/ingredient-icons.tsx similarity index 100% rename from apps/web/src/features/recipes/ingredient-icons.tsx rename to apps/web/src/features/recipes/ingredients/ingredient-icons.tsx diff --git a/apps/web/src/features/recipes/RecipeImportForm.tsx b/apps/web/src/features/recipes/sources/RecipeImportForm.tsx similarity index 97% rename from apps/web/src/features/recipes/RecipeImportForm.tsx rename to apps/web/src/features/recipes/sources/RecipeImportForm.tsx index 0202249..1f98e66 100644 --- a/apps/web/src/features/recipes/RecipeImportForm.tsx +++ b/apps/web/src/features/recipes/sources/RecipeImportForm.tsx @@ -13,14 +13,14 @@ import { } from "@batch-cooking/shared"; import { type FormEvent, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; -import { ApiError, apiClient } from "../../api/client"; -import { makeClientKey } from "../../lib/client-key"; -import { errorMessageService } from "../../services/error-message.service"; -import { DietTagSelect } from "./DietTagSelect"; -import { IngredientPicker } from "./IngredientPicker"; -import { IngredientRow } from "./IngredientRow"; -import { type StepDraft, StepListEditor } from "./StepListEditor"; -import "./recipes.scss"; +import { ApiError, apiClient } from "../../../api/client"; +import { makeClientKey } from "../../../lib/client-key"; +import { errorMessageService } from "../../../services/error-message.service"; +import { DietTagSelect } from "../badges/DietTagSelect"; +import { IngredientPicker } from "../ingredients/IngredientPicker"; +import { IngredientRow } from "../ingredients/IngredientRow"; +import { type StepDraft, StepListEditor } from "../steps/StepListEditor"; +import "../recipes.scss"; /** In display order — mirrors `RecipeVisibility` (schema.prisma/shared types). Same list as `RecipeFormPage`. */ const VISIBILITY_OPTIONS: RecipeVisibility[] = ["PERSONAL", "HOUSE", "PUBLIC"]; diff --git a/apps/web/src/features/recipes/RecipeSourcesPanel.tsx b/apps/web/src/features/recipes/sources/RecipeSourcesPanel.tsx similarity index 98% rename from apps/web/src/features/recipes/RecipeSourcesPanel.tsx rename to apps/web/src/features/recipes/sources/RecipeSourcesPanel.tsx index 7099ebb..bf01cb4 100644 --- a/apps/web/src/features/recipes/RecipeSourcesPanel.tsx +++ b/apps/web/src/features/recipes/sources/RecipeSourcesPanel.tsx @@ -1,10 +1,10 @@ import type { BrowsableSourceItemView, RecipeView } from "@batch-cooking/shared"; import { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; -import { apiClient } from "../../api/client"; -import { RecipeDetailPanel, type RecipeDetailState } from "./RecipeDetailPanel"; +import { apiClient } from "../../../api/client"; +import { RecipeDetailPanel, type RecipeDetailState } from "../RecipeDetailPanel"; import { SourceItemTable } from "./SourceItemTable"; -import "./recipes.scss"; +import "../recipes.scss"; /** Debounce for the search field — same idea/value as `RecipesPage`'s own search. */ const SEARCH_DEBOUNCE_MS = 300; diff --git a/apps/web/src/features/recipes/SourceItemTable.tsx b/apps/web/src/features/recipes/sources/SourceItemTable.tsx similarity index 98% rename from apps/web/src/features/recipes/SourceItemTable.tsx rename to apps/web/src/features/recipes/sources/SourceItemTable.tsx index 16b46dd..bd5ff89 100644 --- a/apps/web/src/features/recipes/SourceItemTable.tsx +++ b/apps/web/src/features/recipes/sources/SourceItemTable.tsx @@ -1,6 +1,6 @@ import type { BrowsableSourceItemView } from "@batch-cooking/shared"; import { useTranslation } from "react-i18next"; -import "./recipes.scss"; +import "../recipes.scss"; /** * List of one source's browsable items (`RecipeSourcesPanel`) — same diff --git a/apps/web/src/features/recipes/recipe-import-draft.ts b/apps/web/src/features/recipes/sources/recipe-import-draft.ts similarity index 100% rename from apps/web/src/features/recipes/recipe-import-draft.ts rename to apps/web/src/features/recipes/sources/recipe-import-draft.ts diff --git a/apps/web/src/features/recipes/useEnabledSources.ts b/apps/web/src/features/recipes/sources/useEnabledSources.ts similarity index 96% rename from apps/web/src/features/recipes/useEnabledSources.ts rename to apps/web/src/features/recipes/sources/useEnabledSources.ts index dbef06b..80b2ca1 100644 --- a/apps/web/src/features/recipes/useEnabledSources.ts +++ b/apps/web/src/features/recipes/sources/useEnabledSources.ts @@ -1,6 +1,6 @@ import type { SourceView } from "@batch-cooking/shared"; import { useEffect, useState } from "react"; -import { apiClient } from "../../api/client"; +import { apiClient } from "../../../api/client"; export type EnabledSourcesState = | { status: "loading" } diff --git a/apps/web/src/features/recipes/StepDescription.tsx b/apps/web/src/features/recipes/steps/StepDescription.tsx similarity index 97% rename from apps/web/src/features/recipes/StepDescription.tsx rename to apps/web/src/features/recipes/steps/StepDescription.tsx index 43ab638..cbbd317 100644 --- a/apps/web/src/features/recipes/StepDescription.tsx +++ b/apps/web/src/features/recipes/steps/StepDescription.tsx @@ -1,7 +1,7 @@ import type { StepTechStepView } from "@batch-cooking/shared"; import { Fragment } from "react"; import { useTranslation } from "react-i18next"; -import { Tooltip } from "../../components/ui/Tooltip"; +import { Tooltip } from "../../../components/ui/Tooltip"; import { splitDescriptionByTechSteps } from "./highlight-tech-steps"; /** diff --git a/apps/web/src/features/recipes/StepListEditor.tsx b/apps/web/src/features/recipes/steps/StepListEditor.tsx similarity index 97% rename from apps/web/src/features/recipes/StepListEditor.tsx rename to apps/web/src/features/recipes/steps/StepListEditor.tsx index a809bd5..568ada7 100644 --- a/apps/web/src/features/recipes/StepListEditor.tsx +++ b/apps/web/src/features/recipes/steps/StepListEditor.tsx @@ -1,6 +1,6 @@ import { useTranslation } from "react-i18next"; -import { makeClientKey } from "../../lib/client-key"; -import "./recipes.scss"; +import { makeClientKey } from "../../../lib/client-key"; +import "../recipes.scss"; /** One in-progress preparation step in the recipe form. `key` is a client-only stable identity for React/reordering — the server derives the real `order`/`id` from array position on save (see `schemas/recipe.ts`), never from this. */ export interface StepDraft { diff --git a/apps/web/src/features/recipes/highlight-tech-steps.ts b/apps/web/src/features/recipes/steps/highlight-tech-steps.ts similarity index 100% rename from apps/web/src/features/recipes/highlight-tech-steps.ts rename to apps/web/src/features/recipes/steps/highlight-tech-steps.ts diff --git a/apps/web/src/pages/recipes/ImportRecipePage.tsx b/apps/web/src/pages/recipes/ImportRecipePage.tsx index 51e5689..5398193 100644 --- a/apps/web/src/pages/recipes/ImportRecipePage.tsx +++ b/apps/web/src/pages/recipes/ImportRecipePage.tsx @@ -1,7 +1,7 @@ import { MEALS, type Meal, WEEK_DAYS, type WeekDay } from "@batch-cooking/shared"; import { useTranslation } from "react-i18next"; import { useNavigate, useParams, useSearchParams } from "react-router-dom"; -import { RecipeImportForm } from "../../features/recipes/RecipeImportForm"; +import { RecipeImportForm } from "../../features/recipes/sources/RecipeImportForm"; import "../../features/recipes/recipes.scss"; /** diff --git a/apps/web/src/pages/recipes/RecipeFormPage.tsx b/apps/web/src/pages/recipes/RecipeFormPage.tsx index 8a13fb1..b26a1c5 100644 --- a/apps/web/src/pages/recipes/RecipeFormPage.tsx +++ b/apps/web/src/pages/recipes/RecipeFormPage.tsx @@ -11,10 +11,10 @@ import { type FormEvent, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { useNavigate, useParams } from "react-router-dom"; import { ApiError, apiClient } from "../../api/client"; -import { DietTagSelect } from "../../features/recipes/DietTagSelect"; -import { IngredientPicker } from "../../features/recipes/IngredientPicker"; -import { IngredientRow } from "../../features/recipes/IngredientRow"; -import { type StepDraft, StepListEditor } from "../../features/recipes/StepListEditor"; +import { DietTagSelect } from "../../features/recipes/badges/DietTagSelect"; +import { IngredientPicker } from "../../features/recipes/ingredients/IngredientPicker"; +import { IngredientRow } from "../../features/recipes/ingredients/IngredientRow"; +import { type StepDraft, StepListEditor } from "../../features/recipes/steps/StepListEditor"; import "../../features/recipes/recipes.scss"; import { makeClientKey } from "../../lib/client-key"; import { errorMessageService } from "../../services/error-message.service"; diff --git a/apps/web/src/pages/recipes/RecipesPage.tsx b/apps/web/src/pages/recipes/RecipesPage.tsx index 0a963b9..5abd041 100644 --- a/apps/web/src/pages/recipes/RecipesPage.tsx +++ b/apps/web/src/pages/recipes/RecipesPage.tsx @@ -7,10 +7,6 @@ import { RecipeDetailPanel, type RecipeDetailState, } from "../../features/recipes/RecipeDetailPanel"; -import { - RecipeSourcesPanel, - type SourceItemSelection, -} from "../../features/recipes/RecipeSourcesPanel"; import { RecipeTable } from "../../features/recipes/RecipeTable"; import { isSourceTab, @@ -19,7 +15,11 @@ import { RecipeTabs, sourceTabValue, } from "../../features/recipes/RecipeTabs"; -import { useEnabledSources } from "../../features/recipes/useEnabledSources"; +import { + RecipeSourcesPanel, + type SourceItemSelection, +} from "../../features/recipes/sources/RecipeSourcesPanel"; +import { useEnabledSources } from "../../features/recipes/sources/useEnabledSources"; import "../../features/recipes/recipes.scss"; /** Debounce for the search field — avoids firing a request on every keystroke, same idea as the household name's autosave (`HouseholdSettingsPage`). */ diff --git a/apps/web/src/pages/settings/CreditsPage.tsx b/apps/web/src/pages/settings/CreditsPage.tsx index 086d91d..c9b8420 100644 --- a/apps/web/src/pages/settings/CreditsPage.tsx +++ b/apps/web/src/pages/settings/CreditsPage.tsx @@ -4,7 +4,7 @@ import "./settings-pages.scss"; /** * Third-party attribution — routed at `/parametres/credits`. Exists solely * to satisfy the CC BY 4.0 requirement on the ingredient icon set (see - * `features/recipes/ingredient-icons.tsx`'s `FilledIcon`-based components): + * `features/recipes/ingredients/ingredient-icons.tsx`'s `FilledIcon`-based components): * most of it comes from foodiconpack.com's free "Common ingredient icons" * and "Common Utensils" collections, which require crediting the source, * linking the license, and noting that the icons were adapted (recolored diff --git a/specs/batch-cooking-modele.md b/specs/batch-cooking-modele.md index 78c9c54..dde2798 100644 --- a/specs/batch-cooking-modele.md +++ b/specs/batch-cooking-modele.md @@ -316,7 +316,7 @@ Table de référence (seedée, jamais créée/éditée/supprimée via l'API), co |---|---| | `id` | Identifiant | | `key` | Slug unique — libellé dans `catalog.ingredients.` (locale) | -| `icon` | `IngredientIcon` — ~20 pictogrammes génériques par *type* de chose (légume, bouteille d'huile, fromage…), pas un emoji par ingrédient (437 rejetés comme peu pro) — voir `apps/web/src/features/recipes/ingredient-icons.tsx` | +| `icon` | `IngredientIcon` — ~20 pictogrammes génériques par *type* de chose (légume, bouteille d'huile, fromage…), pas un emoji par ingrédient (437 rejetés comme peu pro) — voir `apps/web/src/features/recipes/ingredients/ingredient-icons.tsx` | | `category` / `subcategory` | `IngredientCategory` (7 rayons) / `IngredientSubcategory` (racks plus fins) — organisation "rayon de supermarché français" pour permettre le parcours par catégorie dans le picker (400+ ingrédients, la recherche seule ne suffit pas) | | `reproducible` | Vrai si raisonnablement faisable maison (un pain burger, une béchamel) plutôt qu'un achat systématique — juste un flag, pas un lien vers une recette précise (un ancien `alternateRecipeId` jamais câblé a été retiré) | diff --git a/specs/frontend-architecture.md b/specs/frontend-architecture.md index 560448d..b037865 100644 --- a/specs/frontend-architecture.md +++ b/specs/frontend-architecture.md @@ -39,14 +39,17 @@ apps/web/src/ │ ├── planning/ │ │ ├── RecipePickerDialog.tsx # dialogue "ajouter au planning" — parcourir/prévisualiser/importer, voir plus bas │ │ └── recipe-picker-dialog.scss -│ └── recipes/ # catalogue, import, édition — voir plus bas -│ ├── RecipeTable.tsx / RecipeTabs.tsx / RecipeDetailPanel.tsx -│ ├── RecipeSourcesPanel.tsx / SourceItemTable.tsx / useEnabledSources.ts -│ ├── RecipeImportForm.tsx / recipe-import-draft.ts -│ ├── IngredientPicker.tsx / IngredientRow.tsx / StepListEditor.tsx / StepDescription.tsx -│ ├── highlight-tech-steps.ts / ingredient-icons.tsx -│ ├── DietTagSelect.tsx / DietBadges.tsx / AllergenBadges.tsx / ReproducibleBadge.tsx / FavoriteStarButton.tsx -│ └── recipes.scss +│ └── recipes/ # catalogue, import, édition — voir plus bas ; sous-dossiers par sous-domaine, pas de fichiers à plat +│ ├── RecipeTable.tsx / RecipeTabs.tsx / RecipeDetailPanel.tsx # racine : composants transverses au sous-domaine (utilisés par plusieurs des sous-dossiers ci-dessous) +│ ├── recipes.scss # feuille de style partagée, importée depuis chaque sous-dossier via ../recipes.scss +│ ├── badges/ +│ │ └── DietTagSelect.tsx / DietBadges.tsx / AllergenBadges.tsx / ReproducibleBadge.tsx / FavoriteStarButton.tsx +│ ├── ingredients/ +│ │ └── IngredientPicker.tsx / IngredientRow.tsx / ingredient-icons.tsx +│ ├── steps/ +│ │ └── StepListEditor.tsx / StepDescription.tsx / highlight-tech-steps.ts +│ └── sources/ +│ └── RecipeSourcesPanel.tsx / SourceItemTable.tsx / RecipeImportForm.tsx / recipe-import-draft.ts / useEnabledSources.ts ├── layouts/ │ ├── AppLayout.tsx + .scss # sidebar (nav, sous-menu Paramètres, menu compte) commune à tout l'espace connecté, voir plus bas │ └── nav-icons.tsx # ré-export nommé des icônes lucide-react utilisées par la sidebar