From 3dc7187910fcabafdff6541e1a795ec12fb5e24b Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Wed, 26 Nov 2025 18:44:21 +0200 Subject: [PATCH] feat(web): add 404 page --- web/src/app.rs | 8 ++++--- web/src/main.rs | 12 ++++++---- web/src/pages/footer.rs | 5 ++-- web/src/pages/mod.rs | 1 + web/src/pages/not_found.rs | 17 +++++++++++++ web/style/main.scss | 49 +++++++++++++++++++++++++++++++++++++- 6 files changed, 80 insertions(+), 12 deletions(-) create mode 100644 web/src/pages/not_found.rs diff --git a/web/src/app.rs b/web/src/app.rs index 92592c5..3d56275 100644 --- a/web/src/app.rs +++ b/web/src/app.rs @@ -1,5 +1,7 @@ -use crate::pages::{aes::AesPage, des::DesPage, footer::Footer, header::Header, home::Home}; -use leptos::prelude::*; +use crate::pages::{ + aes::AesPage, des::DesPage, footer::Footer, header::Header, home::Home, not_found::NotFound, +}; +use leptos::{prelude::*, svg::view}; use leptos_meta::{MetaTags, Stylesheet, Title, provide_meta_context}; use leptos_router::{ StaticSegment, @@ -43,7 +45,7 @@ pub fn App() -> impl IntoView {
- + }> diff --git a/web/src/main.rs b/web/src/main.rs index d770c44..b003dcf 100644 --- a/web/src/main.rs +++ b/web/src/main.rs @@ -5,9 +5,10 @@ async fn main() { use leptos::logging::log; use leptos::prelude::*; use leptos_axum::{LeptosRoutes, generate_route_list}; + use tokio::net::TcpListener; use web::app::*; - let conf = get_configuration(None).unwrap(); + let conf = get_configuration(None).expect("Valid config file"); let addr = conf.leptos_options.site_addr; let leptos_options = conf.leptos_options; // Generate the list of routes in your Leptos App @@ -24,10 +25,11 @@ async fn main() { // run our app with hyper // `axum::Server` is a re-export of `hyper::Server` log!("listening on http://{}", &addr); - let listener = tokio::net::TcpListener::bind(&addr).await.unwrap(); - axum::serve(listener, app.into_make_service()) - .await - .unwrap(); + if let Ok(listener) = TcpListener::bind(&addr).await { + axum::serve(listener, app.into_make_service()) + .await + .expect("valid serving"); + } } #[cfg(not(feature = "ssr"))] diff --git a/web/src/pages/footer.rs b/web/src/pages/footer.rs index d91a653..602c17f 100644 --- a/web/src/pages/footer.rs +++ b/web/src/pages/footer.rs @@ -1,5 +1,4 @@ use leptos::prelude::*; -use leptos_router::components::A; #[component] pub fn Footer() -> impl IntoView { @@ -12,9 +11,9 @@ pub fn Footer() -> impl IntoView { "No data is transmitted to any server. You can verify this by disconnecting your internet connection."

diff --git a/web/src/pages/mod.rs b/web/src/pages/mod.rs index 19183cc..21c85c1 100644 --- a/web/src/pages/mod.rs +++ b/web/src/pages/mod.rs @@ -3,3 +3,4 @@ pub mod des; pub mod footer; pub mod header; pub mod home; +pub mod not_found; diff --git a/web/src/pages/not_found.rs b/web/src/pages/not_found.rs new file mode 100644 index 0000000..871a799 --- /dev/null +++ b/web/src/pages/not_found.rs @@ -0,0 +1,17 @@ +use leptos::prelude::*; +#[component] +pub fn NotFound() -> impl IntoView { + view! { +
+
"404"
+

"Page Not Found"

+

"The data you are looking for has been encrypted into the void."

+
+ "01000100 01000101 01000001 01000100 00100000 01001100 01001001 01001110 01001011" +
+ + "Return to Home" + +
+ } +} diff --git a/web/style/main.scss b/web/style/main.scss index 4fd42e8..023ae87 100644 --- a/web/style/main.scss +++ b/web/style/main.scss @@ -150,7 +150,7 @@ main { .app-footer { margin-top: auto; padding: 2rem 0; - border-top: 1px solid var(--border); + border-top: 2px solid var(--border); background: var(--bg-card); text-align: center; font-size: 0.9rem; @@ -537,3 +537,50 @@ main { color: var(--text-main); font-weight: 500; } + +.not-found-container { + text-align: center; + padding: 4rem 1rem; + max-width: 600px; + margin: 0 auto; + animation: fadeIn 0.5s ease-out; + + .error-code { + font-size: 6rem; + font-weight: 800; + color: var(--error); + font-family: "Consolar", "Monaco", monospace; + opacity: 0.8; + line-height: 1; + margin-bottom: 1rem; + text-shadow: 4px 4px 0px rgba(0, 0, 0, 0.1); + } + + h1 { + font-size: 2rem; + color: var(--text-main); + margin-bottom: 1rem; + } + + p { + color: var(--text-muted); + font-size: 1.1rem; + margin-bottom: 2rem; + } + + .binary-decoration { + font-family: "Consolas", "Monaco", monospace; + color: var(--text-muted); + font-size: 0.85rem; + opacity: 0.5; + margin-bottom: 2.5rem; + word-break: break-all; + } +} + +.btn-link { + text-decoration: none; + display: inline-block; + width: auto; + text-align: center; +}