mirror of
https://github.com/zaphar/kitchen.git
synced 2025-07-22 19:40:14 -04:00
Thread statehandler through router to pages
This commit is contained in:
parent
e21353eeba
commit
90346d55eb
@ -14,7 +14,7 @@
|
|||||||
use sycamore::{futures::spawn_local_scoped, prelude::*};
|
use sycamore::{futures::spawn_local_scoped, prelude::*};
|
||||||
use tracing::{debug, info};
|
use tracing::{debug, info};
|
||||||
|
|
||||||
use crate::app_state;
|
use crate::app_state::{self, StateHandler};
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn LoginForm<G: Html>(cx: Scope) -> View<G> {
|
pub fn LoginForm<G: Html>(cx: Scope) -> View<G> {
|
||||||
@ -50,7 +50,7 @@ pub fn LoginForm<G: Html>(cx: Scope) -> View<G> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn LoginPage<G: Html>(cx: Scope) -> View<G> {
|
pub fn LoginPage<'ctx, G: Html>(cx: Scope<'ctx>, sh: StateHandler<'ctx>) -> View<G> {
|
||||||
view! {cx,
|
view! {cx,
|
||||||
LoginForm()
|
LoginForm()
|
||||||
}
|
}
|
||||||
|
@ -12,12 +12,12 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
use super::ManagePage;
|
use super::ManagePage;
|
||||||
use crate::components::add_recipe::AddRecipe;
|
use crate::{app_state::StateHandler, components::add_recipe::AddRecipe};
|
||||||
|
|
||||||
use sycamore::prelude::*;
|
use sycamore::prelude::*;
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn AddRecipePage<G: Html>(cx: Scope) -> View<G> {
|
pub fn AddRecipePage<'ctx, G: Html>(cx: Scope<'ctx>, sh: StateHandler<'ctx>) -> View<G> {
|
||||||
view! {cx,
|
view! {cx,
|
||||||
ManagePage(
|
ManagePage(
|
||||||
selected=Some("New Recipe".to_owned()),
|
selected=Some("New Recipe".to_owned()),
|
||||||
|
@ -12,12 +12,12 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
use super::ManagePage;
|
use super::ManagePage;
|
||||||
use crate::components::categories::*;
|
use crate::{app_state::StateHandler, components::categories::*};
|
||||||
|
|
||||||
use sycamore::prelude::*;
|
use sycamore::prelude::*;
|
||||||
|
|
||||||
#[component()]
|
#[component()]
|
||||||
pub fn CategoryPage<G: Html>(cx: Scope) -> View<G> {
|
pub fn CategoryPage<'ctx, G: Html>(cx: Scope<'ctx>, sh: StateHandler<'ctx>) -> View<G> {
|
||||||
view! {cx,
|
view! {cx,
|
||||||
ManagePage(
|
ManagePage(
|
||||||
selected=Some("Categories".to_owned()),
|
selected=Some("Categories".to_owned()),
|
||||||
|
@ -12,14 +12,14 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
use super::ManagePage;
|
use super::ManagePage;
|
||||||
use crate::components::recipe::Editor;
|
use crate::{app_state::StateHandler, components::recipe::Editor};
|
||||||
|
|
||||||
use sycamore::prelude::*;
|
use sycamore::prelude::*;
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
#[instrument]
|
#[instrument(skip_all)]
|
||||||
#[component()]
|
#[component()]
|
||||||
pub fn StaplesPage<G: Html>(cx: Scope) -> View<G> {
|
pub fn StaplesPage<'ctx, G: Html>(cx: Scope<'ctx>, sh: StateHandler<'ctx>) -> View<G> {
|
||||||
view! {cx,
|
view! {cx,
|
||||||
ManagePage(
|
ManagePage(
|
||||||
selected=Some("Staples".to_owned()),
|
selected=Some("Staples".to_owned()),
|
||||||
|
@ -14,10 +14,10 @@
|
|||||||
use sycamore::prelude::*;
|
use sycamore::prelude::*;
|
||||||
|
|
||||||
use super::PlanningPage;
|
use super::PlanningPage;
|
||||||
use crate::components::recipe_list::*;
|
use crate::{app_state::StateHandler, components::recipe_list::*};
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn CookPage<G: Html>(cx: Scope) -> View<G> {
|
pub fn CookPage<'ctx, G: Html>(cx: Scope<'ctx>, sh: StateHandler<'ctx>) -> View<G> {
|
||||||
view! {cx,
|
view! {cx,
|
||||||
PlanningPage(
|
PlanningPage(
|
||||||
selected=Some("Cook".to_owned()),
|
selected=Some("Cook".to_owned()),
|
||||||
|
@ -14,10 +14,10 @@
|
|||||||
use sycamore::prelude::*;
|
use sycamore::prelude::*;
|
||||||
|
|
||||||
use super::PlanningPage;
|
use super::PlanningPage;
|
||||||
use crate::components::shopping_list::*;
|
use crate::{app_state::StateHandler, components::shopping_list::*};
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn InventoryPage<G: Html>(cx: Scope) -> View<G> {
|
pub fn InventoryPage<'ctx, G: Html>(cx: Scope<'ctx>, sh: StateHandler<'ctx>) -> View<G> {
|
||||||
view! {cx,
|
view! {cx,
|
||||||
PlanningPage(
|
PlanningPage(
|
||||||
selected=Some("Inventory".to_owned()),
|
selected=Some("Inventory".to_owned()),
|
||||||
|
@ -12,12 +12,12 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
use super::PlanningPage;
|
use super::PlanningPage;
|
||||||
use crate::components::recipe_plan::*;
|
use crate::{app_state::StateHandler, components::recipe_plan::*};
|
||||||
|
|
||||||
use sycamore::prelude::*;
|
use sycamore::prelude::*;
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn PlanPage<G: Html>(cx: Scope) -> View<G> {
|
pub fn PlanPage<'ctx, G: Html>(cx: Scope<'ctx>, sh: StateHandler<'ctx>) -> View<G> {
|
||||||
view! {cx,
|
view! {cx,
|
||||||
PlanningPage(
|
PlanningPage(
|
||||||
selected=Some("Plan".to_owned()),
|
selected=Some("Plan".to_owned()),
|
||||||
|
@ -17,13 +17,14 @@ use crate::components::recipe::Editor;
|
|||||||
use sycamore::prelude::*;
|
use sycamore::prelude::*;
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
#[instrument]
|
#[instrument(skip_all, fields(recipe=props.recipe))]
|
||||||
#[component()]
|
#[component()]
|
||||||
pub fn RecipeEditPage<G: Html>(cx: Scope, props: RecipePageProps) -> View<G> {
|
pub fn RecipeEditPage<G: Html>(cx: Scope, props: RecipePageProps) -> View<G> {
|
||||||
|
let RecipePageProps { recipe, sh } = props;
|
||||||
view! {cx,
|
view! {cx,
|
||||||
RecipePage(
|
RecipePage(
|
||||||
selected=Some("Edit".to_owned()),
|
selected=Some("Edit".to_owned()),
|
||||||
recipe=props.recipe.clone(),
|
recipe=recipe.clone(),
|
||||||
) { Editor(props.recipe) }
|
) { Editor(recipe) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,16 +13,17 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
use sycamore::prelude::*;
|
use sycamore::prelude::*;
|
||||||
|
|
||||||
use crate::components::tabs::*;
|
use crate::{app_state::StateHandler, components::tabs::*};
|
||||||
|
|
||||||
mod edit;
|
mod edit;
|
||||||
mod view;
|
mod view;
|
||||||
pub use edit::*;
|
pub use edit::*;
|
||||||
pub use view::*;
|
pub use view::*;
|
||||||
|
|
||||||
#[derive(Debug, Props)]
|
#[derive(Props)]
|
||||||
pub struct RecipePageProps {
|
pub struct RecipePageProps<'ctx> {
|
||||||
pub recipe: String,
|
pub recipe: String,
|
||||||
|
pub sh: StateHandler<'ctx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Props)]
|
#[derive(Props)]
|
||||||
|
@ -18,13 +18,14 @@ use tracing::instrument;
|
|||||||
|
|
||||||
use super::{RecipePage, RecipePageProps};
|
use super::{RecipePage, RecipePageProps};
|
||||||
|
|
||||||
#[instrument]
|
#[instrument(skip_all, fields(recipe=props.recipe))]
|
||||||
#[component()]
|
#[component()]
|
||||||
pub fn RecipeViewPage<G: Html>(cx: Scope, props: RecipePageProps) -> View<G> {
|
pub fn RecipeViewPage<G: Html>(cx: Scope, props: RecipePageProps) -> View<G> {
|
||||||
|
let RecipePageProps { recipe, sh } = props;
|
||||||
view! {cx,
|
view! {cx,
|
||||||
RecipePage(
|
RecipePage(
|
||||||
selected=Some("View".to_owned()),
|
selected=Some("View".to_owned()),
|
||||||
recipe=props.recipe.clone(),
|
recipe=recipe.clone(),
|
||||||
) { Viewer(props.recipe) }
|
) { Viewer(recipe) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,65 +16,8 @@ use crate::app_state::StateHandler;
|
|||||||
use sycamore::prelude::*;
|
use sycamore::prelude::*;
|
||||||
use sycamore_router::{HistoryIntegration, Route, Router};
|
use sycamore_router::{HistoryIntegration, Route, Router};
|
||||||
|
|
||||||
use tracing::{debug, instrument};
|
|
||||||
|
|
||||||
use crate::pages::*;
|
use crate::pages::*;
|
||||||
|
|
||||||
#[instrument(skip_all, fields(?route))]
|
|
||||||
fn route_switch<'ctx, G: Html>(
|
|
||||||
cx: Scope<'ctx>,
|
|
||||||
sh: StateHandler<'ctx>,
|
|
||||||
route: &'ctx ReadSignal<Routes>,
|
|
||||||
) -> View<G> {
|
|
||||||
// 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)]
|
#[derive(Route, Debug)]
|
||||||
pub enum Routes {
|
pub enum Routes {
|
||||||
#[to("/ui/planning/<_..>")]
|
#[to("/ui/planning/<_..>")]
|
||||||
@ -131,11 +74,49 @@ pub struct HandlerProps<'ctx> {
|
|||||||
#[component]
|
#[component]
|
||||||
pub fn Handler<'ctx, G: Html>(cx: Scope<'ctx>, props: HandlerProps<'ctx>) -> View<G> {
|
pub fn Handler<'ctx, G: Html>(cx: Scope<'ctx>, props: HandlerProps<'ctx>) -> View<G> {
|
||||||
let HandlerProps { sh } = props;
|
let HandlerProps { sh } = props;
|
||||||
|
use ManageRoutes::*;
|
||||||
|
use PlanningRoutes::*;
|
||||||
view! {cx,
|
view! {cx,
|
||||||
Router(
|
Router(
|
||||||
integration=HistoryIntegration::new(),
|
integration=HistoryIntegration::new(),
|
||||||
view=|cx, route| {
|
view=move |cx: Scope, route: &ReadSignal<Routes>| {
|
||||||
route_switch(cx, sh, route)
|
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)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user