diff options
author | thaissiqueira <thais.siqueira@thoughtworks.com> | 2017-03-16 11:51:00 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-03-16 11:51:00 -0300 |
commit | d1459b65bc24e51b4cf350de052cf8cfa5cd88d8 (patch) | |
tree | c46172a8ad735864121bfd7195075bc82a1a178d | |
parent | ea05559a4346b7119287356e408db453e39d1cb7 (diff) | |
parent | a36902d4a520e933e4ffde1e6bbc8fae20522f10 (diff) |
Merge pull request #1011 from pixelated/confirmation-page
[#971] Add backup account confirmation page
-rw-r--r-- | web-ui/app/images/sent-mail.svg | 18 | ||||
-rw-r--r-- | web-ui/app/locales/en_US/translation.json | 7 | ||||
-rw-r--r-- | web-ui/app/locales/pt_BR/translation.json | 7 | ||||
-rw-r--r-- | web-ui/src/backup_account/backup_email/backup_email.js | 15 | ||||
-rw-r--r-- | web-ui/src/backup_account/backup_email/backup_email.scss | 75 | ||||
-rw-r--r-- | web-ui/src/backup_account/backup_email/backup_email.spec.js | 12 | ||||
-rw-r--r-- | web-ui/src/backup_account/confirmation/confirmation.js | 45 | ||||
-rw-r--r-- | web-ui/src/backup_account/confirmation/confirmation.scss | 60 | ||||
-rw-r--r-- | web-ui/src/backup_account/confirmation/confirmation.spec.js | 29 | ||||
-rw-r--r-- | web-ui/src/backup_account/page.js | 14 | ||||
-rw-r--r-- | web-ui/src/backup_account/page.scss | 62 | ||||
-rw-r--r-- | web-ui/src/backup_account/page.spec.js | 28 |
12 files changed, 312 insertions, 60 deletions
diff --git a/web-ui/app/images/sent-mail.svg b/web-ui/app/images/sent-mail.svg new file mode 100644 index 00000000..311f81d8 --- /dev/null +++ b/web-ui/app/images/sent-mail.svg @@ -0,0 +1,18 @@ +<svg width="163px" height="67px" viewBox="401 289 163 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <!-- Generator: Sketch 42 (36781) - http://www.bohemiancoding.com/sketch --> + <desc>Created with Sketch.</desc> + <defs></defs> + <g id="Group-9" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" transform="translate(402.000000, 290.000000)"> + <g id="Group-Copy-2" transform="translate(32.892081, 32.683048) rotate(-270.000000) translate(-32.892081, -32.683048) translate(0.892081, 0.183048)" stroke="#4A4A4A" stroke-width="1.35" stroke-linecap="round" stroke-linejoin="round"> + <path d="M3.72712277,34.6380793 L59.936399,34.6380793" id="Line-Copy-13" transform="translate(31.500366, 35.390421) rotate(-90.000000) translate(-31.500366, -35.390421) "></path> + <path d="M-13.6686342,17.2732996 L18.8468726,17.2732996" id="Line-Copy-12" transform="translate(2.610897, 18.025641) rotate(-90.000000) translate(-2.610897, -18.025641) "></path> + <path d="M45.3663671,17.2732996 L77.8818739,17.2732996" id="Line-Copy-14" transform="translate(61.645898, 18.025641) rotate(-90.000000) translate(-61.645898, -18.025641) "></path> + </g> + <g id="Group-17-Copy-3" transform="translate(72.919982, 1.615479)"> + <path d="M84.9721851,7.79098121 C84.9721851,6.73632467 84.6000441,5.86143914 83.8498552,5.16033224 C83.0937593,4.45922534 82.2018024,4.10567571 81.1621705,4.10567571 L7.44281913,4.10567571 C6.40318725,4.10567571 5.51123036,4.45922534 4.76104144,5.16033224 C4.00494553,5.86143914 3.63280458,6.73632467 3.63280458,7.79098121 L3.63280458,52.7337312 C3.63280458,53.7883877 4.00494553,54.6632733 4.76104144,55.3703725 C5.51123036,56.0714794 6.40318725,56.4190367 7.44281913,56.4190367 L81.1621705,56.4190367 C82.2018024,56.4190367 83.0937593,56.0714794 83.8498552,55.3703725 C84.6000441,54.6632733 84.9721851,53.7883877 84.9721851,52.7337312 L84.9721851,7.79098121 Z" id="Path" fill="#E9E7F3"></path> + <path d="M84.9721851,7.79098121 C84.9721851,6.73632467 84.9272524,5.86143914 84.8366739,5.16033224 C84.7453822,4.45922534 84.6376865,4.10567571 84.5121604,4.10567571 L75.6112169,4.10567571 C75.4856908,4.10567571 75.3779951,4.45922534 75.2874166,5.16033224 C75.1961249,5.86143914 75.1511922,6.73632467 75.1511922,7.79098121 L75.1511922,52.7337312 C75.1511922,53.7883877 75.1961249,54.6632733 75.2874166,55.3703725 C75.3779951,56.0714794 75.4856908,56.4190367 75.6112169,56.4190367 L84.5121604,56.4190367 C84.6376865,56.4190367 84.7453822,56.0714794 84.8366739,55.3703725 C84.9272524,54.6632733 84.9721851,53.7883877 84.9721851,52.7337312 L84.9721851,7.79098121 Z" id="Path" fill="#DDD9ED"></path> + <path d="M78.5689978,45.5368988 C79.6086297,46.1241508 79.7799327,46.9990363 79.0888138,48.1675478 C78.7403008,48.7547997 78.2204849,49.0484257 77.529366,49.0484257 C77.298993,49.0484257 76.95048,48.9285784 76.4897341,48.6948761 L59.879252,37.4591886 C58.8396201,36.877929 58.6683172,35.9970511 59.3594361,34.8285396 C59.938322,33.7738831 60.8007439,33.6001044 61.9526088,34.3012113 L78.5689978,45.5368988 Z M44.3024948,39.9220513 L11.9439526,18.6791114 C10.9043207,17.9720122 10.7330177,17.1570503 11.4241367,16.2162487 C12.1152556,15.0477372 12.9186075,14.8140349 13.8460064,15.5151418 L44.3024948,35.5296465 L74.7589833,15.5151418 C75.6863822,14.8140349 76.4897341,15.0477372 77.18676,16.2162487 C77.8778789,17.1570503 77.7065759,17.9720122 76.6669441,18.6791114 L44.3024948,39.9220513 Z M29.2455536,34.8285396 C29.9425795,35.9970511 29.7653695,36.877929 28.7257376,37.4591886 L12.1152556,48.6948761 C11.6545096,48.9285784 11.3059967,49.0484257 11.0756237,49.0484257 C10.3845048,49.0484257 9.86468885,48.7547997 9.52208289,48.1675478 C8.82505697,46.9990363 9.00226695,46.1241508 10.0359918,45.5368988 L26.6523809,34.3012113 C27.8042458,33.6001044 28.6666677,33.7738831 29.2455536,34.8285396 L29.2455536,34.8285396 Z M84.9721851,7.79098121 C84.9721851,6.73632467 84.6000441,5.86143914 83.8498552,5.16033224 C83.0937593,4.45922534 82.2018024,4.10567571 81.1621705,4.10567571 L7.44281913,4.10567571 C6.40318725,4.10567571 5.51123036,4.45922534 4.76104144,5.16033224 C4.00494553,5.86143914 3.63280458,6.73632467 3.63280458,7.79098121 L3.63280458,52.7337312 C3.63280458,53.7883877 4.00494553,54.6632733 4.76104144,55.3703725 C5.51123036,56.0714794 6.40318725,56.4190367 7.44281913,56.4190367 L81.1621705,56.4190367 C82.2018024,56.4190367 83.0937593,56.0714794 83.8498552,55.3703725 C84.6000441,54.6632733 84.9721851,53.7883877 84.9721851,52.7337312 L84.9721851,7.79098121 Z M86.4430279,2.43979777 C87.8843357,3.90193524 88.6049897,5.68766051 88.6049897,7.79098121 L88.6049897,52.7337312 C88.6049897,54.8430443 87.8843357,56.6287695 86.4430279,58.090907 C84.9958131,59.5530445 83.2414343,60.2841132 81.1621705,60.2841132 L7.44281913,60.2841132 C5.36355537,60.2841132 3.60917658,59.5530445 2.16196175,58.090907 C0.720653916,56.6287695 0,54.8430443 0,52.7337312 L0,7.79098121 C0,5.68766051 0.720653916,3.90193524 2.16196175,2.43979777 C3.60917658,0.971667939 5.36355537,0.240599205 7.44281913,0.240599205 L81.1621705,0.240599205 C83.2414343,0.240599205 84.9958131,0.971667939 86.4430279,2.43979777 L86.4430279,2.43979777 Z" id="Fill-1" fill="#4A4A4A"></path> + <path d="M44.3024948,39.9220513 L11.9439526,18.6791114 C10.9043207,17.9720122 10.7330177,17.1570503 11.4241367,16.2162487 C12.1152556,15.0477372 12.9186075,14.8140349 13.8460064,15.5151418 L44.3024948,35.5296465 L44.3024948,39.9220513 Z" id="Path" fill="#4A4A4A"></path> + </g> + </g> +</svg> diff --git a/web-ui/app/locales/en_US/translation.json b/web-ui/app/locales/en_US/translation.json index 25d406b2..d69b7472 100644 --- a/web-ui/app/locales/en_US/translation.json +++ b/web-ui/app/locales/en_US/translation.json @@ -91,6 +91,13 @@ "error": { "invalid-email": "Please enter a valid email address" } + }, + "confirmation": { + "title1": "Success!", + "title2": "A message was sent to your backup account", + "paragraph": "Save this message, it is really important.", + "button": "Got it! I'm ready!", + "retry-button": "Hey, I didn't received it" } }, "back-to-inbox": "Back to my inbox", diff --git a/web-ui/app/locales/pt_BR/translation.json b/web-ui/app/locales/pt_BR/translation.json index ec353ff1..4e179363 100644 --- a/web-ui/app/locales/pt_BR/translation.json +++ b/web-ui/app/locales/pt_BR/translation.json @@ -91,6 +91,13 @@ "error": { "invalid-email": "Por favor informe um e-mail válido" } + }, + "confirmation": { + "title1": "Sucesso!", + "title2": "Uma mensagem foi enviada para seu e-mail de recuperação", + "paragraph": "Salve esse e-mail, ele é bem importante.", + "button": "Recebi! Pronto!", + "retry-button": "Ei, eu não recebi" } }, "back-to-inbox": "Voltar", diff --git a/web-ui/src/backup_account/backup_email/backup_email.js b/web-ui/src/backup_account/backup_email/backup_email.js index 3d5df1b0..05cba35e 100644 --- a/web-ui/src/backup_account/backup_email/backup_email.js +++ b/web-ui/src/backup_account/backup_email/backup_email.js @@ -21,6 +21,7 @@ import SubmitButton from 'src/common/submit_button/submit_button'; import InputField from 'src/common/input_field/input_field'; import validator from 'validator'; +import './backup_email.scss'; export class BackupEmail extends React.Component { @@ -39,16 +40,23 @@ export class BackupEmail extends React.Component { }); } + submitHandler = (event) => { + event.preventDefault(); + if (typeof this.props.onSubmit === 'function') { + this.props.onSubmit(); + } + } + render() { const t = this.props.t; return ( - <div className='container'> + <div className='container backup-email-container'> <img className='backup-account-image' src='/public/images/forgot-my-password.svg' alt={t('backup-account.backup-email.image-description')} /> - <form> + <form onSubmit={this.submitHandler}> <h1>{t('backup-account.backup-email.title')}</h1> <p>{t('backup-account.backup-email.paragraph1')}</p> <p>{t('backup-account.backup-email.paragraph2')}</p> @@ -68,7 +76,8 @@ export class BackupEmail extends React.Component { BackupEmail.propTypes = { - t: React.PropTypes.func.isRequired + t: React.PropTypes.func.isRequired, + onSubmit: React.PropTypes.func.isRequired }; export default translate('', { wait: true })(BackupEmail); diff --git a/web-ui/src/backup_account/backup_email/backup_email.scss b/web-ui/src/backup_account/backup_email/backup_email.scss new file mode 100644 index 00000000..a7e09ba3 --- /dev/null +++ b/web-ui/src/backup_account/backup_email/backup_email.scss @@ -0,0 +1,75 @@ +/* + * 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/vendor/reset"; +@import "~scss/base/colors"; +@import "~scss/base/fonts"; + + +form { + width: 100%; +} + +.backup-email-container { + width: 84%; + padding: 6% 5%; + display: flex; + align-items: flex-start; + flex-direction: column; +} + +.backup-account-image { + width: 50%; + height: 100%; + align-self: center; +} + +@media only screen and (min-width : 500px) { + form { + display: flex; + flex-direction: column; + + .input-field-group, .submit-button, .link-content { + width: 70%; + align-self: center; + } + } +} + +@media only screen and (min-width : 960px) { + .backup-email-container{ + width: 60%; + max-width: 700px; + padding: 3em; + align-items: flex-start; + flex-direction: row; + + form { + margin-left: 2.5em; + min-height: 492px; + + .input-field-group, .submit-button, .link-content { + width: 300px; + align-self: flex-start; + } + } + } + + .backup-account-image { + width: 300px; + } +} diff --git a/web-ui/src/backup_account/backup_email/backup_email.spec.js b/web-ui/src/backup_account/backup_email/backup_email.spec.js index b2b297f4..8732003b 100644 --- a/web-ui/src/backup_account/backup_email/backup_email.spec.js +++ b/web-ui/src/backup_account/backup_email/backup_email.spec.js @@ -5,9 +5,10 @@ import { BackupEmail } from 'src/backup_account/backup_email/backup_email'; describe('BackupEmail', () => { let page; + let mockTranslations; beforeEach(() => { - const mockTranslations = key => key; + mockTranslations = key => key; page = shallow(<BackupEmail t={mockTranslations} />); }); @@ -23,6 +24,15 @@ describe('BackupEmail', () => { expect(page.find('SubmitButton').props().buttonText).toEqual('backup-account.backup-email.button'); }); + it('form submit should call parameter custom submit', () => { + const mockOnSubmit = expect.createSpy(); + const event = { preventDefault() {} }; + page = shallow(<BackupEmail t={mockTranslations} onSubmit={mockOnSubmit} />); + + page.instance().submitHandler(event); + expect(mockOnSubmit).toHaveBeenCalled(); + }); + describe('Email validation', () => { let pageInstance; diff --git a/web-ui/src/backup_account/confirmation/confirmation.js b/web-ui/src/backup_account/confirmation/confirmation.js new file mode 100644 index 00000000..41637dab --- /dev/null +++ b/web-ui/src/backup_account/confirmation/confirmation.js @@ -0,0 +1,45 @@ +/* + * 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 React from 'react'; +import { translate } from 'react-i18next'; +import SubmitButton from 'src/common/submit_button/submit_button'; + +import './confirmation.scss'; + +export const Confirmation = ({ t }) => ( + <div className='container confirmation-container'> + <h1>{t('backup-account.confirmation.title1')} <br /> {t('backup-account.confirmation.title2')}</h1> + <p>{t('backup-account.confirmation.paragraph')}</p> + <img src='/public/images/sent-mail.svg' alt='Sent mail' /> + <form action='/'> + <SubmitButton buttonText={t('backup-account.confirmation.button')} type='submit' /> + </form> + <div className='link-content'> + <a href='/backup-account' className='link'> + <i className='fa fa-angle-left' aria-hidden='true' /> + <span>{t('backup-account.confirmation.retry-button')}</span> + </a> + </div> + </div> +); + +Confirmation.propTypes = { + t: React.PropTypes.func.isRequired +}; + +export default translate('', { wait: true })(Confirmation); diff --git a/web-ui/src/backup_account/confirmation/confirmation.scss b/web-ui/src/backup_account/confirmation/confirmation.scss new file mode 100644 index 00000000..241442ff --- /dev/null +++ b/web-ui/src/backup_account/confirmation/confirmation.scss @@ -0,0 +1,60 @@ +/* + * 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/vendor/reset"; +@import "~scss/base/colors"; +@import "~scss/base/fonts"; + +.confirmation-container { + width: 84%; + padding: 6% 5%; + display: flex; + align-items: center; + flex-direction: column; + + img { + padding: 2em 3.2em 2em 0; + } +} + + .submit-button { + align-self: center; + } + +@media only screen and (min-width : 500px) { + .confirmation-container { + width: 50%; + padding: 1em 2em; + } + + .submit-button { + width: 70%; + } +} + +@media only screen and (min-width : 960px) { + .confirmation-container { + width: 30%; + padding: 1em 2em; + display: flex; + flex-direction: column; + } + + .submit-button { + width: 65%; + } +} diff --git a/web-ui/src/backup_account/confirmation/confirmation.spec.js b/web-ui/src/backup_account/confirmation/confirmation.spec.js new file mode 100644 index 00000000..291d156d --- /dev/null +++ b/web-ui/src/backup_account/confirmation/confirmation.spec.js @@ -0,0 +1,29 @@ +import { shallow } from 'enzyme'; +import expect from 'expect'; +import React from 'react'; +import { Confirmation } from 'src/backup_account/confirmation/confirmation'; + +describe('Confirmation', () => { + let page; + + beforeEach(() => { + const mockTranslations = key => key; + page = shallow(<Confirmation t={mockTranslations} />); + }); + + it('renders confirmation title', () => { + expect(page.find('h1').text()).toContain('backup-account.confirmation.title1'); + }); + + it('renders confirmation submit button', () => { + expect(page.find('SubmitButton').props().buttonText).toEqual('backup-account.confirmation.button'); + }); + + it('renders confirmation retry button', () => { + expect(page.find('a').text()).toEqual('backup-account.confirmation.retry-button'); + }); + + it('retries button redirects to backup account', () => { + expect(page.find('a').props().href).toEqual('/backup-account'); + }); +}); diff --git a/web-ui/src/backup_account/page.js b/web-ui/src/backup_account/page.js index 5a75850a..221c6978 100644 --- a/web-ui/src/backup_account/page.js +++ b/web-ui/src/backup_account/page.js @@ -21,6 +21,7 @@ import DocumentTitle from 'react-document-title'; import Footer from 'src/common/footer/footer'; import Header from 'src/common/header/header'; import BackupEmail from 'src/backup_account/backup_email/backup_email'; +import Confirmation from 'src/backup_account/confirmation/confirmation'; import 'font-awesome/scss/font-awesome.scss'; import './page.scss'; @@ -33,6 +34,17 @@ export class Page extends React.Component { this.state = { status: '' }; } + saveBackupEmail = () => { + this.setState({ + status: 'success' + }); + } + + mainContent = () => { + if (this.state.status === 'success') return <Confirmation />; + return <BackupEmail onSubmit={this.saveBackupEmail} />; + }; + render() { const t = this.props.t; return ( @@ -40,7 +52,7 @@ export class Page extends React.Component { <div className='page'> <Header /> <section> - <BackupEmail /> + {this.mainContent()} </section> <Footer /> </div> diff --git a/web-ui/src/backup_account/page.scss b/web-ui/src/backup_account/page.scss index aa973fcd..71e3f074 100644 --- a/web-ui/src/backup_account/page.scss +++ b/web-ui/src/backup_account/page.scss @@ -31,6 +31,12 @@ a { text-decoration: none; } +.container { + background: $white; + margin: 3% auto; + box-shadow: 0 2px 3px 0 $shadow; +} + .page { font-family: "Open Sans", "Microsoft YaHei", "Hiragino Sans GB", "Hiragino Sans GB W3", "微软雅黑", "Helvetica Neue", Arial, sans-serif; background: $dark_blue; /* For browsers that do not support gradients */ @@ -48,10 +54,6 @@ section { flex: 1 0 auto; } -form { - width: 100%; -} - h1 { font-size: 1.3em; font-weight: 600; @@ -65,6 +67,7 @@ p { .link { color: $dark_blue; font-style: italic; + font-size: 0.8em; .fa { font-size: 1.6em; @@ -75,59 +78,8 @@ p { } -.container { - background: $white; - width: 84%; - margin: 3% auto; - padding: 6% 5%; - display: flex; - align-items: flex-start; - flex-direction: column; - box-shadow: 0 2px 3px 0 $shadow; -} - -.backup-account-image { - width: 50%; - height: 100%; - align-self: center; -} - @media only screen and (min-width : 500px) { body { font-size: 1.3em; } - - form { - display: flex; - flex-direction: column; - - .input-field-group, .submit-button, .link-content { - width: 70%; - align-self: center; - } - } -} - -@media only screen and (min-width : 960px) { - .container{ - width: 60%; - padding: 3em; - align-items: flex-start; - flex-direction: row; - max-width: 700px; - } - - form { - margin-left: 2.5em; - min-height: 492px; - - .input-field-group, .submit-button, .link-content { - width: 300px; - align-self: flex-start; - } - } - - .backup-account-image { - width: 300px; - } } diff --git a/web-ui/src/backup_account/page.spec.js b/web-ui/src/backup_account/page.spec.js index 2f4bc7c1..23c117a0 100644 --- a/web-ui/src/backup_account/page.spec.js +++ b/web-ui/src/backup_account/page.spec.js @@ -2,6 +2,8 @@ import { shallow } from 'enzyme'; import expect from 'expect'; import React from 'react'; import { Page } from 'src/backup_account/page'; +import BackupEmail from 'src/backup_account/backup_email/backup_email'; +import Confirmation from 'src/backup_account/confirmation/confirmation'; describe('BackupAccount', () => { let page; @@ -14,4 +16,30 @@ describe('BackupAccount', () => { it('renders backup account page title', () => { expect(page.props().title).toEqual('backup-account.page-title'); }); + + describe('save backup email', () => { + let pageInstance; + + beforeEach(() => { + pageInstance = page.instance(); + }); + + it('verifies initial state', () => { + expect(pageInstance.state.status).toEqual(''); + }); + + it('changes state', () => { + pageInstance.saveBackupEmail(); + expect(pageInstance.state.status).toEqual('success'); + }); + + it('renders backup email component', () => { + expect(page.find(BackupEmail).length).toEqual(1); + }); + + it('renders confirmation component', () => { + pageInstance.saveBackupEmail(); + expect(page.find(Confirmation).length).toEqual(1); + }); + }); }); |