app: Allow to edit the default person count of a recipe
This commit is contained in:
parent
fe187c2885
commit
e54bb35ff4
1 changed files with 141 additions and 13 deletions
|
|
@ -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,8 +948,10 @@ fn RecipeInfoView(props: &RecipeInfoProps) -> Html {
|
|||
update={props.update.clone()}
|
||||
/>
|
||||
</div>
|
||||
<div class="mt-2">
|
||||
<div class="w-50 text-start input-group">
|
||||
<div class="mt-2 container text-start">
|
||||
<div class="row">
|
||||
<div class="col-8">
|
||||
<div class="input-group">
|
||||
<input
|
||||
class="form-control"
|
||||
type="number"
|
||||
|
|
@ -845,6 +963,16 @@ fn RecipeInfoView(props: &RecipeInfoProps) -> Html {
|
|||
<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 {
|
||||
<div class={classes!("alert", "alert-danger")} role="alert">
|
||||
{e}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue