app: Allow to edit the default person count of a recipe

This commit is contained in:
traxys 2023-06-30 13:14:44 +02:00
parent fe187c2885
commit e54bb35ff4

View file

@ -1,8 +1,8 @@
use std::rc::Rc; use std::rc::Rc;
use api::{ use api::{
AddRecipeIngredientRequest, IngredientInfo, RecipeEditRating, RecipeEditStepsRequest, AddRecipeIngredientRequest, IngredientInfo, RecipeEditPersonCount, RecipeEditRating,
RecipeInfo, RecipeIngredientEditRequest, RecipeRenameRequest, RecipeEditStepsRequest, RecipeInfo, RecipeIngredientEditRequest, RecipeRenameRequest,
}; };
use itertools::Itertools; use itertools::Itertools;
use uuid::Uuid; use uuid::Uuid;
@ -758,6 +758,122 @@ fn EditRating(props: &EditRatingProps) -> Html {
</>} </>}
} }
async fn do_edit_person_count(
token: String,
household: Uuid,
recipe: i64,
person_count: u32,
) -> anyhow::Result<()> {
let rsp =
gloo_net::http::Request::patch(api!("household/{household}/recipe/{recipe}/person_count"))
.json(&RecipeEditPersonCount { person_count })?
.header("Authorization", &format!("Bearer {token}"))
.send()
.await?;
if !rsp.ok() {
let body = rsp.text().await.unwrap_or_default();
anyhow::bail!(
"Could not edit person_count (code={}): {body}",
rsp.status()
);
}
Ok(())
}
#[derive(Properties, PartialEq, Clone)]
struct EditPersonCountProps {
token: String,
household: Uuid,
recipe: i64,
person_count: u32,
}
#[function_component]
fn EditPersonCount(props: &EditPersonCountProps) -> Html {
let person_count = use_state(|| props.person_count);
let error = use_state(|| None::<String>);
let onchange = {
let person_count = person_count.clone();
Callback::from(move |e: Event| {
let Some(target) = e.target() else {
return;
};
let Ok(target) = target.dyn_into::<HtmlInputElement>() else {
return;
};
if !target.report_validity() {
return;
}
person_count.set(target.value().parse().expect("invalid number"));
})
};
let on_submit = {
let person_count = person_count.clone();
let token = props.token.clone();
let household = props.household;
let recipe = props.recipe;
let error = error.clone();
Callback::from(move |_| {
let token = token.clone();
let person_count = person_count.clone();
let error = error.clone();
wasm_bindgen_futures::spawn_local(async move {
match do_edit_person_count(token.clone(), household, recipe, *person_count)
.await
{
Ok(_) => {
let modal = bs::Modal::get_instance("#rcpEditPersonCount");
modal.hide();
error.set(None);
}
Err(e) => {
error.set(Some(format!("Could not edit person count: {e}")));
}
}
});
})
};
html! {<>
<ModalToggleButton modal_id="rcpEditPersonCount" classes={classes!("btn", "btn-secondary")}>
{"Edit"}
</ModalToggleButton>
<FormModal
id="rcpEditPersonCount"
fade=true
centered=true
submit_label="Edit"
title="Edit default person count"
{on_submit}
>
if let Some(e) = &*error {
<div class={classes!("alert", "alert-danger")} role="alert">
{e}
</div>
}
<div class="form-floating">
<input
type="number"
min="1"
class="form-control"
id="rcpEditPersonCountInp"
value={(*person_count).to_string()}
{onchange}
/>
<label for="rcpEditPersonCountInp">{"Default person count"}</label>
</div>
</FormModal>
</>}
}
#[derive(Properties, PartialEq, Clone)] #[derive(Properties, PartialEq, Clone)]
struct RecipeInfoProps { struct RecipeInfoProps {
token: String, token: String,
@ -832,17 +948,29 @@ fn RecipeInfoView(props: &RecipeInfoProps) -> Html {
update={props.update.clone()} update={props.update.clone()}
/> />
</div> </div>
<div class="mt-2"> <div class="mt-2 container text-start">
<div class="w-50 text-start input-group"> <div class="row">
<input <div class="col-8">
class="form-control" <div class="input-group">
type="number" <input
id="rcpPeopleCount" class="form-control"
min="1" type="number"
value={person_count.to_string()} id="rcpPeopleCount"
{onchange} min="1"
/> value={person_count.to_string()}
<span class="input-group-text">{"people"}</span> {onchange}
/>
<span class="input-group-text">{"people"}</span>
</div>
</div>
<div class="col">
<EditPersonCount
token={props.token.clone()}
recipe={props.recipe_id}
household={props.household}
person_count={props.info.person_count}
/>
</div>
</div> </div>
</div> </div>
if let Some(e) = &*error { if let Some(e) = &*error {