diff --git a/axum_server/.zellij/default.kdl b/axum_server/.zellij/default.kdl new file mode 100644 index 0000000..4434b29 --- /dev/null +++ b/axum_server/.zellij/default.kdl @@ -0,0 +1,9 @@ +layout { + pane size=1 borderless=true { + plugin location="zellij:tab-bar" + } + pane + pane size=2 borderless=true { + plugin location="zellij:status-bar" + } +} diff --git a/axum_server/.zellij/dev-layout.kdl b/axum_server/.zellij/dev-layout.kdl new file mode 100644 index 0000000..99d4bc0 --- /dev/null +++ b/axum_server/.zellij/dev-layout.kdl @@ -0,0 +1,25 @@ +layout { + pane size=1 borderless=true { + plugin location="zellij:tab-bar" + } + pane split_direction="vertical" focus=true { + pane edit="src/main.rs" + pane split_direction="horizontal" size=60 { + just { args "server_dev"; } + just { args "test"; } + } + } + pane_template name="just" { + command "just" + start_suspended true + } + floating_panes { + pane { + command "just" + args "tailwind" + } + } + pane size=2 borderless=true { + plugin location="zellij:status-bar" + } +} diff --git a/axum_server/Cargo.toml b/axum_server/Cargo.toml index 1541f9a..9d8a492 100644 --- a/axum_server/Cargo.toml +++ b/axum_server/Cargo.toml @@ -17,5 +17,6 @@ serde = "1.0.195" serde_json = "1.0.111" tokio = { version = "1.35.1", features = ["full"] } tower-http = { version = "0.5.0", features = ["trace", "fs"] } +tower-livereload = "0.9.2" tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } diff --git a/axum_server/justfile b/axum_server/justfile index 1b9d18c..42ab7ca 100644 --- a/axum_server/justfile +++ b/axum_server/justfile @@ -11,6 +11,10 @@ server_dev: dev: (just server_dev; just tailwind) | parallel +# Run dev server in watch mode +test: + cargo test + # Run server in production mode prod: cargo run --release diff --git a/axum_server/src/components/site_header.rs b/axum_server/src/components/site_header.rs index 62f36d8..d485709 100644 --- a/axum_server/src/components/site_header.rs +++ b/axum_server/src/components/site_header.rs @@ -4,26 +4,20 @@ pub struct Link { } pub struct HeaderProps { - pub links: Vec, + pub back_link: Option, } impl Default for HeaderProps { fn default() -> Self { + Self { back_link: None } + } +} + +impl HeaderProps { + pub fn with_back_link(link: Link) -> Self { Self { - links: vec![ - Link { - href: "/".to_string(), - label: "Introduction".to_string(), - }, - Link { - href: "/blog".to_string(), - label: "Blog".to_string(), - }, - Link { - href: "/portfolio".to_string(), - label: "Portfolio".to_string(), - }, - ], + back_link: Some(link), + ..Default::default() } } } diff --git a/axum_server/src/main.rs b/axum_server/src/main.rs index d868f4e..23650c3 100644 --- a/axum_server/src/main.rs +++ b/axum_server/src/main.rs @@ -1,5 +1,6 @@ use axum; use tower_http::services::ServeDir; +use tower_livereload::LiveReloadLayer; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; mod components; @@ -25,6 +26,10 @@ async fn main() { // build our application with a single route let app = router::get_router().nest_service("/styles", ServeDir::new("styles")); + + #[cfg(debug_assertions)] + let app = app.layer(LiveReloadLayer::new()); + // run our app with hyper, listening globally on port 3080 let port = std::option_env!("PORT").unwrap_or("3080"); let addr = format!("0.0.0.0:{}", port); diff --git a/axum_server/src/pages/post_list.rs b/axum_server/src/pages/post_list.rs index 25f0e32..5d797bc 100644 --- a/axum_server/src/pages/post_list.rs +++ b/axum_server/src/pages/post_list.rs @@ -4,7 +4,7 @@ use axum::{extract::Path, http::StatusCode}; use crate::{ components::{ site_footer::{render_site_footer, SiteFooter}, - site_header::HeaderProps, + site_header::{HeaderProps, Link}, }, post_list::get_post_list, post_parser::ParseResult, @@ -50,12 +50,21 @@ pub async fn render_post_list(tag: Option>) -> Result HeaderProps::with_back_link(Link { + href: "/blog".to_string(), + label: "All posts".to_string(), + }), + None => HeaderProps::default(), + }; + Ok(PostListTemplate { title: "Posts".to_owned(), posts, tag, site_footer, - header_props: HeaderProps::default(), + header_props, }) } diff --git a/axum_server/styles/output.css b/axum_server/styles/output.css index 2aad1d9..0209517 100644 --- a/axum_server/styles/output.css +++ b/axum_server/styles/output.css @@ -544,19 +544,188 @@ video { --tw-backdrop-sepia: ; } +.m-3 { + margin: 0.75rem; +} + +.m-1 { + margin: 0.25rem; +} + +.my-3 { + margin-top: 0.75rem; + margin-bottom: 0.75rem; +} + +.my-5 { + margin-top: 1.25rem; + margin-bottom: 1.25rem; +} + +.my-8 { + margin-top: 2rem; + margin-bottom: 2rem; +} + +.my-10 { + margin-top: 2.5rem; + margin-bottom: 2.5rem; +} + +.my-12 { + margin-top: 3rem; + margin-bottom: 3rem; +} + +.mx-4 { + margin-left: 1rem; + margin-right: 1rem; +} + +.mb-3 { + margin-bottom: 0.75rem; +} + .block { display: block; } +.inline { + display: inline; +} + +.flex { + display: flex; +} + +.h-0 { + height: 0px; +} + .min-h-full { min-height: 100%; } +.flex-grow { + flex-grow: 1; +} + +.content-end { + align-content: flex-end; +} + +.justify-end { + justify-content: flex-end; +} + +.border-blue-200 { + --tw-border-opacity: 1; + border-color: rgb(191 219 254 / var(--tw-border-opacity)); +} + .bg-blue-50 { --tw-bg-opacity: 1; background-color: rgb(239 246 255 / var(--tw-bg-opacity)); } +.bg-blue-800 { + --tw-bg-opacity: 1; + background-color: rgb(30 64 175 / var(--tw-bg-opacity)); +} + +.p-3 { + padding: 0.75rem; +} + +.p-2 { + padding: 0.5rem; +} + +.px-2 { + padding-left: 0.5rem; + padding-right: 0.5rem; +} + +.px-4 { + padding-left: 1rem; + padding-right: 1rem; +} + +.px-5 { + padding-left: 1.25rem; + padding-right: 1.25rem; +} + +.pr-2 { + padding-right: 0.5rem; +} + +.pr-3 { + padding-right: 0.75rem; +} + +.text-right { + text-align: right; +} + +.text-lg { + font-size: 1.125rem; + line-height: 1.75rem; +} + +.text-base { + font-size: 1rem; + line-height: 1.5rem; +} + +.text-2xl { + font-size: 1.5rem; + line-height: 2rem; +} + +.text-sm { + font-size: 0.875rem; + line-height: 1.25rem; +} + +.font-medium { + font-weight: 500; +} + +.italic { + font-style: italic; +} + +.text-gray-600 { + --tw-text-opacity: 1; + color: rgb(75 85 99 / var(--tw-text-opacity)); +} + +.text-blue-700 { + --tw-text-opacity: 1; + color: rgb(29 78 216 / var(--tw-text-opacity)); +} + +.text-blue-800 { + --tw-text-opacity: 1; + color: rgb(30 64 175 / var(--tw-text-opacity)); +} + +.text-gray-800 { + --tw-text-opacity: 1; + color: rgb(31 41 55 / var(--tw-text-opacity)); +} + +.drop-shadow-md { + --tw-drop-shadow: drop-shadow(0 4px 3px rgb(0 0 0 / 0.07)) drop-shadow(0 2px 2px rgb(0 0 0 / 0.06)); + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); +} + .filter { filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); } + +.after\:content-\[\'\2c \'\]::after { + --tw-content: ','; + content: var(--tw-content); +} diff --git a/axum_server/templates/base.html b/axum_server/templates/base.html index a820914..35d23db 100644 --- a/axum_server/templates/base.html +++ b/axum_server/templates/base.html @@ -33,7 +33,7 @@ - + {% include "site_header.html" %} {% block content %} Placeholder {% endblock %} {# footer, should be not dependant on the each individual handler but it should have it's own handler #} diff --git a/axum_server/templates/post_list.html b/axum_server/templates/post_list.html index 56d5480..c81f3b0 100644 --- a/axum_server/templates/post_list.html +++ b/axum_server/templates/post_list.html @@ -11,7 +11,7 @@