frontend templating

This commit is contained in:
realaravinth 2021-04-03 17:18:18 +05:30
parent ecc0076cdd
commit a78b1eb25d
No known key found for this signature in database
GPG key ID: AD9F0F08E855ED88
27 changed files with 189 additions and 107 deletions

53
Cargo.lock generated
View file

@ -19,7 +19,7 @@ dependencies = [
"parking_lot",
"pin-project 0.4.28",
"smallvec",
"tokio",
"tokio 0.2.25",
"tokio-util",
"trust-dns-proto",
"trust-dns-resolver",
@ -37,7 +37,7 @@ dependencies = [
"futures-sink",
"log",
"pin-project 0.4.28",
"tokio",
"tokio 0.2.25",
"tokio-util",
]
@ -176,7 +176,7 @@ dependencies = [
"futures-channel",
"futures-util",
"smallvec",
"tokio",
"tokio 0.2.25",
]
[[package]]
@ -1114,6 +1114,16 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "frontend"
version = "0.1.0"
dependencies = [
"log",
"pretty_env_logger",
"sailfish",
"tokio 1.4.0",
]
[[package]]
name = "fuchsia-zircon"
version = "0.3.3"
@ -1335,7 +1345,7 @@ dependencies = [
"http",
"indexmap",
"slab",
"tokio",
"tokio 0.2.25",
"tokio-util",
"tracing",
"tracing-futures",
@ -2681,7 +2691,7 @@ dependencies = [
"actix-rt",
"actix-threadpool",
"once_cell",
"tokio",
"tokio 0.2.25",
"tokio-rustls",
]
@ -2950,10 +2960,22 @@ dependencies = [
"pin-project-lite 0.1.12",
"signal-hook-registry",
"slab",
"tokio-macros",
"tokio-macros 0.2.6",
"winapi 0.3.9",
]
[[package]]
name = "tokio"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134af885d758d645f0f0505c9a8b3f9bf8a348fd822e112ab5248138348f1722"
dependencies = [
"autocfg",
"num_cpus",
"pin-project-lite 0.2.6",
"tokio-macros 1.1.0",
]
[[package]]
name = "tokio-macros"
version = "0.2.6"
@ -2965,6 +2987,17 @@ dependencies = [
"syn",
]
[[package]]
name = "tokio-macros"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "caf7b11a536f46a809a8a9f0bb4237020f70ecbf115b842360afb127ea2fda57"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tokio-rustls"
version = "0.14.1"
@ -2973,7 +3006,7 @@ checksum = "e12831b255bcfa39dc0436b01e19fea231a37db570686c06ee72c423479f889a"
dependencies = [
"futures-core",
"rustls",
"tokio",
"tokio 0.2.25",
"webpki",
]
@ -2989,7 +3022,7 @@ dependencies = [
"futures-sink",
"log",
"pin-project-lite 0.1.12",
"tokio",
"tokio 0.2.25",
]
[[package]]
@ -3048,7 +3081,7 @@ dependencies = [
"rand 0.7.3",
"smallvec",
"thiserror",
"tokio",
"tokio 0.2.25",
"url",
]
@ -3067,7 +3100,7 @@ dependencies = [
"resolv-conf",
"smallvec",
"thiserror",
"tokio",
"tokio 0.2.25",
"trust-dns-proto",
]

View file

@ -21,6 +21,12 @@ path = "./src/main.rs"
name = "tests-migrate"
path = "./src/tests-migrate.rs"
[workspace]
members = [
".",
"frontend",
]
[dependencies]
actix-web = "3.3.2"
actix = "0.10"

3
frontend/.gitignore vendored
View file

@ -1,2 +1,5 @@
node_modules/
dist/
/target
.html
output/

14
frontend/Cargo.toml Normal file
View file

@ -0,0 +1,14 @@
[package]
name = "frontend"
version = "0.1.0"
authors = ["realaravinth <realaravinth@batsense.net>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
sailfish = { version = "0.3.2", features = ["derive"]}
tokio = { version = "1.4.0", features = [ "rt-multi-thread", "macros", "fs", "test-util" ]}
pretty_env_logger = "0.4"
log = "0.4"

View file

@ -7,8 +7,8 @@
"author": "Aravinth Manivannan <realaravinth@batsense.net>",
"license": "AGPLv3 or above",
"scripts": {
"start": "webpack-dev-server --config webpack.dev.js --open",
"build": "webpack --config webpack.prod.js"
"start": "cargo run && webpack-dev-server --config webpack.dev.js --open",
"build": "cargo run && webpack --config webpack.prod.js"
},
"private": true,

View file

@ -1,75 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Login | mCaptcha</title>
</head>
<body>
<div class="form-container">
<img src="/img/icon-trans.png" class="form__logo" alt="" />
<h2 class="form__brand">Join mCaptcha</h2>
<form class="form__box" id="form">
<label class="form__in-group" for="username"
>Username
<input
class="form__in-field"
id="username"
type="text"
name="username"
id="username"
required
/>
</label>
<label class="form__in-group" for="username"
>Email
<input
class="form__in-field"
id="email"
type="email"
name="email"
id="email"
required
/>
</label>
<label for="password" class="form__in-group"
>Password
<input
class="form__in-field"
type="password"
id="password"
name="password"
id="password"
required
/>
</label>
<label for="password" class="form__in-group"
>Re-enter Password
<input
class="form__in-field"
type="password"
id="password-check"
name="password-check"
id="password-check"
required
/>
</label>
<button class="form__submit-button" type="submit">
Submit
</button>
</form>
<div class="form__secondary-action">
<p class="form__secondary-action__banner">
Already have an account?
<a href="/" class="form__secondary-action__link"
>Click here to login</a
>
</p>
</div>
</div>
</body>
</html>

70
frontend/src/main.rs Normal file
View file

@ -0,0 +1,70 @@
use log::{debug, info};
use sailfish::TemplateOnce;
use tokio::fs;
use tokio::io::{Error, ErrorKind};
#[derive(TemplateOnce)] // automatically implement `TemplateOnce` trait
#[template(path = "index.stpl")] // specify the path to template
struct IndexPage {
// data to be passed to the template
name: String,
title: String,
}
const BASE_DIR: &str = "./output";
#[tokio::main]
async fn main() {
pretty_env_logger::init();
match fs::create_dir(BASE_DIR).await {
Err(e) => {
if e.kind() == ErrorKind::AlreadyExists {
info!("cleaning up old assetes");
fs::remove_dir_all(BASE_DIR).await.unwrap();
debug!("creating target location");
fs::create_dir(BASE_DIR).await.unwrap();
}
}
_ => (),
};
let ctx = IndexPage {
name: "mCaptcha".into(),
title: "Login".into(),
};
// Now render templates with given data
info!("rendering {}", path("index.html"));
let index = ctx.render_once().unwrap();
fs::write(path("index.html"), index).await.unwrap();
info!("wrote {}", path("index.html"));
let ctx = signup::IndexPage {
name: "mCaptcha".into(),
title: "Register".into(),
};
// Now render templates with given data
info!("rendering {}", path("signup/index.html"));
let index = ctx.render_once().unwrap();
fs::create_dir(path("signup")).await.unwrap();
info!("creating dir {}", path("signup/"));
fs::write(path("signup/index.html"), index).await.unwrap();
info!("wrote {}", path("signup/index.html"));
}
fn path(rel: &str) -> String {
format!("{}/{}", BASE_DIR, rel)
}
mod signup {
use super::*;
#[derive(TemplateOnce)] // automatically implement `TemplateOnce` trait
#[template(path = "signup/index.stpl", escape = false)] // specify the path to template
pub struct IndexPage {
// data to be passed to the template
pub name: String,
pub title: String,
}
}

View file

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

View file

Before

Width:  |  Height:  |  Size: 455 KiB

After

Width:  |  Height:  |  Size: 455 KiB

View file

@ -0,0 +1,4 @@
* {
padding: 0;
margin: 0;
}

View file

@ -1,7 +1,4 @@
* {
padding: 0;
margin: 0;
}
@import 'reset';
.form__logo {
width: 110px;

View file

View file

@ -0,0 +1,7 @@
<html lang="en"><head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%= title %>|<%= name %></title>
</head>
<body>

View file

@ -1,11 +1,6 @@
<html lang="en"><head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login | mCaptcha</title>
</head>
<body>
<% include!("components/headers.stpl"); %>
<div class="form-container">
<img src="/img/icon-trans.png" class="form__logo" alt="">
<img src="../static/img/icon-trans.png" class="form__logo" alt="">
<h2 class="form__brand">Sign in to mCaptcha</h2>
<form class="form__box" id="form">
@ -32,7 +27,4 @@
</p>
</div>
</div>
<link rel="stylesheet" href="/css/forms.css">
</body></html>

View file

@ -0,0 +1,31 @@
<% include!("../components/headers.stpl"); %>
<body>
<div class="form-container">
<img src="../../static/img/icon-trans.png" class="form__logo" alt="">
<h2 class="form__brand">Join mCaptcha</h2>
<form class="form__box" id="form">
<label class="form__in-group" for="username">Username
<input class="form__in-field" id="username" type="text" name="username" required="">
</label>
<label for="password" class="form__in-group">Password
<input class="form__in-field" type="password" id="password" name="password" required="">
<!--
<a class="form__pw-recovery" -href="/recovert/password"
>Forgot password?</a
>
-->
</label>
<button class="form__submit-button" type="submit">
Submit
</button>
</form>
<div class="form__secondary-action">
<p class="form__secondary-action__banner">
New to mCaptcha?
<a href="/signup" class="form__secondary-action__link">Create account</a>
</p>
</div>
</div>
</body></html>

View file

@ -2,7 +2,7 @@ const path = require('path');
module.exports = {
entry: {
main: './src/index.js',
main: './static/js/index.js',
},
module: {
rules: [

View file

@ -11,11 +11,11 @@ module.exports = merge(common, {
},
plugins: [
new HtmlWebpackPlugin({
template: "./public/index.html"
template: "./output/index.html"
}),
new HtmlWebpackPlugin({
filename: "signup/index.html",
template: "./public/signup/index.html"
template: "./output/signup/index.html"
})
],

View file

@ -18,7 +18,7 @@ module.exports = merge(common, {
new OptimizeCssAssetsPlugin(),
new TerserPlugin(),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'public/', 'index.html'),
template: path.resolve(__dirname, 'output', 'index.html'),
minify: {
removeAttributeQuotes: true,
collapseWhitespace: true,
@ -26,8 +26,8 @@ module.exports = merge(common, {
},
}),
new HtmlWebpackPlugin({
filename: 'signup/index.html',
template: path.resolve(__dirname, 'public/signup/', 'index.html'),
filename: 'signup/index.html', // output filename
template: path.resolve(__dirname, 'output/signup/', 'index.html'),
minify: {
removeAttributeQuotes: true,
collapseWhitespace: true,