add 404 page
This commit is contained in:
parent
3a4c00a5fb
commit
a7726f994a
@ -2,7 +2,7 @@ use actix_web::{ web, Route };
|
||||
use std::collections::HashMap;
|
||||
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
|
||||
pub struct ActixAdminBuilder {
|
||||
@ -80,6 +80,7 @@ impl ActixAdminBuilderTrait for ActixAdminBuilder {
|
||||
.route("/delete", web::delete().to(delete_many::<T, E>))
|
||||
.route("/delete/{id}", web::delete().to(delete::<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);
|
||||
@ -163,7 +164,9 @@ impl ActixAdminBuilderTrait for ActixAdminBuilder {
|
||||
Some(handler) => handler,
|
||||
_ => 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 {
|
||||
admin_scope = admin_scope.service(scope);
|
||||
|
@ -31,4 +31,12 @@ pub async fn index<T: ActixAdminAppDataTrait>(session: Session, data: web::Data<
|
||||
.render("index.html", &ctx)
|
||||
.map_err(|_| error::ErrorInternalServerError("Template error"))?;
|
||||
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))
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ mod create_or_edit_post;
|
||||
pub use create_or_edit_post::{ create_post, edit_post, create_or_edit_post };
|
||||
|
||||
mod index;
|
||||
pub use index::{ index, get_admin_ctx };
|
||||
pub use index::{ index, not_found, get_admin_ctx };
|
||||
|
||||
mod list;
|
||||
pub use list::list;
|
||||
|
@ -8,70 +8,14 @@
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<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>
|
||||
{% include "head.html" %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="loading" class="loader-wrapper htmx-indicator">
|
||||
<div class="loader is-size-1"></div>
|
||||
</div>
|
||||
{% include "header.html" %}
|
||||
{% include "navbar.html" %}
|
||||
<div class="container is-fluid">
|
||||
{% block content %}
|
||||
{% endblock content %}
|
||||
|
57
templates/head.html
Normal file
57
templates/head.html
Normal 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
25
templates/not_found.html
Normal 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 you’re looking for doesn’t exist.
|
||||
</p>
|
||||
<a href="/admin/" class="button is-primary">Go to Admin</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user