diff --git a/src/components/banner/banner.jsx b/src/components/banner/banner.jsx new file mode 100644 index 000000000..adc45654b --- /dev/null +++ b/src/components/banner/banner.jsx @@ -0,0 +1,29 @@ +var classNames = require('classnames'); +var React = require('react'); + +require('./banner.scss'); + +var Banner = React.createClass({ + type: 'Banner', + propTypes: { + onRequestDismiss: React.PropTypes.func + }, + render: function () { + var classes = classNames( + 'banner', + this.props.className + ); + return ( +
+
+ {this.props.children} + {this.props.onRequestDismiss ? [ + x + ] : []} +
+
+ ); + } +}); + +module.exports = Banner; diff --git a/src/components/banner/banner.scss b/src/components/banner/banner.scss new file mode 100644 index 000000000..4164171e2 --- /dev/null +++ b/src/components/banner/banner.scss @@ -0,0 +1,41 @@ +@import "../../colors"; + +$navigation-height: 50px; + +.banner { + position: fixed; + top: $navigation-height; + z-index: 99; + box-shadow: 0 1px 1px $ui-dark-gray; + background-color: $ui-orange; + width: 100%; + overflow: hidden; + text-align: center; + line-height: $navigation-height; + + &, a { + color: $ui-white; + } + + a { + text-decoration: underline; + } + + .close { + float: right; + margin-top: $navigation-height/4; + border-radius: $navigation-height/4; + background-color: $box-shadow-gray; + width: $navigation-height/2; + height: $navigation-height/2; + text-decoration: none; + text-shadow: none; + line-height: $navigation-height/2; + color: $ui-white; + font-weight: normal; + } + + &.warning { + background-color: $ui-orange; + } +} diff --git a/src/components/box/box.jsx b/src/components/box/box.jsx index ce6222e04..b85d8e71b 100644 --- a/src/components/box/box.jsx +++ b/src/components/box/box.jsx @@ -1,3 +1,4 @@ +var classNames = require('classnames'); var React = require('react'); require('./box.scss'); @@ -11,8 +12,12 @@ var Box = React.createClass({ moreProps: React.PropTypes.object }, render: function () { + var classes = classNames( + 'box', + this.props.className + ); return ( -
+

{this.props.title}

diff --git a/src/components/carousel/carousel.jsx b/src/components/carousel/carousel.jsx index 1a0bd6711..6df20b26b 100644 --- a/src/components/carousel/carousel.jsx +++ b/src/components/carousel/carousel.jsx @@ -1,3 +1,4 @@ +var classNames = require('classnames'); var defaults = require('lodash.defaults'); var React = require('react'); var Slider = require('react-slick'); @@ -31,9 +32,12 @@ var Carousel = React.createClass({ variableWidth: true }); var arrows = this.props.items.length > settings.slidesToShow; - + var classes = classNames( + 'carousel', + this.props.className + ); return ( - + {this.props.items.map(function (item) { var href = ''; switch (item.type) { diff --git a/src/components/navigation/navigation.jsx b/src/components/navigation/navigation.jsx index c1e33087f..d88701e5f 100644 --- a/src/components/navigation/navigation.jsx +++ b/src/components/navigation/navigation.jsx @@ -317,7 +317,7 @@ var Navigation = React.createClass({ + style={{content:{padding: 15}}}>

Your Account Will Not Be Deleted

Your account was scheduled for deletion but you logged in. Your account has been reactivated. diff --git a/src/views/hoc/hoc.jsx b/src/views/hoc/hoc.jsx index 2423cc60c..f98fe4d3c 100644 --- a/src/views/hoc/hoc.jsx +++ b/src/views/hoc/hoc.jsx @@ -1,3 +1,4 @@ +var classNames = require('classnames'); var React = require('react'); var render = require('../../lib/render.jsx'); @@ -20,9 +21,13 @@ var Hoc = React.createClass({ }); }, render: function () { + var classes = classNames( + 'top-banner', + this.state.bgClass + ); return (

-
+

Get Creative with Coding

With Scratch, you can program your own stories, games, and animations — diff --git a/src/views/splash/splash.jsx b/src/views/splash/splash.jsx index 95d3b9036..b3d7cbb83 100644 --- a/src/views/splash/splash.jsx +++ b/src/views/splash/splash.jsx @@ -1,4 +1,5 @@ var injectIntl = require('react-intl').injectIntl; +var omit = require('lodash.omit'); var React = require('react'); var render = require('../../lib/render.jsx'); @@ -7,10 +8,12 @@ var Session = require('../../mixins/session.jsx'); var Activity = require('../../components/activity/activity.jsx'); var AdminPanel = require('../../components/adminpanel/adminpanel.jsx'); +var Banner = require('../../components/banner/banner.jsx'); var Box = require('../../components/box/box.jsx'); var Button = require('../../components/forms/button.jsx'); var Carousel = require('../../components/carousel/carousel.jsx'); var Intro = require('../../components/intro/intro.jsx'); +var Modal = require('../../components/modal/modal.jsx'); var News = require('../../components/news/news.jsx'); var Welcome = require('../../components/welcome/welcome.jsx'); @@ -28,7 +31,8 @@ var Splash = injectIntl(React.createClass({ activity: [], news: [], featuredCustom: {}, - featuredGlobal: {} + featuredGlobal: {}, + showEmailConfirmationModal: false }; }, componentDidUpdate: function (prevProps, prevState) { @@ -43,6 +47,11 @@ var Splash = injectIntl(React.createClass({ this.setState({news: []}); this.getProjectCount(); } + if (this.shouldShowEmailConfirmation()) { + window.addEventListener('message', this.onMessage); + } else { + window.removeEventListener('message', this.onMessage); + } } }, componentDidMount: function () { @@ -54,6 +63,22 @@ var Splash = injectIntl(React.createClass({ } else { this.getProjectCount(); } + if (this.shouldShowEmailConfirmation()) window.addEventListener('message', this.onMessage); + }, + componentWillUnmount: function () { + window.removeEventListener('message', this.onMessage); + }, + onMessage: function (e) { + if (e.origin != window.location.origin) return; + if (e.source != this.refs.emailConfirmationiFrame.contentWindow) return; + if (e.data == 'resend-done') { + this.hideEmailConfirmationModal(); + } else { + var data = JSON.parse(e.data); + if (data['action'] === 'leave-page') { + window.location.href = data['uri']; + } + } }, getActivity: function () { this.api({ @@ -90,6 +115,12 @@ var Splash = injectIntl(React.createClass({ if (!err) this.setState({projectCount: body.count}); }.bind(this)); }, + showEmailConfirmationModal: function () { + this.setState({emailConfirmationModalOpen: true}); + }, + hideEmailConfirmationModal: function () { + this.setState({emailConfirmationModalOpen: false}); + }, handleDismiss: function (cue) { this.api({ host: '', @@ -108,6 +139,11 @@ var Splash = injectIntl(React.createClass({ new Date(new Date - 2*7*24*60*60*1000) // Two weeks ago ); }, + shouldShowEmailConfirmation: function () { + return ( + this.state.session.user && this.state.session.flags.has_outstanding_email_confirmation && + this.state.session.flags.confirm_email_banner); + }, renderHomepageRows: function () { var formatMessage = this.props.intl.formatMessage; @@ -249,58 +285,78 @@ var Splash = injectIntl(React.createClass({ }, render: function () { var featured = this.renderHomepageRows(); + var emailConfirmationStyle = {width: 500, height: 330, padding: 1}; return ( -

- {this.state.session.user ? [ -
- {this.shouldShowWelcome() ? [ - - ] : [ - - ]} - -
- ] : [ - - ]} +
+ {this.shouldShowEmailConfirmation() ? [ + + Confirm your email + {' '}to enable sharing.{' '} + Having trouble? + , + +