mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2025-03-25 20:29:45 -04:00
Merge pull request #1008 from mewtaylor/issue/gh-980
Implement GH-980: add new TTT modal component
This commit is contained in:
commit
25f61fdb77
25 changed files with 561 additions and 167 deletions
|
@ -72,7 +72,7 @@
|
|||
"react": "15.1.0",
|
||||
"react-dom": "15.0.1",
|
||||
"react-intl": "2.1.2",
|
||||
"react-modal": "1.3.0",
|
||||
"react-modal": "1.5.2",
|
||||
"react-onclickoutside": "4.1.1",
|
||||
"react-redux": "4.4.5",
|
||||
"react-responsive": "1.1.4",
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
var connect = require('react-redux').connect;
|
||||
var omit = require('lodash.omit');
|
||||
var React = require('react');
|
||||
|
||||
var sessionActions = require('../../redux/session.js');
|
||||
|
||||
var Modal = require('../modal/modal.jsx');
|
||||
var IframeModal = require('../modal/iframe/modal.jsx');
|
||||
var Registration = require('../registration/registration.jsx');
|
||||
|
||||
require('./intro.scss');
|
||||
|
||||
Modal.setAppElement(document.getElementById('view'));
|
||||
|
||||
var Intro = React.createClass({
|
||||
type: 'Intro',
|
||||
getDefaultProps: function () {
|
||||
|
@ -52,11 +49,6 @@ var Intro = React.createClass({
|
|||
this.closeRegistration();
|
||||
},
|
||||
render: function () {
|
||||
var frameProps = {
|
||||
width: 570,
|
||||
height: 357,
|
||||
padding: 15
|
||||
};
|
||||
return (
|
||||
<div className="intro">
|
||||
<div className="content">
|
||||
|
@ -130,15 +122,12 @@ var Intro = React.createClass({
|
|||
<img src="//cdn.scratch.mit.edu/scratchr2/static/images/hp-video-screenshot.png"
|
||||
alt="Intro Video" />
|
||||
</div>
|
||||
<Modal
|
||||
className="video-modal"
|
||||
isOpen={this.state.videoOpen}
|
||||
onRequestClose={this.closeVideo}
|
||||
style={{content:frameProps}}>
|
||||
<iframe
|
||||
src="//player.vimeo.com/video/65583694?title=0&byline=0&portrait=0"
|
||||
{...omit(frameProps, 'padding')} />
|
||||
</Modal>
|
||||
<IframeModal
|
||||
className="mod-intro-video"
|
||||
isOpen={this.state.videoOpen}
|
||||
onRequestClose={this.closeVideo}
|
||||
src="//player.vimeo.com/video/65583694?title=0&byline=0&portrait=0"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -241,3 +241,13 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal-content.mod-intro-video {
|
||||
padding: 15px;
|
||||
width: 35.625rem;
|
||||
}
|
||||
|
||||
.modal-content-iframe.mod-intro-video {
|
||||
width: 35.625rem;
|
||||
min-height: 22.3125rem;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ require('./microworld.scss');
|
|||
|
||||
var Box = require('../box/box.jsx');
|
||||
var Carousel = require('../carousel/carousel.jsx');
|
||||
var Modal = require('../modal/modal.jsx');
|
||||
var IframeModal = require('../modal/iframe/modal.jsx');
|
||||
var NestedCarousel = require('../nestedcarousel/nestedcarousel.jsx');
|
||||
|
||||
var Microworld = React.createClass({
|
||||
|
@ -50,11 +50,6 @@ var Microworld = React.createClass({
|
|||
);
|
||||
},
|
||||
renderVideo: function (video, key) {
|
||||
var frameProps = {
|
||||
width: 570,
|
||||
height: 357,
|
||||
padding: 15
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<div className="video">
|
||||
|
@ -62,14 +57,12 @@ var Microworld = React.createClass({
|
|||
</div>
|
||||
<img src={video.image} />
|
||||
</div>
|
||||
<Modal
|
||||
className="video-modal"
|
||||
<IframeModal
|
||||
className="mod-microworld-video"
|
||||
isOpen={this.state.videoOpen[key]}
|
||||
onRequestClose={this.markVideoClosed.bind(this, key)}
|
||||
style={{content:frameProps}}>
|
||||
<iframe src={video.link} width="560" height="315" frameBorder="0"
|
||||
webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
</Modal>
|
||||
src={video.link}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
|
|
@ -8,6 +8,19 @@ $base-bg: $ui-white;
|
|||
padding: 0;
|
||||
}
|
||||
|
||||
.modal-content.mod-microworld-video,
|
||||
.modal-content-iframe.mod-microworld-video {
|
||||
width: 35.625rem;
|
||||
}
|
||||
|
||||
.modal-content.mod-microworld-video {
|
||||
padding: 2.5rem;
|
||||
}
|
||||
|
||||
.modal-content-iframe.mod-microworld-video {
|
||||
height: 22.3125rem;
|
||||
}
|
||||
|
||||
.microworld {
|
||||
.sectionheader {
|
||||
margin: 0 auto;
|
||||
|
|
56
src/components/modal/base/modal.jsx
Normal file
56
src/components/modal/base/modal.jsx
Normal file
|
@ -0,0 +1,56 @@
|
|||
var classNames = require('classnames');
|
||||
var omit = require('lodash.omit');
|
||||
var React = require('react');
|
||||
var ReactModal = require('react-modal');
|
||||
|
||||
require('./modal.scss');
|
||||
|
||||
ReactModal.setAppElement(document.getElementById('view'));
|
||||
|
||||
/**
|
||||
* Container for pop up windows (See: registration window)
|
||||
*/
|
||||
var Modal = React.createClass({
|
||||
type: 'Modal',
|
||||
propTypes: {
|
||||
className: React.PropTypes.string,
|
||||
overlayClassName: React.PropTypes.string
|
||||
},
|
||||
requestClose: function () {
|
||||
return this.modal.portal.requestClose();
|
||||
},
|
||||
render: function () {
|
||||
var modalClasses = classNames(
|
||||
'modal-content',
|
||||
this.props.className
|
||||
);
|
||||
var overlayClasses = classNames(
|
||||
'modal-overlay',
|
||||
this.props.overlayClassName
|
||||
);
|
||||
|
||||
return (
|
||||
<ReactModal
|
||||
ref={
|
||||
function (component) {
|
||||
this.modal = component;
|
||||
}.bind(this)
|
||||
}
|
||||
className={modalClasses}
|
||||
overlayClassName={overlayClasses}
|
||||
{...omit(this.props, ['className', 'overlayClassName'])}
|
||||
>
|
||||
<div className="modal-content-close" onClick={this.requestClose}>
|
||||
<img
|
||||
className="modal-content-close-img"
|
||||
src="/svgs/modal/close-x.svg"
|
||||
alt="close-icon"
|
||||
/>
|
||||
</div>
|
||||
{this.props.children}
|
||||
</ReactModal>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = Modal;
|
61
src/components/modal/base/modal.scss
Normal file
61
src/components/modal/base/modal.scss
Normal file
|
@ -0,0 +1,61 @@
|
|||
@import "../../../colors";
|
||||
@import "../../../frameless";
|
||||
|
||||
.modal-content {
|
||||
position: relative;
|
||||
margin: 3.75rem auto;
|
||||
border-radius: 1rem;
|
||||
box-shadow: 0 0 0 1px $active-gray;
|
||||
background-color: $ui-white;
|
||||
padding: 0;
|
||||
width: 48.75rem;
|
||||
}
|
||||
|
||||
.modal-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 100;
|
||||
background-color: transparentize($ui-blue, .3);
|
||||
}
|
||||
|
||||
.ReactModal__Content:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
$modal-close-size: 1rem;
|
||||
.modal-content-close {
|
||||
position: absolute;
|
||||
top: $modal-close-size / 2;
|
||||
right: $modal-close-size / 2;
|
||||
border-radius: $modal-close-size;
|
||||
background-color: $active-dark-gray;
|
||||
cursor: pointer;
|
||||
width: $modal-close-size * 2;
|
||||
height: $modal-close-size * 2;
|
||||
text-align: center;
|
||||
line-height: $modal-close-size * 2;
|
||||
}
|
||||
|
||||
.modal-content-close-img {
|
||||
padding-top: $modal-close-size / 2;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $desktop - 1) {
|
||||
.modal-content {
|
||||
top: 0;
|
||||
left: 0;
|
||||
margin-top: 0;
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.modal-content-close {
|
||||
position: fixed;
|
||||
}
|
||||
}
|
34
src/components/modal/iframe/modal.jsx
Normal file
34
src/components/modal/iframe/modal.jsx
Normal file
|
@ -0,0 +1,34 @@
|
|||
var classNames = require('classnames');
|
||||
var omit = require('lodash.omit');
|
||||
var React = require('react');
|
||||
|
||||
var Modal = require('../base/modal.jsx');
|
||||
|
||||
require('./modal.scss');
|
||||
|
||||
var IframeModal = React.createClass({
|
||||
propTypes: {
|
||||
isOpen: React.PropTypes.bool,
|
||||
onRequestClose: React.PropTypes.func,
|
||||
className: React.PropTypes.string,
|
||||
componentRef: React.PropTypes.func,
|
||||
src: React.PropTypes.string
|
||||
},
|
||||
render: function () {
|
||||
var iframeClasses = classNames(
|
||||
'modal-content-iframe',
|
||||
this.props.className
|
||||
);
|
||||
return (
|
||||
<Modal {...omit(this.props, ['src'])}>
|
||||
<iframe
|
||||
ref={this.props.componentRef}
|
||||
src={this.props.src}
|
||||
className={iframeClasses}
|
||||
/>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = IframeModal;
|
5
src/components/modal/iframe/modal.scss
Normal file
5
src/components/modal/iframe/modal.scss
Normal file
|
@ -0,0 +1,5 @@
|
|||
@import "../../../frameless";
|
||||
|
||||
.modal-content-iframe {
|
||||
border: 0;
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
var clone = require('lodash.clone');
|
||||
var defaultsDeep = require('lodash.defaultsdeep');
|
||||
var React = require('react');
|
||||
var ReactModal = require('react-modal');
|
||||
|
||||
require('./modal.scss');
|
||||
|
||||
var defaultStyle = {
|
||||
overlay: {
|
||||
zIndex: 100,
|
||||
backgroundColor: 'rgba(0, 0, 0, .75)'
|
||||
},
|
||||
content: {
|
||||
position: 'absolute',
|
||||
overflow: 'visible',
|
||||
borderRadius: '6px',
|
||||
width: 500,
|
||||
height: 250,
|
||||
padding: 0,
|
||||
top: '50%',
|
||||
right: 'auto',
|
||||
bottom: 'auto',
|
||||
left: '50%',
|
||||
marginTop: -125,
|
||||
marginLeft: -250
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Container for pop up windows (See: registration window)
|
||||
*/
|
||||
var Modal = React.createClass({
|
||||
type: 'Modal',
|
||||
statics: {
|
||||
setAppElement: ReactModal.setAppElement
|
||||
},
|
||||
getDefaultProps: function () {
|
||||
return {
|
||||
style: defaultStyle
|
||||
};
|
||||
},
|
||||
calculateStyle: function () {
|
||||
var style = clone(this.props.style, true);
|
||||
defaultsDeep(style, defaultStyle);
|
||||
style.content.marginTop = (style.content.height + style.content.padding*2) / -2;
|
||||
style.content.marginLeft = (style.content.width + style.content.padding*2) / -2;
|
||||
return style;
|
||||
},
|
||||
requestClose: function () {
|
||||
return this.refs.modal.portal.requestClose();
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<ReactModal ref="modal"
|
||||
{...this.props}
|
||||
style={this.calculateStyle()}>
|
||||
<div className="modal-close" onClick={this.requestClose}></div>
|
||||
{this.props.children}
|
||||
</ReactModal>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = Modal;
|
|
@ -1,34 +0,0 @@
|
|||
@import "../../colors";
|
||||
|
||||
.ReactModal__Content {
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
iframe {
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-close {
|
||||
$modal-close-size: 20px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
margin-top: -$modal-close-size / 2;
|
||||
margin-right: -$modal-close-size / 2;
|
||||
border: 2px solid $ui-border;
|
||||
border-radius: $modal-close-size / 2;
|
||||
background-color: $active-dark-gray;
|
||||
cursor: pointer;
|
||||
width: $modal-close-size;
|
||||
height: $modal-close-size;
|
||||
text-align: center;
|
||||
line-height: $modal-close-size;
|
||||
color: $type-white;
|
||||
font-size: $modal-close-size;
|
||||
|
||||
&:before {
|
||||
content: "x";
|
||||
}
|
||||
}
|
121
src/components/modal/ttt/modal.jsx
Normal file
121
src/components/modal/ttt/modal.jsx
Normal file
|
@ -0,0 +1,121 @@
|
|||
var FormattedMessage = require('react-intl').FormattedMessage;
|
||||
var MediaQuery = require('react-responsive');
|
||||
var omit = require('lodash.omit');
|
||||
var React = require('react');
|
||||
|
||||
var FlexRow = require('../../flex-row/flex-row.jsx');
|
||||
var frameless = require('../../../lib/frameless');
|
||||
var Modal = require('../base/modal.jsx');
|
||||
var TitleBanner = require('../../title-banner/title-banner.jsx');
|
||||
|
||||
require('../../forms/button.scss');
|
||||
require('./modal.scss');
|
||||
|
||||
var TTTModal = React.createClass({
|
||||
propTypes: {
|
||||
title: React.PropTypes.string.isRequired,
|
||||
description: React.PropTypes.string.isRequired,
|
||||
tutorialLoc: React.PropTypes.string.isRequired,
|
||||
activityLoc: React.PropTypes.string.isRequired,
|
||||
guideLoc: React.PropTypes.string.isRequired,
|
||||
thumbUrl: React.PropTypes.string.isRequired,
|
||||
bannerUrl: React.PropTypes.string.isRequired
|
||||
},
|
||||
render: function () {
|
||||
var modalOmit = [
|
||||
'title',
|
||||
'description',
|
||||
'tutorialLoc',
|
||||
'activityLoc',
|
||||
'guideLoc',
|
||||
'thumbUrl',
|
||||
'bannerUrl'
|
||||
];
|
||||
return (
|
||||
<Modal
|
||||
className="mod-ttt"
|
||||
{...omit(this.props, modalOmit)}
|
||||
>
|
||||
<TitleBanner className="mod-ttt">
|
||||
<MediaQuery minWidth={frameless.mobile}>
|
||||
<img className="mod-ttt-img" src={this.props.bannerUrl} alt="" />
|
||||
</MediaQuery>
|
||||
<MediaQuery maxWidth={frameless.mobile - 1}>
|
||||
<img className="mod-ttt-img" src={this.props.thumbUrl} alt="" />
|
||||
</MediaQuery>
|
||||
</TitleBanner>
|
||||
<div className="ttt-title">
|
||||
<h2>{this.props.title}</h2>
|
||||
<p className="ttt-description">{this.props.description}</p>
|
||||
</div>
|
||||
<ul className="modal-content-ttt">
|
||||
<FlexRow as="li" className="mod-ttt-item">
|
||||
<div className="modal-content-ttt-text">
|
||||
<div className="modal-content-ttt-title">
|
||||
<img
|
||||
className="modal-content-ttt-title-img"
|
||||
src="/svgs/ttt/tutorial.svg"
|
||||
alt="tutorial-icon"
|
||||
/>
|
||||
<FormattedMessage id="ttt.tutorialTitle" />
|
||||
</div>
|
||||
<p className="modal-content-ttt-subtitle">
|
||||
<FormattedMessage id="ttt.tutorialSubtitle" />
|
||||
</p>
|
||||
</div>
|
||||
<a
|
||||
href={this.props.tutorialLoc}
|
||||
className="button white mod-ttt-item"
|
||||
>
|
||||
<FormattedMessage id="ttt.tryIt" />
|
||||
</a>
|
||||
</FlexRow>
|
||||
<FlexRow as="li" className="mod-ttt-item">
|
||||
<div className="modal-content-ttt-text">
|
||||
<div className="modal-content-ttt-title">
|
||||
<img
|
||||
className="modal-content-ttt-title-img"
|
||||
src="/svgs/ttt/activity-cards.svg"
|
||||
alt="activity-cards-icon"
|
||||
/>
|
||||
<FormattedMessage id="ttt.activityTitle" />
|
||||
</div>
|
||||
<p className="modal-content-ttt-subtitle">
|
||||
<FormattedMessage id="ttt.activitySubtitle" />
|
||||
</p>
|
||||
</div>
|
||||
<a
|
||||
href={this.props.activityLoc}
|
||||
className="button white mod-ttt-item"
|
||||
>
|
||||
<FormattedMessage id="ttt.download" />
|
||||
</a>
|
||||
</FlexRow>
|
||||
<FlexRow as="li" className="mod-ttt-item">
|
||||
<div className="modal-content-ttt-text">
|
||||
<div className="modal-content-ttt-title">
|
||||
<img
|
||||
className="modal-content-ttt-title-img"
|
||||
src="/svgs/ttt/educator-guide.svg"
|
||||
alt="educator-guide-icon"
|
||||
/>
|
||||
<FormattedMessage id="ttt.educatorTitle" />
|
||||
</div>
|
||||
<p className="modal-content-ttt-subtitle">
|
||||
<FormattedMessage id="ttt.educatorSubtitle" />
|
||||
</p>
|
||||
</div>
|
||||
<a
|
||||
href={this.props.guideLoc}
|
||||
className="button white mod-ttt-item"
|
||||
>
|
||||
<FormattedMessage id="ttt.download" />
|
||||
</a>
|
||||
</FlexRow>
|
||||
</ul>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = TTTModal;
|
97
src/components/modal/ttt/modal.scss
Normal file
97
src/components/modal/ttt/modal.scss
Normal file
|
@ -0,0 +1,97 @@
|
|||
@import "../../../colors";
|
||||
@import "../../../frameless";
|
||||
|
||||
.modal-content.mod-ttt {
|
||||
overflow: hidden; // Needed to put banner background behind border.
|
||||
}
|
||||
|
||||
.title-banner.mod-ttt {
|
||||
margin-bottom: 0;
|
||||
background-color: transparent;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.mod-ttt-img {
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ttt-title {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ttt-description {
|
||||
margin: 0;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.modal-content-ttt {
|
||||
padding: 0 5rem;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.flex-row.mod-ttt-item {
|
||||
margin: 0;
|
||||
border-top: 1px dashed $ui-border;
|
||||
padding: .5rem;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.modal-content-ttt-text {
|
||||
max-width: 70%;
|
||||
}
|
||||
|
||||
.modal-content-ttt-title,
|
||||
.modal-content-ttt-subtitle {
|
||||
margin: 0;
|
||||
font-size: .875rem;
|
||||
}
|
||||
|
||||
.modal-content-ttt-title {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.modal-content-ttt-title-img {
|
||||
margin-right: .25rem;
|
||||
width: 1.25rem;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.button.white.mod-ttt-item {
|
||||
border: 1px solid $ui-blue;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $mobile - 1) {
|
||||
.modal-content.mod-ttt {
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.modal-content-ttt {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.modal-content-ttt {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: $mobile) and (max-width: $tablet - 1) {
|
||||
.modal-content.mod-ttt {
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.modal-content-ttt {
|
||||
padding: 0 2.5rem;
|
||||
}
|
||||
|
||||
.flex-row.mod-ttt-item {
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: $tablet) and (max-width: $desktop - 1) {
|
||||
.modal-content.mod-ttt {
|
||||
overflow: scroll;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
var React = require('react');
|
||||
|
||||
var NavigationBox = require('../container/navigation.jsx');
|
||||
var NavigationBox = require('../base/navigation.jsx');
|
||||
|
||||
require('./navigation.scss');
|
||||
|
||||
|
|
|
@ -15,14 +15,12 @@ var Form = require('../../forms/form.jsx');
|
|||
var Input = require('../../forms/input.jsx');
|
||||
var log = require('../../../lib/log.js');
|
||||
var Login = require('../../login/login.jsx');
|
||||
var Modal = require('../../modal/modal.jsx');
|
||||
var NavigationBox = require('../container/navigation.jsx');
|
||||
var Modal = require('../../modal/base/modal.jsx');
|
||||
var NavigationBox = require('../base/navigation.jsx');
|
||||
var Registration = require('../../registration/registration.jsx');
|
||||
|
||||
require('./navigation.scss');
|
||||
|
||||
Modal.setAppElement(document.getElementById('view'));
|
||||
|
||||
var Navigation = React.createClass({
|
||||
type: 'Navigation',
|
||||
getInitialState: function () {
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
var React = require('react');
|
||||
var Modal = require('../modal/modal.jsx');
|
||||
var IframeModal = require('../modal/iframe/modal.jsx');
|
||||
|
||||
require('./registration.scss');
|
||||
|
||||
Modal.setAppElement(document.getElementById('view'));
|
||||
|
||||
var Registration = React.createClass({
|
||||
propTypes: {
|
||||
isOpen: React.PropTypes.bool,
|
||||
|
@ -13,10 +11,10 @@ var Registration = React.createClass({
|
|||
},
|
||||
onMessage: function (e) {
|
||||
if (e.origin != window.location.origin) return;
|
||||
if (e.source != this.refs.registrationIframe.contentWindow) return;
|
||||
if (e.source != this.registrationIframe.contentWindow) return;
|
||||
if (e.data == 'registration-done') this.props.onRegistrationDone();
|
||||
if (e.data == 'registration-relaunch') {
|
||||
this.refs.registrationIframe.contentWindow.location.reload();
|
||||
this.registrationIframe.contentWindow.location.reload();
|
||||
}
|
||||
},
|
||||
toggleMessageListener: function (present) {
|
||||
|
@ -36,18 +34,18 @@ var Registration = React.createClass({
|
|||
this.toggleMessageListener(false);
|
||||
},
|
||||
render: function () {
|
||||
var frameProps = {
|
||||
width: 610,
|
||||
height: 438
|
||||
};
|
||||
return (
|
||||
<Modal
|
||||
isOpen={this.props.isOpen}
|
||||
onRequestClose={this.props.onRequestClose}
|
||||
className="registration"
|
||||
style={{content:frameProps}}>
|
||||
<iframe ref="registrationIframe" src="/accounts/standalone-registration/" {...frameProps} />
|
||||
</Modal>
|
||||
<IframeModal
|
||||
isOpen={this.props.isOpen}
|
||||
onRequestClose={this.props.onRequestClose}
|
||||
className="mod-registration"
|
||||
componentRef={
|
||||
function (iframe) {
|
||||
this.registrationIframe = iframe;
|
||||
}.bind(this)
|
||||
}
|
||||
src="/accounts/standalone-registration/"
|
||||
/>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,3 +1,22 @@
|
|||
.registration {
|
||||
@import "../../frameless";
|
||||
|
||||
.modal-content.mod-registration {
|
||||
width: 38.125rem;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.modal-content-iframe.mod-registration {
|
||||
width: 38.125rem;
|
||||
min-height: 27.375rem;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $desktop - 1) {
|
||||
.modal-content.mod-registration {
|
||||
width: 100%;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.modal-content-iframe.mod-registration {
|
||||
height: 27.375rem;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
var connect = require('react-redux').connect;
|
||||
var injectIntl = require('react-intl').injectIntl;
|
||||
var omit = require('lodash.omit');
|
||||
var React = require('react');
|
||||
|
||||
var api = require('../../lib/api');
|
||||
|
@ -16,7 +15,7 @@ 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 IframeModal = require('../../components/modal/iframe/modal.jsx');
|
||||
var News = require('../../components/news/news.jsx');
|
||||
var Page = require('../../components/page/www/page.jsx');
|
||||
var TeacherBanner = require('../../components/teacher-banner/teacher-banner.jsx');
|
||||
|
@ -36,7 +35,7 @@ var Splash = injectIntl(React.createClass({
|
|||
news: [], // gets news posts from the scratch Tumblr
|
||||
featuredCustom: {}, // custom homepage rows, such as "Projects by Scratchers I'm Following"
|
||||
featuredGlobal: {}, // global homepage rows, such as "Featured Projects"
|
||||
showEmailConfirmationModal: false, // flag that determines whether to show banner to request email conf.
|
||||
showEmailConfirmationModal: true, // flag that determines whether to show banner to request email conf.
|
||||
refreshCacheStatus: 'notrequested'
|
||||
};
|
||||
},
|
||||
|
@ -81,7 +80,7 @@ var Splash = injectIntl(React.createClass({
|
|||
},
|
||||
onMessage: function (e) {
|
||||
if (e.origin != window.location.origin) return;
|
||||
if (e.source != this.refs.emailConfirmationiFrame.contentWindow) return;
|
||||
if (e.source != this.emailConfirmationiFrame.contentWindow) return;
|
||||
if (e.data == 'resend-done') {
|
||||
this.hideEmailConfirmationModal();
|
||||
} else {
|
||||
|
@ -308,7 +307,6 @@ var Splash = injectIntl(React.createClass({
|
|||
},
|
||||
render: function () {
|
||||
var featured = this.renderHomepageRows();
|
||||
var emailConfirmationStyle = {width: 500, height: 330, padding: 1};
|
||||
var homepageCacheState = this.getHomepageRefreshStatus();
|
||||
|
||||
var formatHTMLMessage = this.props.intl.formatHTMLMessage;
|
||||
|
@ -344,21 +342,26 @@ var Splash = injectIntl(React.createClass({
|
|||
return (
|
||||
<div className="splash">
|
||||
{this.shouldShowEmailConfirmation() ? [
|
||||
<DropdownBanner key="confirmedEmail"
|
||||
className="warning"
|
||||
onRequestDismiss={this.handleDismiss.bind(this, 'confirmed_email')}>
|
||||
<DropdownBanner
|
||||
key="confirmedEmail"
|
||||
className="warning"
|
||||
onRequestDismiss={this.handleDismiss.bind(this, 'confirmed_email')}
|
||||
>
|
||||
<a href="#" onClick={this.showEmailConfirmationModal}>Confirm your email</a>
|
||||
{' '}to enable sharing.{' '}
|
||||
<a href="/info/faq/#accounts">Having trouble?</a>
|
||||
</DropdownBanner>,
|
||||
<Modal key="emailConfirmationModal"
|
||||
isOpen={this.state.emailConfirmationModalOpen}
|
||||
onRequestClose={this.hideEmailConfirmationModal}
|
||||
style={{content: emailConfirmationStyle}}>
|
||||
<iframe ref="emailConfirmationiFrame"
|
||||
src="/accounts/email_resend_standalone/"
|
||||
{...omit(emailConfirmationStyle, 'padding')} />
|
||||
</Modal>
|
||||
<IframeModal
|
||||
isOpen={this.state.emailConfirmationModalOpen}
|
||||
onRequestClose={this.hideEmailConfirmationModal}
|
||||
className="mod-confirmation"
|
||||
componentRef={
|
||||
function (iframe) {
|
||||
this.emailConfirmationiFrame = iframe;
|
||||
}.bind(this)
|
||||
}
|
||||
src="/accounts/email_resend_standalone/"
|
||||
/>
|
||||
] : []}
|
||||
{this.props.permissions.educator ? [
|
||||
<TeacherBanner key="teacherbanner" messages={messages} />
|
||||
|
|
|
@ -42,6 +42,16 @@
|
|||
}
|
||||
}
|
||||
|
||||
.modal-content.mod-confirmation {
|
||||
width: 31.25rem;
|
||||
}
|
||||
|
||||
.modal-content-iframe.mod-confirmation {
|
||||
border-radius: 1rem;
|
||||
width: 31.25rem;
|
||||
min-height: 20.625rem;
|
||||
}
|
||||
|
||||
//4 columns
|
||||
@media only screen and (max-width: $mobile - 1) {
|
||||
.splash {
|
||||
|
@ -54,6 +64,15 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal-content.mod-confirmation {
|
||||
width: 100%;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.modal-content-iframe.mod-confirmation {
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
//6 columns
|
||||
|
@ -68,6 +87,16 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal-content.mod-confirmation {
|
||||
width: 100%;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.modal-content-iframe.mod-confirmation {
|
||||
border-radius: 0;
|
||||
width: $tablet - 1;
|
||||
}
|
||||
}
|
||||
|
||||
//6 columns
|
||||
|
|
17
static/svgs/modal/close-x.svg
Normal file
17
static/svgs/modal/close-x.svg
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="16px" height="16px" viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;}
|
||||
</style>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st0" d="M12.5,10.3c0.6,0.6,0.6,1.5,0,2.1c-0.3,0.3-0.7,0.4-1.1,0.4c-0.4,0-0.8-0.1-1.1-0.4L8,10.1l-2.3,2.3
|
||||
c-0.3,0.3-0.7,0.4-1.1,0.4c-0.4,0-0.8-0.1-1.1-0.4c-0.6-0.6-0.6-1.5,0-2.1L5.9,8L3.5,5.7C3,5.1,3,4.1,3.5,3.5
|
||||
C4.1,3,5.1,3,5.7,3.5L8,5.9l2.3-2.3c0.6-0.6,1.5-0.6,2.1,0c0.6,0.6,0.6,1.5,0,2.1L10.1,8L12.5,10.3z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After (image error) Size: 801 B |
18
static/svgs/ttt/activity-cards.svg
Normal file
18
static/svgs/ttt/activity-cards.svg
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="16px" height="16px" viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#4C95FF;}
|
||||
</style>
|
||||
<g>
|
||||
<path class="st0" d="M6.9,12.5h5.2c-0.1,0.1-0.3,0.2-0.4,0.2l-5.5,1.8c-0.2,0.1-0.3,0.1-0.5,0.1c-0.6,0-1.2-0.4-1.4-1L2,6.6
|
||||
C1.7,5.9,2.1,5,2.9,4.7l1.7-0.6v6.1C4.6,11.5,5.6,12.5,6.9,12.5z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st0" d="M12.6,1.4H6.9C6,1.4,5.3,2.1,5.3,2.9v7.3c0,0.8,0.7,1.5,1.5,1.5h5.8c0.8,0,1.5-0.7,1.5-1.5V2.9
|
||||
C14.1,2.1,13.4,1.4,12.6,1.4z M12.7,9.8c0,0.3-0.2,0.6-0.6,0.6h-5c-0.3,0-0.6-0.3-0.6-0.6V6c0-0.3,0.3-0.6,0.6-0.6h5
|
||||
c0.3,0,0.6,0.3,0.6,0.6V9.8z M12.2,4H7.3C7,4,6.7,3.8,6.7,3.5c0-0.3,0.3-0.6,0.6-0.6h4.9c0.3,0,0.6,0.3,0.6,0.6
|
||||
C12.7,3.8,12.5,4,12.2,4z"/>
|
||||
</g>
|
||||
</svg>
|
After (image error) Size: 1,010 B |
15
static/svgs/ttt/educator-guide.svg
Normal file
15
static/svgs/ttt/educator-guide.svg
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="16px" height="16px" viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#4C95FF;}
|
||||
</style>
|
||||
<path class="st0" d="M10,9.3h2.3l-3.8,3.9v-2.3C8.5,10,9.2,9.3,10,9.3z"/>
|
||||
<path class="st0" d="M10.9,2.8H5.1c-0.8,0-1.5,0.7-1.5,1.5v7.3c0,0.8,0.7,1.5,1.5,1.5h2.7v-2.3c0-1.2,1-2.3,2.3-2.3h2.3V4.3
|
||||
C12.4,3.5,11.7,2.8,10.9,2.8z M7.3,7.9H5.7c-0.3,0-0.6-0.3-0.6-0.6s0.3-0.6,0.6-0.6h1.7c0.3,0,0.6,0.2,0.6,0.6S7.7,7.9,7.3,7.9z
|
||||
M10.4,5.6H5.7C5.3,5.6,5.1,5.3,5.1,5c0-0.3,0.3-0.6,0.6-0.6h4.7c0.3,0,0.6,0.3,0.6,0.6C10.9,5.3,10.7,5.6,10.4,5.6z"/>
|
||||
<g>
|
||||
<path class="st0" d="M12.4,9.3l-3.8,3.9v-2.3c0-0.8,0.7-1.5,1.5-1.5H12.4z"/>
|
||||
</g>
|
||||
</svg>
|
After (image error) Size: 955 B |
16
static/svgs/ttt/tutorial.svg
Normal file
16
static/svgs/ttt/tutorial.svg
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="16px" height="16px" viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#4C95FF;}
|
||||
</style>
|
||||
<path class="st0" d="M2,2.8h1.3c0.1,0,0.3,0.1,0.3,0.1l0.7,0.7c0.1,0.1,0.2,0.1,0.3,0.1h1.6c0.1,0,0.3-0.1,0.3-0.1L7.2,3
|
||||
c0.1-0.1,0.2-0.1,0.3-0.1H14c0.3,0,0.5,0.2,0.5,0.5v3c0,0.3-0.2,0.5-0.5,0.5H7.6c-0.1,0-0.3,0.1-0.3,0.1L6.5,7.6
|
||||
C6.5,7.7,6.3,7.8,6.2,7.8H4.6c-0.1,0-0.3-0.1-0.3-0.1L3.6,6.9C3.5,6.9,3.4,6.8,3.2,6.8H2c-0.3,0-0.5-0.2-0.5-0.5v-3
|
||||
C1.5,3.1,1.7,2.8,2,2.8z"/>
|
||||
<path class="st0" d="M2,8.2h1.3c0.1,0,0.3,0.1,0.3,0.1l0.7,0.7c0.1,0.1,0.2,0.1,0.3,0.1h1.6c0.1,0,0.3-0.1,0.3-0.1l0.7-0.7
|
||||
c0.1-0.1,0.2-0.1,0.3-0.1h3.1c0.3,0,0.5,0.2,0.5,0.5v3c0,0.3-0.2,0.5-0.5,0.5H7.6c-0.1,0-0.3,0.1-0.3,0.1L6.5,13
|
||||
c-0.1,0.1-0.2,0.1-0.3,0.1H4.6c-0.1,0-0.3-0.1-0.3-0.1l-0.7-0.7c-0.1-0.1-0.2-0.1-0.3-0.1H2c-0.3,0-0.5-0.2-0.5-0.5v-3
|
||||
C1.5,8.4,1.7,8.2,2,8.2z"/>
|
||||
</svg>
|
After (image error) Size: 1.1 KiB |
Loading…
Add table
Reference in a new issue