From 80b6126e10ba6f60861c446a7d0f0bda91a52e6c Mon Sep 17 00:00:00 2001 From: Jeremy Wall Date: Tue, 17 Jan 2023 19:21:37 -0500 Subject: [PATCH] UI for selecting a plan from the list --- web/src/api.rs | 1 + web/src/components/mod.rs | 2 ++ web/src/components/plan_list.rs | 44 ++++++++++++++++++++++++++++++++ web/src/pages/planning/select.rs | 13 ++++++++-- 4 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 web/src/components/plan_list.rs diff --git a/web/src/api.rs b/web/src/api.rs index 8e2b426..97e4ce5 100644 --- a/web/src/api.rs +++ b/web/src/api.rs @@ -572,6 +572,7 @@ impl HttpStore { #[instrument(skip_all)] pub async fn store_app_state(&self, state: AppState) -> Result<(), Error> { + // TODO(jwall): We need to be able to store state for the plan date if set. let mut plan = Vec::new(); for (key, count) in state.recipe_counts.iter() { plan.push((key.clone(), *count as i32)); diff --git a/web/src/components/mod.rs b/web/src/components/mod.rs index 17bf760..e0ad4df 100644 --- a/web/src/components/mod.rs +++ b/web/src/components/mod.rs @@ -16,6 +16,7 @@ pub mod categories; pub mod footer; pub mod header; pub mod number_field; +pub mod plan_list; pub mod recipe; pub mod recipe_list; pub mod recipe_plan; @@ -29,6 +30,7 @@ pub use categories::*; pub use footer::*; pub use header::*; pub use number_field::*; +pub use plan_list::*; pub use recipe::*; pub use recipe_list::*; pub use recipe_plan::*; diff --git a/web/src/components/plan_list.rs b/web/src/components/plan_list.rs new file mode 100644 index 0000000..fb20db6 --- /dev/null +++ b/web/src/components/plan_list.rs @@ -0,0 +1,44 @@ +use chrono::NaiveDate; +// Copyright 2023 Jeremy Wall (Jeremy@marzhilsltudios.com) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// 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 sycamore::prelude::*; + +use crate::app_state::{Message, StateHandler}; +use tracing::instrument; + +#[derive(Props)] +pub struct PlanListProps<'ctx> { + sh: StateHandler<'ctx>, + list: &'ctx ReadSignal>, +} + +// TODO(jwall): We also need a "new plan button" +#[instrument(skip_all, fields(dates=?props.list))] +#[component] +pub fn PlanList<'ctx, G: Html>(cx: Scope<'ctx>, props: PlanListProps<'ctx>) -> View { + let PlanListProps { sh, list } = props; + view! {cx, + Indexed( + iterable=list, + view=move |cx, date| { + let date_display = format!("{}", date); + view!{cx, + div(on:click=move |_| { + sh.dispatch(cx, Message::SelectPlanDate(date)) + }) { (date_display) } + } + }, + ) + } +} diff --git a/web/src/pages/planning/select.rs b/web/src/pages/planning/select.rs index 09908ce..565dad9 100644 --- a/web/src/pages/planning/select.rs +++ b/web/src/pages/planning/select.rs @@ -12,15 +12,24 @@ // See the License for the specific language governing permissions and // limitations under the License. use super::PlanningPage; -use crate::app_state::StateHandler; +use crate::{app_state::StateHandler, components::PlanList}; +use chrono::NaiveDate; use sycamore::prelude::*; #[component] pub fn SelectPage<'ctx, G: Html>(cx: Scope<'ctx>, sh: StateHandler<'ctx>) -> View { + let plan_dates = sh.get_selector(cx, |state| { + state + .get() + .plan_dates + .iter() + .cloned() + .collect::>() + }); view! {cx, PlanningPage( selected=Some("Select".to_owned()), - ) { "TODO(jwall)" } + ) { PlanList(sh=sh, list=plan_dates) } } }