diff --git a/web/src/components/mod.rs b/web/src/components/mod.rs new file mode 100644 index 0000000..2421d13 --- /dev/null +++ b/web/src/components/mod.rs @@ -0,0 +1,17 @@ +// Copyright 2022 Jeremy Wall +// +// 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. +pub mod recipe; +pub mod root; +//mod recipe; +//mod menu; diff --git a/web/src/components/recipe.rs b/web/src/components/recipe.rs new file mode 100644 index 0000000..eb2e29a --- /dev/null +++ b/web/src/components/recipe.rs @@ -0,0 +1,66 @@ +// Copyright 2022 Jeremy Wall +// +// 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 crate::service::AppService; + +use recipes; +use sycamore::{context::use_context, prelude::*}; + +#[component(Steps)] +fn steps(steps: ReadSignal>) -> View { + view! { + h2 { "Steps: " } + ul(class="recipe_steps") { + Indexed(IndexedProps{ + iterable: steps, + template: |step: recipes::Step| { view! { + li { + //div() {} + div(class="instructions") {} + ul(class="ingredients") { + Indexed(IndexedProps{ + iterable: Signal::new(step.ingredients).handle(), + template: |i| { view! { + li { + (i.amt) (i.name) (i.form.as_ref().map(|f| format!("({})", f)).unwrap_or(String::new())) + } + }} + }) + } + }} + } + }) + } + } +} + +#[component(Recipe)] +pub fn recipe(idx: ReadSignal) -> View { + let app_service = use_context::(); + // TODO(jwall): This does unnecessary copies. Can we eliminate that? + let recipe = create_memo(move || app_service.get_recipes().get()[*idx.get()].1.clone()); + let title = create_memo(cloned!((recipe) => move || recipe.get().title.clone())); + let desc = create_memo( + cloned!((recipe) => move || recipe.clone().get().desc.clone().unwrap_or_else(|| String::new())), + ); + let steps = create_memo(cloned!((recipe) => move || recipe.get().steps.clone())); + view! { + div(class="recipe") { + h1(class="recipe_title") { (title.get()) } + div(class="recipe_description") { + (desc.get()) + } + Steps(steps) + } + } +} diff --git a/web/src/root.rs b/web/src/components/root.rs similarity index 100% rename from web/src/root.rs rename to web/src/components/root.rs diff --git a/web/src/main.rs b/web/src/main.rs index 3d7416e..91f4b36 100644 --- a/web/src/main.rs +++ b/web/src/main.rs @@ -11,12 +11,11 @@ // 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. -mod typings; +mod components; mod service; +mod typings; mod web; -mod root; -//mod recipe; -//mod menu; + use sycamore::prelude::*; use web::UI; diff --git a/web/src/service.rs b/web/src/service.rs index 0b55339..b0c3116 100644 --- a/web/src/service.rs +++ b/web/src/service.rs @@ -20,6 +20,7 @@ use recipes::{parse, Recipe}; #[derive(Clone)] pub struct AppService { + // TODO(jwall): Should each Recipe also be a Signal? recipes: Signal>, } diff --git a/web/src/web.rs b/web/src/web.rs index f7b50d0..e3da97f 100644 --- a/web/src/web.rs +++ b/web/src/web.rs @@ -11,8 +11,8 @@ // 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 crate::{components::root, service::AppService}; use crate::{console_debug, console_error, console_log}; -use crate::{root, service::AppService}; use sycamore::{ context::{ContextProvider, ContextProviderProps},