mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2025-03-27 05:11:42 -04:00
Merge pull request #5345 from benjiwheeler/donate-banner
add donate banner, make close button a mode of button component
This commit is contained in:
commit
4591c65e6f
8 changed files with 257 additions and 37 deletions
src
|
@ -26,6 +26,7 @@ $background-color: hsla(0, 0, 99, 1); //#FDFDFD
|
|||
/* 3.0 colors */
|
||||
/* Using www naming convention for now, should be consistent with gui */
|
||||
$ui-aqua: hsla(163, 85, 40, 1); // #0FBD8C Extension Primary
|
||||
$ui-aqua-dark: hsla(163, 85, 30, 1); // #0B8E69 Extension Aqua 3
|
||||
$ui-purple: hsla(260, 100, 70, 1); // #9966FF Looks Primary
|
||||
$ui-purple-dark: hsla(260, 60, 60, 1); // #774DCB Looks Secondary
|
||||
$ui-magenta: hsla(300, 53%, 60%, 1); /* #CF63CF Sounds Primary */
|
||||
|
|
|
@ -6,21 +6,38 @@ const React = require('react');
|
|||
require('./button.scss');
|
||||
|
||||
const Button = props => {
|
||||
const classes = classNames('button', props.className);
|
||||
const classes = classNames('button', props.className, {'close-button': props.isCloseType});
|
||||
|
||||
return (
|
||||
<button
|
||||
className={classes}
|
||||
{...omit(props, ['className', 'children'])}
|
||||
{...omit(props, ['className', 'children', 'isCloseType'])}
|
||||
>
|
||||
{props.children}
|
||||
{
|
||||
props.isCloseType ? (
|
||||
<img
|
||||
alt="close-icon"
|
||||
className="modal-content-close-img"
|
||||
draggable="false"
|
||||
src="/svgs/modal/close-x.svg"
|
||||
/>
|
||||
) : [
|
||||
props.children
|
||||
]
|
||||
}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
Button.propTypes = {
|
||||
children: PropTypes.node,
|
||||
className: PropTypes.string
|
||||
className: PropTypes.string,
|
||||
isCloseType: PropTypes.bool
|
||||
};
|
||||
|
||||
Button.defaultProps = {
|
||||
className: '',
|
||||
isCloseType: false
|
||||
};
|
||||
|
||||
module.exports = Button;
|
||||
|
|
|
@ -53,3 +53,22 @@ $pass-bg: $ui-aqua;
|
|||
margin-right: -.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
.close-button {
|
||||
padding: 0;
|
||||
|
||||
position: absolute;
|
||||
top: 0.5rem;
|
||||
right: 0.5rem;
|
||||
border-radius: 1rem;
|
||||
background-color: $active-gray;
|
||||
cursor: pointer;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
text-align: center;
|
||||
line-height: 2rem;
|
||||
}
|
||||
|
||||
.close-button img {
|
||||
padding-top: 0.5rem;
|
||||
}
|
||||
|
|
56
src/views/splash/donate/donate-banner.jsx
Normal file
56
src/views/splash/donate/donate-banner.jsx
Normal file
|
@ -0,0 +1,56 @@
|
|||
const FormattedMessage = require('react-intl').FormattedMessage;
|
||||
const injectIntl = require('react-intl').injectIntl;
|
||||
const PropTypes = require('prop-types');
|
||||
const React = require('react');
|
||||
|
||||
const TitleBanner = require('../../../components/title-banner/title-banner.jsx');
|
||||
const Button = require('../../../components/forms/button.jsx');
|
||||
|
||||
require('./donate-banner.scss');
|
||||
|
||||
const navigateToDonatePage = () => {
|
||||
window.location = 'https://secure.donationpay.org/scratchfoundation';
|
||||
};
|
||||
|
||||
const DonateTopBanner = ({
|
||||
onRequestClose
|
||||
}) => (
|
||||
<TitleBanner className="donate-banner">
|
||||
<div className="donate-container">
|
||||
<img
|
||||
className="donate-icon"
|
||||
src="/images/ideas/try-it-icon.svg"
|
||||
/>
|
||||
<div className="donate-central-items">
|
||||
<p className="donate-text">
|
||||
<FormattedMessage id="donatebanner.askSupport" />
|
||||
</p>
|
||||
<Button
|
||||
className="donate-button"
|
||||
key="add-to-studio-button"
|
||||
onClick={navigateToDonatePage}
|
||||
>
|
||||
<FormattedMessage id="general.donate" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
isCloseType
|
||||
className="donate-close-button"
|
||||
key="closeButton"
|
||||
name="closeButton"
|
||||
type="button"
|
||||
onClick={onRequestClose}
|
||||
>
|
||||
<div className="action-button-text">
|
||||
<FormattedMessage id="general.close" />
|
||||
</div>
|
||||
</Button>
|
||||
</TitleBanner>
|
||||
);
|
||||
|
||||
DonateTopBanner.propTypes = {
|
||||
onRequestClose: PropTypes.func
|
||||
};
|
||||
|
||||
module.exports = injectIntl(DonateTopBanner);
|
77
src/views/splash/donate/donate-banner.scss
Normal file
77
src/views/splash/donate/donate-banner.scss
Normal file
|
@ -0,0 +1,77 @@
|
|||
@import "../../../colors";
|
||||
@import "../../../frameless";
|
||||
|
||||
$tile-height: 244px;
|
||||
|
||||
.donate-banner {
|
||||
display: flex;
|
||||
position: fixed;
|
||||
z-index: 8;
|
||||
background-color: $ui-aqua-dark;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.donate-container {
|
||||
display: flex;
|
||||
margin: 0.375rem auto;
|
||||
align-items: center;
|
||||
|
||||
.donate-icon {
|
||||
margin: 0.6875rem;
|
||||
width: 1.75rem;
|
||||
height: 1.75rem;
|
||||
}
|
||||
|
||||
.donate-central-items {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.donate-text {
|
||||
text-align: left;
|
||||
color: $ui-white;
|
||||
font-size: 1rem;
|
||||
font-weight: bold;
|
||||
margin-right: 1rem;
|
||||
max-width: 70vw;
|
||||
}
|
||||
|
||||
.donate-button {
|
||||
margin: 0 7rem 0 .5rem;
|
||||
border-radius: 1.25rem;
|
||||
background-color: $ui-white;
|
||||
color: $ui-aqua-dark;
|
||||
padding: 0 1.75rem;
|
||||
height: 2.25rem;
|
||||
text-decoration: none;
|
||||
line-height: .875rem;
|
||||
font-size: 1rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.donate-close-button {
|
||||
right: 1rem;
|
||||
top: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $mobileIntermediate) {
|
||||
.donate-banner .donate-container .donate-central-items {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.donate-banner .donate-container .donate-icon {
|
||||
padding-bottom: 2rem;
|
||||
}
|
||||
.donate-banner .donate-container .donate-button {
|
||||
margin-left: 0;
|
||||
margin-bottom: 1rem
|
||||
}
|
||||
.donate-banner .donate-close-button {
|
||||
top: 1rem;
|
||||
}
|
||||
}
|
|
@ -29,6 +29,8 @@
|
|||
"intro.watchVideo": "Watch Video",
|
||||
"news.scratchNews": "Scratch News",
|
||||
|
||||
"donatebanner.askSupport": "Scratch is the world's largest free coding community for kids. Your support makes a difference.",
|
||||
|
||||
"teacherbanner.greeting": "Hi",
|
||||
"teacherbanner.subgreeting": "Teacher Account",
|
||||
"teacherbanner.classesButton": "My Classes",
|
||||
|
|
|
@ -32,12 +32,10 @@ const LoveProjectMessage = require('./activity-rows/love-project.jsx');
|
|||
const RemixProjectMessage = require('./activity-rows/remix-project.jsx');
|
||||
const ShareProjectMessage = require('./activity-rows/share-project.jsx');
|
||||
|
||||
// Hour of Code Banner Components
|
||||
const TopBanner = require('./hoc/top-banner.jsx');
|
||||
const MiddleBanner = require('./hoc/middle-banner.jsx');
|
||||
|
||||
const HOC_START_TIME = 1605484800000; // 2020-11-16 00:00:00
|
||||
const HOC_END_TIME = 1608681600000; // 2020-12-23 00:00:00
|
||||
// Banner Components
|
||||
const DonateBanner = require('./donate/donate-banner.jsx');
|
||||
const HOCTopBanner = require('./hoc/top-banner.jsx');
|
||||
const HOCMiddleBanner = require('./hoc/middle-banner.jsx');
|
||||
|
||||
require('./splash.scss');
|
||||
|
||||
|
@ -352,6 +350,7 @@ class SplashPresentation extends React.Component { // eslint-disable-line react/
|
|||
|
||||
const formatHTMLMessage = this.props.intl.formatHTMLMessage;
|
||||
const formatMessage = this.props.intl.formatMessage;
|
||||
|
||||
const messages = {
|
||||
'general.viewAll': formatMessage({id: 'general.viewAll'}),
|
||||
'news.scratchNews': formatMessage({id: 'news.scratchNews'}),
|
||||
|
@ -412,21 +411,28 @@ class SplashPresentation extends React.Component { // eslint-disable-line react/
|
|||
/>
|
||||
] : []}
|
||||
{
|
||||
this.props.sessionStatus === sessionActions.Status.FETCHED &&
|
||||
Object.keys(this.props.user).length === 0 && (// Only show top banner if user is not logged in
|
||||
(Date.now() >= HOC_START_TIME && Date.now() < HOC_END_TIME) ? (
|
||||
<MediaQuery
|
||||
key="frameless-tablet"
|
||||
minWidth={frameless.tabletPortrait}
|
||||
>
|
||||
<TopBanner />
|
||||
</MediaQuery>
|
||||
) : (
|
||||
<Intro
|
||||
key="intro"
|
||||
messages={messages}
|
||||
/>
|
||||
)
|
||||
this.props.shouldShowHOCTopBanner && (
|
||||
<MediaQuery
|
||||
key="frameless-tablet"
|
||||
minWidth={frameless.tabletPortrait}
|
||||
>
|
||||
<HOCTopBanner />
|
||||
</MediaQuery>
|
||||
)
|
||||
}
|
||||
{
|
||||
this.props.shouldShowDonateBanner && (
|
||||
<DonateBanner
|
||||
onRequestClose={this.props.onCloseDonateBanner}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{
|
||||
this.props.shouldShowIntro && (
|
||||
<Intro
|
||||
key="intro"
|
||||
messages={messages}
|
||||
/>
|
||||
)
|
||||
}
|
||||
<div
|
||||
|
@ -464,17 +470,14 @@ class SplashPresentation extends React.Component { // eslint-disable-line react/
|
|||
{featured.shift()}
|
||||
</div>
|
||||
{
|
||||
this.props.sessionStatus === sessionActions.Status.FETCHED &&
|
||||
Object.keys(this.props.user).length !== 0 && // Only show if user is logged in
|
||||
Date.now() >= HOC_START_TIME && // Show middle banner on and after Dec 3
|
||||
Date.now() < HOC_END_TIME && // Hide middle banner after Dec 14
|
||||
false && // we did not use this middle banner in last HoC
|
||||
<MediaQuery
|
||||
key="frameless-desktop"
|
||||
minWidth={frameless.tabletPortrait}
|
||||
>
|
||||
<MiddleBanner />
|
||||
</MediaQuery>
|
||||
this.props.shouldShowHOCMiddleBanner && (
|
||||
<MediaQuery
|
||||
key="frameless-desktop"
|
||||
minWidth={frameless.tabletPortrait}
|
||||
>
|
||||
<HOCMiddleBanner />
|
||||
</MediaQuery>
|
||||
)
|
||||
}
|
||||
|
||||
<div
|
||||
|
@ -573,6 +576,7 @@ SplashPresentation.propTypes = {
|
|||
lovedByFollowing: PropTypes.arrayOf(PropTypes.object),
|
||||
news: PropTypes.arrayOf(PropTypes.object),
|
||||
onCloseAdminPanel: PropTypes.func.isRequired,
|
||||
onCloseDonateBanner: PropTypes.func.isRequired,
|
||||
onDismiss: PropTypes.func.isRequired,
|
||||
onHideEmailConfirmationModal: PropTypes.func.isRequired,
|
||||
onOpenAdminPanel: PropTypes.func.isRequired,
|
||||
|
@ -581,7 +585,11 @@ SplashPresentation.propTypes = {
|
|||
refreshCacheStatus: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
||||
sessionStatus: PropTypes.string.isRequired,
|
||||
sharedByFollowing: PropTypes.arrayOf(PropTypes.object),
|
||||
shouldShowDonateBanner: PropTypes.bool.isRequired,
|
||||
shouldShowEmailConfirmation: PropTypes.bool.isRequired,
|
||||
shouldShowHOCTopBanner: PropTypes.bool.isRequired,
|
||||
shouldShowIntro: PropTypes.bool.isRequired,
|
||||
shouldShowHOCMiddleBanner: PropTypes.bool.isRequired,
|
||||
shouldShowWelcome: PropTypes.bool.isRequired,
|
||||
user: PropTypes.object.isRequired // eslint-disable-line react/forbid-prop-types
|
||||
};
|
||||
|
|
|
@ -12,6 +12,11 @@ const splashActions = require('../../redux/splash.js');
|
|||
const Page = require('../../components/page/www/page.jsx');
|
||||
const SplashPresentation = require('./presentation.jsx');
|
||||
|
||||
const SCRATCH_WEEK_START_TIME = 1621224000000; // 2021-05-17 00:00:00
|
||||
const SCRATCH_WEEK_END_TIME = 1621828800000; // 2021-05-24 00:00:00
|
||||
const HOC_START_TIME = 1605484800000; // 2020-11-16 00:00:00
|
||||
const HOC_END_TIME = 1608681600000; // 2020-12-23 00:00:00
|
||||
|
||||
class Splash extends React.Component {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
|
@ -22,6 +27,7 @@ class Splash extends React.Component {
|
|||
'handleShowEmailConfirmationModal',
|
||||
'handleHideEmailConfirmationModal',
|
||||
'handleCloseAdminPanel',
|
||||
'handleCloseDonateBanner',
|
||||
'handleOpenAdminPanel',
|
||||
'handleDismiss',
|
||||
'shouldShowWelcome',
|
||||
|
@ -29,8 +35,9 @@ class Splash extends React.Component {
|
|||
]);
|
||||
this.state = {
|
||||
adminPanelOpen: false,
|
||||
dismissedDonateBanner: false,
|
||||
news: [], // gets news posts from the scratch Tumblr
|
||||
emailConfirmationModalOpen: false, // flag that determines whether to show banner to request email conf.
|
||||
emailConfirmationModalOpen: false,
|
||||
refreshCacheStatus: 'notrequested'
|
||||
};
|
||||
}
|
||||
|
@ -114,6 +121,9 @@ class Splash extends React.Component {
|
|||
handleOpenAdminPanel () {
|
||||
this.setState({adminPanelOpen: true});
|
||||
}
|
||||
handleCloseDonateBanner () {
|
||||
this.setState({dismissedDonateBanner: true});
|
||||
}
|
||||
handleShowEmailConfirmationModal () {
|
||||
this.setState({emailConfirmationModalOpen: true});
|
||||
}
|
||||
|
@ -144,8 +154,33 @@ class Splash extends React.Component {
|
|||
this.props.flags.confirm_email_banner
|
||||
);
|
||||
}
|
||||
shouldShowHOCTopBanner () {
|
||||
return (
|
||||
this.props.sessionStatus === sessionActions.Status.FETCHED && // done fetching session
|
||||
Object.keys(this.props.user).length === 0 && // no user session found
|
||||
Date.now() >= HOC_START_TIME &&
|
||||
Date.now() < HOC_END_TIME
|
||||
);
|
||||
}
|
||||
shouldShowHOCMiddleBanner () {
|
||||
return false; // we did not use this middle banner in last HoC
|
||||
}
|
||||
shouldShowDonateBanner () {
|
||||
return (
|
||||
this.state.dismissedDonateBanner === false &&
|
||||
this.props.sessionStatus === sessionActions.Status.FETCHED && // done fetching session
|
||||
Object.keys(this.props.user).length === 0 && // no user session found
|
||||
Date.now() >= SCRATCH_WEEK_START_TIME &&
|
||||
Date.now() < SCRATCH_WEEK_END_TIME &&
|
||||
this.shouldShowHOCTopBanner() !== true
|
||||
);
|
||||
}
|
||||
render () {
|
||||
const showEmailConfirmation = this.shouldShowEmailConfirmation() || false;
|
||||
const showDonateBanner = this.shouldShowDonateBanner() || false;
|
||||
const showHOCTopBanner = this.shouldShowHOCTopBanner() || false;
|
||||
const showHOCMiddleBanner = this.shouldShowHOCMiddleBanner() || false;
|
||||
const showIntro = showHOCTopBanner !== true;
|
||||
const showWelcome = this.shouldShowWelcome();
|
||||
const homepageRefreshStatus = this.getHomepageRefreshStatus();
|
||||
|
||||
|
@ -163,9 +198,14 @@ class Splash extends React.Component {
|
|||
refreshCacheStatus={homepageRefreshStatus}
|
||||
sessionStatus={this.props.sessionStatus}
|
||||
sharedByFollowing={this.props.shared}
|
||||
shouldShowDonateBanner={showDonateBanner}
|
||||
shouldShowEmailConfirmation={showEmailConfirmation}
|
||||
shouldShowHOCTopBanner={showHOCTopBanner}
|
||||
shouldShowIntro={showIntro}
|
||||
shouldShowHOCMiddleBanner={showHOCMiddleBanner}
|
||||
shouldShowWelcome={showWelcome}
|
||||
user={this.props.user}
|
||||
onCloseDonateBanner={this.handleCloseDonateBanner}
|
||||
onCloseAdminPanel={this.handleCloseAdminPanel}
|
||||
onDismiss={this.handleDismiss}
|
||||
onHideEmailConfirmationModal={this.handleHideEmailConfirmationModal}
|
||||
|
|
Loading…
Add table
Reference in a new issue