front/login: add view
This commit is contained in:
parent
06ede91d31
commit
8b5ebebd01
11 changed files with 166 additions and 20 deletions
|
@ -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);
|
||||
|
|
|
@ -17,6 +17,7 @@ body {
|
|||
color: var(--text-color);
|
||||
font-family: 'Droid Sans' !important;
|
||||
font-size: 12pt;
|
||||
line-height: 20pt;
|
||||
}
|
||||
|
||||
a {
|
||||
|
|
|
@ -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
25
static/html/login.tpl
Normal 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>
|
|
@ -1,6 +1,5 @@
|
|||
<div class='center' id='user-registration'>
|
||||
<h1>Registration</h1>
|
||||
<br/>
|
||||
<form autocomplete='off'>
|
||||
<fieldset class='input'>
|
||||
<ul>
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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'),
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}});
|
||||
|
|
|
@ -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
|
||||
|
|
29
static/js/views/login_view.js
Normal file
29
static/js/views/login_view.js
Normal 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;
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue