feat(web): add 404 page

This commit is contained in:
Kristofers Solo 2025-11-26 18:44:21 +02:00
parent a04abffe45
commit 3dc7187910
Signed by: kristoferssolo
GPG Key ID: 8687F2D3EEE6F0ED
6 changed files with 80 additions and 12 deletions

View File

@ -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 {
<div class="app-containter">
<Header />
<main>
<Routes fallback=|| "Page not found.".into_view()>
<Routes fallback=|| view! { <NotFound /> }>
<Route path=StaticSegment("/") view=Home />
<Route path=StaticSegment("/des") view=DesPage />
<Route path=StaticSegment("/aes") view=AesPage />

View File

@ -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"))]

View File

@ -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."
</p>
<div class="footer-links">
<A href="https://github.com/kristoferssolo/cipher-workshop" target="_blank">
<a href="https://github.com/kristoferssolo/cipher-workshop" target="_blank">
"View Source on GitHub"
</A>
</a>
</div>
</div>
</footer>

View File

@ -3,3 +3,4 @@ pub mod des;
pub mod footer;
pub mod header;
pub mod home;
pub mod not_found;

View File

@ -0,0 +1,17 @@
use leptos::prelude::*;
#[component]
pub fn NotFound() -> impl IntoView {
view! {
<div class="not-found-container">
<div class="error-code">"404"</div>
<h1>"Page Not Found"</h1>
<p>"The data you are looking for has been encrypted into the void."</p>
<div class="binary-decoration">
"01000100 01000101 01000001 01000100 00100000 01001100 01001001 01001110 01001011"
</div>
<a href="/" class="btn-primary btn-link">
"Return to Home"
</a>
</div>
}
}

View File

@ -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;
}