From 8b5ebebd0133202a87472a8023fec42796a124f4 Mon Sep 17 00:00:00 2001 From: rr- Date: Mon, 28 Mar 2016 00:19:44 +0200 Subject: [PATCH] front/login: add view --- static/css/forms.css | 94 ++++++++++++++++++- static/css/main.css | 1 + static/css/users.css | 16 ++-- static/html/login.tpl | 25 +++++ static/html/user_registration.tpl | 1 - static/js/controllers/auth_controller.js | 8 +- .../controllers/top_navigation_controller.js | 2 +- static/js/controllers/users_controller.js | 2 +- static/js/main.js | 4 +- static/js/views/login_view.js | 29 ++++++ static/js/views/registration_view.js | 4 +- 11 files changed, 166 insertions(+), 20 deletions(-) create mode 100644 static/html/login.tpl create mode 100644 static/js/views/login_view.js diff --git a/static/css/forms.css b/static/css/forms.css index 0a24fbe7..4635b009 100644 --- a/static/css/forms.css +++ b/static/css/forms.css @@ -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); diff --git a/static/css/main.css b/static/css/main.css index 04017df0..f176df1d 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -17,6 +17,7 @@ body { color: var(--text-color); font-family: 'Droid Sans' !important; font-size: 12pt; + line-height: 20pt; } a { diff --git a/static/css/users.css b/static/css/users.css index 61bbd908..c28f5dcc 100644 --- a/static/css/users.css +++ b/static/css/users.css @@ -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; } diff --git a/static/html/login.tpl b/static/html/login.tpl new file mode 100644 index 00000000..98a5980a --- /dev/null +++ b/static/html/login.tpl @@ -0,0 +1,25 @@ +
+

Log in

+
+
+
    +
  • + + +
  • +
  • + + +
  • +
  • + + +
  • +
+
+
+ + Forgot the password? +
+
+
diff --git a/static/html/user_registration.tpl b/static/html/user_registration.tpl index fe012533..2b005021 100644 --- a/static/html/user_registration.tpl +++ b/static/html/user_registration.tpl @@ -1,6 +1,5 @@

Registration

-
    diff --git a/static/js/controllers/auth_controller.js b/static/js/controllers/auth_controller.js index e23d7535..9372af0e 100644 --- a/static/js/controllers/auth_controller.js +++ b/static/js/controllers/auth_controller.js @@ -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() { diff --git a/static/js/controllers/top_navigation_controller.js b/static/js/controllers/top_navigation_controller.js index 2bd098dd..4ca79711 100644 --- a/static/js/controllers/top_navigation_controller.js +++ b/static/js/controllers/top_navigation_controller.js @@ -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'), }; diff --git a/static/js/controllers/users_controller.js b/static/js/controllers/users_controller.js index a5e800de..24494928 100644 --- a/static/js/controllers/users_controller.js +++ b/static/js/controllers/users_controller.js @@ -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); }}); diff --git a/static/js/main.js b/static/js/main.js index bd9216e2..d1d16bf6 100644 --- a/static/js/main.js +++ b/static/js/main.js @@ -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 diff --git a/static/js/views/login_view.js b/static/js/views/login_view.js new file mode 100644 index 00000000..5d13b3b9 --- /dev/null +++ b/static/js/views/login_view.js @@ -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; diff --git a/static/js/views/registration_view.js b/static/js/views/registration_view.js index 2f1a31b2..a414be29 100644 --- a/static/js/views/registration_view.js +++ b/static/js/views/registration_view.js @@ -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); }); } }