diff --git a/web/src/pages/login.rs b/web/src/pages/login.rs index bd0a8c3..0f4a243 100644 --- a/web/src/pages/login.rs +++ b/web/src/pages/login.rs @@ -14,7 +14,7 @@ use sycamore::{futures::spawn_local_scoped, prelude::*}; use tracing::{debug, info}; -use crate::app_state; +use crate::app_state::{self, StateHandler}; #[component] pub fn LoginForm(cx: Scope) -> View { @@ -50,7 +50,7 @@ pub fn LoginForm(cx: Scope) -> View { } #[component] -pub fn LoginPage(cx: Scope) -> View { +pub fn LoginPage<'ctx, G: Html>(cx: Scope<'ctx>, sh: StateHandler<'ctx>) -> View { view! {cx, LoginForm() } diff --git a/web/src/pages/manage/add_recipe.rs b/web/src/pages/manage/add_recipe.rs index 7f68088..68830b7 100644 --- a/web/src/pages/manage/add_recipe.rs +++ b/web/src/pages/manage/add_recipe.rs @@ -12,12 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. use super::ManagePage; -use crate::components::add_recipe::AddRecipe; +use crate::{app_state::StateHandler, components::add_recipe::AddRecipe}; use sycamore::prelude::*; #[component] -pub fn AddRecipePage(cx: Scope) -> View { +pub fn AddRecipePage<'ctx, G: Html>(cx: Scope<'ctx>, sh: StateHandler<'ctx>) -> View { view! {cx, ManagePage( selected=Some("New Recipe".to_owned()), diff --git a/web/src/pages/manage/categories.rs b/web/src/pages/manage/categories.rs index 1ebbc83..ac78bf6 100644 --- a/web/src/pages/manage/categories.rs +++ b/web/src/pages/manage/categories.rs @@ -12,12 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. use super::ManagePage; -use crate::components::categories::*; +use crate::{app_state::StateHandler, components::categories::*}; use sycamore::prelude::*; #[component()] -pub fn CategoryPage(cx: Scope) -> View { +pub fn CategoryPage<'ctx, G: Html>(cx: Scope<'ctx>, sh: StateHandler<'ctx>) -> View { view! {cx, ManagePage( selected=Some("Categories".to_owned()), diff --git a/web/src/pages/manage/staples.rs b/web/src/pages/manage/staples.rs index 59361bf..d3aa9af 100644 --- a/web/src/pages/manage/staples.rs +++ b/web/src/pages/manage/staples.rs @@ -12,14 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. use super::ManagePage; -use crate::components::recipe::Editor; +use crate::{app_state::StateHandler, components::recipe::Editor}; use sycamore::prelude::*; use tracing::instrument; -#[instrument] +#[instrument(skip_all)] #[component()] -pub fn StaplesPage(cx: Scope) -> View { +pub fn StaplesPage<'ctx, G: Html>(cx: Scope<'ctx>, sh: StateHandler<'ctx>) -> View { view! {cx, ManagePage( selected=Some("Staples".to_owned()), diff --git a/web/src/pages/planning/cook.rs b/web/src/pages/planning/cook.rs index 60100b5..7779912 100644 --- a/web/src/pages/planning/cook.rs +++ b/web/src/pages/planning/cook.rs @@ -14,10 +14,10 @@ use sycamore::prelude::*; use super::PlanningPage; -use crate::components::recipe_list::*; +use crate::{app_state::StateHandler, components::recipe_list::*}; #[component] -pub fn CookPage(cx: Scope) -> View { +pub fn CookPage<'ctx, G: Html>(cx: Scope<'ctx>, sh: StateHandler<'ctx>) -> View { view! {cx, PlanningPage( selected=Some("Cook".to_owned()), diff --git a/web/src/pages/planning/inventory.rs b/web/src/pages/planning/inventory.rs index 953503d..e6ea29f 100644 --- a/web/src/pages/planning/inventory.rs +++ b/web/src/pages/planning/inventory.rs @@ -14,10 +14,10 @@ use sycamore::prelude::*; use super::PlanningPage; -use crate::components::shopping_list::*; +use crate::{app_state::StateHandler, components::shopping_list::*}; #[component] -pub fn InventoryPage(cx: Scope) -> View { +pub fn InventoryPage<'ctx, G: Html>(cx: Scope<'ctx>, sh: StateHandler<'ctx>) -> View { view! {cx, PlanningPage( selected=Some("Inventory".to_owned()), diff --git a/web/src/pages/planning/plan.rs b/web/src/pages/planning/plan.rs index ef6a0cf..838eb76 100644 --- a/web/src/pages/planning/plan.rs +++ b/web/src/pages/planning/plan.rs @@ -12,12 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. use super::PlanningPage; -use crate::components::recipe_plan::*; +use crate::{app_state::StateHandler, components::recipe_plan::*}; use sycamore::prelude::*; #[component] -pub fn PlanPage(cx: Scope) -> View { +pub fn PlanPage<'ctx, G: Html>(cx: Scope<'ctx>, sh: StateHandler<'ctx>) -> View { view! {cx, PlanningPage( selected=Some("Plan".to_owned()), diff --git a/web/src/pages/recipe/edit.rs b/web/src/pages/recipe/edit.rs index 9e29ae1..fa6e9b5 100644 --- a/web/src/pages/recipe/edit.rs +++ b/web/src/pages/recipe/edit.rs @@ -17,13 +17,14 @@ use crate::components::recipe::Editor; use sycamore::prelude::*; use tracing::instrument; -#[instrument] +#[instrument(skip_all, fields(recipe=props.recipe))] #[component()] pub fn RecipeEditPage(cx: Scope, props: RecipePageProps) -> View { + let RecipePageProps { recipe, sh } = props; view! {cx, RecipePage( selected=Some("Edit".to_owned()), - recipe=props.recipe.clone(), - ) { Editor(props.recipe) } + recipe=recipe.clone(), + ) { Editor(recipe) } } } diff --git a/web/src/pages/recipe/mod.rs b/web/src/pages/recipe/mod.rs index f137c8c..9e4a5c1 100644 --- a/web/src/pages/recipe/mod.rs +++ b/web/src/pages/recipe/mod.rs @@ -13,16 +13,17 @@ // limitations under the License. use sycamore::prelude::*; -use crate::components::tabs::*; +use crate::{app_state::StateHandler, components::tabs::*}; mod edit; mod view; pub use edit::*; pub use view::*; -#[derive(Debug, Props)] -pub struct RecipePageProps { +#[derive(Props)] +pub struct RecipePageProps<'ctx> { pub recipe: String, + pub sh: StateHandler<'ctx>, } #[derive(Props)] diff --git a/web/src/pages/recipe/view.rs b/web/src/pages/recipe/view.rs index 8685608..b98331c 100644 --- a/web/src/pages/recipe/view.rs +++ b/web/src/pages/recipe/view.rs @@ -18,13 +18,14 @@ use tracing::instrument; use super::{RecipePage, RecipePageProps}; -#[instrument] +#[instrument(skip_all, fields(recipe=props.recipe))] #[component()] pub fn RecipeViewPage(cx: Scope, props: RecipePageProps) -> View { + let RecipePageProps { recipe, sh } = props; view! {cx, RecipePage( selected=Some("View".to_owned()), - recipe=props.recipe.clone(), - ) { Viewer(props.recipe) } + recipe=recipe.clone(), + ) { Viewer(recipe) } } } diff --git a/web/src/routing/mod.rs b/web/src/routing/mod.rs index c8c3024..1bba2b9 100644 --- a/web/src/routing/mod.rs +++ b/web/src/routing/mod.rs @@ -16,65 +16,8 @@ use crate::app_state::StateHandler; use sycamore::prelude::*; use sycamore_router::{HistoryIntegration, Route, Router}; -use tracing::{debug, instrument}; - use crate::pages::*; -#[instrument(skip_all, fields(?route))] -fn route_switch<'ctx, G: Html>( - cx: Scope<'ctx>, - sh: StateHandler<'ctx>, - route: &'ctx ReadSignal, -) -> View { - // NOTE(jwall): This needs to not be a dynamic node. The rules around - // this are somewhat unclear and underdocumented for Sycamore. But basically - // avoid conditionals in the `view!` macro calls here. - - let switcher = |cx: Scope, sh: StateHandler, route: &Routes| { - debug!(?route, "Dispatching for route"); - match route { - Routes::Planning(Plan) => view! {cx, - PlanPage() - }, - Routes::Planning(Inventory) => view! {cx, - InventoryPage() - }, - Routes::Planning(Cook) => view! {cx, - CookPage() - }, - Routes::Login => view! {cx, - LoginPage() - }, - Routes::Recipe(RecipeRoutes::View(id)) => view! {cx, - RecipeViewPage(recipe=id.clone()) - }, - Routes::Recipe(RecipeRoutes::Edit(id)) => view! {cx, - RecipeEditPage(recipe=id.clone()) - }, - Routes::Manage(ManageRoutes::Categories) => view! {cx, - CategoryPage() - }, - Routes::Manage(ManageRoutes::NewRecipe) => view! {cx, - AddRecipePage() - }, - Routes::Manage(ManageRoutes::Staples) => view! {cx, - StaplesPage() - }, - Routes::NotFound - | Routes::Manage(ManageRoutes::NotFound) - | Routes::Planning(PlanningRoutes::NotFound) - | Routes::Recipe(RecipeRoutes::NotFound) => view! {cx, - // TODO(Create a real one) - PlanPage() - }, - } - }; - use PlanningRoutes::*; - view! {cx, - (switcher(cx, sh, route.get().as_ref())) - } -} - #[derive(Route, Debug)] pub enum Routes { #[to("/ui/planning/<_..>")] @@ -131,11 +74,49 @@ pub struct HandlerProps<'ctx> { #[component] pub fn Handler<'ctx, G: Html>(cx: Scope<'ctx>, props: HandlerProps<'ctx>) -> View { let HandlerProps { sh } = props; + use ManageRoutes::*; + use PlanningRoutes::*; view! {cx, Router( integration=HistoryIntegration::new(), - view=|cx, route| { - route_switch(cx, sh, route) + view=move |cx: Scope, route: &ReadSignal| { + match route.get().as_ref() { + Routes::Planning(Plan) => view! {cx, + PlanPage(sh) + }, + Routes::Planning(Inventory) => view! {cx, + InventoryPage(sh) + }, + Routes::Planning(Cook) => view! {cx, + CookPage(sh) + }, + Routes::Login => view! {cx, + LoginPage(sh) + }, + Routes::Recipe(RecipeRoutes::View(id)) => view! {cx, + RecipeViewPage(recipe=id.clone(), sh=sh) + }, + Routes::Recipe(RecipeRoutes::Edit(id)) => view! {cx, + RecipeEditPage(recipe=id.clone(), sh=sh) + }, + Routes::Manage(Categories) => view! {cx, + CategoryPage(sh) + }, + Routes::Manage(NewRecipe) => view! {cx, + AddRecipePage(sh) + }, + Routes::Manage(Staples) => view! {cx, + StaplesPage(sh) + }, + Routes::NotFound + | Routes::Manage(ManageRoutes::NotFound) + | Routes::Planning(PlanningRoutes::NotFound) + | Routes::Recipe(RecipeRoutes::NotFound) => view! {cx, + // TODO(Create a real one) + PlanPage(sh) + }, + } + }, ) }