diff options
Diffstat (limited to 'web-ui/src')
| -rw-r--r-- | web-ui/src/backup_account/backup_account.html | 2 | ||||
| -rw-r--r-- | web-ui/src/common/input_field/input_field.js | 14 | ||||
| -rw-r--r-- | web-ui/src/login/app.js | 36 | ||||
| -rw-r--r-- | web-ui/src/login/app.scss | 70 | ||||
| -rw-r--r-- | web-ui/src/login/login.css | 143 | ||||
| -rw-r--r-- | web-ui/src/login/login.html | 12 | ||||
| -rw-r--r-- | web-ui/src/login/login.js | 5 | ||||
| -rw-r--r-- | web-ui/src/login/opensans.css | 20 | ||||
| -rw-r--r-- | web-ui/src/util.js | 7 | 
9 files changed, 161 insertions, 148 deletions
| diff --git a/web-ui/src/backup_account/backup_account.html b/web-ui/src/backup_account/backup_account.html index 55881444..084824f2 100644 --- a/web-ui/src/backup_account/backup_account.html +++ b/web-ui/src/backup_account/backup_account.html @@ -1,7 +1,7 @@  <!DOCTYPE html>  <html>    <head> -    <link rel="icon" type="image/png" href="public/images/Favicon.png" /> +    <link rel="icon" type="image/png" href="public/images/favicon.png" />      <meta charset="utf-8"/>      <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />      <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0"/> diff --git a/web-ui/src/common/input_field/input_field.js b/web-ui/src/common/input_field/input_field.js index 1378ba74..d4876d9f 100644 --- a/web-ui/src/common/input_field/input_field.js +++ b/web-ui/src/common/input_field/input_field.js @@ -19,16 +19,24 @@ import React from 'react';  import './input-field.scss'; -const InputField = ({ label, name }) => ( +const InputField = ({ label, name, type = 'text' }) => (    <div className='input-field-group'> -    <input type='text' name={name} className='input-field' required /> +    <input +      type={type} name={name} className='input-field' +      autoFocus='' required +    />      <label className='input-field-label' htmlFor={name}>{label}</label>    </div>  );  InputField.propTypes = {    label: React.PropTypes.string.isRequired, -  name: React.PropTypes.string.isRequired +  name: React.PropTypes.string.isRequired, +  type: React.PropTypes.string +}; + +InputField.defaultProps = { +  type: 'text'  };  export default InputField; diff --git a/web-ui/src/login/app.js b/web-ui/src/login/app.js index e6ac3192..07099c60 100644 --- a/web-ui/src/login/app.js +++ b/web-ui/src/login/app.js @@ -17,19 +17,31 @@  import React from 'react';  import { translate } from 'react-i18next'; +import InputField from 'src/common/input_field/input_field'; +import SubmitButton from 'src/common/submit_button/submit_button'; -const App = () => ( -  <form className='standard' id='login_form' action='/login' method='post'> -    <input -      type='text' name='username' id='email' className='text-field' -      placeholder='username' autoFocus='' -    /> -    <input -      type='password' name='password' id='password' className='text-field' -      placeholder='password' autoComplete='off' -    /> -    <input type='submit' name='login' value='Login' className='button' /> -  </form> +import './app.scss'; + +const errorMessage = (t, authError) => { +  if (authError) return <p className='error'>{t('error.auth')}</p>; +  return <div />; +}; + +export const App = ({ t, authError }) => ( +  <div className='login'> +    <img className='logo' src='/public/images/logo-orange.svg' alt='Pixelated logo' /> +    {errorMessage(t, authError)} +    <form className='standard' id='login_form' action='/login' method='post'> +      <InputField name='username' label={t('login.email')} /> +      <InputField type='password' name='password' label={t('login.password')} /> +      <SubmitButton buttonText={t('login.submit')} /> +    </form> +  </div>  ); +App.propTypes = { +  t: React.PropTypes.func.isRequired, +  authError: React.PropTypes.bool +}; +  export default translate('', { wait: true })(App); diff --git a/web-ui/src/login/app.scss b/web-ui/src/login/app.scss new file mode 100644 index 00000000..f6e6bc11 --- /dev/null +++ b/web-ui/src/login/app.scss @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2017 ThoughtWorks, Inc. + * + * Pixelated is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Pixelated is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Pixelated. If not, see <http://www.gnu.org/licenses/>. + */ + +@import "~scss/base/colors"; + +.error { +  color: $error; +  margin: 10px 0 0 0; +} + +.login { +  display: block; +  width: 90%; +  margin: auto; +  max-width: 400px; +  padding: 2em 0; +  margin-top: 3%; +  margin-bottom: 3%; +  background-color: $white; +  display: flex; +  flex-direction: column; +  align-items: center; +} + +#login_form { +  padding: 20px 0; +  width: 70%; + +  .input-field-group { +    width: 100%; +  } + +  .submit-button { +    width: 100%; +  } +} + +.logo { +  width: 70%; +} + +@media only screen and (min-width : 500px) { +  #login_form .input-field-group { +    margin-top: 1em; +  } + +  .login { +    width: 60%; +  } +} + +@media only screen and (min-width : 960px) { +  .login { +    width: 40%; +  } +} diff --git a/web-ui/src/login/login.css b/web-ui/src/login/login.css index 51ab2046..d1206a39 100644 --- a/web-ui/src/login/login.css +++ b/web-ui/src/login/login.css @@ -16,130 +16,47 @@   */  body { -    font-family: "Open Sans", "Microsoft YaHei", "Hiragino Sans GB", "Hiragino Sans GB W3", "微软雅黑", "Helvetica Neue", Arial, sans-serif; -    background-color: #EAEAEA; -    height: 100vh; -    color: #3E3A37; +  font-family: "Open Sans", "Microsoft YaHei", "Hiragino Sans GB", "Hiragino Sans GB W3", "微软雅黑", "Helvetica Neue", Arial, sans-serif; +  background-color: #EAEAEA; +  height: 100vh; +  color: #3E3A37; -    background-image: url("/public/images/hive-bg.png"); -    background-repeat: repeat; -} - -.content { -    height: 100vh; -    width: 100%; -} - -.error { -    color: #D72A25; -    margin: 10px 0 0 0; -} - -.message-panel { -  width: 100%; -  margin: 10px auto; -  z-index: 10000; -  text-align: center; -  } - -.message-panel span{ -    background: #F7E8AF; -    padding: 5px 60px; -    border: 1px solid #f2db81; -    color: #987b0f; -    box-shadow: 1px 1px 3px #69560b; -} - -.message-panel.message-panel-small span{ -    padding: 5px 0px; -    display: inline-block; -    width: 100%; -} - -.login { -    display: block; -    width: 240px; -    margin: auto; -    padding: 45px 40px 35px 40px; -    background-color: #FFF; -    margin-top: 2%; -    margin-bottom: 2%; -} - -form#login_form { -  padding: 10px 0; +  background-image: url("/public/images/hive-bg.png"); +  background-repeat: repeat;  }  .disclaimer { -    display: block; -    margin-top: 10%; -    width: 50%; -    margin: auto; -    background-color: #2BA6CB; -    color: #FFFFFF; -    font-weight: 300; -    font-size: 0.8rem; -    padding: 1em; -    margin-bottom: 20px; +  display: block; +  width: 90%; +  margin: auto; +  max-width: 400px; +  background-color: #2BA6CB; +  color: #FFFFFF; +  font-weight: 300; +  font-size: 0.8rem; +  margin-bottom: 20px;  } -.disclaimer li { -    margin-top: 1em; -} - -.logo { -  width: 100%; -  height: auto; -} - -input { -    display: block; -    margin: 10px 0; -    padding-left: 5px; -} - -input.text-field { -  width: 97%; +.disclaimer-content { +  padding: 1em;  } -button, .button, input[type=button] { -  cursor: pointer; -  margin: 0 0 1.25rem; -  border: none; -  position: relative; -  text-decoration: none; -  text-align: center; -  -webkit-appearance: none; -  display: inline-block; -  padding: 0.4rem 1.1rem; -  font-size: 0.9rem; -  background-color: #2ba6cb; -  border-color: #2285a2; -  color: white; -  -webkit-border-radius: 2px; -  -moz-border-radius: 2px; -  -ms-border-radius: 2px; -  -o-border-radius: 2px; -  border-radius: 2px; -} - -button:hover, button:focus, .button:hover, .button:focus, input[type=button]:hover, input[type=button]:focus { -  background-color: #2285a2; -  outline: none; -  color: white; +.disclaimer li { +  margin-top: 1em;  } -ul.accounts { -  margin-bottom: 5%; -} +@media only screen and (min-width : 500px) { +  body { +    font-size: 1.2em; +  } -ul.accounts li { -  display: inline-block; -  list-style: none; -  margin-right: 35px; -  margin-top: 0px; +  .disclaimer { +    width: 60%; +  }  } -ul.accounts li span { -  font-weight: bold; +@media only screen and (min-width : 960px) { +  .disclaimer { +    width: 40%; +  }  } diff --git a/web-ui/src/login/login.html b/web-ui/src/login/login.html index b8c45180..3cebf6f4 100644 --- a/web-ui/src/login/login.html +++ b/web-ui/src/login/login.html @@ -1,7 +1,7 @@  <!DOCTYPE html>  <html xmlns:t="http://twistedmatrix.com/ns/twisted.web.template/0.1">    <head> -    <link rel="icon" type="image/png" href="/public/images/Favicon.png" /> +    <link rel="icon" type="image/png" href="/public/images/favicon.png" />      <meta charset="utf-8"/>      <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />      <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0"/> @@ -12,13 +12,11 @@    </head>    <body>      <div class="content"> -      <div class="login"> -        <img class="logo" src="/public/images/logo-orange.svg" alt="Pixelated logo"/> -        <p t:render="error_msg" class="error"></p> -        <div id="root"/> -      </div> +      <div id="root"/>        <div class="disclaimer"> -        <div t:render="disclaimer"></div> +        <div class="disclaimer-content"> +          <div t:render="disclaimer"></div> +        </div>        </div>      </div>      <script type="text/javascript" src="/public/login.js"></script> diff --git a/web-ui/src/login/login.js b/web-ui/src/login/login.js index ddbe1943..74e5a14e 100644 --- a/web-ui/src/login/login.js +++ b/web-ui/src/login/login.js @@ -20,14 +20,15 @@ import { render } from 'react-dom';  import a11y from 'react-a11y';  import { I18nextProvider } from 'react-i18next'; -import App from './app'; +import AppWrapper from './app';  import i18n from '../i18n'; +import { hasQueryParameter } from '../util';  if (process.env.NODE_ENV === 'development') a11y(React);  render(    <I18nextProvider i18n={i18n}> -    <App /> +    <AppWrapper authError={hasQueryParameter('auth-error')} />    </I18nextProvider>,    document.getElementById('root')  ); diff --git a/web-ui/src/login/opensans.css b/web-ui/src/login/opensans.css index a42f346c..8795bdf7 100644 --- a/web-ui/src/login/opensans.css +++ b/web-ui/src/login/opensans.css @@ -2,68 +2,68 @@    font-family: 'Open Sans';    font-style: normal;    font-weight: 300; -  src: local("Open Sans Light"), local("OpenSans-Light"), url("/fonts/OpenSans-Light.woff") format("woff"); +  src: local("Open Sans Light"), local("OpenSans-Light"), url("/assets/fonts/OpenSans-Light.woff") format("woff");  }  @font-face {    font-family: 'Open Sans';    font-style: normal;    font-weight: 400; -  src: local("Open Sans"), local("OpenSans"), url("/fonts/OpenSans.woff") format("woff"); +  src: local("Open Sans"), local("OpenSans"), url("/assets/fonts/OpenSans.woff") format("woff");  }  @font-face {    font-family: 'Open Sans';    font-style: normal;    font-weight: 600; -  src: local("Open Sans Semibold"), local("OpenSans-Semibold"), url("/fonts/OpenSans-Semibold.woff") format("woff"); +  src: local("Open Sans Semibold"), local("OpenSans-Semibold"), url("/assets/fonts/OpenSans-Semibold.woff") format("woff");  }  @font-face {    font-family: 'Open Sans';    font-style: normal;    font-weight: 700; -  src: local("Open Sans Bold"), local("OpenSans-Bold"), url("/fonts/OpenSans-Bold.woff") format("woff"); +  src: local("Open Sans Bold"), local("OpenSans-Bold"), url("/assets/fonts/OpenSans-Bold.woff") format("woff");  }  @font-face {    font-family: 'Open Sans';    font-style: normal;    font-weight: 800; -  src: local("Open Sans Extrabold"), local("OpenSans-Extrabold"), url("/fonts/OpenSans-Extrabold.woff") format("woff"); +  src: local("Open Sans Extrabold"), local("OpenSans-Extrabold"), url("/assets/fonts/OpenSans-Extrabold.woff") format("woff");  }  @font-face {    font-family: 'Open Sans';    font-style: italic;    font-weight: 300; -  src: local("Open Sans Light Italic"), local("OpenSansLight-Italic"), url("/fonts/OpenSansLight-Italic.woff") format("woff"); +  src: local("Open Sans Light Italic"), local("OpenSansLight-Italic"), url("/assets/fonts/OpenSansLight-Italic.woff") format("woff");  }  @font-face {    font-family: 'Open Sans';    font-style: italic;    font-weight: 400; -  src: local("Open Sans Italic"), local("OpenSans-Italic"), url("/fonts/OpenSans-Italic.woff") format("woff"); +  src: local("Open Sans Italic"), local("OpenSans-Italic"), url("/assets/fonts/OpenSans-Italic.woff") format("woff");  }  @font-face {    font-family: 'Open Sans';    font-style: italic;    font-weight: 600; -  src: local("Open Sans Semibold Italic"), local("OpenSans-SemiboldItalic"), url("/fonts/OpenSans-SemiboldItalic.woff ") format("woff"); +  src: local("Open Sans Semibold Italic"), local("OpenSans-SemiboldItalic"), url("/assets/fonts/OpenSans-SemiboldItalic.woff ") format("woff");  }  @font-face {    font-family: 'Open Sans';    font-style: italic;    font-weight: 700; -  src: local("Open Sans Bold Italic"), local("OpenSans-BoldItalic"), url("/fonts/OpenSans-BoldItalic.woff") format("woff"); +  src: local("Open Sans Bold Italic"), local("OpenSans-BoldItalic"), url("/assets/fonts/OpenSans-BoldItalic.woff") format("woff");  }  @font-face {    font-family: 'Open Sans';    font-style: italic;    font-weight: 800; -  src: local("Open Sans Extrabold Italic"), local("OpenSans-ExtraboldItalic"), url("/fonts/OpenSans-ExtraboldItalic.woff") format("woff"); +  src: local("Open Sans Extrabold Italic"), local("OpenSans-ExtraboldItalic"), url("/assets/fonts/OpenSans-ExtraboldItalic.woff") format("woff");  } diff --git a/web-ui/src/util.js b/web-ui/src/util.js new file mode 100644 index 00000000..1b244458 --- /dev/null +++ b/web-ui/src/util.js @@ -0,0 +1,7 @@ +export const hasQueryParameter = param => ( +  decodeURIComponent(window.location.search.substring(1)).includes(param) +); + +export default { +  hasQueryParameter +}; | 
