From bf40d2125865158babfffb8a6e69e515eecd0032 Mon Sep 17 00:00:00 2001 From: Vivek Chand Date: Wed, 14 Aug 2019 23:18:25 +0530 Subject: [PATCH] [component] restyle components --- client/components/404/404.js | 37 +- client/components/404/index.css | 19 +- client/components/404/index.js | 10 +- client/components/footer/index.css | 15 +- .../header/__snapshots__/header.test.js.snap | 290 +++++++--- client/components/header/header.js | 108 +++- client/components/header/header.test.js | 32 +- client/components/header/index.css | 110 +++- .../login/__snapshots__/login.test.js.snap | 511 ++++++++++-------- client/components/login/index.css | 156 +++--- client/components/login/login.js | 407 +++++++------- client/components/login/login.test.js | 21 +- client/components/modal/modal.test.js | 3 + .../components/organization-wrapper/index.css | 5 + .../organization-wrapper.js | 8 +- client/components/password-confirm/index.css | 76 +-- .../password-confirm/password-confirm.js | 9 +- .../__snapshots__/password-reset.test.js.snap | 4 +- client/components/password-reset/index.css | 65 +-- .../__snapshots__/registration.test.js.snap | 284 +++++----- client/components/registration/index.css | 83 ++- .../components/registration/registration.js | 511 +++++++++--------- .../registration/registration.test.js | 16 +- config/webpack.config.js | 1 + org-configurations/default-configuration.yml | 19 +- package-lock.json | 81 +-- package.json | 2 +- 27 files changed, 1659 insertions(+), 1224 deletions(-) diff --git a/client/components/404/404.js b/client/components/404/404.js index e6a4babe..8e618261 100644 --- a/client/components/404/404.js +++ b/client/components/404/404.js @@ -1,19 +1,50 @@ +/* eslint-disable react/require-default-props */ import "./index.css"; +import PropTypes from "prop-types"; import React from "react"; +import {Link} from "react-router-dom"; + +import getText from "../../utils/get-text"; export default class DoesNotExist extends React.Component { render() { + const {orgSlug, language, page} = this.props; return (
-
Oops!
-
404 Not Found
+
+ {page && page.heading ? getText(page.heading, language) : "Oops!"} +
+
+ {page && page.sub_heading + ? getText(page.sub_heading, language) + : "404 Not Found"} +
- Sorry, an error has occurred, Requested page not found! + {page && page.message + ? getText(page.message, language) + : "Sorry, an error has occurred, Requested page not found!"}
+ {page && page.homepage_link ? ( +
+ + {getText(page.homepage_link.text, language)} + +
+ ) : null}
); } } +DoesNotExist.propTypes = { + page: PropTypes.shape({ + heading: PropTypes.object, + sub_heading: PropTypes.object, + message: PropTypes.object, + homepage_link: PropTypes.object, + }), + language: PropTypes.string, + orgSlug: PropTypes.string, +}; diff --git a/client/components/404/index.css b/client/components/404/index.css index 670f4b19..54bac252 100644 --- a/client/components/404/index.css +++ b/client/components/404/index.css @@ -3,7 +3,6 @@ color: #333; width: 100%; height: 100%; - min-height: 100vh; display: flex; flex-direction: column; justify-content: center; @@ -11,13 +10,16 @@ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-weight: 500; line-height: 1.1; + flex-grow: 1; + box-sizing: border-box; + padding: 20px; } .owisp-404-row-1 { font-size: 36px; } .owisp-404-row-2 { - font-size: 30px; - margin-top: 20px; + font-size: 24px; + margin-top: 4px; margin-bottom: 10px; } .owisp-404-row-3 { @@ -25,3 +27,14 @@ font-weight: normal; line-height: 1.4; } +.owisp-404-row-4 { + font-size: 14px; + + line-height: 1.4; +} +.owisp-404-row-4 > a { + color: #333; +} +.owisp-404-row-4 > a:hover { + text-decoration: none; +} diff --git a/client/components/404/index.js b/client/components/404/index.js index 551a6800..ffa258fb 100644 --- a/client/components/404/index.js +++ b/client/components/404/index.js @@ -2,7 +2,15 @@ import {connect} from "react-redux"; import Component from "./404"; +const mapStateToProps = state => { + return { + page: state.organization.configuration.components["404_page"], + language: state.language, + orgSlug: state.organization.configuration.slug, + }; +}; + export default connect( - null, + mapStateToProps, null, )(Component); diff --git a/client/components/footer/index.css b/client/components/footer/index.css index 7df2e712..8063a050 100644 --- a/client/components/footer/index.css +++ b/client/components/footer/index.css @@ -5,8 +5,8 @@ align-items: center; flex-wrap: nowrap; font-family: sans-serif; - background: #2b3a42; - padding: 10px 0; + background: #282828; + padding: 20px 0; } .owisp-footer-row-1 { width: 100%; @@ -20,16 +20,17 @@ justify-content: center; align-items: center; flex-wrap: wrap; + flex-grow: 1; + max-width: 1000px; } .owisp-footer-link { color: #ffffff; padding: 0 2px; - margin-right: 5px; - text-decoration: none; + margin-right: 10px; text-transform: capitalize; } .owisp-footer-link:hover { - color: #8dd6f9; + text-decoration: none; } .owisp-footer-row-2 { display: flex; @@ -37,7 +38,9 @@ justify-content: center; align-items: center; flex-wrap: nowrap; - width: 100%; + flex-grow: 1; + max-width: 1000px; + margin-top: 4px; } .owisp-footer-row-2-inner { display: flex; diff --git a/client/components/header/__snapshots__/header.test.js.snap b/client/components/header/__snapshots__/header.test.js.snap index 1c4a39ab..542773b4 100644 --- a/client/components/header/__snapshots__/header.test.js.snap +++ b/client/components/header/__snapshots__/header.test.js.snap @@ -1,61 +1,136 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`
rendering should render with links 1`] = ` -
+Array [
+
+ +
+
+
- - + link-2 +
-
+ ,
+
+
+
+ + openwisp + +
+
+ -
+
, +] `; exports[`
rendering should render without links 1`] = ` -
+Array [
+
+ +
+
+
+
+
+
+
, +
+
+
+
+
+ + openwisp + +
+
+
+
+
- +
+
+
+
+
-
-
-
-
-
+
, +] `; diff --git a/client/components/header/header.js b/client/components/header/header.js index 57dd786c..b897e7b8 100644 --- a/client/components/header/header.js +++ b/client/components/header/header.js @@ -8,12 +8,42 @@ import getAssetPath from "../../utils/get-asset-path"; import getText from "../../utils/get-text"; export default class Header extends React.Component { + constructor(props) { + super(props); + this.state = { + menu: false, + }; + this.handleHamburger = this.handleHamburger.bind(this); + this.handleKeyUp = this.handleKeyUp.bind(this); + } + + handleHamburger() { + const {menu} = this.state; + this.setState({ + menu: !menu, + }); + } + + handleKeyUp(event) { + const {menu} = this.state; + switch (event.keyCode) { + case 13: + this.setState({ + menu: !menu, + }); + break; + default: + break; + } + } + render() { + const {menu} = this.state; const {header, languages, language, orgSlug, setLanguage} = this.props; const {logo, links} = header; return ( -
+
@@ -23,7 +53,7 @@ export default class Header extends React.Component { {logo.alternate_text} ) : null} @@ -36,7 +66,7 @@ export default class Header extends React.Component { type="button" className={`${ language === lang.slug ? "active " : "" - }owisp-header-language-btn owisp-header-language-btn-${ + }owisp-header-language-btn owisp-header-desktop-language-btn owisp-header-language-btn-${ lang.slug }`} key={lang.slug} @@ -55,7 +85,7 @@ export default class Header extends React.Component { return (
+
+
+
+
+
+ {logo && logo.url ? ( + + {logo.alternate_text} + + ) : null} +
+
+
+
+
+
+
+
+
+
+
+
+ {links.map((link, index) => { + return ( + + {getText(link.text, language)} + + ); + })} +
+ {languages.map(lang => { + return ( + + ); + })} +
+
+
); } diff --git a/client/components/header/header.test.js b/client/components/header/header.test.js index 2deb79f7..dfd8dd47 100644 --- a/client/components/header/header.test.js +++ b/client/components/header/header.test.js @@ -53,21 +53,27 @@ describe("
rendering", () => { expect(component).toMatchSnapshot(); }); it("should render 2 links", () => { - expect(wrapper.find(".owisp-header-link")).toHaveLength(2); + expect(wrapper.find(".owisp-header-desktop-link")).toHaveLength(2); }); it("should render 2 languages", () => { - expect(wrapper.find(".owisp-header-language-btn")).toHaveLength(2); + expect(wrapper.find(".owisp-header-desktop-language-btn")).toHaveLength(2); }); it("should render english as default language", () => { - expect(wrapper.find(".owisp-header-language-btn-en.active")).toHaveLength( - 1, - ); - expect(wrapper.find(".owisp-header-language-btn-it.active")).toHaveLength( - 0, - ); + expect( + wrapper.find( + ".owisp-header-desktop-language-btn.owisp-header-language-btn-en.active", + ), + ).toHaveLength(1); + expect( + wrapper.find( + ".owisp-header-desktop-language-btn.owisp-header-language-btn-it.active", + ), + ).toHaveLength(0); }); it("should render logo", () => { - expect(wrapper.find(".owisp-header-logo-image")).toHaveLength(1); + expect( + wrapper.find(".owisp-header-logo-image.owisp-header-desktop-logo-image"), + ).toHaveLength(1); }); it("should not render logo", () => { const logo = { @@ -78,7 +84,9 @@ describe("
rendering", () => { }; props = createTestProps(logo); wrapper = shallow(
); - expect(wrapper.find(".owisp-header-logo-image")).toHaveLength(0); + expect( + wrapper.find(".owisp-header-logo-image.owisp-header-desktop-logo-image"), + ).toHaveLength(0); }); }); @@ -90,7 +98,9 @@ describe("
interactions", () => { wrapper = shallow(
); }); it("should call setLanguage function when 'language button' is clicked", () => { - wrapper.find(".owisp-header-language-btn-it").simulate("click"); + wrapper + .find(".owisp-header-language-btn-it.owisp-header-desktop-language-btn") + .simulate("click"); expect(props.setLanguage).toHaveBeenCalledTimes(1); }); }); diff --git a/client/components/header/index.css b/client/components/header/index.css index 895096f7..db40a4c4 100644 --- a/client/components/header/index.css +++ b/client/components/header/index.css @@ -8,7 +8,7 @@ } .owisp-header-row-1 { width: 100%; - background: #f2f2f2; + background: #4a8456; display: flex; flex-direction: row; justify-content: center; @@ -19,7 +19,8 @@ justify-content: space-between; align-items: center; flex-wrap: nowrap; - width: 98%; + flex-grow: 1; + max-width: 1000px; padding: 5px 0; } .owisp-header-logo-div { @@ -44,17 +45,14 @@ margin: 0 5px; text-transform: uppercase; border: none; - color: #465e69; + color: #ffffff; background: none; outline: none; cursor: pointer; border-bottom: 3px rgba(0, 0, 0, 0) solid; } -.owisp-header-language-btn:active { - outline: none; -} .owisp-header-language-btn.active { - border-bottom-color: #465e69; + border-bottom-color: #ffffff; } .owisp-header-row-2 { display: flex; @@ -63,7 +61,7 @@ align-items: center; flex-wrap: nowrap; width: 100%; - background: #2b3a42; + background: #6f9d78; } .owisp-header-row-2-inner { display: flex; @@ -71,16 +69,98 @@ justify-content: flex-start; align-items: center; flex-wrap: nowrap; - width: 90%; + max-width: 1000px; + flex-grow: 1; + padding: 10px 0; } .owisp-header-link { - padding: 5px; - color: #ffffff; + padding: 8px 15px; + margin-right: 10px; + border-radius: 5px; + background-color: rgba(0, 0, 0, 0.3); + color: #fff; + font-weight: bold; + font-size: 14px; text-decoration: none; - margin: 5px; - outline: none; - font-size: large; + border: 0 none; + cursor: pointer; } .owisp-header-link:hover { - color: #8dd6f9; + background-color: rgba(0, 0, 0, 0.5); +} +.owisp-header-mobile { + display: none; +} +.owisp-display-none { + display: none; +} +.owisp-display-flex { + display: flex; +} +.owisp-opacity-hidden { + opacity: 0; +} +@media screen and (min-width: 0px) and (max-width: 767px) { + .owisp-header-hamburger { + width: 38px; + margin-right: 10px; + height: 30px; + cursor: pointer; + } + .owisp-header-hamburger:focus { + outline: dotted 1px #fff; + } + .owisp-header-hamburger > div { + height: 5px; + background: #fff; + content: ""; + position: relative; + transition: 0.25s all ease-in-out; + border-radius: 1px; + } + .owisp-rot45 { + transform: rotate(45deg); + top: 10px !important; + } + + .owisp-rot-45 { + transform: rotate(-45deg); + } + + .owisp-header-hamburger div:nth-child(1) { + top: 0; + } + .owisp-header-hamburger div:nth-child(2) { + top: 5px; + } + .owisp-header-hamburger div:nth-child(3) { + top: 10px; + } + .owisp-header-mobile { + display: flex; + flex-direction: column; + } + .owisp-header-mobile-menu { + transition: 0.25s all ease-in-out; + + flex-direction: column; + background: #6f9d78; + align-items: center; + } + .owisp-header-mobile-menu > .owisp-header-link { + margin-right: 0; + margin: 4px 0; + width: 90%; + box-sizing: border-box; + } + .owisp-header-desktop { + display: none; + } + .owisp-mobile-languages-row { + width: 90%; + margin: 0 0 12px 0; + } + .owisp-header-language-btn.active { + cursor: auto; + } } diff --git a/client/components/login/__snapshots__/login.test.js.snap b/client/components/login/__snapshots__/login.test.js.snap index d48d35c8..e0255895 100644 --- a/client/components/login/__snapshots__/login.test.js.snap +++ b/client/components/login/__snapshots__/login.test.js.snap @@ -1,275 +1,312 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[` rendering should render correctly with social links 1`] = ` -
-
+
-
- sign in -
-
-
-
+ + +
+ + - + + + + +
- password + By logging in, you accept the + + terms and conditions + + and the + + privacy policy + + of this WiFi service.
- - -
-
- By logging in, you accept the - - terms and conditions - - and the - - privacy policy - - of this WiFi service. -
- - - -
-
+
+ + `; exports[` rendering should render correctly without social links 1`] = ` -
-
+
-
- sign in -
-
-
- -
-
- By logging in, you accept the - - terms and conditions - - and the - - privacy policy - - of this WiFi service. -
- -
-
- login with -
- +
+ + `; diff --git a/client/components/login/index.css b/client/components/login/index.css index 350d3a3d..0306bd8d 100644 --- a/client/components/login/index.css +++ b/client/components/login/index.css @@ -4,24 +4,38 @@ flex-direction: row; justify-content: center; align-items: flex-start; - background: #f2f2f2; width: 100%; + box-sizing: border-box; + padding: 27px 0 27px 0; +} +.owisp-login-container-inner { + display: flex; + flex-direction: row; + justify-content: space-between; + flex-grow: 1; + max-width: 1000px; } .owisp-login-form { font-family: sans-serif; - background: #ffffff; + background: #4a8456; display: flex; flex-direction: column; justify-content: center; align-items: center; + width: 53%; + box-sizing: border-box; padding: 24px 50px; } +.owisp-login-contact-container { + width: 44%; + box-sizing: border-box; +} .owisp-login-form.success .owisp-login-input:invalid { box-shadow: none; } .owisp-login-header-content { text-transform: capitalize; - color: #444; + color: #ffffff; font-size: 28px; margin-bottom: 4px; } @@ -31,23 +45,25 @@ justify-content: flex-start; align-items: flex-start; align-self: flex-start; + width: 100%; } .owisp-login-label { margin-top: 15px; margin-bottom: 5px; + width: 100%; } .owisp-login-label-text { - color: #6b6b6b; + color: #ffffff; text-transform: capitalize; } .owisp-login-input { - padding: 10px; + padding: 6px 10px; border-radius: 3px; font-size: 18px; border: 2px solid #e7e7e7; margin-top: 5px; - width: 380px; box-sizing: border-box; + width: 100%; } .owisp-login-input:focus { border-color: #a7a7a7; @@ -59,7 +75,7 @@ width: 100%; font-size: 18px; height: 50px; - background: #293b52; + background-color: rgba(0, 0, 0, 0.3); color: #ffffff; text-transform: capitalize; border: 0; @@ -67,34 +83,36 @@ cursor: pointer; } .owisp-login-form-btn:focus { - outline: dotted 1px #444; + outline: dotted 1px #ffffff; outline-offset: 0.5px; } .owisp-login-login-btn { - margin-top: 4px; + margin-top: 8px; } .owisp-login-form-btn:hover { - background: #223144; + background-color: rgba(0, 0, 0, 0.5); } .owisp-login-error { - font-size: 12px; - color: #d93025; - width: 324px; + margin-top: 3px; + font-size: 14px; display: flex; flex-direction: row; justify-content: flex-start; flex-wrap: nowrap; + align-items: center; + width: 100%; + color: #ffffff; + background: #d93025; + border-radius: 3px; + padding: 4px; + box-sizing: border-box; } .owisp-login-error-icon { display: inline-block; - background: #d93025; - color: #ffffff; min-width: 16px; - align-self: center; height: 16px; - border-radius: 50%; text-align: center; - margin-right: 8px; + margin-right: 4px; font-weight: 600; } .owisp-login-register-link { @@ -103,85 +121,58 @@ } .owisp-login-add-info { margin-top: 15px; - color: #444; - max-width: 380px; + color: #ffffff; } .owisp-login-additional-link { - color: #444; + color: #ffffff; } .owisp-login-additional-link:hover, .owisp-login-additional-link:focus { - outline: dotted 1px #444; + outline: dotted 1px #ffffff; outline-offset: 0.5px; -} -.owisp-login-social-hr { - outline: 0; - border: 0; - text-align: center; - height: 1.5em; - line-height: 1em; - position: relative; - width: 100%; -} -.owisp-login-social-hr:before { - content: ""; - background: #e6e6e6; - position: absolute; - left: 0; - top: 48%; - width: 100%; - height: 2px; -} -.owisp-login-social-hr:after { - content: attr(data-content); - position: relative; - display: inline-block; - padding: 0 0.5em; - line-height: 1.5em; - color: #798993; - background-color: #fcfcfa; -} -.owisp-login-divider-description { - color: #798993; - text-transform: uppercase; - font-size: 0.9rem; - width: 100%; - text-align: center; + text-decoration: none; } .owisp-login-social-links-div { width: 100%; + display: flex; + flex-direction: column; + justify-content: flex-start; +} +.owisp-login-social-link { display: flex; flex-direction: row; + text-decoration: none; + background-color: rgba(0, 0, 0, 0.3); + font-size: 16px; + font-weight: bold; + color: #ffffff; + align-items: center; + margin: 10px 0; + padding: 8px 0; justify-content: center; - flex-wrap: wrap; - margin-top: 8px; + border-radius: 5px; } -.owisp-login-social-link { +.owisp-login-social-link > div { display: flex; flex-direction: row; flex-wrap: nowrap; - padding: 4px 8px; - align-items: center; - text-decoration: none; - color: #798993; - border-radius: 3px; - margin-right: 12px; - box-shadow: 1px 1px 1px 1px hsla(0, 0%, 53%, 0.33); + width: 80%; } .owisp-login-social-link:hover { - background: #efefef; + background-color: rgba(0, 0, 0, 0.5); } .owisp-login-social-link:focus { - outline: dotted 1px #444; + outline: dotted 1px #ffffff; outline-offset: 0.5px; } .owisp-login-social-link-icon { - width: 28px; - height: auto; + width: auto; + height: 28px; } .owisp-login-social-link-text { - margin-left: 3px; + line-height: 28px; text-transform: capitalize; + margin-left: 30px; } .owisp-login-links-div { display: flex; @@ -189,25 +180,36 @@ width: 100%; justify-content: flex-start; align-items: center; - margin-top: 20px; + margin-top: 12px; } .owisp-login-link { line-height: 1.4; - text-decoration: none; text-transform: capitalize; - color: #444; + color: #ffffff; + margin-top: 6px; } .owisp-login-link:focus { - outline: dotted 1px #444; + outline: dotted 1px #ffffff; outline-offset: 0.5px; } .owisp-login-link:hover { - text-decoration: underline; + text-decoration: none; } .owisp-login-error-non-field { box-sizing: border-box; font-size: 16px; width: 100%; - max-width: 380px; margin-top: 15px; } +@media screen and (min-width: 0px) and (max-width: 767px) { + .owisp-login-container-inner { + flex-direction: column; + } + .owisp-login-form { + width: 100%; + margin-bottom: 20px; + } + .owisp-login-contact-container { + width: 100%; + } +} diff --git a/client/components/login/login.js b/client/components/login/login.js index 405b5046..eebae785 100644 --- a/client/components/login/login.js +++ b/client/components/login/login.js @@ -11,6 +11,7 @@ import {loginApiUrl} from "../../constants"; import getAssetPath from "../../utils/get-asset-path"; import getText from "../../utils/get-text"; import renderAdditionalInfo from "../../utils/render-additional-info"; +import Contact from "../contact-box"; import Modal from "../modal"; export default class Login extends React.Component { @@ -88,221 +89,217 @@ export default class Login extends React.Component { return (
-
-
-
- {getText(header, language)} -
-
-
- {errors.nonField && ( -
- ! - - {errors.nonField} - +
+ +
+
+ {getText(header, language)}
- )} - {input_fields.username ? ( - <> - - {errors.username && ( -
- ! - - {errors.username} - -
- )} - - ) : null} - {input_fields.password ? ( +
+ {social_login ? ( <> - - {errors.password && ( -
- ! - - {errors.password1} - -
- )} + {social_login.links.length ? ( + <> +
+ {social_login.links.map(link => { + if (link.url) + return ( + +
+ {link.icon ? ( + { + ) : null} + {link.text ? ( +
+ {getText(link.text, language)} +
+ ) : null} +
+
+ ); + return null; + })} +
+ + ) : null} ) : null} -
- {additional_info_text ? ( -
- {renderAdditionalInfo( - additional_info_text, - language, - termsAndConditions, - privacyPolicy, - orgSlug, - "login", - )} -
- ) : null} - {buttons.login ? ( - <> - {buttons.login.label ? ( - - ) : null} - - - ) : null} - {social_login ? ( - <> - {social_login.divider_text ? ( -
- ) : null} - {social_login.description ? ( -
- {getText(social_login.description, language)} +
+ {errors.nonField && ( +
+ ! + + {errors.nonField} +
- ) : null} - {social_login.links.length ? ( + )} + {input_fields.username ? ( <> -
- {social_login.links.map(link => { - if (link.url) - return ( - - {link.icon ? ( - { - ) : null} - {link.text ? ( -
- {getText(link.text, language)} -
- ) : null} -
- ); - return null; - })} -
+ + {errors.username && ( +
+ ! + + {errors.username} + +
+ )} ) : null} - - ) : null} - {links ? ( -
- {links.forget_password ? ( - - {getText(links.forget_password, language)} - - ) : null} - {links.register ? ( - - {getText(links.register, language)} - + {input_fields.password ? ( + <> + + {errors.password && ( +
+ ! + + {errors.password1} + +
+ )} + ) : null}
- ) : null} - + {additional_info_text ? ( +
+ {renderAdditionalInfo( + additional_info_text, + language, + termsAndConditions, + privacyPolicy, + orgSlug, + "login", + )} +
+ ) : null} + {buttons.login ? ( + <> + {buttons.login.label ? ( + + ) : null} + + + ) : null} + {links ? ( +
+ {links.forget_password ? ( + + {getText(links.forget_password, language)} + + ) : null} + {links.register ? ( + + {getText(links.register, language)} + + ) : null} +
+ ) : null} + +
+ +
+
rendering", () => { let props; it("should render correctly without social links", () => { props = createTestProps(); - const component = renderer - .create( - - - , - ) - .toJSON(); + const renderer = new ShallowRenderer(); + const component = renderer.render(); expect(component).toMatchSnapshot(); }); it("should render correctly with social links", () => { @@ -61,13 +55,8 @@ describe(" rendering", () => { }, }, }); - const component = renderer - .create( - - - , - ) - .toJSON(); + const renderer = new ShallowRenderer(); + const component = renderer.render(); expect(component).toMatchSnapshot(); }); }); diff --git a/client/components/modal/modal.test.js b/client/components/modal/modal.test.js index 8adeaf39..ad401b94 100644 --- a/client/components/modal/modal.test.js +++ b/client/components/modal/modal.test.js @@ -17,6 +17,9 @@ const createTestProps = props => { }, }, prevPath: "/default/login", + history: { + push: jest.fn(), + }, ...props, }; }; diff --git a/client/components/organization-wrapper/index.css b/client/components/organization-wrapper/index.css index 0fa05bda..219d1022 100644 --- a/client/components/organization-wrapper/index.css +++ b/client/components/organization-wrapper/index.css @@ -26,6 +26,11 @@ height: 50px; animation: spin 0.8s linear infinite; } +.owisp-org-wrapper-not-found { + display: flex; + flex-direction: column; + height: 100vh; +} @keyframes spin { 0% { transform: rotate(0deg); diff --git a/client/components/organization-wrapper/organization-wrapper.js b/client/components/organization-wrapper/organization-wrapper.js index cf82b461..66f8b73c 100644 --- a/client/components/organization-wrapper/organization-wrapper.js +++ b/client/components/organization-wrapper/organization-wrapper.js @@ -7,7 +7,8 @@ import {Helmet} from "react-helmet"; import {Redirect, Route, Switch} from "react-router-dom"; import getAssetPath from "../../utils/get-asset-path"; -import DoesNotExist from "../404"; +import ConnectedDoesNotExist from "../404"; +import DoesNotExist from "../404/404"; import Footer from "../footer"; import Header from "../header"; import Login from "../login"; @@ -90,6 +91,11 @@ export default class OrganizationWrapper extends React.Component { return ; }} /> + { + return ; + }} + />
} />
diff --git a/client/components/password-confirm/index.css b/client/components/password-confirm/index.css index 0372c4be..f638c2c5 100644 --- a/client/components/password-confirm/index.css +++ b/client/components/password-confirm/index.css @@ -4,40 +4,31 @@ flex-direction: row; justify-content: center; align-items: flex-start; - background: #f2f2f2; width: 100%; + padding: 27px 0 27px 0; } .owisp-password-confirm-form { font-family: sans-serif; display: flex; flex-direction: column; justify-content: center; - align-items: center; - padding: 40px 50px; - background: #ffffff; - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.18); + align-items: flex-start; + width: 95%; } .owisp-password-confirm-input:invalid { box-shadow: none; } -.owisp-password-confirm-header { - display: flex; - flex-direction: column; - justify-content: flex-start; - align-items: center; -} .owisp-password-confirm-heading { text-transform: capitalize; - color: #444; - font-size: 28px; + color: #666; + font-size: 20px; font-family: "Comic Sans MS", cursive, sans-serif; } .owisp-password-confirm-subheading { - color: #444; - font-size: 16px; - line-height: 1.5; - width: 324px; - text-align: center; + color: #333; + font-size: 14px; + line-height: 1.3; + margin-top: 20px; } .owisp-password-confirm-subheading::first-letter { text-transform: uppercase; @@ -47,37 +38,33 @@ flex-direction: column; justify-content: flex-start; align-items: flex-start; - margin-top: 28px; + margin-top: 8px; } .owisp-password-confirm-label { - margin-top: 4px; margin-bottom: 4px; } .owisp-password-confirm-label-text { - color: #6b6b6b; + color: #333; text-transform: capitalize; } .owisp-password-confirm-input { - padding: 10px; + padding: 5px 10px; border-radius: 3px; font-size: 18px; - border: 2px solid #e7e7e7; + border: 1px solid #ccc; margin-top: 4px; - text-transform: capitalize; - width: 300px; } .owisp-password-confirm-input:focus { - border-color: #a7a7a7; + border-color: #aaa; } .owisp-password-confirm-input.error { border-color: #d93025; } .owisp-password-confirm-submit-btn { - width: 100%; margin-top: 16px; - font-size: 18px; - height: 50px; - background: #293b52; + padding: 10px 15px; + font-size: 14px; + background-color: rgba(50, 96, 59, 0.9); color: #ffffff; text-transform: capitalize; border: 0; @@ -85,16 +72,14 @@ cursor: pointer; } .owisp-password-confirm-submit-btn:hover { - background: #223144; + background-color: rgba(50, 96, 59, 1); } .owisp-password-confirm-submit-btn:focus { - outline: dotted 1px #444; - outline-offset: 0.5px; + outline: dotted 1px #333; } .owisp-password-confirm-error { font-size: 12px; color: #d93025; - width: 324px; display: flex; flex-direction: row; justify-content: flex-start; @@ -103,7 +88,7 @@ .owisp-password-confirm-error-non-field { border-radius: 3px; box-sizing: border-box; - font-size: 16px; + font-size: 12px; margin-bottom: 12px; } .owisp-password-confirm-error-icon { @@ -117,30 +102,25 @@ margin-right: 8px; font-weight: 600; } -.owisp-password-confirm-links { - color: #0d3455; - margin-top: 16px; - text-decoration: none; -} -.owisp-password-confirm-links:hover { - opacity: 0.8; -} .owisp-password-confirm-success { - color: #444; + color: #333; margin-top: 16px; - font-size: 18px; - max-width: 350px; - text-align: center; + font-size: 14px; +} +.owisp-password-confirm-message-container { + display: flex; + flex-direction: column; } .owisp-password-confirm-icon { width: 56px; height: 56px; - background: #39c03c; + background: #6f9d78; display: flex; flex-direction: row; justify-content: center; align-items: center; border-radius: 50%; + align-self: center; } .owisp-password-confirm-tick { display: inline-block; diff --git a/client/components/password-confirm/password-confirm.js b/client/components/password-confirm/password-confirm.js index c7ca959b..4256001a 100644 --- a/client/components/password-confirm/password-confirm.js +++ b/client/components/password-confirm/password-confirm.js @@ -34,7 +34,6 @@ export default class PasswordConfirm extends React.Component { if (newPassword1 !== newPassword2) { this.setState({ errors: { - ...errors, newPassword2: passwordConfirmError, }, }); @@ -93,10 +92,12 @@ export default class PasswordConfirm extends React.Component {
{success ? (
-
-
+
+
+
+
+
{success}
-
{success}
) : (
rendering should render correctly 1`] = `
- enter your email and we'll send you the instructions to reset your password + Forgotten your password? Enter your e-mail address below, and we'll send you an e-mail allowing you to reset it.
rendering should render correctly 1`] = ` rendering should render correctly 1`] = ` - + + `; diff --git a/client/components/registration/index.css b/client/components/registration/index.css index 6b5b0564..55621d7e 100644 --- a/client/components/registration/index.css +++ b/client/components/registration/index.css @@ -4,25 +4,39 @@ flex-direction: row; justify-content: center; align-items: flex-start; - background: #f2f2f2; width: 100%; + box-sizing: border-box; + padding: 27px 0 27px 0; +} +.owisp-registration-container-inner { + display: flex; + flex-direction: row; + justify-content: space-between; + flex-grow: 1; + max-width: 1000px; } .owisp-registration-form { font-family: sans-serif; - background: #ffffff; + background: #4a8456; display: flex; flex-direction: column; justify-content: center; align-items: center; - padding: 40px 50px; + padding: 24px 50px; + width: 53%; + box-sizing: border-box; } .owisp-registration-form.success .owisp-registration-input:invalid { box-shadow: none; } +.owisp-registration-contact-container { + width: 44%; + box-sizing: border-box; +} .owisp-registration-header-content { text-transform: capitalize; - color: #444; - font-size: 35px; + color: #ffffff; + font-size: 28px; margin-bottom: 15px; } .owisp-registration-fieldset { @@ -30,40 +44,43 @@ flex-direction: column; justify-content: flex-start; align-items: flex-start; + width: 100%; } .owisp-registration-label { margin-top: 15px; margin-bottom: 5px; + width: 100%; } .owisp-registration-label-text { - color: #6b6b6b; + color: #ffffff; text-transform: capitalize; } .owisp-registration-input { - padding: 10px; + padding: 5px 10px; border-radius: 3px; font-size: 18px; border: 2px solid #e7e7e7; margin-top: 5px; - width: 300px; + width: 100%; + box-sizing: border-box; } .owisp-registration-input:focus { - border-color: #a7a7a7; + border-color: #666666; } .owisp-registration-input.error { border-color: #d93025; } .owisp-registration-add-info { margin-top: 15px; - color: #444; - max-width: 330px; + color: #ffffff; + margin-bottom: 15px; } .owisp-registration-additional-link { - color: #444; + color: #ffffff; } .owisp-registration-additional-link:hover, .owisp-registration-additional-link:focus { - outline: dotted 1px #444; + outline: dotted 1px #ffffff; outline-offset: 0.5px; } .owisp-registration-label-registration-btn { @@ -73,7 +90,7 @@ width: 100%; font-size: 18px; height: 50px; - background: #293b52; + background-color: rgba(0, 0, 0, 0.3); color: #ffffff; text-transform: capitalize; border: 0; @@ -81,42 +98,56 @@ cursor: pointer; } .owisp-registration-submit-btn:hover { - background: #223144; + background-color: rgba(0, 0, 0, 0.5); } .owisp-registration-submit-btn:focus { - outline: dotted 1px #444; + outline: dotted 1px #ffffff; outline-offset: 0.5px; } .owisp-registration-error { - font-size: 12px; - color: #d93025; - width: 324px; + margin-top: 3px; + font-size: 14px; display: flex; flex-direction: row; justify-content: flex-start; flex-wrap: nowrap; + align-items: center; + width: 100%; + color: #ffffff; + background: #d93025; + border-radius: 3px; + padding: 4px; + box-sizing: border-box; } .owisp-registration-error-icon { display: inline-block; - background: #d93025; - color: #ffffff; min-width: 16px; height: 16px; - border-radius: 50%; text-align: center; - margin-right: 8px; + margin-right: 4px; font-weight: 600; } .owisp-registration-link { line-height: 1.4; - text-decoration: none; text-transform: capitalize; - color: #444; + color: #ffffff; } .owisp-registration-link:focus { outline: dotted 1px #444; outline-offset: 0.5px; } .owisp-registration-link:hover { - text-decoration: underline; + text-decoration: none; +} +@media screen and (min-width: 0px) and (max-width: 767px) { + .owisp-registration-container-inner { + flex-direction: column; + } + .owisp-registration-form { + width: 100%; + margin-bottom: 20px; + } + .owisp-registration-contact-container { + width: 100%; + } } diff --git a/client/components/registration/registration.js b/client/components/registration/registration.js index 38a3763c..8dc51b3b 100644 --- a/client/components/registration/registration.js +++ b/client/components/registration/registration.js @@ -10,6 +10,7 @@ import {Link, Route} from "react-router-dom"; import {passwordConfirmError, registerApiUrl} from "../../constants"; import getText from "../../utils/get-text"; import renderAdditionalInfo from "../../utils/render-additional-info"; +import Contact from "../contact-box"; import Modal from "../modal"; export default class Registration extends React.Component { @@ -40,7 +41,6 @@ export default class Registration extends React.Component { if (password1 !== password2) { this.setState({ errors: { - ...errors, password2: passwordConfirmError, }, }); @@ -88,6 +88,9 @@ export default class Registration extends React.Component { ...(data.password2 ? {password2: data.password2.toString()} : {password2: ""}), + ...(data.detail + ? {nonField: data.detail.toString()} + : {nonField: ""}), }, }); }); @@ -107,264 +110,278 @@ export default class Registration extends React.Component { return (
-
-
-
- {getText(registration.header, language)} +
+ +
+
+ {getText(registration.header, language)} +
-
-
- {input_fields.username ? ( - <> - + {errors.username && ( +
+ ! + + {errors.username} + +
+ )} + + ) : null} - {input_fields.email ? ( - <> - - {errors.email && ( -
- ! - - {errors.email} - -
- )} - - ) : null} + {input_fields.email ? ( + <> + + {errors.email && ( +
+ ! + + {errors.email} + +
+ )} + + ) : null} - {input_fields.password ? ( - <> - + {errors.password1 && ( +
+ ! + + {errors.password1} + +
+ )} + + ) : null} + + {input_fields.password_confirm ? ( + <> + + {errors.password2 && ( +
+ ! + + {errors.password2} + +
+ )} + + ) : null} +
+ {additional_info_text ? ( +
+ {renderAdditionalInfo( + additional_info_text, + language, + termsAndConditions, + privacyPolicy, + orgSlug, + "registration", )} - +
) : null} - - {input_fields.password_confirm ? ( + {buttons.register ? ( <> - - {errors.password2 && ( -
- ! - - {errors.password2} - -
- )} + {buttons.register.label ? ( + + ) : null} + ) : null} + {links ? ( +
+ {links.forget_password ? ( + + {getText(links.forget_password, language)} + + ) : null} + {links.login ? ( + + {getText(links.login, language)} + + ) : null} +
+ ) : null} + +
+
- {additional_info_text ? ( -
- {renderAdditionalInfo( - additional_info_text, - language, - termsAndConditions, - privacyPolicy, - orgSlug, - "registration", - )} -
- ) : null} - {buttons.register ? ( - <> - {buttons.register.label ? ( - - ) : null} - - - ) : null} - {links ? ( -
- {links.forget_password ? ( - - {getText(links.forget_password, language)} - - ) : null} - {links.login ? ( - - {getText(links.login, language)} - - ) : null} -
- ) : null} - +
rendering", () => { }); it("should render correctly", () => { props = createTestProps(); - const component = renderer - .create( - - - , - ) - .toJSON(); + const renderer = new ShallowRenderer(); + const component = renderer.render(); expect(component).toMatchSnapshot(); }); }); @@ -79,6 +73,7 @@ describe(" interactions", () => { data: { username: "username error", email: "email error", + detail: "nonField error", password1: "password1 error", password2: "password2 error", }, @@ -108,10 +103,11 @@ describe(" interactions", () => { expect(wrapper.instance().state.errors).toEqual({ username: "username error", email: "email error", + nonField: "nonField error", password1: "password1 error", password2: "password2 error", }); - expect(wrapper.find(".owisp-registration-error")).toHaveLength(4); + expect(wrapper.find(".owisp-registration-error")).toHaveLength(5); }) .then(() => { return wrapper diff --git a/config/webpack.config.js b/config/webpack.config.js index 1f8ab1b0..6c212052 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -47,6 +47,7 @@ module.exports = (env, argv) => { filename: "index.html", template: path.resolve(CURRENT_WORKING_DIR, "public/index.html"), }), + new HardSourceWebpackPlugin(), new CopyPlugin([ { from: path.resolve(CURRENT_WORKING_DIR, "client/assets"), diff --git a/org-configurations/default-configuration.yml b/org-configurations/default-configuration.yml index c95fd03d..ffd34915 100644 --- a/org-configurations/default-configuration.yml +++ b/org-configurations/default-configuration.yml @@ -117,7 +117,7 @@ client: heading: en: "reset your password" additional_text: - en: "enter your email and we'll send you the instructions to reset your password" + en: "Forgotten your password? Enter your e-mail address below, and we'll send you an e-mail allowing you to reset it." input_fields: email: type: "email" @@ -130,7 +130,7 @@ client: en: "email" buttons: send: - en: 'send' + en: 'Reset My Password' login_page_link: text: en: "Take me Back to Sign In" @@ -204,10 +204,6 @@ client: header: en: " sign in" social_login: - divider_text: - en: "OR" - description: - en: "login with" links: - text: null @@ -244,6 +240,17 @@ client: en: "Forgot your password?" register: en: "Not registered yet? Create an account" + 404_page: + heading: + en: "404" + sub_heading: + en: "Not Found" + message: + en: "Sorry, we couldn't find the page you were looking for." + homepage_link: + text: + en: "Go back to homepage" + privacy_policy: title: en: "privacy policy" diff --git a/package-lock.json b/package-lock.json index f58fe7cc..d5013355 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1862,12 +1862,6 @@ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "dev": true }, - "JSV": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/JSV/-/JSV-4.0.2.tgz", - "integrity": "sha1-0Hf2glVx+CEy+d/67Vh7QCn+/1c=", - "dev": true - }, "abab": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.0.tgz", @@ -5752,22 +5746,32 @@ } }, "hard-source-webpack-plugin": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/hard-source-webpack-plugin/-/hard-source-webpack-plugin-0.12.0.tgz", - "integrity": "sha512-xELLABhB3WtdVxDZ4iku8W5Xi0Tq5w+1fOXrSWjeML90uWikykkiQmTV6Lk0MKC5uFEKUZcSuTY5BZS+8ZXr8A==", + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/hard-source-webpack-plugin/-/hard-source-webpack-plugin-0.13.1.tgz", + "integrity": "sha512-r9zf5Wq7IqJHdVAQsZ4OP+dcUSvoHqDMxJlIzaE2J0TZWn3UjMMrHqwDHR8Jr/pzPfG7XxSe36E7Y8QGNdtuAw==", "dev": true, "requires": { "chalk": "^2.4.1", "find-cache-dir": "^2.0.0", - "jsonlint": "^1.6.3", + "graceful-fs": "^4.1.11", "lodash": "^4.15.0", "mkdirp": "^0.5.1", "node-object-hash": "^1.2.0", + "parse-json": "^4.0.0", "pkg-dir": "^3.0.0", "rimraf": "^2.6.2", + "semver": "^5.6.0", "tapable": "^1.0.0-beta.5", "webpack-sources": "^1.0.1", "write-json-file": "^2.3.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } } }, "has": { @@ -5779,12 +5783,6 @@ "function-bind": "^1.1.1" } }, - "has-color": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz", - "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=", - "dev": true - }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -7262,16 +7260,6 @@ "minimist": "^1.2.0" } }, - "jsonlint": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/jsonlint/-/jsonlint-1.6.3.tgz", - "integrity": "sha512-jMVTMzP+7gU/IyC6hvKyWpUU8tmTkK5b3BPNuMI9U8Sit+YAWLlZwB6Y6YrdCxfg2kNz05p3XY3Bmm4m26Nv3A==", - "dev": true, - "requires": { - "JSV": "^4.0.x", - "nomnom": "^1.5.x" - } - }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", @@ -8098,41 +8086,6 @@ } } }, - "nomnom": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.8.1.tgz", - "integrity": "sha1-IVH3Ikcrp55Qp2/BJbuMjy5Nwqc=", - "dev": true, - "requires": { - "chalk": "~0.4.0", - "underscore": "~1.6.0" - }, - "dependencies": { - "ansi-styles": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", - "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=", - "dev": true - }, - "chalk": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", - "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", - "dev": true, - "requires": { - "ansi-styles": "~1.0.0", - "has-color": "~0.1.0", - "strip-ansi": "~0.1.0" - } - }, - "strip-ansi": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", - "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=", - "dev": true - } - } - }, "nopt": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", @@ -11030,12 +10983,6 @@ "debug": "^2.2.0" } }, - "underscore": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", - "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=", - "dev": true - }, "unicode-canonical-property-names-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", diff --git a/package.json b/package.json index 10bdb4af..b0de8aaa 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "eslint-plugin-jsx-a11y": "^6.2.3", "eslint-plugin-prettier": "^3.1.0", "eslint-plugin-react": "^7.14.3", - "hard-source-webpack-plugin": "^0.12.0", + "hard-source-webpack-plugin": "^0.13.1", "html-webpack-plugin": "^3.2.0", "jest": "^24.8.0", "prettier": "^1.18.2",