Merge branch 'feature/better_ui' into develop

This commit is contained in:
Kilerd Chan 2019-04-21 20:14:53 +08:00
commit 3c519032f1
8 changed files with 356 additions and 76 deletions

41
Cargo.lock generated
View File

@ -39,7 +39,7 @@ dependencies = [
[[package]]
name = "actix-connect"
version = "0.1.4"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"actix-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -57,11 +57,11 @@ dependencies = [
[[package]]
name = "actix-files"
version = "0.1.0-alpha.6"
version = "0.1.0-betsa.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"actix-service 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"actix-web 1.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)",
"actix-web 1.0.0-beta.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -75,11 +75,11 @@ dependencies = [
[[package]]
name = "actix-http"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"actix-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"actix-connect 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"actix-connect 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"actix-server-config 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"actix-service 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"actix-threadpool 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -89,6 +89,7 @@ dependencies = [
"brotli2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"copyless 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -217,11 +218,11 @@ dependencies = [
[[package]]
name = "actix-web"
version = "1.0.0-alpha.6"
version = "1.0.0-beta.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"actix-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"actix-http 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"actix-http 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"actix-router 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"actix-rt 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"actix-server 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -229,8 +230,8 @@ dependencies = [
"actix-service 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"actix-threadpool 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"actix-utils 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"actix-web-codegen 0.1.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)",
"awc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"actix-web-codegen 0.1.0-beta.1 (registry+https://github.com/rust-lang/crates.io-index)",
"awc 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
@ -250,7 +251,7 @@ dependencies = [
[[package]]
name = "actix-web-codegen"
version = "0.1.0-alpha.6"
version = "0.1.0-beta.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
@ -315,11 +316,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "awc"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"actix-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"actix-http 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"actix-http 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"actix-service 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1542,8 +1543,8 @@ name = "rubble"
version = "0.2.1"
dependencies = [
"actix 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"actix-files 0.1.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)",
"actix-web 1.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)",
"actix-files 0.1.0-betsa.1 (registry+https://github.com/rust-lang/crates.io-index)",
"actix-web 1.0.0-beta.1 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"diesel 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"diesel_derives 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2255,9 +2256,9 @@ dependencies = [
[metadata]
"checksum actix 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "409b193241782089260e5567aa8ac607a7607153613dbe8a15170ed3b29984fd"
"checksum actix-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9f2c11af4b06dc935d8e1b1491dad56bfb32febc49096a91e773f8535c176453"
"checksum actix-connect 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "88eeefeaed14672fff20e181c8afffa8c6760afcce32ba35b9ab57aa1b7683ad"
"checksum actix-files 0.1.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1326d2a68eb6e716f448a7c4aec00846abc627ccec5c1df9536421822df64e0e"
"checksum actix-http 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd169f69caa4d14e306140feda2238c08fc658dcc10530b6048cdb801965290c"
"checksum actix-connect 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0dc9fb88787e5904e5030cae7d395f9908c2118ed655e48905f37febcad9a653"
"checksum actix-files 0.1.0-betsa.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d2cd0e88f4009725e2a99d88653367d1175d27ba724ed7be23cb21d04f19ad97"
"checksum actix-http 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edcf9a20d654a8ae52f3a1b5346b566d45e3707eef76a72b714d6a8dd81a6c21"
"checksum actix-router 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fb9a57b0d5259f83006f6c54501900396198951e7420b06d5149e78845fa52fe"
"checksum actix-rt 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ed0424cdf6542a43b32a8885c7c5099bf4110fad9b50d7fb220ab9c038ecf5ec"
"checksum actix-server 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "39e2ead8e439b674917c1a1f10f1af5ba90eab903ee6164f5cde6d9504668696"
@ -2265,8 +2266,8 @@ dependencies = [
"checksum actix-service 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dcbfa034a61a48c128de169a019a5f9aa3ac2f7c63b18972e11b4c069321f36b"
"checksum actix-threadpool 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97fa58548067c1f0a16a82cdb7c8823deac793d27efd17b51d6ea7861c6d3966"
"checksum actix-utils 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "80b12b95a3550c49b8f75e80341608bceaa6c544b0c754a0a6ffcf89bdd6d723"
"checksum actix-web 1.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)" = "76e713b2333cb5bcefb04825c62756967d7002377bd914ed0d08d78e508cf8a9"
"checksum actix-web-codegen 0.1.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)" = "26f935cab95e8090c418062a7116ef3a5b06b151c90cedbbe3fe83e48e6645fe"
"checksum actix-web 1.0.0-beta.1 (registry+https://github.com/rust-lang/crates.io-index)" = "07bb9785af50024414b64cda28b727cbe9c24424601a6bd699d16bce3e48822f"
"checksum actix-web-codegen 0.1.0-beta.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b26f9ce2dff34bda98b3c5b3ec2467a8f1bf08c69b0ae8ff02bc7d74d6af9d84"
"checksum actix_derive 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0bf5f6d7bf2d220ae8b4a7ae02a572bb35b7c4806b24049af905ab8110de156c"
"checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c"
"checksum aho-corasick 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "81ce3d38065e618af2d7b77e10c5ad9a069859b4be3c2250f674af3840d9c8a5"
@ -2275,7 +2276,7 @@ dependencies = [
"checksum arc-swap 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "bc4662175ead9cd84451d5c35070517777949a2ed84551764129cedb88384841"
"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
"checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799"
"checksum awc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0746b821ee39f66adaf069acdb108e6b138b0b0e5c83a15193294cf83dc9f37"
"checksum awc 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eeef7718dd236a395988abf75ecd749c6f22ec2a7e819310a3a5e3ae5ea990d9"
"checksum backtrace 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f106c02a3604afcdc0df5d36cc47b44b55917dbaf3d808f71c163a0ddba64637"
"checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6"
"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"

View File

@ -56,7 +56,7 @@ fn main() {
CookieIdentityPolicy::new(&random_cookie_key)
.name("auth-cookie")
.secure(false)
.max_age(Duration::days(3)),
.max_age_time(Duration::days(3)),
))
.service(routers::article::homepage)
.service(routers::article::single_article)

View File

@ -33,6 +33,17 @@ pub struct NewArticle {
}
impl Article {
pub fn link(&self) -> String {
match self.url {
Some(ref to) if to.len() != 0 => {
format!("/{}", to)
},
_ => format!("/archives/{}", self.id)
}
}
pub fn find_by_url(conn: &PgConnection, url: &str) -> Result<Self, Error> {
articles::table
.filter(articles::url.eq(url))

View File

@ -43,8 +43,10 @@ pub fn single_article(
}
let article1 = article.unwrap();
if let Some(to) = article1.url {
return RubbleResponder::Redirect(format!("/{}", to));
if let Some(ref to) = article1.url {
if to.len()!= 0 {
return RubbleResponder::Redirect(format!("/{}", to));
}
}
let view = ArticleView::from(&article1);

View File

@ -1,6 +1,29 @@
<form method="POST">
<input type="text" name="username" placeholder="username">
<input type="password" name="password" placeholder="password">
<button>login</button>
</form>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="/statics/admin.css">
<title>Admin Panel</title>
</head>
<body>
<div class="center-container">
<div class="login-box">
<img src="/statics/cloud.png" alt="CLOUD">
<h1>Login</h1>
<form method="POST" class="login">
<div class="line">
<input type="text" name="username" placeholder="username">
</div>
<div class="line">
<input type="password" name="password" placeholder="password">
</div>
<div class="line">
<button>LOGIN</button>
</div>
</form>
</div>
</div>
</body>
</html>

View File

@ -1,43 +1,102 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="/statics/admin.css">
<title>Admin Panel</title>
</head>
<body>
<h2>login as: {{ admin.username }}</h2>
<header class="admin">
<section class="container">
<img src="/statics/cloud.png" alt="" class="logo">
<nav>
<a href="">Dashboard</a>
<a href="">Articles</a>
<a href="">User Management</a>
<a href="">Site Setting</a>
</nav>
{{ admin.username }}
</section>
</header>
<section class="content">
<section class="container">
<a href="/admin/article/new">new article</a>
<section class="box">
<header>
Articles
<span><a href="/admin/article/new">new article</a></span>
</header>
<section class="body">
<table class="articles">
<thead>
<tr>
<th>ID</th>
<th>Title</th>
<th>URL</th>
<th>Published Time</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{% for article in articles %}
<tr>
<td>{{ article.id }}</td>
<td>
{% if article.published == false %}
DRAW
{% endif %}
{{ article.title }}
</td>
<td>{{ article.url }}</td>
<td>{{ article.publish_at | date(format="%B %d, %Y") }}</td>
<td class="action">
<a href="/admin/article/{{ article.id }}">EDIT</a>
<form action="/admin/article/delete/{{ article.id }}" method="POST">
<input type="hidden" name="_method" value="DELETE">
<button>DELETE</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</section>
</section>
<h2>Article List</h2>
<table>
<tr>
<th>id</th>
<th>title</th>
<th>url</th>
<th>publish time</th>
<th>action</th>
</tr>
{% for article in articles %}
<tr>
<td>{{ article.id }}</td>
<td>{{ article.title }}</td>
<td>{{ article.url }}</td>
<td>{{ article.publish_at }}</td>
<td><a href="/admin/article/{{ article.id }}">EDIT</a> <form action="/admin/article/delete/{{ article.id }}" method="POST"> <input type="hidden" name="_method" value="DELETE"> <button>DELETE</button></form></td>
</tr>
{% endfor %}
</table>
<section class="box">
<header>
Change Password
</header>
<section class="body">
<form action="/admin/password" method="post">
<h2>Change Password</h2>
<input type="password" name="password" placeholder="new password" required>
<form action="/admin/password" method="post">
<button>change</button>
</form>
</section>
</section>
<section class="box">
<header>
Change setting
</header>
<section class="body">
<form action="/admin/setting" method="post">
<input type="password" name="password" placeholder="new password" required>
<input type="text" name="name" placeholder="setting name" required>
<input type="text" name="value" placeholder="value" required>
<button>change</button>
</form>
</section>
</section>
<button>change</button>
</form>
</section>
<h2>Change setting</h2>
</section>
<form action="/admin/setting" method="post">
<input type="text" name="name" placeholder="setting name" required>
<input type="text" name="value" placeholder="value" required>
<button>change</button>
</form>
</body>
</html>

View File

@ -0,0 +1,183 @@
* {
box-sizing: border-box;
margin: 0;
padding: 0;
/*font: 300 1em/1.5 PingFangSC-Regular, Microsoft Yahei UI, Noto Sans CJK SC DemiLight, sans-serif;*/
font-family: PingFangSC-Regular, Microsoft Yahei UI, Noto Sans CJK SC DemiLight, sans-serif;
}
.center-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
}
div.login-box {
display: flex;
flex-direction: column;
align-items: center;
border: 1px solid #e5e5e5;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
padding: 5rem;
}
div.login-box > img {
height: 90px;
}
div.login-box > h1 {
font-size: 1.5rem;
font-weight: 400;
}
div.login-box > form.login {
margin: 2rem 0;
}
div.login-box > form.login div.line {
margin: .35rem 0;
}
div.login-box > form.login input {
font-size: 1rem;
padding: .25rem .75rem;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
border: 1px solid #e5e5e5;
outline: none;
}
div.login-box > form.login input:focus, div.login-box > form.login input:hover {
border: 1px solid #70ccf6;
}
div.login-box > form.login button {
font-size: 1rem;
padding: .25rem .75rem;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
border: 1px solid #70ccf6;
outline: none;
width: 100%;
background-color: #70ccf6;
color: #fff;
}
body {
}
section.container {
max-width: 960px;
display: flex;
margin: 0 auto;
}
header.admin {
padding: 2rem 0;
background-color: #f3f4fe;
}
header.admin section.container {
max-width: 960px;
margin: 0 auto;
display: flex;
justify-content: space-between;
align-items: center;
}
header.admin img.logo {
height: 50px;
}
header.admin a {
font-size: 1rem;
margin: 0 .5rem;
color: #444443;
text-decoration: none;
border-bottom: none;
padding: 1px 0;
text-transform: uppercase;
}
header.admin a:hover {
color: #000;
border-bottom: 1px solid #000;
}
section.content section.container {
flex-direction: column;
}
section.content section.box {
display: flex;
flex-direction: column;
}
section.content section.box header {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: flex-end;
font-size: 1.5rem;
padding: .5rem 0;
margin: 2rem 0 1rem;
border-bottom: 1px solid #e5e5e5;
}
section.content section.box header span {
font-size: 1rem;
}
section.content section.box header {
font-size: 1.5rem;
}
table.articles {
width: 100%;
text-align: left;
border-collapse: collapse;
}
table.articles td {
border-bottom: 1px solid #EFF1FE;
padding: .75rem 1rem;
}
table.articles th {
border-bottom: 1px solid #EFF1FE;
padding: .5rem 1rem;
}
table.articles tr:nth-child(even) {
background: #F3F4FE;
}
table.articles thead {
color: #fff;
background: #405EF7;
background: -moz-linear-gradient(top, #7086f9 0%, #536ef7 66%, #405EF7 100%);
background: -webkit-linear-gradient(top, #7086f9 0%, #536ef7 66%, #405EF7 100%);
background: linear-gradient(to bottom, #7086f9 0%, #536ef7 66%, #405EF7 100%);
}
table.articles thead th {
font-weight: bold;
text-align: left;
}
table.articles td.action {
display: flex;
}

View File

@ -46,7 +46,8 @@ header p {
section.article {
margin: 4rem 0;
padding: 3rem 0 2rem;
border-bottom: 1px solid #e5e5e5;
}
section.article p.mate {
@ -94,9 +95,9 @@ section.article section.desc {
margin: 0 auto;
}
.single.article h2 {
font-size: 1.5em;
margin-bottom: 1rem;
.single.article>h2 {
font-size: 1.5rem;
margin-bottom: 3rem;
margin-top: 0.5rem;
text-transform: uppercase;
color: #444;
@ -120,12 +121,12 @@ footer a:hover {
/*MARKDOWN*/
.yue {
font: 300 16px/1.62 Georgia, "Xin Gothic", "Hiragino Sans GB", "Droid Sans Fallback", "Microsoft YaHei", sans-serif;
font: 300 15px/1.62 Georgia, "Xin Gothic", "Hiragino Sans GB", "Droid Sans Fallback", "Microsoft YaHei", sans-serif;
color: #444443
}
.windows .yue {
font-size: 16px;
font-size: 15px;
font-family: Georgia, SimSun, sans-serif
}
@ -139,7 +140,7 @@ footer a:hover {
.yue h1, .yue h2, .yue h3, .yue h4, .yue h5, .yue h6 {
font-family: PingFang SC, Verdana, Helvetica Neue, Microsoft Yahei, Hiragino Sans GB, Microsoft Sans Serif, WenQuanYi Micro Hei, sans-serif;
color: #000;
color: #444;
font-weight: 400
}
@ -190,18 +191,18 @@ footer a:hover {
}
.yue h2 {
font-size: 1.5em;
margin: .83em 0
font-size: 1.35rem;
margin: .83rem 0
}
.yue h3 {
font-size: 1.17em;
margin: 1em 0
font-size: 1.17rem;
margin: 1rem 0
}
.yue h4, .yue h5, .yue h6 {
font-size: 1em;
margin: 1.6em 0 1em 0
font-size: 1rem;
margin: 1.6rem 0 1rem 0
}
.yue h6 {
@ -210,7 +211,7 @@ footer a:hover {
.yue p {
margin-top: 0;
margin-bottom: 1.46em
margin-bottom: 1.46rem
}
.yue a {