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 api::{
AddRecipeIngredientRequest, IngredientInfo, RecipeEditRating, RecipeEditStepsRequest,
RecipeInfo, RecipeIngredientEditRequest, RecipeRenameRequest,
AddRecipeIngredientRequest, IngredientInfo, RecipeEditPersonCount, RecipeEditRating,
RecipeEditStepsRequest, RecipeInfo, RecipeIngredientEditRequest, RecipeRenameRequest,
};
use itertools::Itertools;
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)]
struct RecipeInfoProps {
token: String,
@ -832,17 +948,29 @@ fn RecipeInfoView(props: &RecipeInfoProps) -> Html {
update={props.update.clone()}
/>
</div>
<div class="mt-2">
<div class="w-50 text-start input-group">
<input
class="form-control"
type="number"
id="rcpPeopleCount"
min="1"
value={person_count.to_string()}
{onchange}
/>
<span class="input-group-text">{"people"}</span>
<div class="mt-2 container text-start">
<div class="row">
<div class="col-8">
<div class="input-group">
<input
class="form-control"
type="number"
id="rcpPeopleCount"
min="1"
value={person_count.to_string()}
{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>
if let Some(e) = &*error {