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 +}; |