From f3788e31a961a2c986451ce2efac8b16ec7dd364 Mon Sep 17 00:00:00 2001 From: traxys Date: Sun, 25 Jun 2023 14:12:09 +0200 Subject: [PATCH] app: Allow to list recipes --- app/src/main.rs | 40 ++++++++++++++++++++++ app/src/recipe.rs | 84 ++++++++++++++++++++++++++++++++++++++++++++++ app/src/sidebar.rs | 18 ++++++---- 3 files changed, 136 insertions(+), 6 deletions(-) create mode 100644 app/src/recipe.rs diff --git a/app/src/main.rs b/app/src/main.rs index ecfa528..f9ea807 100644 --- a/app/src/main.rs +++ b/app/src/main.rs @@ -22,6 +22,7 @@ mod bootstrap; mod ingredients; mod recipe_creator; mod sidebar; +mod recipe; const API_ROUTE: &str = match option_env!("REGALADE_API_SERVER_BASE") { None => "http://localhost:8085", @@ -50,11 +51,45 @@ enum Route { NewRecipe, #[at("/recipe/:id")] Recipe { id: i64 }, + #[at("/recipe")] + SearchRecipe, #[at("/404")] #[not_found] NotFound, } +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +enum RouteKind { + Index, + Ingredients, + NewRecipe, + Recipe, +} + +impl Route { + fn kind(&self) -> Option { + match self { + Route::Index => Some(RouteKind::Index), + Route::Ingredients => Some(RouteKind::Ingredients), + Route::NewRecipe => Some(RouteKind::NewRecipe), + Route::Recipe { .. } => Some(RouteKind::Recipe), + Route::SearchRecipe => Some(RouteKind::Recipe), + _ => None, + } + } +} + +impl RouteKind { + fn redirect_to(&self) -> Route { + match self { + RouteKind::Index => Route::Index, + RouteKind::Ingredients => Route::Ingredients, + RouteKind::NewRecipe => Route::NewRecipe, + RouteKind::Recipe => Route::SearchRecipe, + } + } +} + #[function_component] fn App() -> Html { html! { @@ -483,6 +518,11 @@ fn switch(route: Route) -> Html { {format!("RECIPE {id}")} }, + Route::SearchRecipe => html!{ + + + + }, Route::NotFound => html! { "Page not found" }, diff --git a/app/src/recipe.rs b/app/src/recipe.rs new file mode 100644 index 0000000..ec20d49 --- /dev/null +++ b/app/src/recipe.rs @@ -0,0 +1,84 @@ +use uuid::Uuid; +use yew::{prelude::*, suspense::use_future}; +use yew_router::prelude::*; + +use crate::{api, RegaladeGlobalState, Route}; + +async fn get_all_recipes( + token: String, + household: Uuid, +) -> anyhow::Result { + let rsp = gloo_net::http::Request::get(api!("household/{household}/recipe")) + .header("Authorization", &format!("Bearer {token}")) + .send() + .await?; + + if !rsp.ok() { + let body = rsp.text().await.unwrap_or_default(); + anyhow::bail!("Could not get recipes (code={}): {body}", rsp.status()); + } + + Ok(rsp.json().await?) +} + +#[derive(Debug, Clone, PartialEq, Eq, Properties)] +struct RecipeListProps { + token: String, + household: Uuid, +} + +#[function_component] +fn RecipeListInner(props: &RecipeListProps) -> HtmlResult { + let state = use_future(|| get_all_recipes(props.token.clone(), props.household))?; + + Ok(match &*state { + Ok(l) => html! { +
+
+ {for l.recipes.iter().map(|(id, name)| html!{ +
+
+ + classes={classes!( + "link-light", + "link-offset-2", + "link-underline-opacity-25", + "link-underline-opacity-100-hover", + )} + to={Route::Recipe { id: *id }} + > + {name} + > +
+
+ })} +
+
+ }, + Err(e) => html! { + + }, + }) +} + +#[function_component] +pub fn RecipeList() -> Html { + let fallback = html! {"Loading ..."}; + let global_state = use_state(RegaladeGlobalState::get); + + html! { +
+
+

{"Recipes"}

+ + + +
+
+ } +} diff --git a/app/src/sidebar.rs b/app/src/sidebar.rs index c3d0481..3abc770 100644 --- a/app/src/sidebar.rs +++ b/app/src/sidebar.rs @@ -10,13 +10,14 @@ use crate::{ api, bootstrap::{bs, ConfirmDangerModal, FormModal}, do_add_user_to_household, do_resolve_user, HouseholdInfo, RegaladeGlobalState, Route, + RouteKind, }; #[derive(PartialEq)] struct MenuEntry { icon: &'static str, label: &'static str, - page: Route, + page: RouteKind, } #[derive(Properties, PartialEq)] @@ -298,7 +299,7 @@ fn Sidebar(props: &SidebarProps) -> Html { )}> { for props.entries.iter().map(|e| { - let active = if e.page == props.current { + let active = if Some(e.page) == props.current.kind() { Some("active") } else { None @@ -311,7 +312,7 @@ fn Sidebar(props: &SidebarProps) -> Html { "text-white", active, )} - to={e.page} + to={e.page.redirect_to()} > @@ -433,17 +434,22 @@ pub(crate) fn RegaladeSidebar(props: &RegaladeSidebarProps) -> Html { MenuEntry { label: "Home", icon: "bi-house", - page: Route::Index, + page: RouteKind::Index, + }, + MenuEntry { + label: "Recipes", + icon: "bi-book", + page: RouteKind::Recipe, }, MenuEntry { label: "Ingredients", icon: "bi-egg-fill", - page: Route::Ingredients, + page: RouteKind::Ingredients, }, MenuEntry { label: "New Recipe", icon: "bi-clipboard2-plus-fill", - page: Route::NewRecipe, + page: RouteKind::NewRecipe, }, ];