frontend templating
This commit is contained in:
parent
ecc0076cdd
commit
a78b1eb25d
27 changed files with 189 additions and 107 deletions
53
Cargo.lock
generated
53
Cargo.lock
generated
|
@ -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",
|
||||
]
|
||||
|
||||
|
|
|
@ -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
3
frontend/.gitignore
vendored
|
@ -1,2 +1,5 @@
|
|||
node_modules/
|
||||
dist/
|
||||
/target
|
||||
.html
|
||||
output/
|
||||
|
|
14
frontend/Cargo.toml
Normal file
14
frontend/Cargo.toml
Normal 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"
|
|
@ -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,
|
||||
|
||||
|
|
|
@ -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
70
frontend/src/main.rs
Normal 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,
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 1.3 MiB |
Before Width: | Height: | Size: 455 KiB After Width: | Height: | Size: 455 KiB |
4
frontend/static/js/css/_reset.scss
Normal file
4
frontend/static/js/css/_reset.scss
Normal file
|
@ -0,0 +1,4 @@
|
|||
* {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
|
@ -1,7 +1,4 @@
|
|||
* {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
@import 'reset';
|
||||
|
||||
.form__logo {
|
||||
width: 110px;
|
0
frontend/static/js/css/main.scss
Normal file
0
frontend/static/js/css/main.scss
Normal file
7
frontend/templates/components/headers.stpl
Normal file
7
frontend/templates/components/headers.stpl
Normal 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>
|
||||
|
|
@ -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>
|
31
frontend/templates/signup/index.stpl
Normal file
31
frontend/templates/signup/index.stpl
Normal 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>
|
|
@ -2,7 +2,7 @@ const path = require('path');
|
|||
|
||||
module.exports = {
|
||||
entry: {
|
||||
main: './src/index.js',
|
||||
main: './static/js/index.js',
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
|
|
|
@ -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"
|
||||
})
|
||||
|
||||
],
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue