From d736b3f6de7430351b22eebc918f231d5fcaa28e Mon Sep 17 00:00:00 2001 From: Kimmo Puputti Date: Fri, 27 Oct 2017 15:25:07 +0300 Subject: [PATCH 01/13] Make AuthenticationPage into a class --- .../AuthenticationPage/AuthenticationPage.js | 390 +++++++++--------- 1 file changed, 196 insertions(+), 194 deletions(-) diff --git a/src/containers/AuthenticationPage/AuthenticationPage.js b/src/containers/AuthenticationPage/AuthenticationPage.js index 4d186af3..f5e7a45a 100644 --- a/src/containers/AuthenticationPage/AuthenticationPage.js +++ b/src/containers/AuthenticationPage/AuthenticationPage.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { compose } from 'redux'; import { connect } from 'react-redux'; @@ -33,208 +33,210 @@ import { sendVerificationEmail } from '../../ducks/user.duck'; import css from './AuthenticationPage.css'; -export const AuthenticationPageComponent = props => { - const { - authInProgress, - currentUser, - intl, - isAuthenticated, - location, - loginError, - logoutError, - scrollingDisabled, - signupError, - submitLogin, - submitSignup, - tab, - sendVerificationEmailInProgress, - sendVerificationEmailError, - onResendVerificationEmail, - } = props; - const isLogin = tab === 'login'; - const from = location.state && location.state.from ? location.state.from : null; +export class AuthenticationPageComponent extends Component { + render() { + const { + authInProgress, + currentUser, + intl, + isAuthenticated, + location, + loginError, + logoutError, + scrollingDisabled, + signupError, + submitLogin, + submitSignup, + tab, + sendVerificationEmailInProgress, + sendVerificationEmailError, + onResendVerificationEmail, + } = this.props; + const isLogin = tab === 'login'; + const from = location.state && location.state.from ? location.state.from : null; - const user = ensureCurrentUser(currentUser); - const currentUserLoaded = !!user.id; + const user = ensureCurrentUser(currentUser); + const currentUserLoaded = !!user.id; - // We only want to show the email verification dialog in the signup - // tab if the user isn't being redirected somewhere else - // (i.e. `from` is present). We must also check the `emailVerified` - // flag only when the current user is fully loaded. - const showEmailVerification = !isLogin && currentUserLoaded && !user.attributes.emailVerified; + // We only want to show the email verification dialog in the signup + // tab if the user isn't being redirected somewhere else + // (i.e. `from` is present). We must also check the `emailVerified` + // flag only when the current user is fully loaded. + const showEmailVerification = !isLogin && currentUserLoaded && !user.attributes.emailVerified; - // Already authenticated, redirect away from auth page - if (isAuthenticated && from) { - return ; - } else if (isAuthenticated && currentUserLoaded && !showEmailVerification) { - return ; - } + // Already authenticated, redirect away from auth page + if (isAuthenticated && from) { + return ; + } else if (isAuthenticated && currentUserLoaded && !showEmailVerification) { + return ; + } - /* eslint-disable no-console */ - if (loginError && console && console.error) { - console.error(loginError); - } - if (signupError && console && console.error) { - console.error(signupError); - } - /* eslint-enable no-console */ + /* eslint-disable no-console */ + if (loginError && console && console.error) { + console.error(loginError); + } + if (signupError && console && console.error) { + console.error(signupError); + } + /* eslint-enable no-console */ - const loginErrorMessage = ( -
- -
- ); - - const signupErrorMessage = ( -
- {isSignupEmailTakenError(signupError) ? ( - - ) : ( - - )} -
- ); - - // eslint-disable-next-line no-confusing-arrow - const errorMessage = (error, message) => (error ? message : null); - const loginOrSignupError = isLogin - ? errorMessage(loginError, loginErrorMessage) - : errorMessage(signupError, signupErrorMessage); - - const fromState = { state: from ? { from } : null }; - - const tabs = [ - { - text: ( -

- -

- ), - selected: !isLogin, - linkProps: { - name: 'SignupPage', - to: fromState, - }, - }, - { - text: ( -

- -

- ), - selected: isLogin, - linkProps: { - name: 'LoginPage', - to: fromState, - }, - }, - ]; - - const formContent = ( -
- - {loginOrSignupError} - {isLogin ? ( - - ) : ( - - )} -
- ); - - const name = user.attributes.profile.firstName; - const email = {user.attributes.email}; - - const resendEmailLink = ( - - - - ); - const fixEmailLink = ( - - - - ); - - const resendErrorTranslationId = isTooManyEmailVerificationRequestsError( - sendVerificationEmailError - ) - ? 'AuthenticationPage.resendFailedTooManyRequests' - : 'AuthenticationPage.resendFailed'; - const resendErrorMessage = sendVerificationEmailError ? ( -

- -

- ) : null; - - const emailVerificationContent = ( -
- - - - - - - -

- -

-

- -

- {resendErrorMessage} - -
-

- {sendVerificationEmailInProgress ? ( - - ) : ( - - )} -

-

- -

+ const loginErrorMessage = ( +
+
-
- ); + ); - const siteTitle = config.siteTitle; - const schemaTitle = isLogin - ? intl.formatMessage({ id: 'AuthenticationPage.schemaTitleLogin' }, { siteTitle }) - : intl.formatMessage({ id: 'AuthenticationPage.schemaTitleSignup' }, { siteTitle }); + const signupErrorMessage = ( +
+ {isSignupEmailTakenError(signupError) ? ( + + ) : ( + + )} +
+ ); - const topbarClasses = classNames({ - [css.hideOnMobile]: showEmailVerification, - }); + // eslint-disable-next-line no-confusing-arrow + const errorMessage = (error, message) => (error ? message : null); + const loginOrSignupError = isLogin + ? errorMessage(loginError, loginErrorMessage) + : errorMessage(signupError, signupErrorMessage); - return ( - - - - - - -
- {showEmailVerification ? emailVerificationContent : formContent} -
-
- -
- - - - ); -}; + const fromState = { state: from ? { from } : null }; + + const tabs = [ + { + text: ( +

+ +

+ ), + selected: !isLogin, + linkProps: { + name: 'SignupPage', + to: fromState, + }, + }, + { + text: ( +

+ +

+ ), + selected: isLogin, + linkProps: { + name: 'LoginPage', + to: fromState, + }, + }, + ]; + + const formContent = ( +
+ + {loginOrSignupError} + {isLogin ? ( + + ) : ( + + )} +
+ ); + + const name = user.attributes.profile.firstName; + const email = {user.attributes.email}; + + const resendEmailLink = ( + + + + ); + const fixEmailLink = ( + + + + ); + + const resendErrorTranslationId = isTooManyEmailVerificationRequestsError( + sendVerificationEmailError + ) + ? 'AuthenticationPage.resendFailedTooManyRequests' + : 'AuthenticationPage.resendFailed'; + const resendErrorMessage = sendVerificationEmailError ? ( +

+ +

+ ) : null; + + const emailVerificationContent = ( +
+ + + + + + + +

+ +

+

+ +

+ {resendErrorMessage} + +
+

+ {sendVerificationEmailInProgress ? ( + + ) : ( + + )} +

+

+ +

+
+
+ ); + + const siteTitle = config.siteTitle; + const schemaTitle = isLogin + ? intl.formatMessage({ id: 'AuthenticationPage.schemaTitleLogin' }, { siteTitle }) + : intl.formatMessage({ id: 'AuthenticationPage.schemaTitleSignup' }, { siteTitle }); + + const topbarClasses = classNames({ + [css.hideOnMobile]: showEmailVerification, + }); + + return ( + + + + + + +
+ {showEmailVerification ? emailVerificationContent : formContent} +
+
+ +
+ + + + ); + } +} AuthenticationPageComponent.defaultProps = { currentUser: null, From 8f7cdeab425c25cfbced3141b330ae1289468c26 Mon Sep 17 00:00:00 2001 From: Kimmo Puputti Date: Fri, 27 Oct 2017 16:16:13 +0300 Subject: [PATCH 02/13] Add empty Terms of Service component --- .../TermsOfService/TermsOfService.css | 2 ++ .../TermsOfService/TermsOfService.js | 25 +++++++++++++++++++ src/components/index.js | 1 + 3 files changed, 28 insertions(+) create mode 100644 src/components/TermsOfService/TermsOfService.css create mode 100644 src/components/TermsOfService/TermsOfService.js diff --git a/src/components/TermsOfService/TermsOfService.css b/src/components/TermsOfService/TermsOfService.css new file mode 100644 index 00000000..c3a2af63 --- /dev/null +++ b/src/components/TermsOfService/TermsOfService.css @@ -0,0 +1,2 @@ +.root { +} diff --git a/src/components/TermsOfService/TermsOfService.js b/src/components/TermsOfService/TermsOfService.js new file mode 100644 index 00000000..97460bea --- /dev/null +++ b/src/components/TermsOfService/TermsOfService.js @@ -0,0 +1,25 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import classNames from 'classnames'; + +import css from './TermsOfService.css'; + +const TermsOfService = props => { + const { rootClassName, className } = props; + const classes = classNames(rootClassName || css.root, className); + return
TODO: TOS here
; +}; + +TermsOfService.defaultProps = { + rootClassName: null, + className: null, +}; + +const { string } = PropTypes; + +TermsOfService.propTypes = { + rootClassName: string, + className: string, +}; + +export default TermsOfService; diff --git a/src/components/index.js b/src/components/index.js index 59d2229e..897080f3 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -91,6 +91,7 @@ export { export { default as TabNav } from './TabNav/TabNav'; export { default as TabNavHorizontal } from './TabNavHorizontal/TabNavHorizontal'; export { default as Tabs } from './Tabs/Tabs'; +export { default as TermsOfService } from './TermsOfService/TermsOfService'; export { default as TextInputField } from './TextInputField/TextInputField'; export { default as Topbar } from './Topbar/Topbar'; export { default as TopbarDesktop } from './TopbarDesktop/TopbarDesktop'; From f66c4698756e084d4ca75bb7bdbd991efed5a1ed Mon Sep 17 00:00:00 2001 From: Kimmo Puputti Date: Fri, 27 Oct 2017 16:17:17 +0300 Subject: [PATCH 03/13] Add Terms of Service link --- src/containers/SignupForm/SignupForm.css | 17 ++++++++++ .../SignupForm/SignupForm.example.js | 3 ++ src/containers/SignupForm/SignupForm.js | 32 ++++++++++++++++++- src/containers/SignupForm/SignupForm.test.js | 4 ++- .../__snapshots__/SignupForm.test.js.snap | 22 +++++++++++++ src/translations/en.json | 4 +-- 6 files changed, 78 insertions(+), 4 deletions(-) diff --git a/src/containers/SignupForm/SignupForm.css b/src/containers/SignupForm/SignupForm.css index bd3f2f37..d439dedf 100644 --- a/src/containers/SignupForm/SignupForm.css +++ b/src/containers/SignupForm/SignupForm.css @@ -29,3 +29,20 @@ .bottomWrapper { @apply --marketplaceModalBottomWrapper; } + +.bottomWrapperText { + @apply --marketplaceModalBottomWrapperText; +} + +.termsText { + @apply --marketplaceModalHelperText; +} + +.termsLink { + @apply --marketplaceModalHelperLink; + + &:hover { + text-decoration: underline; + cursor: pointer; + } +} diff --git a/src/containers/SignupForm/SignupForm.example.js b/src/containers/SignupForm/SignupForm.example.js index 47580c55..bfe81efc 100644 --- a/src/containers/SignupForm/SignupForm.example.js +++ b/src/containers/SignupForm/SignupForm.example.js @@ -7,6 +7,9 @@ export const Empty = { onSubmit(values) { console.log('sign up with form values:', values); }, + onOpenTermsOfService() { + console.log('open terms of service'); + }, }, group: 'forms', }; diff --git a/src/containers/SignupForm/SignupForm.js b/src/containers/SignupForm/SignupForm.js index 4d1fbb07..70d84275 100644 --- a/src/containers/SignupForm/SignupForm.js +++ b/src/containers/SignupForm/SignupForm.js @@ -9,6 +9,8 @@ import * as validators from '../../util/validators'; import css from './SignupForm.css'; +const KEY_CODE_ENTER = 13; + const SignupFormComponent = props => { const { rootClassName, @@ -19,6 +21,7 @@ const SignupFormComponent = props => { inProgress, invalid, intl, + onOpenTermsOfService, } = props; // email @@ -102,6 +105,24 @@ const SignupFormComponent = props => { const submitInProgress = submitting || inProgress; const submitDisabled = invalid || submitInProgress; + const handleTermsKeyUp = e => { + // Allow click action with keyboard like with normal links + if (e.keyCode === KEY_CODE_ENTER) { + onOpenTermsOfService(); + } + }; + const termsLink = ( + + + + ); + return (
@@ -145,6 +166,11 @@ const SignupFormComponent = props => {
+

+ + + +

{ SignupFormComponent.defaultProps = { inProgress: false }; -const { bool } = PropTypes; +const { bool, func } = PropTypes; SignupFormComponent.propTypes = { ...formPropTypes, inProgress: bool, + + onOpenTermsOfService: func.isRequired, + + // from injectIntl intl: intlShape.isRequired, }; diff --git a/src/containers/SignupForm/SignupForm.test.js b/src/containers/SignupForm/SignupForm.test.js index bbe0624f..692f194e 100644 --- a/src/containers/SignupForm/SignupForm.test.js +++ b/src/containers/SignupForm/SignupForm.test.js @@ -2,9 +2,11 @@ import React from 'react'; import { renderDeep } from '../../util/test-helpers'; import SignupForm from './SignupForm'; +const noop = () => null; + describe('SignupForm', () => { it('matches snapshot', () => { - const tree = renderDeep(); + const tree = renderDeep(); expect(tree).toMatchSnapshot(); }); }); diff --git a/src/containers/SignupForm/__snapshots__/SignupForm.test.js.snap b/src/containers/SignupForm/__snapshots__/SignupForm.test.js.snap index 76e5c5c2..d2fa4f49 100644 --- a/src/containers/SignupForm/__snapshots__/SignupForm.test.js.snap +++ b/src/containers/SignupForm/__snapshots__/SignupForm.test.js.snap @@ -104,6 +104,28 @@ exports[`SignupForm matches snapshot 1`] = `
+

+ + + By signing up you accept the + + + terms and conditions + + + + +

); @@ -228,6 +241,14 @@ export class AuthenticationPageComponent extends Component {
{showEmailVerification ? emailVerificationContent : formContent}
+ this.setState({ tosModalOpen: false })} + onManageDisableScrolling={onManageDisableScrolling} + > + +
@@ -264,6 +285,7 @@ AuthenticationPageComponent.propTypes = { sendVerificationEmailInProgress: bool.isRequired, sendVerificationEmailError: propTypes.error, onResendVerificationEmail: func.isRequired, + onManageDisableScrolling: func.isRequired, // from withRouter location: shape({ state: object }).isRequired, @@ -292,6 +314,8 @@ const mapDispatchToProps = dispatch => ({ submitLogin: ({ email, password }) => dispatch(login(email, password)), submitSignup: params => dispatch(signup(params)), onResendVerificationEmail: () => dispatch(sendVerificationEmail()), + onManageDisableScrolling: (componentId, disableScrolling) => + dispatch(manageDisableScrolling(componentId, disableScrolling)), }); // Note: it is important that the withRouter HOC is **outside** the diff --git a/src/containers/AuthenticationPage/__snapshots__/AuthenticationPage.test.js.snap b/src/containers/AuthenticationPage/__snapshots__/AuthenticationPage.test.js.snap index 9980bf65..518fc389 100644 --- a/src/containers/AuthenticationPage/__snapshots__/AuthenticationPage.test.js.snap +++ b/src/containers/AuthenticationPage/__snapshots__/AuthenticationPage.test.js.snap @@ -82,6 +82,17 @@ exports[`AuthenticationPageComponent matches snapshot 1`] = ` />
+ + + Date: Fri, 27 Oct 2017 16:43:54 +0300 Subject: [PATCH 05/13] Wrap terms to set width and top padding --- .../AuthenticationPage/AuthenticationPage.css | 12 ++++++++++++ .../AuthenticationPage/AuthenticationPage.js | 4 +++- .../__snapshots__/AuthenticationPage.test.js.snap | 10 ++++++---- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/containers/AuthenticationPage/AuthenticationPage.css b/src/containers/AuthenticationPage/AuthenticationPage.css index 39e40c40..7f0a8446 100644 --- a/src/containers/AuthenticationPage/AuthenticationPage.css +++ b/src/containers/AuthenticationPage/AuthenticationPage.css @@ -50,6 +50,18 @@ text-align: left; } +/* Terms of Service modal*/ + +.termsWrapper { + width: 100%; + padding-top: 40px; + + @media (--viewportMedium) { + width: 571px; + padding-top: 11px; + } +} + /* ================ Hide Top bar in screens smaller than 768px ================ */ .hideOnMobile { diff --git a/src/containers/AuthenticationPage/AuthenticationPage.js b/src/containers/AuthenticationPage/AuthenticationPage.js index 9bdeccd3..05362867 100644 --- a/src/containers/AuthenticationPage/AuthenticationPage.js +++ b/src/containers/AuthenticationPage/AuthenticationPage.js @@ -247,7 +247,9 @@ export class AuthenticationPageComponent extends Component { onClose={() => this.setState({ tosModalOpen: false })} onManageDisableScrolling={onManageDisableScrolling} > - +
+ +
diff --git a/src/containers/AuthenticationPage/__snapshots__/AuthenticationPage.test.js.snap b/src/containers/AuthenticationPage/__snapshots__/AuthenticationPage.test.js.snap index 518fc389..7904a06f 100644 --- a/src/containers/AuthenticationPage/__snapshots__/AuthenticationPage.test.js.snap +++ b/src/containers/AuthenticationPage/__snapshots__/AuthenticationPage.test.js.snap @@ -88,10 +88,12 @@ exports[`AuthenticationPageComponent matches snapshot 1`] = ` onClose={[Function]} onManageDisableScrolling={[Function]} > - +
+ +
Date: Fri, 27 Oct 2017 16:44:12 +0300 Subject: [PATCH 06/13] Add TOS content --- .../TermsOfService/TermsOfService.js | 162 +++++++++++++++++- 1 file changed, 161 insertions(+), 1 deletion(-) diff --git a/src/components/TermsOfService/TermsOfService.js b/src/components/TermsOfService/TermsOfService.js index 97460bea..942091e6 100644 --- a/src/components/TermsOfService/TermsOfService.js +++ b/src/components/TermsOfService/TermsOfService.js @@ -7,7 +7,167 @@ import css from './TermsOfService.css'; const TermsOfService = props => { const { rootClassName, className } = props; const classes = classNames(rootClassName || css.root, className); - return
TODO: TOS here
; + return ( +
+

Saunatime Platform Terms and Conditions

+

Last updated: October 5th, 2017

+

+ Welcome to Saunatime.io, a peer-to-peer water sports equipment rental marketplace and online + service provided by Sharetribe Oy. ("Saunatime," "we," or "us"). This Terms of Service + Agreement ("Agreement") describes the terms and conditions that govern your use of and + participation in Saunatime services. By accessing or using the Service, you signify that you + have read, understood, and agree to be bound by this Agreement.  If you do not agree to any + of these terms or any future amendments, do not use or access (or continue to access) the + Service. This Agreement applies to all visitors, users, and others who access the Service + ("Users"). +

+

+ Please read this agreement carefully to ensure that you understand each provision.  You + understand and agree that Saunatime is not a party to any agreements entered into between + renters and owners, nor is Saunatime an agent or insurer.  Saunatime has no control over the + conduct of renters or other users of the service and disclaims all liability in this + regard.  This agreement contains a mandatory arbitration of disputes provision that requires + the use of arbitration on an individual basis to resolve disputes, rather than jury trials + or class actions, and also limits the remedies available to you in the event of a dispute. +

+ +

Eligibility

+ +

+ This Service is intended solely for people eighteen (18) years of age or older, and any + registration, use or access to the Service by anyone under 18 is strictly prohibited. + Saunatime reserves the right to limit or restrict access by any person, in our sole + discretion. +

+

End User License

+

+ Subject to the terms and conditions of this Agreement, you are hereby granted a + non-exclusive, limited, non-transferable, freely revocable, license to use the Service for + your personal, noncommercial use only. Saunatime may terminate this license at any time for + any reason or no reason. +

+

Indemnity

+

+ You agree to defend, indemnify and hold harmless Saunatime and its subsidiaries, agents, + licensors, managers, and other affiliated companies, and their employees, contractors, + agents, officers and directors, from and against any and all claims, damages, obligations, + losses, liabilities, costs or debt, and expenses (including but not limited to attorney's + fees) arising from: (i) your use of and access to the Service or Products; (ii) your + violation of any term of this Agreement, including without limitation your breach of any of + the representations and warranties; (iii) your violation of any third-party right, including + without limitation any right of privacy, publicity rights or Intellectual Property Rights; + (iv) your violation of any law, rule or regulation of the United States or any other + country; (v) any claim or damages that arise as a result of any of your User Content or any + that is submitted via your account; or (vi) any other party’s access and use of the Service + with your unique username, password or other appropriate security code. +

+

No Warranty

+

+ If you choose to use the service and/or participate in a rental, you do so at your own + risk.  The service and any products are provided on an “as is” and “as available” basis.  To + the maximum extent permitted by applicable law, the service is provided without warranties + of any kind, whether express or implied, including, but not limited to implied warranties of + merchantability, fitness for a particular purpose, or non-infringement.  No advice or + information, whether oral or written, obtained by you from Saunatime or through the service + will create any warranty not expressly stated herein.  Without limiting the foregoing, + Saunatime, its subsidiaries, and its licensors do not warrant that the content is accurate, + reliable or correct; that the service or any rental will meet your requirements; that the + service will be available at any particular time or location, uninterrupted or secure; that + any defects or errors will be corrected; or that the service is free of viruses or other + harmful components.  You will be solely responsible for any damage or loss that results from + your use of the service or products. +

+

Limitation of Liability

+

+ Except as expressly provided in the insurance provision, to the maximum extent permitted by + applicable law, in no event shall Saunatime, its affiliates, agents, directors, employees, + supplier, or its licensors be liable for any direct, indirect, punitive, incidental, + special, consequential, or exemplary damages, including without limitation damages for loss + of profits, goodwill, use, data or other intangible losses, that result from the use of, or + inability to use this service, including without limitation any rental. +

+

+ To the maximum extent permitted by applicable law, Saunatime assumes no liability or + responsibility for any (I) Errors, mistakes, or inaccuracies of content; (II) Personal + injury or property damage of any nature whatsoever, resulting from your access to or use of + our service or products; (III) Any unauthorized access to or use of our secure servers + and/or any and all personal information stored therein; (IV) Any interruption or cessation + of transmission to or from the service; (V) Any bugs, viruses, or the like that may be + transmitted to or through our service by any third party; (IV) Any errors or omissions in + any content or for any loss or damage incurred as a result of the us of any content posted, + emailed, transmitted, or otherwise made available through the service; and/or (VII) User + content or the defamatory, offensive, or illegal conduct of any third party.  In no event + shall Saunatime, its affiliates, agents, directors, employees, suppliers, or licensors be + liable to you for any claims, proceedings, liabilities, obligations, damages, losses or + costs in an amount exceeding the greater of either (a) The amounts paid by Saunatime to you + in the twelve (12) month period prior to the event giving rise to the liability; or (b) One + hundred dollars ($100).  The limitations of damages set forth above are fundamental elements + of the basis of the bargain between Saunatime and you.  This limitation of liability section + applies whether the alleged liability is based on contract, tort, negligence, strict + liability, or any other basis, even if Saunatime has been advised of the possibility of such + damage.  The forgoing limitation of liability shall apply to the fullest extent permitted by + law in the applicable jurisdiction. +

+

Assignment

+

+ This Agreement, and any rights and licenses granted hereunder, may not be transferred or + assigned by you, but may be assigned by Saunatime without restriction.  Any attempted + transfer or assignment in violation hereof shall be null and void. +

+

Termination

+

+ We may terminate your participation in the Service at any time, for any reason or no reason, + without explanation. We maintain sole discretion to bar your use of the Service in the + future, for any reason that we determine or for no reason. This Agreement will remain in + effect after your participation in the Service terminates. +

+

Governing Law

+

+ You agree that: (i) the Service shall be deemed solely based in New York; and (ii) the + Service shall be deemed a passive one that does not give rise to personal jurisdiction over + Saunatime, either specific or general, in jurisdictions other than New York. This Agreement + shall be governed by the internal substantive laws of the State of New York. You agree to + submit to the personal jurisdiction of a state court located in New York County, New York or + the U.S. District Court for the Southern District of New York for any actions for which we + retain the right to seek injunctive or other equitable relief in a court of competent + jurisdiction to prevent the actual or threatened infringement, misappropriation or violation + of a our copyrights, trademarks, trade secrets, patents, or other intellectual property or + proprietary rights, as set forth in the Arbitration provision below. +

+

Arbitration

+

+ In the unlikely event that Saunatime has not been able to resolve a dispute it has with you + after attempting to do so informally, we each agree to resolve any claim, dispute, or + controversy (excluding any Saunatime claims for injunctive or other equitable relief) + arising out of or in connection with or relating to this Agreement, or the breach or alleged + breach thereof (collectively, "Claims"), by binding arbitration in the county of New York. + The award rendered by the arbitrator shall include costs of arbitration, reasonable + attorney's fees and reasonable costs for expert and other witnesses, and any judgment on the + award rendered by the arbitrator may be entered in any court of competent jurisdiction. + Nothing in this Section shall be deemed as preventing Saunatime from seeking injunctive or + other equitable relief from the courts as necessary to protect any of Saunatime’s + proprietary interests. All claims must be brought in the party’s individual capacity, and + not as a class member in any purported class or representative proceeding.  You agree that, + by entering into this agreement, you and Saunatime are each waiving the right to a trial by + jury or to participate in a class action. +

+

Entire Agreement/Severability

+

+ This Agreement, together with all amendments, all documents referenced in this Agreement, + and any other legal notices and agreements published by Saunatime via the Service, shall + constitute the entire agreement between you and Saunatime concerning the Service. If a court + of competent jurisdiction deems any provision of this Agreement invalid, the invalidity of + such provision shall not affect the validity of the remaining provisions of this Agreement, + which shall remain in full force and effect. +

+

No Waiver

+

+ No waiver of any term of this Agreement shall be deemed a further or continuing waiver of + such term or any other term, and Quiver’s failure to assert any right or provision under + this Agreement shall not constitute a waiver of such right or provision. +

+
+ ); }; TermsOfService.defaultProps = { From 43228d11ca82cb0a7cec28ab56e8c8aa4dbda8a2 Mon Sep 17 00:00:00 2001 From: Kimmo Puputti Date: Fri, 27 Oct 2017 16:44:30 +0300 Subject: [PATCH 07/13] TOS styling --- .../TermsOfService/TermsOfService.css | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/components/TermsOfService/TermsOfService.css b/src/components/TermsOfService/TermsOfService.css index c3a2af63..6a253662 100644 --- a/src/components/TermsOfService/TermsOfService.css +++ b/src/components/TermsOfService/TermsOfService.css @@ -1,2 +1,31 @@ +@import '../../marketplace.css'; + .root { + & p { + @apply --marketplaceH4FontStyles; + } + + & .lastUpdated { + @apply --marketplaceBodyFontStyles; + margin-top: 0; + margin-bottom: 53px; + + @media (--viewportMedium) { + margin-top: 0; + margin-bottom: 53px; + } + } +} + +.mainHeading { + margin-top: 0; + margin-bottom: 19px; + + @media (--viewportMedium) { + margin-top: 0; + margin-bottom: 19px; + } +} + +.sectionHeading { } From 557cb49365b149ff7685d04e3668eb932acde1aa Mon Sep 17 00:00:00 2001 From: Kimmo Puputti Date: Mon, 30 Oct 2017 14:30:20 +0200 Subject: [PATCH 08/13] Update TOS content --- .../TermsOfService/TermsOfService.js | 185 ++++-------------- 1 file changed, 37 insertions(+), 148 deletions(-) diff --git a/src/components/TermsOfService/TermsOfService.js b/src/components/TermsOfService/TermsOfService.js index 942091e6..ae63f7c3 100644 --- a/src/components/TermsOfService/TermsOfService.js +++ b/src/components/TermsOfService/TermsOfService.js @@ -9,162 +9,51 @@ const TermsOfService = props => { const classes = classNames(rootClassName || css.root, className); return (
-

Saunatime Platform Terms and Conditions

-

Last updated: October 5th, 2017

-

- Welcome to Saunatime.io, a peer-to-peer water sports equipment rental marketplace and online - service provided by Sharetribe Oy. ("Saunatime," "we," or "us"). This Terms of Service - Agreement ("Agreement") describes the terms and conditions that govern your use of and - participation in Saunatime services. By accessing or using the Service, you signify that you - have read, understood, and agree to be bound by this Agreement.  If you do not agree to any - of these terms or any future amendments, do not use or access (or continue to access) the - Service. This Agreement applies to all visitors, users, and others who access the Service - ("Users"). -

-

- Please read this agreement carefully to ensure that you understand each provision.  You - understand and agree that Saunatime is not a party to any agreements entered into between - renters and owners, nor is Saunatime an agent or insurer.  Saunatime has no control over the - conduct of renters or other users of the service and disclaims all liability in this - regard.  This agreement contains a mandatory arbitration of disputes provision that requires - the use of arbitration on an individual basis to resolve disputes, rather than jury trials - or class actions, and also limits the remedies available to you in the event of a dispute. -

- -

Eligibility

+

Terms of Service

+

Last updated: October 30, 2017

- This Service is intended solely for people eighteen (18) years of age or older, and any - registration, use or access to the Service by anyone under 18 is strictly prohibited. - Saunatime reserves the right to limit or restrict access by any person, in our sole - discretion. + Thank you for using Saunatime! Ut enim ad minim veniam, quis nostrud exercitation ullamco + laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in + voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat + cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

-

End User License

+ +

1 Lorem ipsum dolor sit amet

- Subject to the terms and conditions of this Agreement, you are hereby granted a - non-exclusive, limited, non-transferable, freely revocable, license to use the Service for - your personal, noncommercial use only. Saunatime may terminate this license at any time for - any reason or no reason. + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut + labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco + laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in + voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat + cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

-

Indemnity

+ +

2 Sed ut perspiciatis unde

- You agree to defend, indemnify and hold harmless Saunatime and its subsidiaries, agents, - licensors, managers, and other affiliated companies, and their employees, contractors, - agents, officers and directors, from and against any and all claims, damages, obligations, - losses, liabilities, costs or debt, and expenses (including but not limited to attorney's - fees) arising from: (i) your use of and access to the Service or Products; (ii) your - violation of any term of this Agreement, including without limitation your breach of any of - the representations and warranties; (iii) your violation of any third-party right, including - without limitation any right of privacy, publicity rights or Intellectual Property Rights; - (iv) your violation of any law, rule or regulation of the United States or any other - country; (v) any claim or damages that arise as a result of any of your User Content or any - that is submitted via your account; or (vi) any other party’s access and use of the Service - with your unique username, password or other appropriate security code. + Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque + laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi + architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit + aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione + voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, + consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et + dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum + exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi + consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil + molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?

-

No Warranty

+ +

3 At vero eos et accusamus

- If you choose to use the service and/or participate in a rental, you do so at your own - risk.  The service and any products are provided on an “as is” and “as available” basis.  To - the maximum extent permitted by applicable law, the service is provided without warranties - of any kind, whether express or implied, including, but not limited to implied warranties of - merchantability, fitness for a particular purpose, or non-infringement.  No advice or - information, whether oral or written, obtained by you from Saunatime or through the service - will create any warranty not expressly stated herein.  Without limiting the foregoing, - Saunatime, its subsidiaries, and its licensors do not warrant that the content is accurate, - reliable or correct; that the service or any rental will meet your requirements; that the - service will be available at any particular time or location, uninterrupted or secure; that - any defects or errors will be corrected; or that the service is free of viruses or other - harmful components.  You will be solely responsible for any damage or loss that results from - your use of the service or products. -

-

Limitation of Liability

-

- Except as expressly provided in the insurance provision, to the maximum extent permitted by - applicable law, in no event shall Saunatime, its affiliates, agents, directors, employees, - supplier, or its licensors be liable for any direct, indirect, punitive, incidental, - special, consequential, or exemplary damages, including without limitation damages for loss - of profits, goodwill, use, data or other intangible losses, that result from the use of, or - inability to use this service, including without limitation any rental. -

-

- To the maximum extent permitted by applicable law, Saunatime assumes no liability or - responsibility for any (I) Errors, mistakes, or inaccuracies of content; (II) Personal - injury or property damage of any nature whatsoever, resulting from your access to or use of - our service or products; (III) Any unauthorized access to or use of our secure servers - and/or any and all personal information stored therein; (IV) Any interruption or cessation - of transmission to or from the service; (V) Any bugs, viruses, or the like that may be - transmitted to or through our service by any third party; (IV) Any errors or omissions in - any content or for any loss or damage incurred as a result of the us of any content posted, - emailed, transmitted, or otherwise made available through the service; and/or (VII) User - content or the defamatory, offensive, or illegal conduct of any third party.  In no event - shall Saunatime, its affiliates, agents, directors, employees, suppliers, or licensors be - liable to you for any claims, proceedings, liabilities, obligations, damages, losses or - costs in an amount exceeding the greater of either (a) The amounts paid by Saunatime to you - in the twelve (12) month period prior to the event giving rise to the liability; or (b) One - hundred dollars ($100).  The limitations of damages set forth above are fundamental elements - of the basis of the bargain between Saunatime and you.  This limitation of liability section - applies whether the alleged liability is based on contract, tort, negligence, strict - liability, or any other basis, even if Saunatime has been advised of the possibility of such - damage.  The forgoing limitation of liability shall apply to the fullest extent permitted by - law in the applicable jurisdiction. -

-

Assignment

-

- This Agreement, and any rights and licenses granted hereunder, may not be transferred or - assigned by you, but may be assigned by Saunatime without restriction.  Any attempted - transfer or assignment in violation hereof shall be null and void. -

-

Termination

-

- We may terminate your participation in the Service at any time, for any reason or no reason, - without explanation. We maintain sole discretion to bar your use of the Service in the - future, for any reason that we determine or for no reason. This Agreement will remain in - effect after your participation in the Service terminates. -

-

Governing Law

-

- You agree that: (i) the Service shall be deemed solely based in New York; and (ii) the - Service shall be deemed a passive one that does not give rise to personal jurisdiction over - Saunatime, either specific or general, in jurisdictions other than New York. This Agreement - shall be governed by the internal substantive laws of the State of New York. You agree to - submit to the personal jurisdiction of a state court located in New York County, New York or - the U.S. District Court for the Southern District of New York for any actions for which we - retain the right to seek injunctive or other equitable relief in a court of competent - jurisdiction to prevent the actual or threatened infringement, misappropriation or violation - of a our copyrights, trademarks, trade secrets, patents, or other intellectual property or - proprietary rights, as set forth in the Arbitration provision below. -

-

Arbitration

-

- In the unlikely event that Saunatime has not been able to resolve a dispute it has with you - after attempting to do so informally, we each agree to resolve any claim, dispute, or - controversy (excluding any Saunatime claims for injunctive or other equitable relief) - arising out of or in connection with or relating to this Agreement, or the breach or alleged - breach thereof (collectively, "Claims"), by binding arbitration in the county of New York. - The award rendered by the arbitrator shall include costs of arbitration, reasonable - attorney's fees and reasonable costs for expert and other witnesses, and any judgment on the - award rendered by the arbitrator may be entered in any court of competent jurisdiction. - Nothing in this Section shall be deemed as preventing Saunatime from seeking injunctive or - other equitable relief from the courts as necessary to protect any of Saunatime’s - proprietary interests. All claims must be brought in the party’s individual capacity, and - not as a class member in any purported class or representative proceeding.  You agree that, - by entering into this agreement, you and Saunatime are each waiving the right to a trial by - jury or to participate in a class action. -

-

Entire Agreement/Severability

-

- This Agreement, together with all amendments, all documents referenced in this Agreement, - and any other legal notices and agreements published by Saunatime via the Service, shall - constitute the entire agreement between you and Saunatime concerning the Service. If a court - of competent jurisdiction deems any provision of this Agreement invalid, the invalidity of - such provision shall not affect the validity of the remaining provisions of this Agreement, - which shall remain in full force and effect. -

-

No Waiver

-

- No waiver of any term of this Agreement shall be deemed a further or continuing waiver of - such term or any other term, and Quiver’s failure to assert any right or provision under - this Agreement shall not constitute a waiver of such right or provision. + At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium + voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati + cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id + est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam + libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod + maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. + Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut + et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a + sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis + doloribus asperiores repellat

); From f7dbe1665c1c5c9dd2b18a0eb6f14ad1b18f35c3 Mon Sep 17 00:00:00 2001 From: Kimmo Puputti Date: Mon, 30 Oct 2017 15:02:42 +0200 Subject: [PATCH 09/13] Move styled side tabs into the layout wrapper --- .../LayoutWrapperSideNav.css | 35 ++++++++++++ .../LayoutWrapperSideNav.js | 17 ++++-- .../ContactDetailsPage/ContactDetailsPage.css | 35 ------------ .../ContactDetailsPage/ContactDetailsPage.js | 5 +- .../ContactDetailsPage.test.js.snap | 53 ++++++++----------- .../__snapshots__/InboxPage.test.js.snap | 2 + .../PasswordChangePage/PasswordChangePage.css | 35 ------------ .../PasswordChangePage/PasswordChangePage.js | 5 +- .../PasswordChangePage.test.js.snap | 53 ++++++++----------- 9 files changed, 98 insertions(+), 142 deletions(-) diff --git a/src/components/LayoutWrapperSideNav/LayoutWrapperSideNav.css b/src/components/LayoutWrapperSideNav/LayoutWrapperSideNav.css index 12015b4a..e57de45c 100644 --- a/src/components/LayoutWrapperSideNav/LayoutWrapperSideNav.css +++ b/src/components/LayoutWrapperSideNav/LayoutWrapperSideNav.css @@ -26,3 +26,38 @@ padding-left: 25vw; } } + +.tabs { + display: flex; + flex-direction: row; + overflow-x: auto; + min-height: 48px; + padding-top: 2px; + + @media (--viewportMedium) { + min-height: 56px; + padding-top: 10px; + } + + @media (--viewportLarge) { + min-height: auto; + flex-direction: column; + margin-top: 28px; + padding-top: 0; + } +} + +.tab { + display: flex; + align-items: flex-end; + height: 100%; + margin-left: 16px; + + &:first-child { + margin-left: 0; + } + + @media (--viewportLarge) { + margin-left: 0; + } +} diff --git a/src/components/LayoutWrapperSideNav/LayoutWrapperSideNav.js b/src/components/LayoutWrapperSideNav/LayoutWrapperSideNav.js index 3a1827d8..772ed0b9 100644 --- a/src/components/LayoutWrapperSideNav/LayoutWrapperSideNav.js +++ b/src/components/LayoutWrapperSideNav/LayoutWrapperSideNav.js @@ -5,26 +5,35 @@ import React from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; +import { TabNav } from '../../components'; import css from './LayoutWrapperSideNav.css'; const LayoutWrapperSideNav = props => { - const { className, rootClassName, children } = props; + const { className, rootClassName, children, tabs } = props; const classes = classNames(rootClassName || css.root, className); - return ; + return ( + + ); }; LayoutWrapperSideNav.defaultProps = { className: null, rootClassName: null, + children: null, + tabs: null, }; -const { node, string } = PropTypes; +const { node, string, array } = PropTypes; LayoutWrapperSideNav.propTypes = { - children: node.isRequired, + children: node, className: string, rootClassName: string, + tabs: array, }; export default LayoutWrapperSideNav; diff --git a/src/containers/ContactDetailsPage/ContactDetailsPage.css b/src/containers/ContactDetailsPage/ContactDetailsPage.css index 30d830f8..3adbf2c2 100644 --- a/src/containers/ContactDetailsPage/ContactDetailsPage.css +++ b/src/containers/ContactDetailsPage/ContactDetailsPage.css @@ -16,41 +16,6 @@ box-shadow: none; } -.tabs { - display: flex; - flex-direction: row; - overflow-x: auto; - min-height: 48px; - padding-top: 2px; - - @media (--viewportMedium) { - min-height: 56px; - padding-top: 10px; - } - - @media (--viewportLarge) { - min-height: auto; - flex-direction: column; - margin-top: 28px; - padding-top: 0; - } -} - -.tab { - display: flex; - align-items: flex-end; - height: 100%; - margin-left: 16px; - - &:first-child { - margin-left: 0; - } - - @media (--viewportLarge) { - margin-left: 0; - } -} - .title { margin-top: 4px; margin-bottom: 19px; diff --git a/src/containers/ContactDetailsPage/ContactDetailsPage.js b/src/containers/ContactDetailsPage/ContactDetailsPage.js index 4948acf6..bb0a9b0f 100644 --- a/src/containers/ContactDetailsPage/ContactDetailsPage.js +++ b/src/containers/ContactDetailsPage/ContactDetailsPage.js @@ -14,7 +14,6 @@ import { LayoutWrapperFooter, Footer, Page, - TabNav, UserNav, } from '../../components'; import { ContactDetailsForm, TopbarContainer } from '../../containers'; @@ -84,9 +83,7 @@ export const ContactDetailsPageComponent = props => { /> - - - +

diff --git a/src/containers/ContactDetailsPage/__snapshots__/ContactDetailsPage.test.js.snap b/src/containers/ContactDetailsPage/__snapshots__/ContactDetailsPage.test.js.snap index e6801544..bee228e0 100644 --- a/src/containers/ContactDetailsPage/__snapshots__/ContactDetailsPage.test.js.snap +++ b/src/containers/ContactDetailsPage/__snapshots__/ContactDetailsPage.test.js.snap @@ -27,38 +27,31 @@ exports[`ContactDetailsPage matches snapshot 1`] = ` - , + tabs={ + Array [ + Object { + "linkProps": Object { + "name": "ContactDetailsPage", }, - Object { - "linkProps": Object { - "name": "PasswordChangePage", - }, - "selected": false, - "text": , + "selected": true, + "text": , + }, + Object { + "linkProps": Object { + "name": "PasswordChangePage", }, - ] - } - /> - + "selected": false, + "text": , + }, + ] + } + />

{ /> - - - +

diff --git a/src/containers/PasswordChangePage/__snapshots__/PasswordChangePage.test.js.snap b/src/containers/PasswordChangePage/__snapshots__/PasswordChangePage.test.js.snap index 382b6dff..af898e49 100644 --- a/src/containers/PasswordChangePage/__snapshots__/PasswordChangePage.test.js.snap +++ b/src/containers/PasswordChangePage/__snapshots__/PasswordChangePage.test.js.snap @@ -27,38 +27,31 @@ exports[`PasswordChangePage matches snapshot 1`] = ` - , + tabs={ + Array [ + Object { + "linkProps": Object { + "name": "ContactDetailsPage", }, - Object { - "linkProps": Object { - "name": "PasswordChangePage", - }, - "selected": true, - "text": , + "selected": false, + "text": , + }, + Object { + "linkProps": Object { + "name": "PasswordChangePage", }, - ] - } - /> - + "selected": true, + "text": , + }, + ] + } + /> Date: Mon, 30 Oct 2017 16:35:34 +0200 Subject: [PATCH 10/13] TOS and privacy pages --- src/components/Footer/Footer.js | 8 +- .../TermsOfService/TermsOfService.css | 25 +++--- .../TermsOfService/TermsOfService.js | 7 +- .../AuthenticationPage/AuthenticationPage.css | 9 ++ .../AuthenticationPage/AuthenticationPage.js | 3 + .../AuthenticationPage.test.js.snap | 6 ++ .../PrivacyPolicyPage/PrivacyPolicyPage.js | 48 ++++++++++ .../TermsOfServicePage/TermsOfServicePage.css | 9 ++ .../TermsOfServicePage/TermsOfServicePage.js | 89 +++++++++++++++++++ src/containers/index.js | 2 + src/routeConfiguration.js | 16 +++- src/translations/en.json | 31 ++++--- 12 files changed, 215 insertions(+), 38 deletions(-) create mode 100644 src/containers/PrivacyPolicyPage/PrivacyPolicyPage.js create mode 100644 src/containers/TermsOfServicePage/TermsOfServicePage.css create mode 100644 src/containers/TermsOfServicePage/TermsOfServicePage.js diff --git a/src/components/Footer/Footer.js b/src/components/Footer/Footer.js index ca38527e..9a06598a 100644 --- a/src/components/Footer/Footer.js +++ b/src/components/Footer/Footer.js @@ -240,12 +240,12 @@ const Footer = props => {
  • - +
  • - +
  • @@ -261,10 +261,10 @@ const Footer = props => {
    - + - +
    diff --git a/src/components/TermsOfService/TermsOfService.css b/src/components/TermsOfService/TermsOfService.css index 6a253662..7df85fc3 100644 --- a/src/components/TermsOfService/TermsOfService.css +++ b/src/components/TermsOfService/TermsOfService.css @@ -4,28 +4,23 @@ & p { @apply --marketplaceH4FontStyles; } + & h2 { + /* Adjust heading margins to work with the reduced body font size */ + margin: 23px 0 19px 0; + + @media (--viewportMedium) { + margin: 24px 0 24px 0; + } + } & .lastUpdated { @apply --marketplaceBodyFontStyles; margin-top: 0; - margin-bottom: 53px; + margin-bottom: 55px; @media (--viewportMedium) { margin-top: 0; - margin-bottom: 53px; + margin-bottom: 54px; } } } - -.mainHeading { - margin-top: 0; - margin-bottom: 19px; - - @media (--viewportMedium) { - margin-top: 0; - margin-bottom: 19px; - } -} - -.sectionHeading { -} diff --git a/src/components/TermsOfService/TermsOfService.js b/src/components/TermsOfService/TermsOfService.js index ae63f7c3..5c312d9d 100644 --- a/src/components/TermsOfService/TermsOfService.js +++ b/src/components/TermsOfService/TermsOfService.js @@ -9,7 +9,6 @@ const TermsOfService = props => { const classes = classNames(rootClassName || css.root, className); return (
    -

    Terms of Service

    Last updated: October 30, 2017

    @@ -19,7 +18,7 @@ const TermsOfService = props => { cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

    -

    1 Lorem ipsum dolor sit amet

    +

    1 Lorem ipsum dolor sit amet

    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco @@ -28,7 +27,7 @@ const TermsOfService = props => { cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

    -

    2 Sed ut perspiciatis unde

    +

    2 Sed ut perspiciatis unde

    Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi @@ -42,7 +41,7 @@ const TermsOfService = props => { molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?

    -

    3 At vero eos et accusamus

    +

    3 At vero eos et accusamus

    At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati diff --git a/src/containers/AuthenticationPage/AuthenticationPage.css b/src/containers/AuthenticationPage/AuthenticationPage.css index 7f0a8446..efc04bf8 100644 --- a/src/containers/AuthenticationPage/AuthenticationPage.css +++ b/src/containers/AuthenticationPage/AuthenticationPage.css @@ -62,6 +62,15 @@ } } +.termsHeading { + @apply --marketplaceH1FontStyles; + margin: 0 0 19px 0; + + @media (--viewportMedium) { + margin: 0 0 19px 0; + } +} + /* ================ Hide Top bar in screens smaller than 768px ================ */ .hideOnMobile { diff --git a/src/containers/AuthenticationPage/AuthenticationPage.js b/src/containers/AuthenticationPage/AuthenticationPage.js index 05362867..b8243b8d 100644 --- a/src/containers/AuthenticationPage/AuthenticationPage.js +++ b/src/containers/AuthenticationPage/AuthenticationPage.js @@ -248,6 +248,9 @@ export class AuthenticationPageComponent extends Component { onManageDisableScrolling={onManageDisableScrolling} >

    +

    + +

    diff --git a/src/containers/AuthenticationPage/__snapshots__/AuthenticationPage.test.js.snap b/src/containers/AuthenticationPage/__snapshots__/AuthenticationPage.test.js.snap index 7904a06f..c5115ea6 100644 --- a/src/containers/AuthenticationPage/__snapshots__/AuthenticationPage.test.js.snap +++ b/src/containers/AuthenticationPage/__snapshots__/AuthenticationPage.test.js.snap @@ -89,6 +89,12 @@ exports[`AuthenticationPageComponent matches snapshot 1`] = ` onManageDisableScrolling={[Function]} >
    +

    + +

    { + const tabs = [ + { + text: , + selected: true, + linkProps: { + name: 'PrivacyPolicyPage', + }, + }, + { + text: , + selected: false, + linkProps: { + name: 'TermsOfServicePage', + }, + }, + ]; + return ( + + + + + + + +

    TODO: Privacy policy

    +
    + +