use std::borrow::Borrow; use std::collections::HashSet; use std::hash::Hash; use dioxus::prelude::*; use tavern::{Adventurer, Legend, Lore, Tale}; use crate::togglable::Togglable; use crate::page::Page; use crate::server::*; use super::tags::*; #[component] pub fn BlogAuthor() -> Element { rsx! { section { class: "blog_author_style", } } } #[component] pub fn BlogItem(title: String, slug: String, author: String, summary: String, tags: Vec) -> Element { println!("Blog Item: {title} -- [{tags:?}]"); rsx! { li { key: "{slug}", class: "blog_item", Link { to: Page::Post { slug: slug.clone() }, h1 { "{title}" } } TagList { for tag in tags { TagItem { tag: tag.clone(), } } } h4 { "Author: {author}" } p { "{summary}" } } } } #[component] pub fn BlogList(tags: Signal>, children: Element) -> Element { let list = use_server_future(move || { let categories = tags().iter().cloned().collect(); async move { get_blog_list(categories).await } })?; rsx! { section { class: "blog_list_style", ul { class: "blog_list", if let Some(Ok(lores)) = &*list.read() { for lore in lores { BlogItem { title: lore.title.clone(), slug: lore.slug.clone(), author: lore.author.clone(), summary: lore.summary.clone(), tags: lore.tags.clone() } } } else if let Some(Err(e)) = &*list.read() { p { "Unable to show post header." } p { "{e}" } } else { p { "Loading..." } } {children} } } } } #[component] pub fn ToggleTag(tag: String, toggled_tags: Signal>) -> Element { rsx! { label { class: "toggle_button", input { r#type: "checkbox", checked: toggled_tags.read().is_toggled(&tag), onchange: move |_| { toggled_tags.write().toggle(&tag.clone()); }, } span { "{tag}" } } } } #[component] pub fn TagSelector(show_all: Signal, toggled_tags: Signal>) -> Element { let toggle_all: bool = show_all(); println!("Tag Selector toggled tags: {:?}", toggled_tags()); let tags_future = use_server_future(move || async move { get_tags().await })?; use_effect(move || { if let Some(Ok(tags)) = &*tags_future.read() { if toggle_all { for tag in tags { toggled_tags.write().insert(tag.clone()); } } } }); rsx! { section { class: "blog_nav_style", div { class: "tag_style", h2 { "Categories" } ul { class: "tag_list", if let Some(Ok(tags)) = tags_future() { for tag in tags { li { key: "selector-{tag}", class: "tag_item", ToggleTag { tag: &tag, toggled_tags: toggled_tags } } } } } } } } }