Initial Bard library commit.
This was added to test the database into server context pipeline.
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "bard"
|
||||
version = "0.1.0"
|
||||
version = "0.0.1"
|
||||
edition = "2024"
|
||||
description = "Dioxus components that will display a Tavern blogging system Blog."
|
||||
repository = "/CyberMages/tavern"
|
||||
@ -10,3 +10,4 @@ readme = "README.md"
|
||||
license = "Apache-2.0"
|
||||
|
||||
[dependencies]
|
||||
tavern = { version = "0.2.4", path = "../tavern", registry = "cybermages" }
|
||||
|
||||
238
bard/src/components.rs
Normal file
238
bard/src/components.rs
Normal file
@ -0,0 +1,238 @@
|
||||
|
||||
use dioxus::prelude::*;
|
||||
|
||||
use tavern::Lore;
|
||||
|
||||
use crate::components::social::*;
|
||||
use crate::page::Page;
|
||||
|
||||
|
||||
|
||||
const AUTHOR_CSS: Asset = asset!("/assets/css/blog_author.css");
|
||||
const LIST_CSS: Asset = asset!("/assets/css/blog_list.css");
|
||||
const NAV_CSS: Asset = asset!("/assets/css/blog_nav.css");
|
||||
const POST_CSS: Asset = asset!("/assets/css/blog_post.css");
|
||||
const TAG_CSS: Asset = asset!("/assets/css/blog_tag.css");
|
||||
|
||||
|
||||
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum TagStyle
|
||||
{
|
||||
Regular,
|
||||
Easy,
|
||||
Medium,
|
||||
Hard
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum Tag
|
||||
{
|
||||
LeetCode,
|
||||
Embedded,
|
||||
Simulation,
|
||||
Web
|
||||
}
|
||||
|
||||
|
||||
|
||||
#[component]
|
||||
pub fn TagItem(tag: Tag, style: TagStyle) -> Element
|
||||
{
|
||||
let text = match tag
|
||||
{
|
||||
Tag::LeetCode => { "LeetCode" }
|
||||
Tag::Embedded => { "Embedded" }
|
||||
Tag::Simulation => { "Simulation" }
|
||||
Tag::Web => { "Web" }
|
||||
};
|
||||
|
||||
let tag_style = match style
|
||||
{
|
||||
TagStyle::Regular => { "none" }
|
||||
TagStyle::Easy => { "easy" }
|
||||
TagStyle::Medium => { "medium" }
|
||||
TagStyle::Hard => { "hard" }
|
||||
};
|
||||
|
||||
rsx!
|
||||
{
|
||||
li
|
||||
{
|
||||
class: "tag_item",
|
||||
a { class: "{tag_style}", "{text}" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn TagList(children: Element) -> Element
|
||||
{
|
||||
rsx!
|
||||
{
|
||||
document::Link { rel: "stylesheet", href: TAG_CSS }
|
||||
|
||||
h5
|
||||
{
|
||||
class: "blog_tag_style",
|
||||
ul
|
||||
{
|
||||
class: "tag_list",
|
||||
{children}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[component]
|
||||
pub fn BlogAuthor() -> Element
|
||||
{
|
||||
rsx!
|
||||
{
|
||||
document::Link { rel: "stylesheet", href: AUTHOR_CSS }
|
||||
|
||||
section
|
||||
{
|
||||
class: "blog_author_style",
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[component]
|
||||
pub fn BlogItem(title: String, slug: String, author: String,
|
||||
summary: String, tags: Vec<(Tag, TagStyle)>) -> Element
|
||||
{
|
||||
rsx!
|
||||
{
|
||||
li
|
||||
{
|
||||
class: "blog_item",
|
||||
Link
|
||||
{
|
||||
to: Page::Post { slug: slug },
|
||||
h1 { "{title}" }
|
||||
}
|
||||
TagList
|
||||
{
|
||||
for (tag, style) in tags
|
||||
{
|
||||
TagItem
|
||||
{
|
||||
tag: tag,
|
||||
style: style
|
||||
}
|
||||
}
|
||||
}
|
||||
h4 { "Author: {author}" }
|
||||
p { "{summary}" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[component]
|
||||
pub fn BlogList(children: Element) -> Element
|
||||
{
|
||||
rsx!
|
||||
{
|
||||
document::Link { rel: "stylesheet", href: LIST_CSS }
|
||||
|
||||
section
|
||||
{
|
||||
class: "blog_list_style",
|
||||
ul
|
||||
{
|
||||
class: "blog_list",
|
||||
{children}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[component]
|
||||
pub fn BlogNav() -> Element
|
||||
{
|
||||
rsx!
|
||||
{
|
||||
document::Link { rel: "stylesheet", href: NAV_CSS }
|
||||
|
||||
section
|
||||
{
|
||||
class: "blog_nav_style",
|
||||
div
|
||||
{
|
||||
class: "tag_style",
|
||||
h3 { "Categories" }
|
||||
ul
|
||||
{
|
||||
class: "tag_list",
|
||||
li
|
||||
{
|
||||
class: "tag_item",
|
||||
a { href: "/blog.html", "LeetCode" }
|
||||
}
|
||||
li
|
||||
{
|
||||
class: "tag_item",
|
||||
a { href: "/blog.html", "Embedded" }
|
||||
}
|
||||
li
|
||||
{
|
||||
class: "tag_item",
|
||||
a { href: "/blog.html", "Simulation" }
|
||||
}
|
||||
li
|
||||
{
|
||||
class: "tag_item",
|
||||
a { href: "/blog.html", "Web" }
|
||||
}
|
||||
}
|
||||
}
|
||||
SocialButtonList
|
||||
{
|
||||
SocialButton
|
||||
{
|
||||
link: String::from("https://www.linkedin.com/company/cybermages-llc"),
|
||||
company: Company::LinkedIn,
|
||||
size: Size::Small
|
||||
}
|
||||
SocialButton
|
||||
{
|
||||
link: String::from("https://bsky.app/profile/cybermages.tech"),
|
||||
company: Company::Bluesky,
|
||||
size: Size::Small
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[component]
|
||||
pub fn BlogPost(children: Element) -> Element
|
||||
{
|
||||
rsx!
|
||||
{
|
||||
document::Link { rel: "stylesheet", href: POST_CSS }
|
||||
|
||||
article
|
||||
{
|
||||
class: "blog_post_style",
|
||||
h1 { "Leet Code: Let's Get Started" }
|
||||
TagList
|
||||
{
|
||||
TagItem
|
||||
{
|
||||
tag: Tag::LeetCode,
|
||||
style: TagStyle::Regular
|
||||
}
|
||||
}
|
||||
h4 { "Author: ", a { href: "https://cybermages.tech", "Jason Smith" } }
|
||||
{children}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,4 +4,16 @@ mod info;
|
||||
|
||||
|
||||
|
||||
use tavern::Database;
|
||||
|
||||
pub use crate::info::{get_name, get_version};
|
||||
|
||||
|
||||
|
||||
pub async fn init_database<P>(path: P)
|
||||
-> Result<std::sync::Arc<Database>, Box<dyn std::error::Error>>
|
||||
where P: AsRef<std::path::Path>
|
||||
{
|
||||
let db = Database::open(path).await?;
|
||||
Ok(std::sync::Arc::new(db))
|
||||
}
|
||||
|
||||
27
bard/src/server.rs
Normal file
27
bard/src/server.rs
Normal file
@ -0,0 +1,27 @@
|
||||
use dioxus::prelude::*;
|
||||
use std::sync::Arc;
|
||||
use crate::{Database, Lore, Tale};
|
||||
|
||||
#[server]
|
||||
pub async fn get_blog_list() -> Result<Vec<Lore>, ServerFnError> {
|
||||
let db = server_context()
|
||||
.get::<Arc<Database>>()
|
||||
.ok_or_else(|| ServerFnError::ServerError("Database context not available".to_string()))?;
|
||||
|
||||
let summaries = db.get_tales_summary(&[]).await
|
||||
.map_err(|e| ServerFnError::ServerError(e.to_string()))?;
|
||||
|
||||
Ok(summaries)
|
||||
}
|
||||
|
||||
#[server]
|
||||
pub async fn get_blog_post(slug: String) -> Result<Tale, ServerFnError> {
|
||||
let db = server_context()
|
||||
.get::<Arc<Database>>()
|
||||
.ok_or_else(|| ServerFnError::ServerError("Database context not available".to_string()))?;
|
||||
|
||||
let tale = db.get_tale_by_slug(&slug).await
|
||||
.map_err(|e| ServerFnError::ServerError(e.to_string()))?;
|
||||
|
||||
tale.ok_or(ServerFnError::ServerError("Post not found".into()))
|
||||
}
|
||||
Reference in New Issue
Block a user