-
Notifications
You must be signed in to change notification settings - Fork 867
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: [UEPR-187] [UEPR-192] [UEPR-194] ToU modal display logic #9248
base: ux-integration
Are you sure you want to change the base?
Changes from 54 commits
8fbe282
b45a5a4
2c0d0ff
1938b3d
dc7e1dd
59f427f
ffe73db
06b83e1
a28dd3a
758b921
79e21e6
6e02ed0
d6c5187
ce07895
7c8e26c
d9da016
2253cd7
9fc12c0
cd23d05
a6eb8c9
f030ba3
bb6a14d
6f019b4
5884f2c
74dc0b1
61cfb3a
6015df0
ce5c661
40219f2
42149da
a4d5374
9496e23
b51d0a5
b9174aa
0df8fbf
6830a4e
4a5a03d
7873f8f
9c32066
f6939f1
49ae1aa
dd0c497
390c0f5
6728662
2d52682
2d2913b
afaa1ce
3b8428c
ba05413
235e1b1
1b6b152
a1d19f6
9eb948c
c5bf924
e23a67e
3aab2ee
e6a2c9b
3af2345
cf28d6b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import React from 'react'; | ||
import {injectIntl, FormattedMessage} from 'react-intl'; | ||
import Modal from '../../base/modal.jsx'; | ||
import {TermsOfUseLink} from '../terms-of-use-modal.jsx'; | ||
import Button from '../../../forms/button.jsx'; | ||
|
||
const TermsOfUseModalOver16 = () => ( | ||
<Modal | ||
overlayClassName="tou-modal-overlay" | ||
className="tou-modal" | ||
showCloseButton={false} | ||
isOpen | ||
> | ||
<div className="tou-modal-top" /> | ||
<div className="tou-modal-content"> | ||
<h1 className="tou-modal-heading"> | ||
<FormattedMessage id="tos.updatedTerms" /> | ||
</h1> | ||
<p> | ||
<FormattedMessage | ||
id="tos.over16.updatedTermsNotice" | ||
values={{ | ||
a: TermsOfUseLink | ||
}} | ||
/> | ||
</p> | ||
<p> | ||
<FormattedMessage id="tos.over16.acceptConfirmation" /> | ||
</p> | ||
<div className="tou-modal-button-container"> | ||
<Button className="tou-modal-button filled"> | ||
<FormattedMessage id="tos.over16.acceptContinue" /> | ||
</Button> | ||
</div> | ||
</div> | ||
</Modal> | ||
); | ||
|
||
export default injectIntl(TermsOfUseModalOver16); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import React, {useCallback, useState} from 'react'; | ||
import {injectIntl, FormattedMessage} from 'react-intl'; | ||
import TermsOfUseReminderModal from './under16/terms-of-use-reminder.jsx'; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMO, following this file hierarchy, there is no need to include |
||
require('./terms-of-use-modal.scss'); | ||
|
||
const TermsOfUseLink = chunks => { | ||
const [isModalVisible, setIsModalVisible] = useState(false); | ||
const handleOpenModal = useCallback(() => { | ||
setIsModalVisible(true); | ||
}, []); | ||
|
||
const handleCloseModal = useCallback(() => { | ||
setIsModalVisible(false); | ||
}, []); | ||
|
||
return ( | ||
<> | ||
<a | ||
className="tou-banner-link" | ||
onClick={handleOpenModal} | ||
> | ||
{chunks} | ||
</a> | ||
<TermsOfUseReminderModal | ||
onClose={handleCloseModal} | ||
isOpen={isModalVisible} | ||
/> | ||
</> | ||
); | ||
|
||
}; | ||
|
||
const TermsOfUseBanner = () => ( | ||
<div className="tou-banner"> | ||
<FormattedMessage | ||
id="tos.banner.parentAgreement" | ||
values={{ | ||
a: TermsOfUseLink | ||
}} | ||
/> | ||
</div> | ||
); | ||
|
||
|
||
export default injectIntl(TermsOfUseBanner); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import React, {useCallback, useState} from 'react'; | ||
import {connect} from 'react-redux'; | ||
import PropTypes from 'prop-types'; | ||
import TermsOfUseModalOver16 from './over16/modal.jsx'; | ||
import TermsOfUseModalUnder16 from './under16/modal.jsx'; | ||
|
||
require('./terms-of-use-modal.scss'); | ||
|
||
export const noShowTermsOfUseModalPages = ['terms_of_use', 'privacy_policy', 'dmca', 'cookies']; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's move this const to the page component, where it is used |
||
|
||
|
||
export const TermsOfUseLink = chunks => ( | ||
<a | ||
className="tou-modal-link" | ||
target="_blank" | ||
href="terms_of_use" | ||
> | ||
{chunks} | ||
</a> | ||
); | ||
|
||
const TermsOfUseModal = ({ | ||
hasAgreedToLatestTermsOfService, | ||
isInTermsOfUseGracePeriod, | ||
isAfterTermsOfUseGracePeriod, | ||
usesParentEmail, | ||
}) => { | ||
const [isModalVisible, setIsModalVisible] = useState(true); | ||
const handleClose = useCallback(() => { | ||
setIsModalVisible(false); | ||
}); | ||
|
||
if (hasAgreedToLatestTermsOfService ?? true) { | ||
return null; | ||
} | ||
|
||
if (usesParentEmail) { | ||
if (!isInTermsOfUseGracePeriod && !isAfterTermsOfUseGracePeriod) { | ||
return (<TermsOfUseModalUnder16 | ||
email={email} | ||
isOpen={isModalVisible} | ||
onClose={handleClose} | ||
/>); | ||
} | ||
if (isAfterTermsOfUseGracePeriod){ | ||
return null; // TODO | ||
} | ||
return null; | ||
} | ||
|
||
return <TermsOfUseModalOver16 />; | ||
}; | ||
|
||
TermsOfUseModal.propTypes = { | ||
hasAgreedToLatestTermsOfService: PropTypes.bool, | ||
isInTermsOfUseGracePeriod: PropTypes.bool, | ||
isAfterTermsOfUseGracePeriod: PropTypes.bool, | ||
usesParentEmail: PropTypes.bool, | ||
email: PropTypes.string | ||
}; | ||
|
||
const mapStateToProps = state => ({ | ||
hasAgreedToLatestTermsOfService: state.session.session.flags?.has_accepted_terms_of_use, | ||
isInTermsOfUseGracePeriod: state.session.session.flags?.is_in_terms_of_use_grace_period, | ||
isAfterTermsOfUseGracePeriod: state.session.session.flags?.is_after_terms_of_use_grace_period, | ||
usesParentEmail: state.session.session.flags?.with_parent_email, | ||
email: state.session.session.user?.email | ||
}); | ||
|
||
export default connect(mapStateToProps)(TermsOfUseModal); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
@import "../../../colors"; | ||
@import "../../../frameless"; | ||
|
||
.tou-modal-overlay { | ||
background-color: transparentize($overlay-gray, 0.2); | ||
} | ||
|
||
.tou-modal-top{ | ||
height: 48px; | ||
background-color: $ui-mint-green; | ||
border-top-left-radius: 1rem; | ||
border-top-right-radius: 1rem; | ||
} | ||
|
||
.tou-modal{ | ||
width: 464px; | ||
} | ||
|
||
.tou-modal-content{ | ||
padding: 2rem; | ||
box-sizing: border-box; | ||
} | ||
|
||
.tou-modal-heading{ | ||
font-size: 24px; | ||
} | ||
.tou-modal-button { | ||
border-radius: 0.3rem; | ||
padding: 0.5rem 1rem; | ||
border-color: transparent; | ||
font-size: 16px; | ||
font-weight: 600; | ||
} | ||
|
||
.tou-modal-button.filled { | ||
background-color: $ui-mint-green; | ||
color: $ui-white; | ||
} | ||
|
||
.tou-modal-button.outlined { | ||
background-color: $ui-white; | ||
color: $ui-mint-green; | ||
border: 1px solid $ui-mint-green; | ||
} | ||
|
||
.tou-modal-button-container { | ||
display: flex; | ||
justify-content: flex-end; | ||
margin-top: 16px; | ||
gap: 8px; | ||
} | ||
|
||
.tou-modal-button:hover { | ||
background-color: hsl(163, 85%, 35%); | ||
color: $ui-white; | ||
} | ||
|
||
.tou-modal-link { | ||
color: $ui-mint-green !important; | ||
text-decoration: underline !important; | ||
} | ||
|
||
.tou-input { | ||
width: calc(100% - 10px); | ||
padding: 10px 5px; | ||
margin: 5px 0; | ||
font-size: 14px; | ||
color: $type-dark-gray; | ||
background-color: white; | ||
border: 1px solid $active-dark-gray; | ||
border-radius: 6px; | ||
outline: none; | ||
transition: border 0.2s ease-in-out; | ||
font-weight: 600; | ||
} | ||
|
||
.tou-center-content{ | ||
display: flex; | ||
flex-direction: column; | ||
justify-content: center; | ||
align-items: center; | ||
text-align: center; | ||
} | ||
|
||
.tou-banner{ | ||
height: 50px; | ||
background-color: $ui-red-dark; | ||
font-size: 16px; | ||
font-weight: 700; | ||
color: white; | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
} | ||
|
||
.tou-banner-link{ | ||
text-decoration: underline !important; | ||
color: white !important; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tos -> termsOfUse
generally it's better to avoid abbreviations where possible, as that tends to confuse readers not familiar with that part of the code