batchCooking/apps/web/src/features/profile/DietSelect.tsx
Nicolas e512c33ffc Web: composants partagés foyer/régime/allergènes (step 3/6)
- ApiClient: getDiets/getAllergies (référence), getCurrentHouse/
  renameHouse, updateDiet, getAllergyIds/updateAllergyIds.
- features/profile/: HouseNameField, DietSelect (toujours une option
  "aucun régime" -> null, étape skippable), AllergySelect (checkboxes
  en grille + fieldset/legend, pas un <select multiple> — plus
  tapable/accessible, notamment sur mobile). Tous "dumb"/contrôlés :
  reçoivent leurs données (diets/allergies) en props plutôt que de les
  fetcher eux-mêmes — le fetch/état de chargement reste à la page
  appelante.
- profile-forms.scss partagé par les trois (même split que
  features/auth/auth-form.scss vs Login/SignupPage : styles de champs
  ici, layout de page dans chaque page consommatrice).

Pas encore utilisés (aucune page ne les importe) — le wizard
d'inscription (étape suivante) et la page /foyer les cablent.
2026-08-16 23:22:19 +02:00

42 lines
1.4 KiB
TypeScript

import type { DietView } from "@batch-cooking/shared";
import { useTranslation } from "react-i18next";
import "./profile-forms.scss";
interface DietSelectProps {
diets: DietView[];
value: number | null;
onChange: (dietId: number | null) => void;
}
/**
* Dropdown picker for a dietary regime — used both by the signup wizard's
* regime step and the `/foyer` settings page. Always includes a "none"
* option (mapped to `null`, not just an empty label) since this step of the
* profile journey is skippable — a profile with no regime is a normal,
* valid state, not an incomplete one.
*
* Receives `diets` as a prop rather than fetching them itself: the caller
* (a page) owns loading state/errors for the reference list, this stays a
* plain, easy-to-test presentational component.
*/
export function DietSelect({ diets, value, onChange }: DietSelectProps) {
const { t } = useTranslation();
return (
<>
<label htmlFor="diet">{t("household.form.dietLabel")}</label>
<select
id="diet"
value={value ?? ""}
onChange={(e) => onChange(e.target.value === "" ? null : Number(e.target.value))}
>
<option value="">{t("household.form.dietNone")}</option>
{diets.map((diet) => (
<option key={diet.id} value={diet.id}>
{diet.name}
</option>
))}
</select>
</>
);
}