feat(dioxus): added backend offline error handling, added titles to each page, and now using stylesheet as it removed content preloading before css
This commit is contained in:
parent
0ec9ee66f2
commit
bff6a997be
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -796,6 +796,7 @@ dependencies = [
|
||||
"dioxus-signals",
|
||||
"dioxus-web",
|
||||
"manganis",
|
||||
"serde",
|
||||
"warnings",
|
||||
]
|
||||
|
||||
|
@ -19,7 +19,9 @@ web = ["dioxus/web"]
|
||||
desktop = ["dioxus/desktop"]
|
||||
# The feature that are only required for the mobile = ["dioxus/mobile"] build target should be optional and only enabled in the mobile = ["dioxus/mobile"] feature
|
||||
mobile = ["dioxus/mobile"]
|
||||
ssg = ["dioxus/fullstack"]
|
||||
|
||||
# "fullstack"
|
||||
[profile]
|
||||
|
||||
[profile.wasm-dev]
|
||||
|
@ -7,30 +7,122 @@
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
#blog a:hover {
|
||||
color: #91a4d2;
|
||||
}
|
||||
|
||||
#blogs {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 80svh;
|
||||
min-height: 80svh;
|
||||
}
|
||||
|
||||
#blogs h1 {
|
||||
border-bottom: var(--underlineTitle);
|
||||
border-radius: var(--underlineTitleBorderRadius);
|
||||
margin: 1svh 2svw;
|
||||
padding: 1svh 2svw;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#blogs button {
|
||||
/* background-color: transparent; */
|
||||
background-color: var(--card-background-color);
|
||||
border-radius: var(--card-border-radius);
|
||||
border: none;
|
||||
color: #ffffff;
|
||||
font-size: xx-large;
|
||||
padding: 1rem;
|
||||
color: inherit;
|
||||
font-size: x-large;
|
||||
padding: 0.5rem;
|
||||
margin: 1svh 0svw;
|
||||
}
|
||||
|
||||
#blogs p {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
#blogs a {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
#blogs a:hover {
|
||||
color: #91a4d2;
|
||||
}
|
||||
|
||||
#blogs-title {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-bottom: 1svh;
|
||||
}
|
||||
|
||||
#blogs-title p {
|
||||
margin: 0svh 1svw;
|
||||
padding: 1svh 0svw;
|
||||
}
|
||||
|
||||
#blog-loading {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-self: center;
|
||||
align-self: center;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
background-color: var(--card-background-color);
|
||||
border-radius: var(--card-border-radius);
|
||||
padding: 2svh 2svw;
|
||||
margin: 8svh 0svw;
|
||||
}
|
||||
|
||||
#blog-out-of {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-self: center;
|
||||
align-self: center;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
background-color: var(--card-background-color);
|
||||
border-radius: var(--card-border-radius);
|
||||
padding: 2svh 2svw;
|
||||
margin: 8svh 0svw;
|
||||
}
|
||||
|
||||
#blog-nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
padding: 0svh 2svw;
|
||||
margin-top: auto;
|
||||
margin-bottom: 2svh;
|
||||
|
||||
background-color: var(--card-background-color);
|
||||
border-radius: var(--card-border-radius);
|
||||
}
|
||||
|
||||
#blog-nav a:last-child {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
#blog-nav div {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
justify-self: center;
|
||||
|
||||
margin: 1svh 0svw;
|
||||
padding: 0.5rem;
|
||||
column-gap: 1svw;
|
||||
min-height: 28px;
|
||||
font-size: large;
|
||||
|
||||
background-color: var(--card-background-color);
|
||||
border-radius: var(--card-border-radius);
|
||||
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
@ -1,6 +1,4 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
const EXPERIENCE_CSS: Asset = asset!("/assets/styling/experience.css");
|
||||
use dioxus::{document, prelude::*};
|
||||
|
||||
#[component]
|
||||
pub fn Experience(professional_jobs: bool) -> Element {
|
||||
@ -10,7 +8,7 @@ pub fn Experience(professional_jobs: bool) -> Element {
|
||||
};
|
||||
rsx! {
|
||||
div { class: "experience-comp",
|
||||
document::Link { rel: "stylesheet", href: EXPERIENCE_CSS }
|
||||
document::Stylesheet { href: asset!("/assets/styling/experience.css") }
|
||||
if professional_jobs {
|
||||
h3 { "Professional" }
|
||||
} else {
|
||||
@ -32,7 +30,6 @@ pub fn Experience(professional_jobs: bool) -> Element {
|
||||
td { "{exp.start_month} - {exp.end_month}" }
|
||||
}
|
||||
tr {
|
||||
// td { "" }
|
||||
td { "{exp.company}" }
|
||||
td { "{exp.location}" }
|
||||
}
|
||||
|
@ -3,8 +3,6 @@ use std::collections::HashMap;
|
||||
use crate::helper_fun::{tech_table_lookup, TechDes};
|
||||
use dioxus::prelude::*;
|
||||
|
||||
const ENDER_CSS: Asset = asset!("/assets/styling/ender.css");
|
||||
|
||||
#[component]
|
||||
pub fn Ender() -> Element {
|
||||
// gets list of items to get
|
||||
@ -16,7 +14,7 @@ pub fn Ender() -> Element {
|
||||
footer_info.insert(used_tech_item, *tech_table_lookup(used_tech_item));
|
||||
}
|
||||
rsx! {
|
||||
document::Link { rel: "stylesheet", href: ENDER_CSS }
|
||||
document::Stylesheet { href: asset!("/assets/styling/ender.css") }
|
||||
footer {
|
||||
p { "Brock Tomlinson © 2025" }
|
||||
div {
|
||||
|
@ -1,8 +1,6 @@
|
||||
use crate::helper_fun::tech_table_lookup;
|
||||
use dioxus::prelude::*;
|
||||
|
||||
const TECHS_CSS: Asset = asset!("/assets/styling/techs.css");
|
||||
|
||||
#[component]
|
||||
pub fn TechCard(tech_props: &'static str) -> Element {
|
||||
let props_tech = tech_table_lookup(tech_props);
|
||||
@ -19,14 +17,12 @@ pub fn TechCard(tech_props: &'static str) -> Element {
|
||||
#[component]
|
||||
pub fn TechCat(cat: &'static str, tech_vec: Vec<&'static str>) -> Element {
|
||||
rsx! {
|
||||
document::Link { rel: "stylesheet", href: TECHS_CSS }
|
||||
document::Stylesheet { href: asset!("/assets/styling/techs.css") }
|
||||
div { class: "tech-cat",
|
||||
h3 { "{cat}" }
|
||||
div { class: "tech-row",
|
||||
for tech in tech_vec {
|
||||
TechCard {
|
||||
tech_props: tech,
|
||||
}
|
||||
TechCard { tech_props: tech }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
16
src/lib.rs
16
src/lib.rs
@ -49,12 +49,10 @@ pub enum Route {
|
||||
PageNotFound { route: Vec<String> },
|
||||
}
|
||||
|
||||
const NOT_FOUND_CSS: Asset = asset!("/assets/styling/notFound.css");
|
||||
|
||||
#[component]
|
||||
fn PageNotFound(route: Vec<String>) -> Element {
|
||||
rsx! {
|
||||
document::Link { rel: "stylesheet", href: NOT_FOUND_CSS }
|
||||
document::Stylesheet { href: asset!("/assets/styling/notFound.css") }
|
||||
div { id: "not-found",
|
||||
h1 { "Page not found" }
|
||||
p { "We are terribly sorry, but the page you requested doesn't exist." }
|
||||
@ -64,3 +62,15 @@ fn PageNotFound(route: Vec<String>) -> Element {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The server function at the endpoint "static_routes" will be called by the CLI to generate the list of static
|
||||
// routes. You must explicitly set the endpoint to `"static_routes"` in the server function attribute instead of
|
||||
// the default randomly generated endpoint.
|
||||
// #[server(endpoint = "static_routes", output = server_fn::codec::Json)]
|
||||
// async fn static_routes() -> Result<Vec<String>, ServerFnError> {
|
||||
// // The `Routable` trait has a `static_routes` method that returns all static routes in the enum
|
||||
// Ok(Route::static_routes()
|
||||
// .iter()
|
||||
// .map(ToString::to_string)
|
||||
// .collect())
|
||||
// }
|
||||
|
28
src/main.rs
28
src/main.rs
@ -7,7 +7,7 @@ use personal_site::Route;
|
||||
// The macro returns an `Asset` type that will display as the path to the asset in the browser or a local path in desktop bundles.
|
||||
const FAVICON: Asset = asset!("/assets/favicon.ico");
|
||||
// The asset macro also minifies some assets like CSS and JS to make bundled smaller
|
||||
const MAIN_CSS: Asset = asset!("/assets/styling/main.css");
|
||||
// const MAIN_CSS: Asset = asset!("/assets/styling/main.css");
|
||||
|
||||
fn main() {
|
||||
// The `launch` function is the main entry point for a dioxus app. It takes a component and renders it with the platform feature
|
||||
@ -26,10 +26,34 @@ fn App() -> Element {
|
||||
// In addition to element and text (which we will see later), rsx can contain other components. In this case,
|
||||
// we are using the `document::Link` component to add a link to our favicon and main CSS file into the head of our app.
|
||||
document::Link { rel: "icon", href: FAVICON }
|
||||
document::Link { rel: "stylesheet", href: MAIN_CSS }
|
||||
// document::Link { rel: "stylesheet", href: MAIN_CSS }
|
||||
document::Stylesheet { href: asset!("/assets/styling/main.css") }
|
||||
|
||||
// The router component renders the route enum we defined above. It will handle synchronization of the URL and render
|
||||
// the layouts and components for the active route.
|
||||
Router::<Route> {}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ssg")]
|
||||
fn main() {
|
||||
use dioxus_fullstack::{incremental::IncrementalRendererConfig, prelude::*};
|
||||
|
||||
LaunchBuilder::new()
|
||||
.with_cfg(
|
||||
ServeConfig::builder()
|
||||
.incremental(
|
||||
IncrementalRendererConfig::new()
|
||||
.static_dir(
|
||||
std::env::current_exe()
|
||||
.unwrap()
|
||||
.parent()
|
||||
.unwrap()
|
||||
.join("public"),
|
||||
)
|
||||
.clear_cache(false),
|
||||
)
|
||||
.enable_out_of_order_streaming(),
|
||||
)
|
||||
.launch(app);
|
||||
}
|
||||
|
@ -1,11 +1,9 @@
|
||||
use std::thread::Scope;
|
||||
|
||||
use crate::Route;
|
||||
use dioxus::{html::script::r#async, logger::tracing, prelude::*};
|
||||
use dioxus::{logger::tracing, prelude::*};
|
||||
use reqwest;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
const BLOG_CSS: Asset = asset!("/assets/styling/blog.css");
|
||||
// const BLOG_CSS: Asset = asset!("/assets/styling/blog.css");
|
||||
|
||||
/// The Blog page component that will be rendered when the current route is `[Route::Blog]`
|
||||
///
|
||||
@ -13,17 +11,32 @@ const BLOG_CSS: Asset = asset!("/assets/styling/blog.css");
|
||||
/// re-run and the rendered HTML will be updated.
|
||||
#[component]
|
||||
pub fn Blog(blog_title: String) -> Element {
|
||||
let blog_content = use_signal(|| {
|
||||
"<h1>This is a blog #blog_title</h1>
|
||||
<p>
|
||||
let blog_content = use_signal(move || {
|
||||
"<h1>This is a blog #blog_title</h1><p>
|
||||
In blog #{blog_title}, we show how the Dioxus router works and
|
||||
how URL parameters can be passed as props to our route components.
|
||||
</p>"
|
||||
.to_string()
|
||||
});
|
||||
rsx! {
|
||||
document::Link { rel: "stylesheet", href: BLOG_CSS }
|
||||
// let blog_content = use_signal(move || BlogContent {
|
||||
// blog_file_name: "blog_title".to_string(),
|
||||
// blog_title: "This is a blog #blog_title".to_string(),
|
||||
// date_last_edit: "2025-5-20".to_string(),
|
||||
// tags: "#test".to_string(),
|
||||
// html_blog_content: "<p>
|
||||
// In blog #{blog_title}, we show how the Dioxus router works and
|
||||
// how URL parameters can be passed as props to our route components.
|
||||
// </p>"
|
||||
// .to_string(),
|
||||
// });
|
||||
let blog = blog_content();
|
||||
|
||||
// let last_edit = &blog.date_last_edit;
|
||||
// let tag = &blog.tags;
|
||||
|
||||
rsx! {
|
||||
document::Stylesheet { href: asset!("/assets/styling/blog.css") }
|
||||
document::Title { "Brock Tomlinson - {blog_title}" }
|
||||
div { id: "blog",
|
||||
|
||||
// Content
|
||||
@ -44,6 +57,13 @@ pub fn Blog(blog_title: String) -> Element {
|
||||
// }
|
||||
// span { " <---> " }
|
||||
Link { to: Route::Blogs { page_num: 0 }, "Go Back" }
|
||||
// div { dangerous_inner_html: *&blog.html_blog_content.as_str(),
|
||||
// h1 { "{blog_title}" }
|
||||
// div {
|
||||
// p { "{&blog.tags}" }
|
||||
// p { "{&blog.date_last_edit}" }
|
||||
// }
|
||||
// }
|
||||
div { dangerous_inner_html: blog_content }
|
||||
}
|
||||
}
|
||||
@ -63,20 +83,26 @@ async fn get_blog(blog_name: String) {
|
||||
pub fn Blogs(page_num: u32) -> Element {
|
||||
let mut _num_limit: Signal<u8> = use_signal(|| 10);
|
||||
|
||||
let blogs_resource: Resource<Vec<BlogPreview>> =
|
||||
use_resource(move || async move { get_blogs_preview(_num_limit(), page_num).await });
|
||||
let blogs_resource: Resource<Vec<BlogContent>> = use_resource(move || async move {
|
||||
get_blogs_preview(_num_limit(), page_num)
|
||||
.await
|
||||
.unwrap_or_else(|_| vec![])
|
||||
});
|
||||
|
||||
rsx! {
|
||||
document::Link { rel: "stylesheet", href: BLOG_CSS }
|
||||
document::Stylesheet { href: asset!("/assets/styling/blog.css") }
|
||||
div { id: "blogs",
|
||||
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" }
|
||||
document::Title { "Brock Tomlinson - Blogs" }
|
||||
div { id: "blogs-title",
|
||||
h1 { "Blogs" }
|
||||
p {
|
||||
"This is a collection of blog posts, ranging from tutorials, technologies I found interesting, and opinion pieces"
|
||||
}
|
||||
p { "These blogs are my opinion and mine alone" }
|
||||
}
|
||||
// Link { to: Route::Home {},
|
||||
// button { "Home" }
|
||||
// }
|
||||
// Link {
|
||||
// to: Route::Blog {
|
||||
// blog_title: "Test_Blog".to_string(),
|
||||
@ -85,61 +111,100 @@ pub fn Blogs(page_num: u32) -> Element {
|
||||
// }
|
||||
div {
|
||||
if let Some(blogs) = &*blogs_resource.read() {
|
||||
for blog in blogs.iter() {
|
||||
if blogs.len() > 0 {
|
||||
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() }
|
||||
Link {
|
||||
to: Route::Blog {
|
||||
blog_title: blog.blog_file_name.clone(),
|
||||
},
|
||||
div { dangerous_inner_html: blog.html_blog_content.as_str(),
|
||||
h1 { "{blog.blog_title}" }
|
||||
div {
|
||||
p { "{blog.tags}" }
|
||||
p { "{blog.date_last_edit}" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
div { id: "blog-out-of",
|
||||
p { "No more blogs available" }
|
||||
Link { to: Route::Blogs { page_num: 0 },
|
||||
button { "Go Back" }
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
div { "Loading blogs..." }
|
||||
div { id: "blog-loading",
|
||||
p { "Loading blogs..." }
|
||||
}
|
||||
}
|
||||
}
|
||||
div {
|
||||
Link {
|
||||
to: Route::Blogs {
|
||||
page_num: page_num + 1,
|
||||
},
|
||||
"Next"
|
||||
}
|
||||
div { id: "blog-nav",
|
||||
if page_num > 0 {
|
||||
Link {
|
||||
to: Route::Blogs {
|
||||
page_num: page_num - 1,
|
||||
},
|
||||
"Go Back"
|
||||
button { "<-- Go Back" }
|
||||
}
|
||||
}
|
||||
div {
|
||||
label { "display: " }
|
||||
select {
|
||||
onchange: move |event| {
|
||||
tracing::info!("Change happened {:?}", event.value());
|
||||
_num_limit.set(event.value().parse::<u8>().unwrap_or(10));
|
||||
},
|
||||
option { "10" }
|
||||
option { "25" }
|
||||
option { "50" }
|
||||
option { "100" }
|
||||
}
|
||||
}
|
||||
Link {
|
||||
to: Route::Blogs {
|
||||
page_num: page_num + 1,
|
||||
},
|
||||
button { "Next -->" }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
struct BlogPreview {
|
||||
struct BlogContent {
|
||||
pub blog_file_name: String,
|
||||
pub date_last_edit: String,
|
||||
pub html_preview: String,
|
||||
pub blog_title: String,
|
||||
pub tags: String,
|
||||
pub html_blog_content: String,
|
||||
}
|
||||
|
||||
async fn get_blogs_preview(_num_limit: u8, page_num: u32) -> Vec<BlogPreview> {
|
||||
let res = reqwest::get(format!(
|
||||
"http://localhost:8000/blogs/{}/{}",
|
||||
_num_limit, page_num
|
||||
))
|
||||
.await
|
||||
.unwrap()
|
||||
.text()
|
||||
.await
|
||||
.unwrap_or("".to_string());
|
||||
async fn get_blogs_preview(
|
||||
_num_limit: u8,
|
||||
page_num: u32,
|
||||
) -> Result<Vec<BlogContent>, reqwest::Error> {
|
||||
let client = reqwest::Client::new();
|
||||
|
||||
let res: String = client
|
||||
.get(format!(
|
||||
"http://localhost:8000/blogs/{}/{}",
|
||||
_num_limit, page_num
|
||||
))
|
||||
.timeout(std::time::Duration::from_secs(10))
|
||||
.send()
|
||||
.await?
|
||||
.text()
|
||||
.await?;
|
||||
|
||||
let json: serde_json::Value = serde_json::from_str(&res).unwrap();
|
||||
|
||||
// Extract the "Blogs" array and deserialize it into Vec<BlogPreview>
|
||||
let blogs: Vec<BlogPreview> = serde_json::from_value(
|
||||
// Extract the "Blogs" array and deserialize it into Vec<BlogContent>
|
||||
let blogs: Vec<BlogContent> = serde_json::from_value(
|
||||
json.get("Blogs")
|
||||
.cloned()
|
||||
.unwrap_or(serde_json::Value::Null),
|
||||
@ -147,5 +212,5 @@ async fn get_blogs_preview(_num_limit: u8, page_num: u32) -> Vec<BlogPreview> {
|
||||
.unwrap_or_default();
|
||||
|
||||
// tracing::info!("{:?}", blogs);
|
||||
blogs
|
||||
Ok(blogs)
|
||||
}
|
||||
|
@ -1,19 +1,18 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
const PROFESSIONAL_PHOTO_JPG: Asset = asset!("assets/professional_photo_2023.jpg");
|
||||
const CONTACT_CSS: Asset = asset!("/assets/styling/contact.css");
|
||||
|
||||
#[component]
|
||||
pub fn Contact() -> Element {
|
||||
rsx! {
|
||||
document::Link { href: CONTACT_CSS, rel: "stylesheet" }
|
||||
document::Stylesheet { href: asset!("/assets/styling/contact.css") }
|
||||
h2 { "Contact" }
|
||||
div { id: "contact",
|
||||
div {
|
||||
div {
|
||||
img {
|
||||
src: PROFESSIONAL_PHOTO_JPG,
|
||||
alt: "Borck's professional photo",
|
||||
alt: "Brock's professional photo",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,8 +6,6 @@ use dioxus::prelude::*;
|
||||
|
||||
use crate::views::Contact;
|
||||
|
||||
const CONTACTME_CSS: Asset = asset!("/assets/styling/contactme.css");
|
||||
|
||||
#[component]
|
||||
pub fn ContactMe() -> Element {
|
||||
let mut contact_me_name = use_signal(|| String::new());
|
||||
@ -17,8 +15,8 @@ pub fn ContactMe() -> Element {
|
||||
let mut _error_box_message = use_signal(|| String::new());
|
||||
|
||||
rsx! {
|
||||
document::Link { rel: "stylesheet", href: CONTACTME_CSS }
|
||||
title { "Brock Tomlinson - Contact" }
|
||||
document::Stylesheet { href: asset!("/assets/styling/contactme.css") }
|
||||
document::Title { "Brock Tomlinson - Contact" }
|
||||
div { id: "ContactMe",
|
||||
div {
|
||||
h2 { "Get in Touch" }
|
||||
|
@ -3,8 +3,6 @@ use crate::views::{Contact, Projects};
|
||||
use crate::Route;
|
||||
use dioxus::prelude::*;
|
||||
|
||||
const HOME_CSS: Asset = asset!("/assets/styling/home.css");
|
||||
|
||||
#[component]
|
||||
pub fn Home() -> Element {
|
||||
let languages = vec![
|
||||
@ -32,8 +30,8 @@ pub fn Home() -> Element {
|
||||
];
|
||||
let platforms = vec!["AWS", "Cloudflare", "Vercel", "Netlify", "Gitea", "Github"];
|
||||
rsx!(
|
||||
document::Link { rel: "stylesheet", href: HOME_CSS }
|
||||
title { "Brock Tomlinson" }
|
||||
document::Title { "Brock Tomlinson - Home" }
|
||||
document::Stylesheet { href: asset!("/assets/styling/home.css") }
|
||||
div {
|
||||
div { id: "home-intro",
|
||||
h1 { "Hi I'm Brock" }
|
||||
|
@ -2,9 +2,6 @@ use crate::components::Ender;
|
||||
use crate::Route;
|
||||
use dioxus::prelude::*;
|
||||
|
||||
const NAVBAR_CSS: Asset = asset!("/assets/styling/navbar.css");
|
||||
const STD_COLOUR_AND_FONTS_CSS: Asset = asset!("assets/styling/standardColoursandFonts.css");
|
||||
|
||||
/// The Navbar component that will be rendered on all pages of our app since every page is under the layout.
|
||||
///
|
||||
///
|
||||
@ -13,8 +10,8 @@ const STD_COLOUR_AND_FONTS_CSS: Asset = asset!("assets/styling/standardColoursan
|
||||
#[component]
|
||||
pub fn Navbar() -> Element {
|
||||
rsx! {
|
||||
document::Link { rel: "stylesheet", href: NAVBAR_CSS }
|
||||
document::Link { rel: "stylesheet", href: STD_COLOUR_AND_FONTS_CSS }
|
||||
document::Stylesheet { href: asset!("/assets/styling/navbar.css") }
|
||||
document::Stylesheet { href: asset!("assets/styling/standardColoursandFonts.css") }
|
||||
|
||||
div { id: "navbar",
|
||||
Link { to: Route::Home {}, "Home" }
|
||||
|
@ -5,7 +5,7 @@ use dioxus::prelude::*;
|
||||
pub fn Projects(#[props(default = true)] independent_page: bool) -> Element {
|
||||
rsx! {
|
||||
if independent_page {
|
||||
title { "Brock Tomlinson - Projects" }
|
||||
document::Title { "Brock Tomlinson - Projects" }
|
||||
}
|
||||
div {
|
||||
h2 { "Projects" }
|
||||
@ -74,8 +74,6 @@ pub fn Projects(#[props(default = true)] independent_page: bool) -> Element {
|
||||
}
|
||||
}
|
||||
|
||||
const PROJECT_CARDS_CSS: Asset = asset!("/assets/styling/projectCards.css");
|
||||
|
||||
#[component]
|
||||
pub fn ProjectCards(
|
||||
website_link: Option<&'static str>,
|
||||
@ -87,7 +85,7 @@ pub fn ProjectCards(
|
||||
#[props(default = "https://picsum.photos/200")] project_img: &'static str,
|
||||
) -> Element {
|
||||
rsx! {
|
||||
document::Link { href: PROJECT_CARDS_CSS, rel: "stylesheet" }
|
||||
document::Stylesheet { href: asset!("/assets/styling/projectCards.css") }
|
||||
div { class: "project-card",
|
||||
img {
|
||||
src: "{project_img}",
|
||||
|
Loading…
x
Reference in New Issue
Block a user