use dioxus::{
hooks::{use_resource, use_signal},
prelude::{Props, component, dioxus_elements, rsx},
signals::ReadableExt as _,
};
use dioxus_core::Element;
use dioxus_i18n::t;
use oparl_types::BodyUrl;
use crate::{
client::{get_body, get_meetings, get_organizations, get_persons},
components::{MeetingList, OrganizationList, PersonList},
route::UrlEncoded,
};
#[derive(Debug, Clone, PartialEq, Props)]
pub struct BodyProps {
body_url: UrlEncoded<BodyUrl>,
}
struct BodyData {
body: oparl_types::Body,
persons: Vec<oparl_types::Person>,
organizations: Vec<oparl_types::Organization>,
meetings: Vec<oparl_types::Meeting>,
}
impl BodyData {
async fn get(body_url: &BodyUrl) -> Result<Self, String> {
let body = get_body(body_url).await?;
let persons = get_persons(&body.person).await?;
let organizations = get_organizations(&body.organization).await?;
let meetings = get_meetings(&body.meeting).await?;
Ok(Self {
body,
persons: persons.data,
organizations: organizations.data,
meetings: meetings.data,
})
}
}
#[component]
pub fn Body(props: BodyProps) -> Element {
let body_url = use_signal(|| props.body_url.get_inner().unwrap().clone());
let data = { use_resource(move || async move { BodyData::get(&body_url()).await }) };
rsx! {
match &*data.read_unchecked() {
Some(Ok(data)) => rsx! {
dioxus::document::Title { { t!("body-label", name: data.body.name.as_str() ) } }
h1 {
{ t!("body-label", name: data.body.name.as_str() ) }
}
MeetingList {
meetings: data.meetings.clone()
}
OrganizationList {
organizations: data.organizations.clone()
}
PersonList {
persons: data.persons.clone()
}
},
Some(Err(e)) => rsx! {
dioxus::document::Title { { t!("loading-failed") } },
p { { t!("loading-body-failed", error: e.to_string()) } }
},
None => rsx! {
dioxus::document::Title { { t!("loading") } },
p { { t!("loading") } }
}
}
}
}