front/login: add view

This commit is contained in:
rr- 2016-03-28 00:19:44 +02:00
parent 06ede91d31
commit 8b5ebebd01
11 changed files with 166 additions and 20 deletions

View file

@ -1,21 +1,34 @@
form {
display: block;
width: 20em;
}
form fieldset {
margin: 0;
padding: 0;
border: 0;
}
form fieldset legend {
display: block;
text-align: center;
width: 100%;
font-size: 17pt;
}
form ul {
list-style-type: none;
margin: 0;
padding: 0;
}
form ul li {
margin-top: 0.5em;
}
form .buttons {
margin-top: 1em;
}
form .input li:first-child label,
form .input li:first-child {
padding-top: 0;
margin-top: 0;
}
form.tabular ul {
display: table;
@ -37,13 +50,81 @@ form.tabular .buttons {
form:not(.tabular) ul li label {
display: block;
padding: 1em 0 0.5em 0;
padding: 0.5em 0;
}
input[type=radio], input[type=checkbox] {
float: left;
display: none;
}
.radio, .checkbox {
box-sizing: border-box;
position: relative;
display: inline-block;
padding-left: calc(20px + 0.5em) !important;
vertical-align: middle;
cursor: pointer;
}
.radio:hover:before, .checkbox:hover:before {
border-color: var(--main-color);
}
.radio:before, .checkbox:before {
transition: border-color 0.1s linear;
position: absolute;
top: 50%;
left: 0;
display: block;
margin-top: -10px;
width: 16px;
height: 16px;
border: 2px solid var(--input-background-color);
background: var(--input-border-color);
content: '';
}
input[type=radio]:checked + .radio:before,
input[type=checkbox]:checked + .checkbox:before {
border-color: var(--main-color);
}
input[type=radio]:checked + .radio:after,
input[type=checkbox]:checked + .checkbox:after {
opacity: 1;
}
.radio:after {
transition: opacity 0.1s linear;
position: absolute;
top: 50%;
left: 5px;
display: block;
margin-top: -5px;
width: 10px;
height: 10px;
border-radius: 50%;
content: '';
opacity: 0;
}
.checkbox:after {
transition: opacity 0.1s linear;
position: absolute;
top: 50%;
left: 6px;
display: block;
margin-top: -7px;
width: 5px;
height: 9px;
border-right: 3px solid var(--main-color);
border-bottom: 3px solid var(--main-color);
content: '';
opacity: 0;
transform: rotate(45deg);
}
textarea,
input[type=text],
input[type=email],
input[type=password] {
transition: border-color 0.1s linear, background-color 0.1s linear;
font-size: 100%;
font-family: 'Inconsolata', monospace;
padding: 0.3em;
@ -55,6 +136,13 @@ input[type=password] {
box-shadow: none; /* :-moz-submit-invalid on FF */
}
textarea:focus,
input[type=text]:focus,
input[type=email]:focus,
input[type=password]:focus {
border-color: var(--main-color);
}
form.show-validation fieldset.input input:invalid {
outline: none;
border: 2px solid var(--input-bad-border-color);

View file

@ -17,6 +17,7 @@ body {
color: var(--text-color);
font-family: 'Droid Sans' !important;
font-size: 12pt;
line-height: 20pt;
}
a {

View file

@ -1,16 +1,14 @@
#user-registration form {
display: block;
width: 20em;
float: left;
}
#user-registration .info {
line-height: 1.8em;
float: left;
margin-left: 3em;
border-radius: 0.2em;
width: 20em;
}
#user-registration .info ul {
line-height: 1.8em;
list-style-type: none;
margin: 0;
padding: 0;
@ -28,15 +26,13 @@
#user-registration .info p:first-child {
margin: 0 0 0.5em 0;
}
#user-registration .input li:first-child label {
padding-top: 0;
margin-top: 0;
}
#user-registration .buttons {
margin-top: 1em;
}
#user-registration p.hint {
margin-top: 0.5em;
color: var(--inactive-link-color);
font-size: 80%;
line-height: 120%;
}
#login .buttons a {
margin-left: 1em;
}

25
static/html/login.tpl Normal file
View file

@ -0,0 +1,25 @@
<div class='center' id='login'>
<h1>Log in</h1>
<form>
<fieldset class='input'>
<ul>
<li>
<label for='user-name'>User name</label>
<input id='user-name' name='user-name' type='text' required/>
</li>
<li>
<label for='user-password'>Password</label>
<input id='user-password' name='user-password' type='password' required/>
</li>
<li>
<input id='remember-user' name='remember-user' type='checkbox'/>
<label for='remember-user' class='checkbox'>Remember me</label>
</li>
</ul>
</fieldset>
<fieldset class='buttons'>
<input type='submit' value='Log in'/>
<a>Forgot the password?</a>
</fieldset>
</form>
</div>

View file

@ -1,6 +1,5 @@
<div class='center' id='user-registration'>
<h1>Registration</h1>
<br/>
<form autocomplete='off'>
<fieldset class='input'>
<ul>

View file

@ -1,8 +1,9 @@
'use strict';
class AuthController {
constructor(topNavigationController) {
constructor(topNavigationController, loginView) {
this.topNavigationController = topNavigationController;
this.loginView = loginView;
this.currentUser = null;
}
@ -24,6 +25,11 @@ class AuthController {
loginRoute() {
this.topNavigationController.activate('login');
this.loginView.render({
login: (user, password) => {
alert(user, password);
//self.authController.login(user);
}});
}
logoutRoute() {

View file

@ -22,7 +22,7 @@ class TopNavigationController {
'users': new NavigationItem('Users', '/users'),
'account': new NavigationItem('Account', '/user/{me}'),
'register': new NavigationItem('Register', '/register'),
'login': new NavigationItem('Login', '/login'),
'login': new NavigationItem('Log in', '/login'),
'logout': new NavigationItem('Logout', '/logout'),
'help': new NavigationItem('Help', '/help'),
};

View file

@ -15,7 +15,7 @@ class UsersController {
const self = this;
this.topNavigationController.activate('register');
this.registrationView.render({
onRegistered: (user) => {
register: (user) => {
alert(user);
self.authController.login(user);
}});

View file

@ -6,6 +6,7 @@
const page = require('page');
const handlebars = require('handlebars');
const LoginView = require('./views/login_view.js');
const RegistrationView = require('./views/registration_view.js');
const TopNavigationView = require('./views/top_navigation_view.js');
const TopNavigationController
@ -24,9 +25,10 @@ const TagsController = require('./controllers/tags_controller.js');
// - resolve objects -
// -------------------
const topNavigationView = new TopNavigationView(handlebars);
const loginView = new LoginView(handlebars);
const registrationView = new RegistrationView(handlebars);
const authController = new AuthController(null);
const authController = new AuthController(null, loginView);
const topNavigationController
= new TopNavigationController(topNavigationView, authController);
// break cyclic dependency topNavigationView<->authController

View file

@ -0,0 +1,29 @@
'use strict';
const config = require('../config.js');
const BaseView = require('./base_view.js');
class LoginView extends BaseView {
constructor(handlebars) {
super(handlebars);
this.template = this.getTemplate('login-template');
}
render(options) {
this.showView(this.template());
const form = document.querySelector('#content-holder form');
this.decorateValidator(form);
const userNameField = document.getElementById('user-name');
const passwordField = document.getElementById('user-password');
userNameField.setAttribute('pattern', config.service.userNameRegex);
passwordField.setAttribute('pattern', config.service.passwordRegex);
form.addEventListener('submit', (e) => {
e.preventDefault();
options.login(userNameField.value, passwordField.value);
});
}
}
module.exports = LoginView;

View file

@ -9,7 +9,7 @@ class RegistrationView extends BaseView {
this.template = this.getTemplate('user-registration-template');
}
render(settings) {
render(options) {
this.showView(this.template());
const form = document.querySelector('#content-holder form');
this.decorateValidator(form);
@ -27,7 +27,7 @@ class RegistrationView extends BaseView {
password: passwordField.value,
email: emailField.value,
};
settings.onRegistered(user);
options.register(user);
});
}
}