regalade/app/src/recipe.rs

85 lines
2.8 KiB
Rust
Raw Normal View History

2023-06-25 14:12:09 +02:00
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<api::ListRecipesResponse> {
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! {
<div class="container text-center">
<div class="row row-cols-2 row-cols-sm-2 row-cols-md-4 g-2 mb-1">
{for l.recipes.iter().map(|(id, name)| html!{
<div class="col" key={*id}>
<div class="p-3 border rounded border-light-subtle h-100">
<Link<Route>
classes={classes!(
"link-light",
"link-offset-2",
"link-underline-opacity-25",
"link-underline-opacity-100-hover",
)}
to={Route::Recipe { id: *id }}
>
{name}
</Link<Route>>
</div>
</div>
})}
</div>
</div>
},
Err(e) => html! {
<div class={classes!("alert", "alert-danger")} role="alert">
{format!("Error fetching recipes: {e}")}
</div>
},
})
}
#[function_component]
pub fn RecipeList() -> Html {
let fallback = html! {"Loading ..."};
let global_state = use_state(RegaladeGlobalState::get);
html! {
<div class="d-flex align-items-center justify-content-center w-100">
<div class={classes!("container", "text-center", "rounded", "border", "pt-2", "m-2")}>
<h2>{"Recipes"}</h2>
<Suspense {fallback}>
<RecipeListInner
token={global_state.token.token.clone()}
household={global_state.household.id}
/>
</Suspense>
</div>
</div>
}
}