This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit bf6285093d90576220ffb4b32904262ae5fd3f1b Author: Sylvain Bavencoff <bavencoff@codelutin.com> Date: Wed Mar 15 14:50:48 2017 +0100 Adaptation de l'écran de de connexion, d'inscription et de confirmation de mail + correction de l'expiration du token de session --- .../chorem/pollen/rest/api/PollenRenderError.java | 46 ++++++ .../rest/api/PollenRestApiRequestFilter.java | 10 +- .../org/chorem/pollen/rest/api/v1/AuthApi.java | 23 +-- .../org/chorem/pollen/rest/api/v1/ErrorAction.java | 17 +- pollen-ui-riot-js/src/main/web/css/main.css | 2 +- pollen-ui-riot-js/src/main/web/i18n.json | 12 +- pollen-ui-riot-js/src/main/web/index.html | 4 +- pollen-ui-riot-js/src/main/web/js/FetchService.js | 3 +- pollen-ui-riot-js/src/main/web/js/PollForm.js | 22 ++- pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html | 8 +- .../tag/{Footer.tag.html => PollenFooter.tag.html} | 12 +- .../tag/{Header.tag.html => PollenHeader.tag.html} | 8 +- .../src/main/web/tag/SignCheck.tag.html | 105 +++++-------- pollen-ui-riot-js/src/main/web/tag/SignIn.tag.html | 85 +++++----- pollen-ui-riot-js/src/main/web/tag/SignUp.tag.html | 173 +++++++++++++-------- .../src/main/web/tag/popup/AccountCreated.tag.html | 131 +++++----------- .../src/main/web/tag/popup/NewPassword.tag.html | 160 +++++-------------- .../main/web/tag/popup/ResendValidation.tag.html | 160 +++++-------------- 18 files changed, 421 insertions(+), 560 deletions(-) diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRenderError.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRenderError.java new file mode 100644 index 0000000..e64f5cf --- /dev/null +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRenderError.java @@ -0,0 +1,46 @@ +package org.chorem.pollen.rest.api; + +import org.chorem.pollen.rest.api.v1.AuthApi; +import org.debux.webmotion.server.call.Call; +import org.debux.webmotion.server.call.HttpContext; +import org.debux.webmotion.server.mapping.Mapping; +import org.debux.webmotion.server.render.RenderError; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class PollenRenderError extends RenderError { + + protected boolean removeConnexionCookie; + + public PollenRenderError(int code, String message, boolean removeConnexionCookie) { + super(code, message); + this.removeConnexionCookie = removeConnexionCookie; + } + + public PollenRenderError(int code, String message) { + this(code, message, false); + } + + @Override + public void create(Mapping mapping, Call call) throws IOException, ServletException { + HttpContext context = call.getContext(); + HttpServletResponse response = context.getResponse(); + + String origin = context.getHeader("Origin"); + if (origin != null) { + response.setHeader(HttpContext.HEADER_ACCESS_CONTROL_ALLOW_ORIGIN, origin); + response.setHeader(HttpContext.HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS, "true"); + response.setHeader(HttpContext.HEADER_ACCESS_CONTROL_ALLOW_METHODS, "GET, POST, DELETE, PUT, OPTIONS"); + } + if (removeConnexionCookie) { + AuthApi.removeAuthCookie(response); + } + + super.create(mapping,call); + } +} diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRestApiRequestFilter.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRestApiRequestFilter.java index 39055b9..9393d19 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRestApiRequestFilter.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRestApiRequestFilter.java @@ -148,15 +148,7 @@ public class PollenRestApiRequestFilter extends WebMotionFilter { } - SessionToken sessionToken = null; - try { - sessionToken = securityService.getSessionTokenByToken(sessionTokenHeader); - } catch (PollenInvalidSessionTokenException e) { - // session token is not valid - if (log.isErrorEnabled()) { - log.error("Found invalid session token, won't use it: " + sessionTokenHeader, e); - } - } + SessionToken sessionToken = securityService.getSessionTokenByToken(sessionTokenHeader); // --- get mainPrincipal (from request parameters) --- // Map<String, String[]> parameters = context.getParameters(); diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/AuthApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/AuthApi.java index b58eb85..604daf9 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/AuthApi.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/AuthApi.java @@ -57,6 +57,19 @@ public class AuthApi extends WebMotionController { private static final String COOKIE_POLLEN_CONNECTED = "pollen-connected"; private final static int COOKIE_MAX_AGE = 60 * 60 * 24 * 365; // 1 year + public static void removeAuthCookie(HttpServletResponse response) { + Cookie authCookie = new Cookie(COOKIE_POLLEN_AUTH, ""); + authCookie.setPath("/"); + authCookie.setMaxAge(0); + response.addCookie(authCookie); + + Cookie connectedCookie = new Cookie(COOKIE_POLLEN_CONNECTED, ""); + connectedCookie.setPath("/"); + connectedCookie.setMaxAge(0); + response.addCookie(connectedCookie); + + } + public PollenEntityRef<PollenUser> login(HttpContext requestContext, SecurityService securityService) throws PollenAuthenticationException, MissingAuthenticationException, PollenInvalidSessionTokenException, PollenCypherTechnicalException { String authHeader = requestContext.getHeader("Authorization"); @@ -124,15 +137,7 @@ public class AuthApi extends WebMotionController { HttpServletResponse response = requestContext.getResponse(); - Cookie authCookie = new Cookie(COOKIE_POLLEN_AUTH, ""); - authCookie.setPath("/"); - authCookie.setMaxAge(0); - response.addCookie(authCookie); - - Cookie connectedCookie = new Cookie(COOKIE_POLLEN_CONNECTED, ""); - connectedCookie.setPath("/"); - connectedCookie.setMaxAge(0); - response.addCookie(connectedCookie); + removeAuthCookie(response); } diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/ErrorAction.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/ErrorAction.java index 24912a3..7839f36 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/ErrorAction.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/ErrorAction.java @@ -21,6 +21,7 @@ package org.chorem.pollen.rest.api.v1; * #L% */ +import org.chorem.pollen.rest.api.PollenRenderError; import org.chorem.pollen.services.service.FavoriteListImportException; import org.chorem.pollen.services.service.InvalidFormException; import org.debux.webmotion.server.WebMotionController; @@ -53,26 +54,34 @@ public class ErrorAction extends WebMotionController { public Render on404(HttpContext context, Exception e) { - return renderError(HttpServletResponse.SC_NOT_FOUND, e.getMessage()); + return pollenRenderError(HttpServletResponse.SC_NOT_FOUND, e.getMessage()); } public Render on401(HttpContext context, Exception e) { - return renderError(HttpServletResponse.SC_UNAUTHORIZED, e.getMessage()); + return pollenRenderError(HttpServletResponse.SC_UNAUTHORIZED, e.getMessage(), true); } public Render on403(HttpContext context, Exception e) { - return renderError(HttpServletResponse.SC_FORBIDDEN, e.getMessage()); + return pollenRenderError(HttpServletResponse.SC_FORBIDDEN, e.getMessage()); } public Render on500(HttpContext context, Exception e) { - return renderError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); + return pollenRenderError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); } + public Render pollenRenderError(int scNotFound, String message) { + return new PollenRenderError(scNotFound, message); + } + + public Render pollenRenderError(int scNotFound, String message, boolean removeConnexionCookie) { + return new PollenRenderError(scNotFound, message, removeConnexionCookie); + } + } diff --git a/pollen-ui-riot-js/src/main/web/css/main.css b/pollen-ui-riot-js/src/main/web/css/main.css index 204c028..964c982 100644 --- a/pollen-ui-riot-js/src/main/web/css/main.css +++ b/pollen-ui-riot-js/src/main/web/css/main.css @@ -48,7 +48,7 @@ input, textarea { } .body-wrapper { - background-color: #f2f2f2; + background-color: white; width: 100%; min-height: 100%; display: flex; diff --git a/pollen-ui-riot-js/src/main/web/i18n.json b/pollen-ui-riot-js/src/main/web/i18n.json index 0283763..8baaf7e 100644 --- a/pollen-ui-riot-js/src/main/web/i18n.json +++ b/pollen-ui-riot-js/src/main/web/i18n.json @@ -60,7 +60,7 @@ "signup_error": "Impossible d'enregister le compte.", "signup_error_email": "L'adresse email est déjà utilisé pour un autre compte.", "createaccount_title": "Votre compte a bien été créé", - "createaccount_description": "Un courriel vous a été envoyé avec vos identifiants ainsi que l'url de validation de votre compte.", + "createaccount_description": "Un courriel vous a été envoyé avec l'url de validation de votre compte.", "createaccount_action": "Continuer", "resendvalidation_title": "Renvoyer un courriel de validation de compte", "resendvalidation_action": "Envoyer", @@ -74,7 +74,7 @@ "signcheck_validating": "Votre compte est en cour de validation...", "signcheck_validating_error": "Votre compte n'a pas pu être validé, essayer de renvoyer une invitation.", "signcheck_validating_success": "Votre compte a été validé. Vous pouvez vous connecter.", - "signin_title": "Déjà membre ?", + "signin_title": "Connexion", "signin_login": "Email", "signin_login_placeholder": "Entrer l'email", "signin_password": "Mot de passe", @@ -303,15 +303,15 @@ "signcheck_validating": "Your account is validating...", "signcheck_validating_error": "Your account could not be validated, try to send a new invitation.", "signcheck_validating_success": "Your account was validated! You can now sign in. Enjoy!", - "createdaccount_title": "Your account was created", - "createdaccount_description": "We sent you an email with the account validation process and your authentication data.", - "createdaccount_action": "Continue", + "createaccount_title": "Your account was created", + "createaccount_description": "We sent you an email with the account validation process.", + "createaccount_action": "Continue", "resendvalidation_title": "Send another validation email", "resendvalidation_action": "Send again", "resendvalidation_sent": "A new invitation email was sent", "resendvalidation_placeholder": "Fill your email", "resendvalidation_error_emailNotFound": "Your email was not found", - "signin_title": "Already member?", + "signin_title": "Connexion", "signin_login": "Email", "signin_login_placeholder": "Entrer your email", "signin_password": "Password", diff --git a/pollen-ui-riot-js/src/main/web/index.html b/pollen-ui-riot-js/src/main/web/index.html index 5c9214a..877f4d1 100644 --- a/pollen-ui-riot-js/src/main/web/index.html +++ b/pollen-ui-riot-js/src/main/web/index.html @@ -31,7 +31,7 @@ </head> <body> <Pollen/> -<script src="./conf.js"></script> -<script src="./pollen.js"></script> +<script type="text/javascript" src="./conf.js"></script> +<script type="text/javascript" src="./pollen.js"></script> </body> </html> diff --git a/pollen-ui-riot-js/src/main/web/js/FetchService.js b/pollen-ui-riot-js/src/main/web/js/FetchService.js index 2c26359..fd13a55 100644 --- a/pollen-ui-riot-js/src/main/web/js/FetchService.js +++ b/pollen-ui-riot-js/src/main/web/js/FetchService.js @@ -48,7 +48,8 @@ class FetchService { return response.json().then(json => Promise.reject(json)); } if (response.status === 401) { - return response.json(); + require("./Session").emitUnauthorize(); + return Promise.reject(); } if (response.status === 503) { require("./Session").emitUnauthorize(); diff --git a/pollen-ui-riot-js/src/main/web/js/PollForm.js b/pollen-ui-riot-js/src/main/web/js/PollForm.js index 1e02149..a643854 100644 --- a/pollen-ui-riot-js/src/main/web/js/PollForm.js +++ b/pollen-ui-riot-js/src/main/web/js/PollForm.js @@ -46,16 +46,23 @@ class PollForm { this.model = {}; this.choices = []; this.choicesToRemove = []; + } - voteCountingTypeService.getVoteCountingTypes().then(result => { - this.voteCountingTypes = result; - }); + _loadVoteCountingTypes() { + if (!this.voteCountingTypes) { + return voteCountingTypeService.getVoteCountingTypes().then(result => { + this.voteCountingTypes = result; + return Promise.resolve(); + }); + } + return Promise.resolve(); } loadPoll(pollId, permission) { return Promise.all([ pollService.getPoll(pollId, permission), - choiceService.getChoices(pollId, permission) + choiceService.getChoices(pollId, permission), + this._loadVoteCountingTypes() ]).then(results => { Object.assign(this.model, results[0]); this.choices = results[1]; @@ -74,8 +81,11 @@ class PollForm { this.creation = true; console.info("init form"); - return pollService.empty(this.choiceType).then((poll) => { - this.model = poll; + return Promise.all([ + pollService.empty(this.choiceType), + this._loadVoteCountingTypes() + ]).then((results) => { + this.model = results[0]; console.info("empty poll"); console.info(this.model); diff --git a/pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html b/pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html index 2b7379d..c822483 100644 --- a/pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html @@ -18,8 +18,8 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * #L% */ -require("./Header.tag.html"); -require("./Footer.tag.html"); +require("./PollenHeader.tag.html"); +require("./PollenFooter.tag.html"); require("./SignIn.tag.html"); require("./SignUp.tag.html"); require("./SignCheck.tag.html"); @@ -30,9 +30,9 @@ require("./poll/Poll.tag.html"); require("./poll/Polls.tag.html"); require("./Users.tag.html"); <Pollen class="body-wrapper"> - <Header></Header> + <PollenHeader/> <div class="body-content" ref="content"></div> - <Footer></Footer> + <PollenFooter/> <script type="es6"> let session = require("../js/Session"); diff --git a/pollen-ui-riot-js/src/main/web/tag/Footer.tag.html b/pollen-ui-riot-js/src/main/web/tag/PollenFooter.tag.html similarity index 93% rename from pollen-ui-riot-js/src/main/web/tag/Footer.tag.html rename to pollen-ui-riot-js/src/main/web/tag/PollenFooter.tag.html index 4834db9..a3990c2 100644 --- a/pollen-ui-riot-js/src/main/web/tag/Footer.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/PollenFooter.tag.html @@ -18,7 +18,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * #L% */ -<footer> +<PollenFooter> <div class="links"> <a href="https://pollen.chorem.org/v/latest/index.html">{__.doc}</a> <a href="https://forge.chorem.org/projects/pollen/files">{__.download}</a> @@ -34,17 +34,17 @@ </script> <style> - footer { + pollenfooter { display: block; } - footer .links { + .links { width: 100%; background-color: black; text-align: center; } - footer .links a { + .links a { display: inline-block; font-size: 0.8em; text-decoration: none; @@ -52,9 +52,9 @@ padding: 0 20px; } - footer .links a:hover { + .links a:hover { color: blue; } </style> -</footer> +</PollenFooter> diff --git a/pollen-ui-riot-js/src/main/web/tag/Header.tag.html b/pollen-ui-riot-js/src/main/web/tag/PollenHeader.tag.html similarity index 98% rename from pollen-ui-riot-js/src/main/web/tag/Header.tag.html rename to pollen-ui-riot-js/src/main/web/tag/PollenHeader.tag.html index e528b71..52fce4b 100644 --- a/pollen-ui-riot-js/src/main/web/tag/Header.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/PollenHeader.tag.html @@ -19,7 +19,7 @@ * #L% */ require("./HeaderI18n.tag.html"); -<Header> +<PollenHeader> <div class="create dropdown"> <a class="header-link"><i class="fa fa-bars"/></a> <div class="dropdown-content"> @@ -107,7 +107,7 @@ require("./HeaderI18n.tag.html"); <style> - header { + pollenheader { display: flex; align-items: center; background-color: #13a2ff; @@ -121,7 +121,7 @@ require("./HeaderI18n.tag.html"); text-transform: uppercase; } - header a { + pollenheader a { color : #ffffff; } @@ -175,4 +175,4 @@ require("./HeaderI18n.tag.html"); } </style> -</Header> +</PollenHeader> diff --git a/pollen-ui-riot-js/src/main/web/tag/SignCheck.tag.html b/pollen-ui-riot-js/src/main/web/tag/SignCheck.tag.html index b9a447a..4d2dd70 100644 --- a/pollen-ui-riot-js/src/main/web/tag/SignCheck.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/SignCheck.tag.html @@ -19,23 +19,32 @@ * #L% */ <SignCheck> - <div class="body-container"> - <div class="body-container"> - <form class="signcheck" method="post" onsubmit="{signIn}"> - <div class="split"> - <div class="legend"> - <i class="fa fa-user fa-3x"> </i>{__.title} - </div> - <div>{__.message}</div> - <br/> - <a if="{!error}" class="button" href="#signin">{__.signin}</a> - <a if="{error}" class="button" href="#signup/validate">{__.resendValidation}</a> + <div class="container"> + <h1 class="c-heading"><i class="fa fa-user"/> {__.title}</h1> - <div class="{error ? 'error' : 'info'}">{message}</div> - </div> - </form> + <div show={waiting}> + {__.validating} + <i class="fa fa-cog fa-spin fa-fw"></i> + </div> + <div show={succes} class="c-alert c-alert--success"> + {__.validating_success} + </div> + <div show={error} class="c-alert c-alert--error"> + {__.validating_error} </div> + <div class="actions"> + <a show={succes} class="c-button c-button--info pull-right" + href="#signin"> + <i class="fa fa-sign-in" aria-hidden="true"></i> + {__.signin} + </a> + <a show={error} class="c-button c-button--info pull-right" + href="#signup/validate"> + <i class="fa fa-paper-plane" aria-hidden="true"></i> + {__.resendValidation} + </a> + </div> </div> <script type="es6"> @@ -43,68 +52,30 @@ let session = require("../js/Session"); this.installBundle(session, "signcheck"); - this.message = this.__.validating; + this.waiting = true; this.error = false; + this.succes = false; authService.validateEmail(this.opts.id, this.opts.token) - .then(() => { - this.message = this.__.validating_success; - this.update(); - }) - .catch(() => { - this.error = true; - this.message = this.__.validating_error; - this.update(); - }); + .then(() => { + this.waiting = false; + this.succes = true; + this.update(); + }) + .catch(() => { + this.waiting = false; + this.error = true; + this.update(); + }); </script> - <style scoped> - - .button { - margin: 5px 0; - } - - .signcheck { - display: flex; - justify-content: space-around; - background: white; - border: solid 2px #c8ccca; - padding: 45px 0; - border-radius: 10px; - text-align: center; - margin: 40px 0; - width: 400px; - } - - .legend { - width: 100%; - height: 70px; - border-bottom: 1px solid #b2c7d3; - display: flex; - justify-content: center; - align-items: center; - margin-bottom: 30px; - font-size: 20px; - } + <style> - .split { - flex-grow: 1; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; + .container { + width: 500px; } - .info { - margin: 3px; - color: #13a2ff; - } - - .error { - margin: 3px; - color: red; - } </style> </SignCheck> diff --git a/pollen-ui-riot-js/src/main/web/tag/SignIn.tag.html b/pollen-ui-riot-js/src/main/web/tag/SignIn.tag.html index 85b2d6c..ec3dee8 100644 --- a/pollen-ui-riot-js/src/main/web/tag/SignIn.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/SignIn.tag.html @@ -20,23 +20,38 @@ */ require("./popup/NewPassword.tag.html"); <SignIn> - <div class="body-container"> - <form class="signin" method="post" onsubmit="{signIn}"> - <div class="split"> - <div class="legend"> - <i class="fa fa-user fa-3x"> </i>{__.title} + <div class="container"> + <h1 class="c-heading">{__.title}</h1> + <form class="signin" onsubmit={signIn}> + <div class="o-form-element"> + <div class="c-input-group c-input-group--stacked"> + <div class="o-field"> + <input class="c-field {c-field--error : message}" + type="email" + id="login" + name="login" + ref="login" + required + placeholder={__.login_placeholder}> + </div> + <div class="o-field o-field--icon-right"> + <input class="c-field {c-field--error : message}" + type="password" + id="password" + name="password" + ref="password" + required + placeholder={__.password_placeholder}> + <button class="c-icon login-btn" + type="submit" + title={__.connexion}> + <i class="fa fa-fw fa-arrow-right"/> + </button> + </div> </div> - <label class="wide" for="login">{__.login}</label> - <input class="wide" type="text" id="login" name="login" ref="login" required - placeholder="{__.login_placeholder}"> - <label class="wide" for="password">{__.password}</label> - <input class="wide" type="password" id="password" name="password" ref="password" required - placeholder="{__.password_placeholder}"> - <a onclick="{newPassword}">{__.lostpassword}</a> - <br/> - <input type="submit" class="button" value="{__.connexion}"> - <div>{message}</div> + <div class="c-hint--static c-hint--error">{message}</div> </div> + <a onclick="{newPassword}">{__.lostpassword}</a> </form> </div> @@ -71,45 +86,21 @@ require("./popup/NewPassword.tag.html"); }; </script> - <style scoped> + <style> - .wide { - width: 320px; + .container { + width: 250px; } - .button { - margin: 5px 0; - } - - .signin { - display: flex; - justify-content: space-around; - background: white; - border: solid 2px #c8ccca; - padding: 45px 0; - border-radius: 10px; + .c-heading { text-align: center; - margin: 40px 0; - width: 400px; } - .legend { - width: 100%; - height: 70px; - border-bottom: 1px solid #b2c7d3; - display: flex; - justify-content: center; - align-items: center; - margin-bottom: 30px; - font-size: 20px; + .login-btn { + border: none; + background: transparent; + font-size: 1em; } - .split { - flex-grow: 1; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - } </style> </SignIn> diff --git a/pollen-ui-riot-js/src/main/web/tag/SignUp.tag.html b/pollen-ui-riot-js/src/main/web/tag/SignUp.tag.html index 61c57c4..0f18966 100644 --- a/pollen-ui-riot-js/src/main/web/tag/SignUp.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/SignUp.tag.html @@ -23,26 +23,77 @@ require("./popup/ResendValidation.tag.html"); require("./popup/AccountCreated.tag.html"); <SignUp> - <div class="body-container"> - <form ref="user" class="signup" method="post" onsubmit="{signUp}"> - <div class="split"> - <div class="legend"><i class="fa fa-user-plus fa-2x"> </i>{__.title}</div> - <label class="wide" for="name">{__.name}</label> - <div if="{errors.name}">{errors.name}</div> - <input class="wide" type="text" name="name" id="name" placeholder="{__.name_placeholder}" required> - <label class="wide" for="email">{__.email}</label> - <div if="{errors.email}">{errors.email}</div> - <input class="wide" type="email" name="email" id="email" placeholder="{__.email_placeholder}" required> - <label class="wide" for="name">{__.password}</label> - <div if="{errors.password}">{errors.password}</div> - <input class="wide" type="password" name="password" id="password" placeholder="{__.password_placeholder}" onblur="{checkPassword}" required> - <label class="wide" for="repeatPassword">{__.repeat_password}</label> - <div if="{errors.repeatPassword}">{errors.repeatPassword}</div> - <input class="wide" type="password" name="repeatPassword" id="repeatPassword" placeholder="{__.repeat_password_placeholder}" - pattern="{refs.user.password.value}" required onblur="{checkPassword}" onkeypress="{clearPasswordError}"> - <a onclick="{resendValidation}">{__.resendValidation}</a> - <br/> - <input type="submit" class="button" value="{__.validate}"> + <div class="container"> + <h1 class="c-heading"><i class="fa fa-user-plus"/> {__.title}</h1> + <form ref="user" class="signup" onsubmit="{signUp}"> + + <div class="o-form-element"> + <label class="c-label" for="name">{__.name}</label> + <input class="c-field {c-field--error : errors.name}" + type="text" + name="name" + ref="name" + placeholder="{__.name_placeholder}" + required> + <div if="{errors.name}" + class="c-hint--static c-hint--error"> + {errors.name} + </div> + </div> + + <div class="o-form-element"> + <label class="c-label" for="email">{__.email}</label> + <input class="c-field {c-field--error : errors.email}" + type="email" + name="email" + ref="email" + placeholder="{__.email_placeholder}" + required> + <div if="{errors.email}" + class="c-hint--static c-hint--error"> + {errors.email} + </div> + </div> + + <div class="o-form-element"> + <label class="c-label" for="password">{__.password}</label> + <input class="c-field {c-field--error : errors.password}" + type="password" + name="password" + ref="password" + placeholder="{__.password_placeholder}" + onblur="{checkPassword}" + required> + <div if="{errors.password}" + class="c-hint--static c-hint--error"> + {errors.password} + </div> + </div> + + <div class="o-form-element"> + <label class="c-label" for="email">{__.repeat_password}</label> + <input class="c-field {c-field--error : errors.repeatPassword}" + type="password" + name="repeatPassword" + ref="repeatPassword" + placeholder="{__.repeat_password_placeholder}" + onblur="{checkPassword}" + onkeypress="{clearPasswordError}" + required> + <div if="{errors.repeatPassword}" + class="c-hint--static c-hint--error"> + {errors.repeatPassword} + </div> + </div> + + <a class="resend-validation" onclick="{resendValidation}">{__.resendValidation}</a> + + <div class="actions"> + <button type="submit" + class="c-button c-button--info pull-right"> + <i class="fa fa-plus" aria-hidden="true"></i> + {__.validate} + </button> </div> </form> </div> @@ -55,17 +106,11 @@ require("./popup/AccountCreated.tag.html"); let session = require("../js/Session"); let FormHelper = require("../js/FormHelper"); - this.on("mount", () => { - if (this.validate) { - this.refs.resendValidation.open(); - } - }); - this.installBundle(session, "signup"); this.errors = {}; this.resendValidation = () => { - this.validate = true; + this.refs.resendValidation.open(); }; this.signUp = (e) => { @@ -74,20 +119,29 @@ require("./popup/AccountCreated.tag.html"); this.errors = {}; - let user = FormHelper.formToMap(this.refs.user); - authService.signUp(user) - .then(() => { + this.checkPassword(); + if (this.errors.repeatPassword === undefined) { + let user = { + name: this.refs.name.value, + email: this.refs.email.value, + password: this.refs.password.value, + repeatPassword: this.refs.repeatPassword.value + }; + + authService.signUp(user).then(() => { this.refs.accountCreated.open(); + this.update(); }) .catch((errors) => { this.errors = errors; this.update(); }); + } }; this.checkPassword = () => { - var password = this.refs.user.password.value; - var repeatPassword = this.refs.user.repeatPassword.value; + var password = this.refs.password.value; + var repeatPassword = this.refs.repeatPassword.value; if (repeatPassword && password !== repeatPassword) { this.errors.repeatPassword = this._l("repeat_password_error"); @@ -105,45 +159,36 @@ require("./popup/AccountCreated.tag.html"); } </script> - <style scoped> + <style> - .wide { - width: 320px; + .container { + max-width: 450px } - .button { - margin: 5px 0; - } - - .signup { - display: flex; - justify-content: space-around; - background: white; - border: solid 2px #c8ccca; - padding: 45px 0; - border-radius: 10px; + .c-heading { text-align: center; - margin: 40px 0; - width: 400px; } - .legend { - width: 100%; - height: 70px; - border-bottom: 1px solid #b2c7d3; - display: flex; - justify-content: center; - align-items: center; - margin-bottom: 30px; - font-size: 20px; - } + @media (min-width: 640px) { + .o-form-element .c-label:first-child { + width: 35%; + display: inline-block; + text-align: right; + float: left; + padding-top: 0.5em; + padding-right: 5px; + } + + .o-form-element .c-field { + width: 65%; + display: inline-block; + } - .split { - flex-grow: 1; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; + .signup .resend-validation, + .signup .c-hint--static { + margin-left: 35%; + } } + </style> </SignUp> diff --git a/pollen-ui-riot-js/src/main/web/tag/popup/AccountCreated.tag.html b/pollen-ui-riot-js/src/main/web/tag/popup/AccountCreated.tag.html index dc045d6..2aa94bd 100644 --- a/pollen-ui-riot-js/src/main/web/tag/popup/AccountCreated.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/popup/AccountCreated.tag.html @@ -18,40 +18,51 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * #L% */ -<AccountCreated class="close"> - - <div class="popup-background"></div> - - <div class="popup-content"> - <div class="popup-close" onclick="{close}"> - <i class="fa fa-times"></i> - </div> - <div class="popup-title">{__.title}</div> - <div class="popup-message"> - <div>{__.description}</div> - <a class="button" onclick="{action}">{__.action}</a> - </div> +<AccountCreated show={openModal}> + <div class="c-overlay"></div> + <div class="o-modal"> + <form class="c-card" + onsubmit={action}> + <header class="c-card__header"> + <button type="button" + onclick={close} + class="c-button c-button--close"> + × + </button> + <h2 class="c-heading"> + {__.title} + </h2> + </header> + <div class="c-card__body"> + {__.description} + </div> + + <footer class="c-card__footer"> + <button type="submit" + class="c-button c-button--brand"> + {__.action} + </button> + </footer> + </form> </div> <script type="es6"> let session = require("../../js/Session"); let route = require("riot-route"); - this.installBundle(session, "createdaccount"); + this.installBundle(session, "createaccount"); + this.openModal = false; this.oldParent = this.parent.root; this.open = () => { - document.body.appendChild(this.root); - this.root.classList.toggle("close"); - this.root.classList.toggle("open"); + this.openModal = true; }; this.close = () => { - this.oldParent.appendChild(this.root); - this.root.classList.toggle("close"); - this.root.classList.toggle("open"); + this.openModal = false; }; + this.action = () => { this.close(); route("home", null, true); @@ -60,83 +71,11 @@ </script> <style> - accountcreated { - justify-content: center; - align-items: center; - flex-direction: column; - position: absolute; - top: 0; - width: 100%; - height: 100%; - } - - .popup-background { - width: 100%; - height: 100%; - background-color: white; - opacity: .8; - position: absolute; - top: 0; - left: 0; - } - - accountcreated.close { - display: none; - } - - accountcreated.open { - display: flex; - } - - .popup-title { - height: 70px; - border-bottom: 1px solid #b2c7d3; - background-color: white; - display: flex; - justify-content: center; - align-items: center; - margin-bottom: 20px; - font-size: 20px; - } - - .popup-content { - position: relative; - z-index: 1; - border-radius: 10px; - background-color: #f2f2f2; - box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.1); - } - - .popup-content .button { - padding: 0; - border: none; - border-radius: 0; - width: 100%; - margin: 20px 0 0; - } - - .popup-close { - cursor: pointer; - position: absolute; - top: 20px; - right: 20px; - } - - .popup-message { - display: flex; - flex-direction: column; - width: 420px; - text-align: left; - } - - .popup-message > div { - margin-right: 22px; + @media (min-width: 640px) { + .o-modal { + width: 400px; + } } - - .popup-message > a { - padding: 0 20px; - } - </style> </AccountCreated> diff --git a/pollen-ui-riot-js/src/main/web/tag/popup/NewPassword.tag.html b/pollen-ui-riot-js/src/main/web/tag/popup/NewPassword.tag.html index 6dd71a4..727944f 100644 --- a/pollen-ui-riot-js/src/main/web/tag/popup/NewPassword.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/popup/NewPassword.tag.html @@ -18,24 +18,44 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * #L% */ -<NewPassword class="close"> - - <div class="popup-background"></div> - - <div class="popup-content"> - <div class="popup-close" onclick="{close}"> - <i class="fa fa-times"></i> - </div> - <div class="popup-title">{__.title}</div> - <form class="popup-message" onsubmit="{action}"> - <div class="popup-message-header"> - <div class="send" if="{sent}"><i class="fa fa-envelope"></i> {__.sent}</div> - <div if="{error}" class="error">{error}</div> +<NewPassword show={openModal}> + <div class="c-overlay"></div> + <div class="o-modal"> + <form class="c-card" + onsubmit={action}> + <header class="c-card__header"> + <button type="button" + onclick={close} + class="c-button c-button--close"> + × + </button> + <h2 class="c-heading"> + {__.title} + </h2> + </header> + <div class="c-card__body"> + <input class="c-field {c-field--error : error}" + ref="email" + type="email" + required + placeholder="{__.placeholder}"> + <div if="{error}" + class="c-hint--static c-hint--error"> + {error} + </div> + <div if="{sent}" + class="c-hint--static c-hint--success"> + <i class="fa fa-envelope"></i> {__.sent} + </div> </div> - <input ref="email" type="text" required placeholder="{__.placeholder}"> - <input type="submit" class="button" value="{__.action}"> - </form> + <footer class="c-card__footer"> + <button type="submit" + class="c-button c-button--brand"> + {__.action} + </button> + </footer> + </form> </div> <script type="es6"> @@ -44,6 +64,7 @@ this.installBundle(session, "newpassword"); this.sent = false; + this.openModal = false; this.error = ""; this.oldParent = this.parent.root; @@ -52,15 +73,11 @@ this.refs.email.value = email; this.error = ""; this.sent = false; - document.body.appendChild(this.root); - this.root.classList.toggle("close"); - this.root.classList.toggle("open"); + this.openModal = true; }; this.close = () => { - this.oldParent.appendChild(this.root); - this.root.classList.toggle("close"); - this.root.classList.toggle("open"); + this.openModal = false; }; this.action = (e) => { @@ -84,102 +101,11 @@ </script> <style> - newpassword { - justify-content: center; - align-items: center; - flex-direction: column; - position: absolute; - top: 0; - width: 100%; - height: 100%; - } - - .popup-background { - width: 100%; - height: 100%; - background-color: white; - opacity: .8; - position: absolute; - top: 0; - left: 0; - } - - newpassword.close { - display: none; - } - - newpassword.open { - display: flex; - } - - .popup-title { - height: 70px; - border-bottom: 1px solid #b2c7d3; - background-color: white; - display: flex; - justify-content: center; - align-items: center; - margin-bottom: 20px; - font-size: 20px; - } - - .popup-content { - position: relative; - z-index: 1; - border-radius: 10px; - background-color: #f2f2f2; - box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.1); - } - - .popup-content .button { - padding: 0; - border: none; - border-radius: 0; - width: 100%; - margin: 20px 0 0; - } - - .popup-close { - cursor: pointer; - position: absolute; - top: 20px; - right: 20px; - } - - .popup-message { - display: flex; - flex-direction: column; - width: 420px; - text-align: left; - } - - .popup-message > div { - margin-right: 22px; - } - - .popup-message-header { - display: flex; - flex-direction: row; - justify-content: flex-end; - height: 30px; - } - - .popup-message > input { - width: 390px; - margin-top: 10px; - margin-bottom: 5px; - } - - .send { - margin: 3px; - color: #13a2ff; - } - - .error { - margin: 3px; - color: red; + @media (min-width: 640px) { + .o-modal { + width: 400px; + } } - </style> </NewPassword> diff --git a/pollen-ui-riot-js/src/main/web/tag/popup/ResendValidation.tag.html b/pollen-ui-riot-js/src/main/web/tag/popup/ResendValidation.tag.html index 7b0d069..2137e44 100644 --- a/pollen-ui-riot-js/src/main/web/tag/popup/ResendValidation.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/popup/ResendValidation.tag.html @@ -18,24 +18,44 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * #L% */ -<ResendValidation class="close"> - - <div class="popup-background"></div> - - <div class="popup-content"> - <div class="popup-close" onclick="{close}"> - <i class="fa fa-times"></i> - </div> - <div class="popup-title">{__.title}</div> - <form class="popup-message" onsubmit="{action}"> - <div class="popup-message-header"> - <div class="send" if="{sent}"><i class="fa fa-envelope"></i> {__.sent}</div> - <div if="{error}" class="error">{error}</div> +<ResendValidation show={openModal}> + <div class="c-overlay"></div> + <div class="o-modal"> + <form class="c-card" + onsubmit={action}> + <header class="c-card__header"> + <button type="button" + onclick={close} + class="c-button c-button--close"> + × + </button> + <h2 class="c-heading"> + {__.title} + </h2> + </header> + <div class="c-card__body"> + <input class="c-field {c-field--error : error}" + ref="email" + type="email" + required + placeholder="{__.placeholder}"> + <div if="{error}" + class="c-hint--static c-hint--error"> + {error} + </div> + <div if="{sent}" + class="c-hint--static c-hint--success"> + <i class="fa fa-envelope"></i> {__.sent} + </div> </div> - <input ref="email" type="text" required placeholder="{__.placeholder}"> - <input type="submit" class="button" value="{__.action}"> - </form> + <footer class="c-card__footer"> + <button type="submit" + class="c-button c-button--brand"> + {__.action} + </button> + </footer> + </form> </div> <script type="es6"> @@ -45,22 +65,18 @@ this.installBundle(session, "resendvalidation"); - this.oldParent = this.parent.root; + this.openModal = false; this.open = () => { this.refs.email.value = ""; this.sent = false; this.error = ""; - document.body.appendChild(this.root); - this.root.classList.toggle("close"); - this.root.classList.toggle("open"); + this.openModal = true; this.update(); }; this.close = () => { - this.oldParent.appendChild(this.root); - this.root.classList.toggle("close"); - this.root.classList.toggle("open"); + this.openModal = false; }; this.action = (e) => { @@ -86,100 +102,10 @@ </script> <style> - resendvalidation { - justify-content: center; - align-items: center; - flex-direction: column; - position: absolute; - top: 0; - width: 100%; - height: 100%; - } - - .popup-background { - width: 100%; - height: 100%; - background-color: white; - opacity: .8; - position: absolute; - top: 0; - left: 0; - } - - resendvalidation.close { - display: none; - } - - resendvalidation.open { - display: flex; - } - - .popup-title { - height: 70px; - border-bottom: 1px solid #b2c7d3; - background-color: white; - display: flex; - justify-content: center; - align-items: center; - margin-bottom: 20px; - font-size: 20px; - } - - .popup-content { - position: relative; - z-index: 1; - border-radius: 10px; - background-color: #f2f2f2; - box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.1); - } - - .popup-content .button { - padding: 0; - border: none; - border-radius: 0; - width: 100%; - margin: 20px 0 0; - } - - .popup-close { - cursor: pointer; - position: absolute; - top: 20px; - right: 20px; - } - - .popup-message { - display: flex; - flex-direction: column; - width: 500px; - text-align: left; - } - - .popup-message > div { - margin-right: 22px; - } - - .popup-message-header { - display: flex; - flex-direction: row; - justify-content: flex-end; - height: 30px; - } - - .popup-message > input { - width: 470px; - margin-top: 10px; - margin-bottom: 5px; - } - - .send { - margin: 3px; - color: #13a2ff; - } - - .error { - margin: 3px; - color: red; + @media (min-width: 640px) { + .o-modal { + width: 400px; + } } </style> -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.