use dioxus::{
hooks::{use_resource, use_signal},
prelude::{Props, component, dioxus_elements, rsx},
signals::ReadableExt as _,
};
use dioxus_core::Element;
use dioxus_router::Link;
use oparl_types::OrganizationUrl;
use crate::{
client::{get_body, get_meetings, get_organization},
components::{MeetingList, OrganizationMembership},
route::{Route, UrlEncoded},
};
#[derive(Debug, Clone, PartialEq, Props)]
pub struct OrganizationProps {
organization_url: UrlEncoded<OrganizationUrl>,
}
struct OrganizationData {
organization: oparl_types::Organization,
meetings: Vec<oparl_types::Meeting>,
body: oparl_types::Body,
}
impl OrganizationData {
async fn get(organization_url: &OrganizationUrl) -> Result<Self, String> {
let organization = get_organization(organization_url).await?;
let meetings = if let Some(meeting_url) = organization.meeting.as_ref() {
get_meetings(meeting_url).await?.data
} else {
Vec::new()
};
let body = get_body(organization.body.as_ref().unwrap()).await?;
Ok(Self {
organization,
meetings,
body,
})
}
}
#[component]
pub fn Organization(props: OrganizationProps) -> Element {
let organization_url = use_signal(|| props.organization_url.get_inner().unwrap().clone());
let data =
{ use_resource(move || async move { OrganizationData::get(&organization_url()).await }) };
rsx! {
match &*data.read_unchecked() {
Some(Ok(data)) => rsx! {
if let Some(name) = &data.organization.name {
dioxus::document::Title { "🛖 {name}" }
} else {
dioxus::document::Title { "🛖 (Unnamed organization)" }
}
h1 {
"🛖 "
if let Some(name) = &data.organization.name {
"{name}"
} else {
"(Unnamed organization)"
}
}
Link {
to: Route::Body{body_url: UrlEncoded::from(data.body.id.clone())},
"🏛️ { data.body.name }"
}
MeetingList {
meetings: data.meetings.clone()
}
h2 {
"Members"
}
ul {
for membership_url in &data.organization.membership {
li {
key: "{membership_url}",
OrganizationMembership {
membership_url: membership_url.clone()
}
}
}
}
},
Some(Err(e)) => rsx! { p { "Loading organization failed, {e}" } },
None => rsx! { p { "Loading..." } }
}
}
}