From c212a453e3814179a9aa9ebceb6a8e410756f6b2 Mon Sep 17 00:00:00 2001 From: Jeremy Wall Date: Fri, 11 Feb 2022 20:04:52 -0500 Subject: [PATCH] Working shopping list creation --- web/src/components/shopping.rs | 14 ++++++-------- web/src/service.rs | 26 +++++++++++++++++++------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/web/src/components/shopping.rs b/web/src/components/shopping.rs index bca6301..2842548 100644 --- a/web/src/components/shopping.rs +++ b/web/src/components/shopping.rs @@ -32,11 +32,12 @@ fn recipe_check_box(props: RecipeCheckBoxProps) -> View { let id_as_str = Rc::new(format!("{}", i)); let id_cloned = id_as_str.clone(); let id_cloned_2 = id_as_str.clone(); + let count = Signal::new(String::from("0")); view! { - input(type="checkbox", name="recipe_id", value=id_as_str.clone(), on:click=move |_| { + input(type="number", min="0", bind:value=count.clone(), name="recipe_id", value=id_as_str.clone(), on:change=move |_| { let mut app_service = app_service.clone(); - console_log!("clicked checkbox for id {}", id_cloned); - app_service.add_recipe_by_index(i); + console_log!("setting recipe id: {} to count: {}", i, *count.get()); + app_service.set_recipe_count_by_index(i, count.get().parse().unwrap()); }) label(for=id_cloned_2) { (props.title) } } @@ -67,11 +68,8 @@ pub fn recipe_selector() -> View { fn shopping_list() -> View { let app_service = use_context::(); let ingredients = create_memo(move || { - let mut acc = IngredientAccumulator::new(); - for r in app_service.get_menu_list().get().iter() { - acc.accumulate_from(r); - } - acc.ingredients() + let ingredients = app_service.get_menu_list(); + ingredients .iter() .map(|(k, v)| (k.clone(), v.clone())) .collect::>() diff --git a/web/src/service.rs b/web/src/service.rs index 8d25852..b2feccc 100644 --- a/web/src/service.rs +++ b/web/src/service.rs @@ -11,6 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +use std::collections::BTreeMap; use std::rc::Rc; use crate::{console_debug, console_error}; @@ -18,20 +19,20 @@ use crate::{console_debug, console_error}; use reqwasm::http; use sycamore::prelude::*; -use recipes::{parse, Recipe}; +use recipes::{parse, Ingredient, IngredientAccumulator, IngredientKey, Recipe}; #[derive(Clone)] pub struct AppService { // TODO(jwall): Should each Recipe also be a Signal? recipes: Signal>, - menu_list: Signal>, + menu_list: Signal>, } impl AppService { pub fn new() -> Self { Self { recipes: Signal::new(Vec::new()), - menu_list: Signal::new(Vec::new()), + menu_list: Signal::new(BTreeMap::new()), } } @@ -64,13 +65,24 @@ impl AppService { } } - pub fn get_menu_list(&self) -> Signal> { - self.menu_list.clone() + pub fn get_recipe_by_index(&self, idx: usize) -> Option { + self.recipes.get().get(idx).map(|(_, r)| r.clone()) } - pub fn add_recipe_by_index(&mut self, i: usize) { + pub fn get_menu_list(&self) -> BTreeMap { + let mut acc = IngredientAccumulator::new(); + let recipe_counts = self.menu_list.get(); + for (idx, count) in recipe_counts.iter() { + for _ in 0..*count { + acc.accumulate_from(&self.get_recipe_by_index(*idx).unwrap()); + } + } + acc.ingredients() + } + + pub fn set_recipe_count_by_index(&mut self, i: usize, count: usize) { let mut v = (*self.menu_list.get()).clone(); - v.push(self.recipes.get()[i].1.clone()); + v.insert(i, count); self.menu_list.set(v); }