feat: bootstrap dashboard homepage
This commit is contained in:
parent
d9fc1b8533
commit
1b9e1215c9
3 changed files with 263 additions and 0 deletions
74
src/pages/dash/home.rs
Normal file
74
src/pages/dash/home.rs
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2022 Aravinth Manivannan <realaravinth@batsense.net>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
use std::cell::RefCell;
|
||||||
|
|
||||||
|
use actix_identity::Identity;
|
||||||
|
use actix_web::http::header::ContentType;
|
||||||
|
use tera::Context;
|
||||||
|
|
||||||
|
use crate::api::v1::RedirectQuery;
|
||||||
|
use crate::ctx::api::v1::auth::Login as LoginPayload;
|
||||||
|
use crate::pages::errors::*;
|
||||||
|
use crate::settings::Settings;
|
||||||
|
use crate::AppCtx;
|
||||||
|
|
||||||
|
pub use super::*;
|
||||||
|
|
||||||
|
pub const DASH_HOME: TemplateFile = TemplateFile::new("dash_home", "pages/dash/index.html");
|
||||||
|
|
||||||
|
pub struct Home {
|
||||||
|
ctx: RefCell<Context>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CtxError for Home {
|
||||||
|
fn with_error(&self, e: &ReadableError) -> String {
|
||||||
|
self.ctx.borrow_mut().insert(ERROR_KEY, e);
|
||||||
|
self.render()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Home {
|
||||||
|
pub fn new(settings: &Settings, payload: Option<&LoginPayload>) -> Self {
|
||||||
|
let ctx = RefCell::new(context(settings));
|
||||||
|
if let Some(payload) = payload {
|
||||||
|
ctx.borrow_mut().insert(PAYLOAD_KEY, payload);
|
||||||
|
}
|
||||||
|
Self { ctx }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render(&self) -> String {
|
||||||
|
TEMPLATES
|
||||||
|
.render(DASH_HOME.name, &self.ctx.borrow())
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn page(s: &Settings) -> String {
|
||||||
|
let p = Self::new(s, None);
|
||||||
|
p.render()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[actix_web_codegen_const_routes::get(path = "PAGES.dash.home")]
|
||||||
|
pub async fn get_home(ctx: AppCtx) -> impl Responder {
|
||||||
|
let home = Home::page(&ctx.settings);
|
||||||
|
let html = ContentType::html();
|
||||||
|
HttpResponse::Ok().content_type(html).body(home)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn services(cfg: &mut web::ServiceConfig) {
|
||||||
|
cfg.service(get_home);
|
||||||
|
}
|
29
src/pages/dash/mod.rs
Normal file
29
src/pages/dash/mod.rs
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2022 Aravinth Manivannan <realaravinth@batsense.net>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
use actix_web::*;
|
||||||
|
|
||||||
|
pub use super::{context, Footer, TemplateFile, PAGES, PAYLOAD_KEY, TEMPLATES};
|
||||||
|
|
||||||
|
mod home;
|
||||||
|
|
||||||
|
pub fn register_templates(t: &mut tera::Tera) {
|
||||||
|
home::DASH_HOME.register(t).expect(home::DASH_HOME.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn services(cfg: &mut web::ServiceConfig) {
|
||||||
|
home::services(cfg);
|
||||||
|
}
|
160
templates/pages/dash/index.html
Normal file
160
templates/pages/dash/index.html
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<link rel="stylesheet" href="{{ assets.css }}" />
|
||||||
|
<title>LibrePages</title>
|
||||||
|
</head>
|
||||||
|
<body class="auth__body">
|
||||||
|
<header>
|
||||||
|
<nav>
|
||||||
|
<p>LibrePages</p>
|
||||||
|
<span class="nav__spacer"></span>
|
||||||
|
<ul class="nav__links">
|
||||||
|
<li class="nav__item">Help</li>
|
||||||
|
<li class="nav__item">Settings</li>
|
||||||
|
<li class="nav__item">Logout</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
<main>
|
||||||
|
<div class="sites__collection">
|
||||||
|
<div class="sites__actions">
|
||||||
|
<a class="sites__actions__new-site" href="/add/new/site">
|
||||||
|
<button>Add new site</button>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<a href="/sites/mcaptcha.org" class="site__container">
|
||||||
|
<div class="site__info--head">
|
||||||
|
<img
|
||||||
|
class="site__container--preview"
|
||||||
|
src="https://mcaptcha.org/favicon.ico"
|
||||||
|
/>
|
||||||
|
<div class="site__info--column">
|
||||||
|
<p href="https://mcaptcha.org"><b>mcaptcha.org</b></p>
|
||||||
|
<p>Deploys from {{ source_url }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="site__info--tail">
|
||||||
|
<p>Last update {{ last_update }}</p>
|
||||||
|
</div></a
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
{% include "footer" %}
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
header {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav {
|
||||||
|
width: 100%;
|
||||||
|
margin: auto;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav__spacer {
|
||||||
|
flex: 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav__links {
|
||||||
|
display: flex;
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav__item {
|
||||||
|
margin: 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
width: 100%;
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sites__collection {
|
||||||
|
margin: auto;
|
||||||
|
width: 70%;
|
||||||
|
|
||||||
|
border: 1px solid #e8ebed;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sites__actions {
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
align-items: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0px 20px;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sites__actions__new-site {
|
||||||
|
min-height: 36px;
|
||||||
|
background: green;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sites__actions__new-site > button {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
height: 100%;
|
||||||
|
border: none;
|
||||||
|
width: 100%;
|
||||||
|
color: white;
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site__container {
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: 10px 0;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 10px 20px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site__container:hover {
|
||||||
|
background: #f7f8f8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site__info--head {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site__info--column {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site__info--column > p,
|
||||||
|
.site__info--column > a {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.site__container:visited,
|
||||||
|
.site__container {
|
||||||
|
color: black;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site__container--preview {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</html>
|
Loading…
Reference in a new issue