add 404 page

This commit is contained in:
Manuel Gugger 2022-10-07 17:03:09 +02:00
parent 3a4c00a5fb
commit a7726f994a
7 changed files with 99 additions and 62 deletions

View File

@ -2,7 +2,7 @@ use actix_web::{ web, Route };
use std::collections::HashMap; use std::collections::HashMap;
use crate::{prelude::*, ActixAdminMenuElement}; use crate::{prelude::*, ActixAdminMenuElement};
use crate::routes::{create_get, create_post, delete, delete_many, edit_get, edit_post, index, list, show}; use crate::routes::{create_get, create_post, not_found, delete, delete_many, edit_get, edit_post, index, list, show};
/// Represents a builder entity which helps generating the ActixAdmin configuration /// Represents a builder entity which helps generating the ActixAdmin configuration
pub struct ActixAdminBuilder { pub struct ActixAdminBuilder {
@ -80,6 +80,7 @@ impl ActixAdminBuilderTrait for ActixAdminBuilder {
.route("/delete", web::delete().to(delete_many::<T, E>)) .route("/delete", web::delete().to(delete_many::<T, E>))
.route("/delete/{id}", web::delete().to(delete::<T, E>)) .route("/delete/{id}", web::delete().to(delete::<T, E>))
.route("/show/{id}", web::get().to(show::<T, E>)) .route("/show/{id}", web::get().to(show::<T, E>))
.default_service(web::to(not_found))
); );
let category = self.actix_admin.entity_names.get_mut(category_name); let category = self.actix_admin.entity_names.get_mut(category_name);
@ -163,7 +164,9 @@ impl ActixAdminBuilderTrait for ActixAdminBuilder {
Some(handler) => handler, Some(handler) => handler,
_ => web::get().to(index::<T>) _ => web::get().to(index::<T>)
}; };
let mut admin_scope = web::scope("/admin").route("/", index_handler); let mut admin_scope = web::scope("/admin")
.route("/", index_handler)
.default_service(web::to(not_found));
for (_entity, scope) in self.scopes { for (_entity, scope) in self.scopes {
admin_scope = admin_scope.service(scope); admin_scope = admin_scope.service(scope);

View File

@ -32,3 +32,11 @@ pub async fn index<T: ActixAdminAppDataTrait>(session: Session, data: web::Data<
.map_err(|_| error::ErrorInternalServerError("Template error"))?; .map_err(|_| error::ErrorInternalServerError("Template error"))?;
Ok(HttpResponse::Ok().content_type("text/html").body(body)) Ok(HttpResponse::Ok().content_type("text/html").body(body))
} }
pub async fn not_found() -> Result<HttpResponse, Error> {
let body = TERA
.render("not_found.html", &Context::new())
.map_err(|_| error::ErrorInternalServerError("Template error"))?;
Ok(HttpResponse::NotFound().content_type("text/html").body(body))
}

View File

@ -5,7 +5,7 @@ mod create_or_edit_post;
pub use create_or_edit_post::{ create_post, edit_post, create_or_edit_post }; pub use create_or_edit_post::{ create_post, edit_post, create_or_edit_post };
mod index; mod index;
pub use index::{ index, get_admin_ctx }; pub use index::{ index, not_found, get_admin_ctx };
mod list; mod list;
pub use list::list; pub use list::list;

View File

@ -8,70 +8,14 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> {% include "head.html" %}
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Actix Admin</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/all.min.css"
integrity="sha512-1sCRPdkRXhBV2PBLUdRb4tMg1w2YPf37qatUFeS7zlBy7jJI8Lf4VHwWfZZfpXtYSLy85pkm9GaYVYMfw5BC1A=="
crossorigin="anonymous" referrerpolicy="no-referrer" />
<script src="https://unpkg.com/htmx.org@1.7.0"></script>
<script>
function checkAll(bx) {
var cbs = document.getElementsByTagName('input');
for (var i = 0; i < cbs.length; i++) {
if (cbs[i].type == 'checkbox') {
cbs[i].checked = bx.checked;
}
}
}
document.addEventListener('DOMContentLoaded', () => {
// Get all "navbar-burger" elements
const $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll('.navbar-burger'), 0);
// Add a click event on each of them
$navbarBurgers.forEach(el => {
el.addEventListener('click', () => {
// Get the target from the "data-target" attribute
const target = el.dataset.target;
const $target = document.getElementById(target);
// Toggle the "is-active" class on both the "navbar-burger" and the "navbar-menu"
el.classList.toggle('is-active');
$target.classList.toggle('is-active');
});
});
});
</script>
<style>
.loader-wrapper {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
display: flex;
background: rgba(255, 255, 255, 0.3);
justify-content: center;
align-items: center;
z-index: 5;
pointer-events: none
}
</style>
</head> </head>
<body> <body>
<div id="loading" class="loader-wrapper htmx-indicator"> <div id="loading" class="loader-wrapper htmx-indicator">
<div class="loader is-size-1"></div> <div class="loader is-size-1"></div>
</div> </div>
{% include "header.html" %} {% include "navbar.html" %}
<div class="container is-fluid"> <div class="container is-fluid">
{% block content %} {% block content %}
{% endblock content %} {% endblock content %}

57
templates/head.html Normal file
View File

@ -0,0 +1,57 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Actix Admin</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/all.min.css"
integrity="sha512-1sCRPdkRXhBV2PBLUdRb4tMg1w2YPf37qatUFeS7zlBy7jJI8Lf4VHwWfZZfpXtYSLy85pkm9GaYVYMfw5BC1A=="
crossorigin="anonymous" referrerpolicy="no-referrer" />
<script src="https://unpkg.com/htmx.org@1.7.0"></script>
<script>
function checkAll(bx) {
var cbs = document.getElementsByTagName('input');
for (var i = 0; i < cbs.length; i++) {
if (cbs[i].type == 'checkbox') {
cbs[i].checked = bx.checked;
}
}
}
document.addEventListener('DOMContentLoaded', () => {
// Get all "navbar-burger" elements
const $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll('.navbar-burger'), 0);
// Add a click event on each of them
$navbarBurgers.forEach(el => {
el.addEventListener('click', () => {
// Get the target from the "data-target" attribute
const target = el.dataset.target;
const $target = document.getElementById(target);
// Toggle the "is-active" class on both the "navbar-burger" and the "navbar-menu"
el.classList.toggle('is-active');
$target.classList.toggle('is-active');
});
});
});
</script>
<style>
.loader-wrapper {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
display: flex;
background: rgba(255, 255, 255, 0.3);
justify-content: center;
align-items: center;
z-index: 5;
pointer-events: none
}
</style>

25
templates/not_found.html Normal file
View File

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="en">
<head>
{% include "head.html" %}
</head>
<body>
<div class="is-flex is-justify-content-center is-align-items-center" style=" height: 100vh;">
<div class="columns">
<div class="has-text-centered is-half ml-4 mt-5">
<h1 class="is-size-1 has-text-weight-bold has-text-primary">404</h1>
<p class="is-size-5 has-text-weight-medium"> <span class="has-text-danger">Oops!</span> Page not
found.</p>
<p class="is-size-6 mb-2">
The page youre looking for doesnt exist.
</p>
<a href="/admin/" class="button is-primary">Go to Admin</a>
</div>
</div>
</div>
</body>
</html>