diff --git a/Cargo.lock b/Cargo.lock index 69ac2de..0b2684e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3178,10 +3178,11 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "personal_site" -version = "1.5.0" +version = "1.6.0" dependencies = [ "dioxus", "reqwest", + "serde", "serde_json", ] diff --git a/Cargo.toml b/Cargo.toml index 991754b..db52898 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "personal_site" -version = "1.5.0" +version = "1.6.0" authors = ["darkicewolf50 "] edition = "2021" @@ -9,6 +9,7 @@ edition = "2021" dioxus = { version = "0.6.0", features = ["router"] } reqwest = { version = "0.12.15", features = ["json"] } serde_json = "1" +serde = { version = "1.0", features = ["derive"] } [features] default = ["web"] diff --git a/src/lib.rs b/src/lib.rs index 7face5b..eb6e9c8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,10 +28,10 @@ pub enum Route { Home {}, // The route attribute can include dynamic parameters that implement [`std::str::FromStr`] and [`std::fmt::Display`] with the `:` syntax. // In this case, id will match any integer like `/blog/123` or `/blog/-456`. - #[route("/blogs/:id")] + #[route("/blogs/:page_num")] // Fields of the route variant will be passed to the component as props. In this case, the blog component must accept // an `id` prop of type `i32`. - Blogs { id: i32 }, + Blogs { page_num: u32 }, #[route("/blogs/:blog_title")] Blog {blog_title: String}, diff --git a/src/views/blog.rs b/src/views/blog.rs index 2fd91b4..263c59e 100644 --- a/src/views/blog.rs +++ b/src/views/blog.rs @@ -1,6 +1,9 @@ +use std::thread::Scope; + use crate::Route; -use dioxus::{logger::tracing, prelude::*}; +use dioxus::{html::script::r#async, logger::tracing, prelude::*}; use reqwest; +use serde::{Deserialize, Serialize}; const BLOG_CSS: Asset = asset!("/assets/styling/blog.css"); @@ -40,8 +43,7 @@ pub fn Blog(blog_title: String) -> Element { // "Previous" // } // span { " <---> " } - // Link { to: Route::Blog { id: id + 1 }, "Next" } - Link { to: Route::Blogs { id: 0 }, "Go Back" } + Link { to: Route::Blogs { page_num: 0 }, "Go Back" } div { dangerous_inner_html: blog_content } } } @@ -58,21 +60,92 @@ async fn get_blog(blog_name: String) { } #[component] -pub fn Blogs(id: i32) -> Element { +pub fn Blogs(page_num: u32) -> Element { + let mut _num_limit: Signal = use_signal(|| 10); + + let blogs_resource: Resource> = + use_resource(move || async move { get_blogs_preview(_num_limit(), page_num).await }); + rsx! { document::Link { rel: "stylesheet", href: BLOG_CSS } div { id: "blogs", - h1 { "Page Under Development" } - p { "Please Try Again Later" } + title { "Blogs" } + h1 { "Blogs" } + p { + "This is a collection of blog posts, ranging from tutorials, technologies I found interesting, and opinion pieces" + } Link { to: Route::Home {}, button { "Home" } } - // Link { - // to: Route::Blog { - // blog_title: "Test_Blog".to_string(), - // }, - // button { "To Test Blog" } - // } + // Link { + // to: Route::Blog { + // blog_title: "Test_Blog".to_string(), + // }, + // button { "To Test Blog" } + // } + div { + if let Some(blogs) = &*blogs_resource.read() { + for blog in blogs.iter() { + + Link { + to: Route::Blog { + blog_title: blog.blog_file_name.clone(), + }, + div { dangerous_inner_html: blog.html_preview.as_str() } + } + } + } else { + div { "Loading blogs..." } + } + } + div { + Link { + to: Route::Blogs { + page_num: page_num + 1, + }, + "Next" + } + if page_num > 0 { + Link { + to: Route::Blogs { + page_num: page_num - 1, + }, + "Go Back" + } + } + } } } } + +#[derive(Deserialize, Serialize, Debug)] +struct BlogPreview { + pub blog_file_name: String, + pub date_last_edit: String, + pub html_preview: String, +} + +async fn get_blogs_preview(_num_limit: u8, page_num: u32) -> Vec { + let res = reqwest::get(format!( + "http://localhost:8000/blogs/{}/{}", + _num_limit, page_num + )) + .await + .unwrap() + .text() + .await + .unwrap_or("".to_string()); + + let json: serde_json::Value = serde_json::from_str(&res).unwrap(); + + // Extract the "Blogs" array and deserialize it into Vec + let blogs: Vec = serde_json::from_value( + json.get("Blogs") + .cloned() + .unwrap_or(serde_json::Value::Null), + ) + .unwrap_or_default(); + + // tracing::info!("{:?}", blogs); + blogs +} diff --git a/src/views/home.rs b/src/views/home.rs index 8d6d7af..7c878a4 100644 --- a/src/views/home.rs +++ b/src/views/home.rs @@ -76,7 +76,7 @@ pub fn Home() -> Element { } } Contact {} - Projects { display_title: false } + Projects { independent_page: false } div { id: "experience", h2 { "Experience" } div { diff --git a/src/views/navbar.rs b/src/views/navbar.rs index 89c70af..7f77981 100644 --- a/src/views/navbar.rs +++ b/src/views/navbar.rs @@ -19,7 +19,7 @@ pub fn Navbar() -> Element { div { id: "navbar", Link { to: Route::Home {}, "Home" } Link { to: Route::Projects {}, "Projects" } - Link { to: Route::Blogs { id: 0 }, "Blogs" } + Link { to: Route::Blogs { page_num: 0 }, "Blogs" } Link { to: Route::ContactMe {}, "Contact" } } diff --git a/src/views/projects.rs b/src/views/projects.rs index cb21ee5..f5b7128 100644 --- a/src/views/projects.rs +++ b/src/views/projects.rs @@ -2,9 +2,9 @@ use crate::helper_fun::get_tech_logos_from_str; use dioxus::prelude::*; #[component] -pub fn Projects(#[props(default = true)] display_title: bool) -> Element { +pub fn Projects(#[props(default = true)] independent_page: bool) -> Element { rsx! { - if display_title { + if independent_page { title { "Brock Tomlinson - Projects" } } div {