Logo ShareMyCode.io ShareMyCode.io
Partagez un extrait de code en quelques secondes.
Ajouter un code
manuel javascript javascript
Voici votre URL de partage
Cliquer pour copier dans le presse-papiers. Copié
Nom du fichier : erreur typage
import { yupResolver } from "@hookform/resolvers/yup";
import { useForm } from "react-hook-form";
import * as yup from "yup";
import { useLoaderData, useNavigate } from "react-router";
import AdminRecipeNav from "../../components/AdminRecipeNav";
import { createRecipe, updateRecipe } from "../../../../../../apis";
import type { recipeForm, recipeI } from "../../../../../../interfaces";

function RecipeForm() {
  // Récupérer la recette courante si mode édition
  const { recipe } = useLoaderData();

  // Mise en place de la navigation programmatique
  const navigate = useNavigate();

  // Schéma de validation
  const recipeSchema = yup.object({
    title: yup
      .string()
      .typeError("Doit être du texte")
      .required("Le titre est obligatoire")
      .min(10, "Minimum 10 caractères")
      .max(40, "Maximum 40 caractères"),
    imageUrl: yup
      .string()
      .typeError("Doit être du texte")
      .required("L'image est obligatoire")
      .url("L'image doit être un lien valide")
      .min(10, "Minimum 10 caractères")
      .max(100, "Maximum 100 caractères"),
    content: yup
      .string()
      .typeError("Doit être du texte")
      .required("Le contenu est obligatoire")
      .min(100, "Minimum 100 caractères")
      .max(1000, "Maximum 1000 caractères"),
  });

  // Gestion du formulaire
  const defaultValues = {
    title: recipe?.title ?? "",
    imageUrl: recipe?.imageUrl ?? "",
    content: recipe?.content ?? "",
  };

  const {
    register,
    formState: { errors, isSubmitting },
    reset,
    setError,
    clearErrors, // vider les erreurs
    handleSubmit,
  } = useForm<recipeForm>({
    defaultValues: defaultValues,
    criteriaMode: "all",
    resolver: yupResolver(recipeSchema)
  });

  // Envoi des données à l'API
  const onSubmit = async (newRecipe: Partial<recipeI>) => {
    console.log(newRecipe);

    try {
      clearErrors();
      if (recipe) {
        await updateRecipe({ ...newRecipe, _id: recipe._id });
      } else {
        await createRecipe(newRecipe); // envoyer la recette à l'API
      }
      reset(defaultValues); // réinitialiser le formulaire avec les valeurs par défaut
      navigate("../"); // rediriger l'utilisateur à la page d'accueil
    } catch (error) {
      setError("generic", { type: "generic", message: "Il y a une erreur" });
    }
  };

  return (
    <>
      <AdminRecipeNav />
      <h3 className="text-center mt-4">
        {recipe
          ? " Formulaire de mise à jour de recette"
          : " Formulaire de création de nouvelle recette"}
      </h3>
      <form
        action="#"
        method="POST"
        className="border rounded-2 p-5 m-auto mt-4"
        style={{ width: 500 }}
        onSubmit={handleSubmit(onSubmit)}
      >
        <div className="mt-4">
          <label htmlFor="title" className="form-label">
            Titre de la recette
          </label>
          <input
            {...register("title")}
            type="text"
            id="title"
            className="form-control"
          />
          {errors?.title?.types && (
            <ul>
              {Object.keys(errors.title.types).map((k) => (
                <li key={k} className="text-danger">
                  {errors.title?.types[k]}
                </li>
              ))}
            </ul>
          )}
        </div>
        <div className="mt-4">
          <label htmlFor="imageUrl" className="form-label">
            Image de la recette
          </label>
          <input
            {...register("imageUrl")}
            type="text"
            id="imageUrl"
            className="form-control"
          />
          {errors?.imageUrl && (
            <ul>
              {Object.keys(errors.imageUrl.types).map((k) => (
                <li key={k} className="text-danger">
                  {errors.imageUrl.types[k]}
                </li>
              ))}
            </ul>
          )}
        </div>
        <div className="mt-4">
          <label htmlFor="content" className="form-label">
            Contenu de la recette
          </label>
          <textarea
            {...register("content")}
            id="content"
            className="form-control"
          ></textarea>
          {errors?.content?.ty && (
            <ul>
              {Object.keys(errors.content.types).map((k) => (
                <li key={k} className="text-danger">
                  {errors.content.types[k]}
                </li>
              ))}
            </ul>
          )}
        </div>
        <button
          type="submit"
          className="btn btn-secondary text-white mt-5"
          disabled={isSubmitting}
        >
          Sauvegarder
        </button>
        {errors?.generic && (
          <p className="text-danger mt-1">{errors.generic.message}</p>
        )}
      </form>
    </>
  );
}

export default RecipeForm;
Informations
Cet extrait a été créé le
02 May 2026 à 15:34:42
Cet extrait expire le
01 Jun 2026 à 15:34:42
Langage :
javascript javascript
Lien
Demander la suppression