From 8cf5803c1e4f759779cec4423376be22fcd6d770 Mon Sep 17 00:00:00 2001 From: traxys Date: Fri, 30 Jun 2023 12:46:31 +0200 Subject: [PATCH] app: Isolate RecipeInfoView in a separate component --- app/src/recipe.rs | 223 ++++++++++++++++++++++++++-------------------- 1 file changed, 124 insertions(+), 99 deletions(-) diff --git a/app/src/recipe.rs b/app/src/recipe.rs index c7ab484..0ac722f 100644 --- a/app/src/recipe.rs +++ b/app/src/recipe.rs @@ -1,3 +1,5 @@ +use std::rc::Rc; + use api::{ AddRecipeIngredientRequest, IngredientInfo, RecipeEditRating, RecipeEditStepsRequest, RecipeInfo, RecipeIngredientEditRequest, RecipeRenameRequest, @@ -128,7 +130,7 @@ struct RecipeViewerInnerProps { household: Uuid, } -async fn fetch_recipe(token: String, household: Uuid, id: i64) -> anyhow::Result { +async fn fetch_recipe(token: String, household: Uuid, id: i64) -> anyhow::Result> { let rsp = gloo_net::http::Request::get(api!("household/{household}/recipe/{id}")) .header("Authorization", &format!("Bearer {token}")) .send() @@ -139,7 +141,7 @@ async fn fetch_recipe(token: String, household: Uuid, id: i64) -> anyhow::Result anyhow::bail!("Could not get recipe (code={}): {body}", rsp.status()); } - Ok(rsp.json().await?) + Ok(Rc::new(rsp.json().await?)) } #[derive(Clone, PartialEq, Properties)] @@ -756,25 +758,23 @@ fn EditRating(props: &EditRatingProps) -> Html { } } +#[derive(Properties, PartialEq, Clone)] +struct RecipeInfoProps { + token: String, + household: Uuid, + update: Callback<()>, + recipe_id: i64, + info: Rc, +} + #[function_component] -fn RecipeViewerInner(props: &RecipeViewerInnerProps) -> HtmlResult { - let recipe_render = use_state(|| 0u64); - let recipe = use_future_with_deps( - |_| fetch_recipe(props.token.clone(), props.household, props.id), - *recipe_render, - )?; - - let update = Callback::from(move |_| { - recipe_render.set((*recipe_render).wrapping_add(1)); - }); - +fn RecipeInfoView(props: &RecipeInfoProps) -> Html { let error = use_state(|| None::); - let mk_del_ig = |&id| { - let update = update.clone(); + let update = props.update.clone(); let token = props.token.clone(); let household = props.household; - let recipe = props.id; + let recipe = props.recipe_id; let err = error.clone(); Callback::from(move |_| { let update = update.clone(); @@ -794,94 +794,119 @@ fn RecipeViewerInner(props: &RecipeViewerInnerProps) -> HtmlResult { }) }; + html! {<> +

{&props.info.name}

+
+ + +
+ if let Some(e) = &*error { + + } +
+
+

{"Ingredients"}

+
    + {for props.info.ingredients.iter().map(|(id, info, amount)| { + let delete_modal_id = format!("rcpRmIg{id}"); + let amount_rounded = amount.round(); + html!{ +
  • + {format!("{amount_rounded}{} {}", info.unit.as_deref().unwrap_or(""), info.name)} +
    + + {format!("Are you sure you to delete '{}'", info.name)} + + + + + +
    +
  • + }})} +
+ +
+
+
+

{"Steps"}

+
    + {for props.info.steps.split('\n').map(|text| html!{ +
  • {text}
  • + })} +
+ +
+ } +} + +#[function_component] +fn RecipeViewerInner(props: &RecipeViewerInnerProps) -> HtmlResult { + let recipe_render = use_state(|| 0u64); + let recipe = use_future_with_deps( + |_| fetch_recipe(props.token.clone(), props.household, props.id), + *recipe_render, + )?; + + let update = Callback::from(move |_| { + recipe_render.set((*recipe_render).wrapping_add(1)); + }); + Ok(match &*recipe { - Ok(r) => html! {<> -

{&r.name}

-
- { + html! { + - -
- if let Some(e) = &*error { - } -
-
-

{"Ingredients"}

-
    - {for r.ingredients.iter().map(|(id, info, amount)| { - let delete_modal_id = format!("rcpRmIg{id}"); - let amount_rounded = amount.round(); - html!{ -
  • - {format!("{amount_rounded}{} {}", info.unit.as_deref().unwrap_or(""), info.name)} -
    - - {format!("Are you sure you to delete '{}'", info.name)} - - - - - -
    -
  • - }})} -
- -
-
-
-

{"Steps"}

-
    - {for r.steps.split('\n').map(|text| html!{ -
  • {text}
  • - })} -
- -
- }, + } Err(e) => html! {