Merge branch 'develop' into microworlds_projects

This commit is contained in:
morantsur 2016-12-20 13:02:46 -05:00 committed by GitHub
commit e95caef368
40 changed files with 384 additions and 89 deletions

View file

@ -5,7 +5,7 @@
"eol-last": [2],
"indent": [2, 4],
"linebreak-style": [2, "unix"],
"max-len": [2, 120, 4],
"max-len": [2, 120, 4, {"ignoreUrls": true}],
"no-trailing-spaces": [2, { "skipBlankLines": true }],
"no-unused-vars": [2, {"args": "after-used", "varsIgnorePattern": "^_"}],
"quotes": [2, "single"],

View file

@ -5,6 +5,7 @@
"ast": "Asturianu",
"id": "Bahasa Indonesia",
"ms": "Bahasa Melayu",
"be": "Беларуская",
"bg": "Български",
"ca": "Català",
"cs": "Česky",

View file

@ -1,4 +1,5 @@
var defaults = require('lodash.defaultsdeep');
var intl = require('../../lib/intl.jsx');
var libphonenumber = require('google-libphonenumber');
var phoneNumberUtil = libphonenumber.PhoneNumberUtil.getInstance();
var React = require('react');
@ -44,5 +45,5 @@ module.exports.validationHOCFactory = function (defaultValidationErrors) {
};
module.exports.defaultValidationHOC = module.exports.validationHOCFactory({
isDefaultRequiredValue: 'This field is required'
isDefaultRequiredValue: <intl.FormattedMessage id="form.validationRequired" />
});

View file

@ -23,7 +23,9 @@ var InformationPage = React.createClass({
<div className="information-page">
<TitleBanner className="masthead">
<div className="inner">
<h1>{this.props.title}</h1>
<h1 className="title-banner-h1">
{this.props.title}
</h1>
</div>
</TitleBanner>
<div className={classes}>

View file

@ -36,7 +36,8 @@ var Navigation = React.createClass({
},
getDefaultProps: function () {
return {
session: {}
session: {},
searchTerm: ''
};
},
componentDidMount: function () {
@ -221,6 +222,7 @@ var Navigation = React.createClass({
<Form onSubmit={this.onSearchSubmit}>
<Button type="submit" className="btn-search" />
<Input type="text"
value={this.props.searchTerm}
aria-label={formatMessage({id: 'general.search'})}
placeholder={formatMessage({id: 'general.search'})}
name="q" />
@ -345,7 +347,8 @@ var Navigation = React.createClass({
var mapStateToProps = function (state) {
return {
session: state.session,
permissions: state.permissions
permissions: state.permissions,
searchTerm: state.navigation
};
};

View file

@ -93,7 +93,7 @@ module.exports = {
callback = callback || function () {};
if (!username) {
this.refs.form.refs.formsy.updateInputsWithError({
'user.username': formatMessage({id: 'teacherRegistration.validationRequired'})
'user.username': this.props.intl.formatMessage({id: 'form.validationRequired'})
});
return callback(false);
}
@ -360,11 +360,9 @@ module.exports = {
options={[
{value: 'female', label: formatMessage({id: 'general.female'})},
{value: 'male', label: formatMessage({id: 'general.male'})},
{value: 'other', label: ''}
]}
required />
<div className="gender-input">
<Input name="user.genderOther"
{value: 'other', label: <Input
className="demographics-step-input-other"
name="user.genderOther"
type="text"
validations={{
maxLength: 25
@ -376,8 +374,10 @@ module.exports = {
}}
disabled={this.state.otherDisabled}
required={!this.state.otherDisabled}
help={null} />
</div>
help={null}
/>}
]}
required />
<Select label={formatMessage({id: 'general.country'})}
name="user.country"
options={getCountryOptions(this.props.intl, DEFAULT_COUNTRY)}
@ -457,7 +457,7 @@ module.exports = {
onValidSubmit: function (formData, reset, invalidate) {
if (!formData.phone || formData.phone.national_number === '+') {
return invalidate({
'phone': this.props.intl.formatMessage({id: 'teacherRegistration.validationRequired'})
'phone': this.props.intl.formatMessage({id: 'form.validationRequired'})
});
}
return this.props.onNextStep(formData);
@ -582,7 +582,7 @@ module.exports = {
}}
validationErrors={{
minLength: formatMessage({
id: 'teacherRegistration.validationRequired'
id: 'form.validationRequired'
})
}}
required />

View file

@ -13,7 +13,6 @@
border-radius: 8px;
}
.gender-input,
.other-input {
float: right;
width: 90%;
@ -61,17 +60,20 @@
}
&.demographics-step {
.gender-input {
margin-top: -5.5rem;
.radio {
margin: 1.5rem 1.5rem 0 0;
}
.radio {
margin-right: 2.5rem;
line-height: 3rem;
input {
input[type="radio"] {
margin-right: 1rem;
}
.demographics-step-input-other {
display: inline-block;
.col-sm-9 {
display: inline-block;
}
}
}

View file

@ -39,7 +39,10 @@ var TeacherBanner = React.createClass({
{this.props.messages['teacherbanner.greeting']},{' '}
{this.props.session.session.user.username}
</h3>,
<p key="subgreeting">
<p
key="subgreeting"
className="title-banner-p"
>
{this.props.messages['teacherbanner.subgreeting']}
</p>
] : []

View file

@ -7,7 +7,7 @@
&.title-banner {
transition: none;
margin-bottom: 20px;
margin-bottom: 0;
text-align: left;
h3,

View file

@ -9,23 +9,23 @@
background-size: cover;
padding: 20px 0;
width: 100%;
}
h1,
p {
.title-banner-h1,
.title-banner-p {
margin: 0 auto;
padding: 5px 0;
text-align: center;
color: $type-white;
}
}
p {
.title-banner-p {
max-width: 500px;
}
}
// On windows strong gets reset to font-weight 500, so make sure to override for banners
strong {
// On windows strong gets reset to font-weight 500, so make sure to override for banners
.title-banner-strong {
font-weight: 700;
}
}
.title-banner.mod-blue-bg {

View file

@ -26,7 +26,7 @@ var TTTTile = React.createClass({
<div className="ttt-tile-image">
<img className="ttt-tile-image-img" src={this.props.thumbUrl} alt="" />
<div className="ttt-tile-image-try">
<div className="button mod-ttt-tile-image-try-button">
<div className="button mod-ttt-try-button">
<FormattedMessage id="tile.tryIt" />
</div>
</div>

View file

@ -54,10 +54,10 @@
left: 50%;
transform: translate(-50%, 0);
text-align: center;
color: $ui-white;
color: $type-white;
}
.mod-ttt-tile-image-try-button {
.mod-ttt-try-button {
border: 1px solid $ui-white;
background-color: transparent;
}

View file

@ -93,6 +93,8 @@
"footer.help": "Help Page",
"footer.scratchFamily": "Scratch Family",
"form.validationRequired": "This field is required",
"login.forgotPassword": "Forgot Password?",
"navigation.signOut": "Sign out",
@ -108,6 +110,7 @@
"registration.choosePasswordStepTitle": "Create a password",
"registration.choosePasswordStepTooltip": "Don't use your name or anything that's easy for someone else to guess.",
"registration.classroomApiGeneralError": "Sorry, we could not find the registration information for this class",
"registration.generalError": "Sorry, an unexpected error occurred.",
"registration.classroomInviteExistingStudentStepDescription": "you have been invited to join the class:",
"registration.classroomInviteNewStudentStepDescription": "has invited you to join the class:",
"registration.confirmYourEmail": "Confirm Your Email",

24
src/redux/navigation.js Normal file
View file

@ -0,0 +1,24 @@
var keyMirror = require('keymirror');
var Types = keyMirror({
SET_SEARCH_TERM: null
});
module.exports.navigationReducer = function (state, action) {
if(typeof state === 'undefined') {
state = '';
}
switch (action.type) {
case Types.SET_SEARCH_TERM:
return action.searchTerm;
default:
return state;
}
};
module.exports.setSearchTerm = function (searchTerm) {
return {
type: Types.SET_SEARCH_TERM,
searchTerm: searchTerm
};
};

View file

@ -4,12 +4,14 @@ var scheduleReducer = require('./conference-schedule.js').scheduleReducer;
var detailsReducer = require('./conference-details.js').detailsReducer;
var permissionsReducer = require('./permissions.js').permissionsReducer;
var sessionReducer = require('./session.js').sessionReducer;
var navigationReducer = require('./navigation.js').navigationReducer;
var appReducer = combineReducers({
session: sessionReducer,
permissions: permissionsReducer,
conferenceSchedule: scheduleReducer,
conferenceDetails: detailsReducer
conferenceDetails: detailsReducer,
navigation: navigationReducer
});
module.exports = appReducer;

View file

@ -6,6 +6,11 @@
"view": "splash/splash",
"title": "Imagine, Program, Share"
},
{
"name": "splash-redirect",
"pattern": "^///?$",
"redirect": "/"
},
{
"name": "about",
"pattern": "^/about/?$",

View file

@ -18,8 +18,10 @@ var Developers = React.createClass({
<div className="developers">
<TitleBanner className="masthead">
<div className="inner">
<h1><FormattedMessage id='developers.title' /></h1>
<p className="intro">
<h1 className="title-banner-h1">
<FormattedMessage id='developers.title' />
</h1>
<p className="title-banner-p intro">
<FormattedHTMLMessage id='developers.intro' />
</p>
</div>

View file

@ -137,7 +137,7 @@ var Explore = injectIntl(React.createClass({
<div className='outer'>
<TitleBanner className="masthead">
<div className="inner">
<h1><FormattedMessage id='general.explore' /></h1>
<h1 className="title-banner-h1"><FormattedMessage id='general.explore' /></h1>
</div>
</TitleBanner>
<Tabs>

View file

@ -195,6 +195,8 @@ var Faq = injectIntl(React.createClass({
<dd><FormattedHTMLMessage id='faq.edBody' /></dd>
<dt><FormattedMessage id='faq.dataTitle' /></dt>
<dd><FormattedMessage id='faq.dataBody' /></dd>
<dt><FormattedMessage id='faq.lawComplianceTitle' /></dt>
<dd><FormattedMessage id='faq.lawComplianceBody' /></dd>
</dl>
<i><FormattedHTMLMessage id='faq.schoolsMoreInfo' /></i>
</section>

View file

@ -13,7 +13,7 @@
"faq.makeGameTitle":"How do I make a game or animation with Scratch?",
"faq.makeGameBody":"Check out the <a href= \"/help \">help page</a> to see lots of ways to get started with Scratch. Or just <a href= \"/projects/editor/?tip_bar=getStarted \">dive in</a> to the project editor.",
"faq.requirementsTitle":"What are the system requirements for Scratch?",
"faq.requirementsBody":"To run Scratch 2, you need to be using (1) a Mac, Linux, or Windows computer; (2) a version of <a href= \" \">Adobe Flash Player</a> released on or after June 15, 2016; (3) a relatively recent web browser: one of the latest two versions of <a href=\"http://google.com/chrome/\">Chrome</a>, <a href=\"http://www.mozilla.org/en-US/firefox/new/\">Firefox</a>, <a href=\"https://support.apple.com/downloads/safari\">Safari</a> (Mac or Windows only), <a href=\"https://www.microsoft.com/EN-US/windows/microsoft-edge\">Edge</a> (Windows only), or <a href=\"https://www.microsoft.com/en-us/download/internet-explorer.aspx\">Internet Explorer 10+</a> (Windows only). If your computer doesnt meet these requirements, you can try downloading and installing <a href=\"/scratch_1.4\">Scratch 1.4</a>, which you can still use to share projects to the Scratch 2 website.",
"faq.requirementsBody":"To run Scratch 2, you need to be using (1) a Mac, Linux, or Windows computer; (2) a version of <a href= \" \">Adobe Flash Player</a> released on or after June 15, 2016; (3) a relatively recent web browser: one of the latest two versions of <a href=\"http://google.com/chrome/\">Chrome</a> (Mac, Windows, or Linux), <a href=\"http://www.mozilla.org/en-US/firefox/new/\">Firefox</a> (Mac or Windows only), <a href=\"https://support.apple.com/downloads/safari\">Safari</a> (Mac or Windows only), <a href=\"https://www.microsoft.com/EN-US/windows/microsoft-edge\">Edge</a> (Windows only), or <a href=\"https://www.microsoft.com/en-us/download/internet-explorer.aspx\">Internet Explorer 10+</a> (Windows only). If your computer doesnt meet these requirements, you can try downloading and installing <a href=\"/scratch_1.4\">Scratch 1.4</a>, which you can still use to share projects to the Scratch 2 website. We do not support Chromium.",
"faq.offlineTitle":"Do you have a downloadable version so I can create and view projects offline?",
"faq.offlineBody":"The Scratch 2 offline editor allows you to create Scratch projects without an internet connection. You can download Scratch 2 from the <a href= \"/scratch2download/ \">website</a>. You can also still use <a href = \"/scratch_1.4 \">Scratch 1.4</a>. Note: You can have both Scratch 1.4 and 2 on your computer.",
"faq.uploadOldTitle":"Can I still upload projects created with older versions of Scratch to the website?",
@ -135,6 +135,8 @@
"faq.edTitle":"What is the difference between a Scratch Teacher Account and a ScratchEd Account?",
"faq.edBody":"Scratch Teacher Accounts are special user accounts on Scratch that have access to additional features to facilitate the creation and management of student accounts. ScratchEd Accounts are accounts on the <a href=\"http://scratched.gse.harvard.edu/\">ScratchEd community</a>, a separate website (managed by the Harvard Graduate School of Education) where educators share stories, exchange resources, ask questions, and meet other Scratch educators.",
"faq.dataTitle":"What data does Scratch collect about students?",
"faq.dataBody":"When a student first signs up on Scratch, we ask for basic demographic data including gender, age (birth month and year), country, and an email address for verification. This data is used (in aggregated form) in research studies intended to improve our understanding of how people learn with Scratch. When an educator uses a Scratch Teacher Account to create student accounts in bulk, no student demographic data is required for account setup.",
"faq.dataBody":"When a student first signs up on Scratch, we ask for basic demographic data including gender, age (birth month and year), country, and an email address for verification. This data is used (in aggregated form) in research studies intended to improve our understanding of how people learn with Scratch. When an educator uses a Scratch Teacher Account to create student accounts in bulk, students are not required to provide an email address for account setup.",
"faq.lawComplianceTitle":"Is Scratch 2.0 (online version) compliant with local and federal data privacy laws?",
"faq.lawComplianceBody":"Scratch cares deeply about the privacy of students and of all individuals who use our platform. We have in place physical and electronic procedures to protect the information we collect on the Scratch website. Although we are not in a position to offer contractual guarantees with each entity that uses our free educational product, we are in compliance with all federal laws that are applicable to MIT, a 501(c)(3) organization and the entity that created and maintains Scratch. We encourage you to read the Scratch Privacy Policy for more information.",
"faq.schoolsMoreInfo":"For more more questions about Teacher Accounts, see the <a href=\"/educators/faq\">Teacher Account FAQ</a>"
}

View file

@ -1,6 +1,7 @@
var injectIntl = require('react-intl').injectIntl;
var FormattedMessage = require('react-intl').FormattedMessage;
var React = require('react');
var connect = require('react-redux').connect;
var render = require('../../lib/render.jsx');
var api = require('../../lib/api');
@ -12,6 +13,7 @@ var Input = require('../../components/forms/input.jsx');
var Button = require('../../components/forms/button.jsx');
var Tabs = require('../../components/tabs/tabs.jsx');
var Grid = require('../../components/grid/grid.jsx');
var navigationActions = require('../../redux/navigation.js');
require('./search.scss');
@ -53,6 +55,7 @@ var Search = injectIntl(React.createClass({
},
componentDidMount: function () {
this.getSearchMore();
this.props.dispatch(navigationActions.setSearchTerm(this.props.searchTerm));
},
getSearchMore: function () {
var termText = '';
@ -103,7 +106,7 @@ var Search = injectIntl(React.createClass({
<div className='outer'>
<TitleBanner className="masthead">
<div className="inner">
<h1><FormattedMessage id="general.search" /></h1>
<h1 className="title-banner-h1"><FormattedMessage id="general.search" /></h1>
<div className="search">
<Form onSubmit={this.onSearchSubmit}>
<Button type="submit" className="btn-search" />
@ -138,4 +141,12 @@ var Search = injectIntl(React.createClass({
}
}));
render(<Page><Search /></Page>, document.getElementById('app'));
var mapStateToProps = function (state) {
return {
navigation: state.searchTerm
};
};
var ConnectedSearch = connect(mapStateToProps)(Search);
render(<Page><ConnectedSearch /></Page>, document.getElementById('app'));

View file

@ -0,0 +1,54 @@
var FormattedMessage = require('react-intl').FormattedMessage;
var React = require('react');
var Button = require('../../../components/forms/button.jsx');
var FlexRow = require('../../../components/flex-row/flex-row.jsx');
require('./hoc-event-row.scss');
var HocEventRow = React.createClass({
type: 'HocEventRow',
propTypes: {
onDismiss: React.PropTypes.func
},
render: function () {
return (
<div className="hoc-event">
<Button
className="mod-hoc-event-dismiss"
onClick={this.props.onDismiss}
>
<FormattedMessage id="hocevent.dismiss" />
<img
className="hoc-event-dismiss-icon"
src="/svgs/modal/close-x.svg"
alt="close-icon"
/>
</Button>
<FlexRow className="mod-hoc-event">
<div className="hoc-event-studio">
<h1 className="hoc-event-studio-h1">
<FormattedMessage id="hocevent.title" />
</h1>
<a href="/studios/3600717/" className="button white mod-hoc-event">
<FormattedMessage id="hocevent.studioLink" />
</a>
</div>
<div className="hoc-event-video">
<iframe
className="hoc-event-video-iframe"
title="Design a Character Studio"
src="https://www.youtube-nocookie.com/embed/_srMcH7oB3Y?rel=0"
frameborder="0"
webkitAllowFullScreen
mozallowfullscreen
allowFullScreen
/>
</div>
</FlexRow>
</div>
);
}
});
module.exports = HocEventRow;

View file

@ -0,0 +1,127 @@
@import "../../../colors";
@import "../../../frameless";
.hoc-event {
position: relative;
opacity: .9;
margin: 0 auto 20px;
border-radius: 1rem;
background-color: $ui-blue;
width: $cols12;
}
.hoc-event:after {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
opacity: .5;
z-index: -1;
border-radius: 1rem;
background: url("/images/splash/hoc-event-bg.jpg");
background-size: cover;
content: "";
}
.flex-row.mod-hoc-event {
padding: 3rem 5rem;
}
.button.mod-hoc-event-dismiss {
position: absolute;
top: .5rem;
right: .5rem;
margin: 0;
border: 1px solid $type-white;
border-radius: 2rem;
box-shadow: none;
background-color: transparent;
padding: .25rem .75rem;
color: $type-white;
font-weight: 300;
}
.hoc-event-dismiss-icon {
margin-left: .25rem;
width: .8rem;
vertical-align: middle;
}
.hoc-event-studio-h1 {
margin-bottom: 1.5rem;
line-height: 2.5rem;
color: $type-white;
}
.button.mod-hoc-event {
padding: .75rem 1.75rem;
}
.hoc-event-studio,
.hoc-event-video-iframe {
width: 23.75rem;
}
.hoc-event-video-iframe {
border: 3px solid $ui-border;
border-radius: 5px;
height: 13.75rem;
}
@media only screen and (max-width: $mobile - 1) {
.hoc-event {
width: $cols4;
}
.flex-row.mod-hoc-event {
padding: 3rem 2rem 2rem;
}
.hoc-event-studio,
.hoc-event-video-iframe {
width: 13.75rem;
}
.hoc-event-studio {
margin-bottom: 1rem;
}
.hoc-event-video-iframe {
height: 8.75rem;
}
}
@media only screen and (min-width: $mobile) and (max-width: $tablet - 1) {
.hoc-event {
width: $cols6;
}
.flex-row.mod-hoc-event {
padding: 2.5rem 2.5rem 1.5rem;
}
.hoc-event-studio {
margin-bottom: 1rem;
}
}
@media only screen and (min-width: $tablet) and (max-width: $desktop - 1) {
.hoc-event {
width: $cols8;
}
.flex-row.mod-hoc-event {
padding: 1.875rem;
}
.hoc-event-studio {
width: 14.625rem;
text-align: left;
}
.hoc-event-video-iframe {
width: 18.375rem;
height: 10rem;
}
}

View file

@ -28,6 +28,10 @@
"teacherbanner.classesButton": "My Classes",
"teacherbanner.faqButton": "Teacher Account FAQ",
"hocevent.dismiss": "Dismiss",
"hocevent.title": "Design and share your own character",
"hocevent.studioLink": "See the studio",
"welcome.welcomeToScratch": "Welcome to Scratch!",
"welcome.learn": "Learn how to make a project in Scratch",
"welcome.tryOut": "Try out starter projects",

View file

@ -14,6 +14,7 @@ var DropdownBanner = require('../../components/dropdown-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 HocEventRow = require('./hoc-event-row/hoc-event-row.jsx');
var Intro = require('../../components/intro/intro.jsx');
var IframeModal = require('../../components/modal/iframe/modal.jsx');
var News = require('../../components/news/news.jsx');
@ -207,6 +208,14 @@ var Splash = injectIntl(React.createClass({
</Box>
];
if (this.props.session.session.user && this.props.session.session.flags.show_hoc_studio) {
rows.push(
<HocEventRow
onDismiss={this.handleDismiss.bind(this, 'show_hoc_studio')}
/>
);
}
if (this.state.featuredGlobal.curator_top_projects &&
this.state.featuredGlobal.curator_top_projects.length > 4) {
@ -366,7 +375,7 @@ var Splash = injectIntl(React.createClass({
{this.props.permissions.educator ? [
<TeacherBanner key="teacherbanner" messages={messages} />
] : []}
<div key="inner" className="inner">
<div key="inner" className="inner mod-splash">
{this.props.session.status === sessionActions.Status.FETCHED ? (
this.props.session.session.user ? [
<div key="header" className="splash-header">

View file

@ -1,5 +1,13 @@
@import "../../frameless";
#view {
padding: 0;
}
.inner.mod-splash {
margin-top: 20px;
}
.splash {
.splash-header {
display: flex;
@ -33,10 +41,6 @@
}
}
.teacher-banner {
margin-top: -20px;
}
.box {
margin-bottom: 20px;
}

View file

@ -86,11 +86,18 @@ var StudentCompleteRegistration = intl.injectIntl(React.createClass({
method: 'post',
useCsrf: true,
formData: submittedData
}, function (err, body) {
}, function (err, body, res) {
this.setState({waiting: false});
if (err) return this.setState({registrationError: err});
if (body.success) return this.advanceStep(formData);
this.setState({registrationErrors: body.errors});
this.setState({
registrationErrors:
body.errors || {
__all__:
this.props.intl.formatMessage({id: 'registration.generalError'}) +
' (' + res.statusCode + ')'
}
});
}.bind(this));
},
goToClass: function () {

View file

@ -78,11 +78,15 @@ var StudentRegistration = intl.injectIntl(React.createClass({
classroom_id: this.props.classroomId,
classroom_token: this.props.classroomToken
}
}, function (err, res) {
}, function (err, body, res) {
this.setState({waiting: false});
if (err) return this.setState({registrationError: err});
if (res[0].success) return this.advanceStep(formData);
this.setState({registrationError: res[0].msg});
if (body[0] && body[0].success) return this.advanceStep(formData);
this.setState({
registrationError:
(body[0] && body[0].msg) ||
this.props.intl.formatMessage({id: 'registration.generalError'}) + ' (' + res.statusCode + ')'
});
}.bind(this));
},
goToClass: function () {

View file

@ -39,6 +39,5 @@
"teacherRegistration.howUseScratch": "How do you plan to use Scratch at your organization?",
"teacherRegistration.emailStepTitle": "Email Address",
"teacherRegistration.emailStepDescription": "We will send you a confirmation email that will allow you to access your Scratch Teacher Account.",
"teacherRegistration.validationEmailMatch": "The emails do not match",
"teacherRegistration.validationRequired": "This field is required"
"teacherRegistration.validationEmailMatch": "The emails do not match"
}

View file

@ -4,6 +4,7 @@ var React = require('react');
var render = require('../../lib/render.jsx');
var api = require('../../lib/api');
var intl = require('../../lib/intl.jsx');
var sessionActions = require('../../redux/session.js');
var Deck = require('../../components/deck/deck.jsx');
@ -13,7 +14,7 @@ var Steps = require('../../components/registration/steps.jsx');
require('./teacherregistration.scss');
var TeacherRegistration = React.createClass({
var TeacherRegistration = intl.injectIntl(React.createClass({
type: 'TeacherRegistration',
getInitialState: function () {
return {
@ -66,16 +67,19 @@ var TeacherRegistration = React.createClass({
address_zip: this.state.formData.address.zip,
how_use_scratch: this.state.formData.useScratch
}
}, function (err, res) {
}, function (err, body, res) {
this.setState({waiting: false});
if (err) return this.setState({registrationError: err});
if (res[0].success) {
if (body[0] && body[0].success) {
this.props.dispatch(sessionActions.refreshSession());
return this.advanceStep(formData);
}
this.setState({registrationError: res[0].msg});
this.setState({
registrationError:
(body[0] && body[0].msg) ||
this.props.intl.formatMessage({id: 'registration.generalError'}) + ' (' + res.statusCode + ')'
});
}.bind(this));
},
render: function () {
var permissions = this.props.session.permissions || {};
@ -118,7 +122,7 @@ var TeacherRegistration = React.createClass({
</Deck>
);
}
});
}));
var mapStateToProps = function (state) {
return {

View file

@ -58,6 +58,10 @@ var TeacherFaq = injectIntl(React.createClass({
<dd><FormattedHTMLMessage id='teacherfaq.studentMultipleBody' /></dd>
<dt><FormattedMessage id='teacherfaq.studentDiscussTitle' /></dt>
<dd><FormattedHTMLMessage id='teacherfaq.studentDiscussBody' /></dd>
<dt><FormattedMessage id='teacherfaq.studentDataTitle' /></dt>
<dd><FormattedMessage id='teacherfaq.studentDataBody' /></dd>
<dt><FormattedMessage id='teacherfaq.studentPrivacyLawsTitle' /></dt>
<dd><FormattedMessage id='teacherfaq.studentPrivacyLawsBody' /></dd>
</dl>
</section>
<section id="community">

View file

@ -34,6 +34,10 @@
"teacherfaq.studentMultipleBody": "A student can only be a part of one class. However, we are looking into adding this functionality in later versions.",
"teacherfaq.studentDiscussTitle": "Is there a space to discuss Teacher Accounts with other teachers?",
"teacherfaq.studentDiscussBody": "Yes, you can engage in discussions with other teachers at <a href=\"http://scratched.gse.harvard.edu/\">ScratchEd</a>, an online community for Scratch educators. Check out their forums to join conversations about a <a href=\"http://scratched.gse.harvard.edu/discussions\">number of topics</a>, including but not limited to Teacher Accounts. ScratchEd is developed and supported by the Harvard Graduate School of Education.",
"teacherfaq.studentDataTitle": "What data does Scratch collect about students?",
"teacherfaq.studentDataBody": "When a student first signs up on Scratch, we ask for basic demographic data including gender, age (birth month and year), country, and an email address for verification. This data is used (in aggregated form) in research studies intended to improve our understanding of how people learn with Scratch. When an educator uses a Scratch Teacher Account to create student accounts in bulk, students are not required to provide an email address for account setup.",
"teacherfaq.studentPrivacyLawsTitle": "Is Scratch 2.0 (online version) compliant with local and federal data privacy laws?",
"teacherfaq.studentPrivacyLawsBody": "Scratch cares deeply about the privacy of students and of all individuals who use our platform. We have in place physical and electronic procedures to protect the information we collect on the Scratch website. Although we are not in a position to offer contractual guarantees with each entity that uses our free educational product, we are in compliance with all federal laws that are applicable to MIT, a 501(c)(3) organization and the entity that created and maintains Scratch. We encourage you to read the Scratch Privacy Policy for more information.",
"teacherfaq.commTitle": "Community",
"teacherfaq.commHiddenTitle": "Can I create a hidden class?",

View file

@ -13,8 +13,8 @@
"teacherlanding.meetupTitle": "In-Person Gatherings",
"teacherlanding.meetupDescription": "<a href=\"http://www.meetup.com/pro/scratched/\">Scratch Educator Meetups</a> are gatherings of Scratch Educators who want to learn with and from each other, sharing their ideas and strategies for supporting computational creativity in all its forms.",
"teacherlanding.guidesTitle": "Guides & Tutorials",
"teacherlanding.helpPage": "On the <a href=\"/help\">Help Page</a>, you can find workshop guides, Scratch Cards, videos, and other resources.",
"teacherlanding.tipsWindow" : "The <a href=\"/projects/editor/?tip_bar=home\">Tips Window</a> features step-by-step tutorials for getting started in Scratch.",
"teacherlanding.tttPage": "The <a href=\"/go\">Things to Try page</a> offers a variety of tutorials, activity cards, and educator guides.",
"teacherlanding.tipsWindow" : "The <a href=\"/projects/editor/?tip_bar=home\">Tips Window</a> provides help for creating projects in Scratch.",
"teacherlanding.creativeComputing": "The <a href=\"http://scratched.gse.harvard.edu/guide/\">Creative Computing Curriculum Guide</a> provides plans, activities, and strategies for introducing creative computing.",
"teacherlanding.accountsTitle": "Teacher Accounts in Scratch",
"teacherlanding.accountsDescription": "As an educator, you can request a Scratch Teacher Account, which makes it easier to create accounts for groups of students and to manage your students projects and comments. To learn more, see the <a href=\"/educators/faq\">Teacher Account FAQ page</a>.",

View file

@ -19,9 +19,11 @@ var Landing = injectIntl(React.createClass({
<div className="educators">
<TitleBanner className="masthead">
<div className="inner">
<h1><FormattedMessage id="teacherlanding.title" /></h1>
<h1 className="title-banner-h1">
<FormattedMessage id="teacherlanding.title" />
</h1>
<FlexRow className="masthead-info">
<p className="intro">
<p className="title-banner-p intro">
<FormattedMessage id="teacherlanding.intro" />
</p>
<div className="ted-talk">
@ -82,11 +84,11 @@ var Landing = injectIntl(React.createClass({
<h3 id="guides-header"><FormattedMessage id="teacherlanding.guidesTitle" /></h3>
<FlexRow className="guides-and-tutorials">
<div>
<a href="/help">
<a href="/go">
<img src="/svgs/teachers/resources.svg" alt="resources icon" />
</a>
<p>
<FormattedHTMLMessage id="teacherlanding.helpPage" />
<FormattedHTMLMessage id="teacherlanding.tttPage" />
</p>
</div>
<div>

View file

@ -4,7 +4,7 @@
"tile.tryIt": "Try It",
"ttt.placeholder": "Placeholder text",
"ttt.title": "Things to Try",
"ttt.subTitle": "You can get started with Scratch in a variety of ways. Click a picture to try the <strong>Tutorial</strong>. You can also download a set of <strong>Activity Cards</strong> and <strong>Educator Guide</strong> for each theme.",
"ttt.subTitle": "You can get started with Scratch in a variety of ways. Click a picture to try the <strong className=\"title-banner-strong\">Tutorial</strong>. You can also download a set of <strong className=\"title-banner-strong\">Activity Cards</strong> and <strong className=\"title-banner-strong\">Educator Guide</strong> for each theme.",
"ttt.tutorialTitle": "Tutorial",
"ttt.tutorialSubtitle": "Find out how to make this project using a step-by-step tutorial in Scratch.",
"ttt.activityTitle": "Activity Cards",

View file

@ -61,10 +61,10 @@ var ThingsToTry = injectIntl(React.createClass({
<section className="ttt-section">
<img className="ttt-banner-image" src="/svgs/ttt/resources.svg" alt=""/>
</section>
<h1>
<h1 className="title-banner-h1">
<FormattedMessage id="ttt.title" />
</h1>
<p className="intro">
<p className="intro title-banner-p">
<FormattedHTMLMessage id="ttt.subTitle" />
</p>
</TitleBanner>

View file

@ -1,9 +1,11 @@
{
"wedo2.intro": "The LEGO® Education WeDo 2.0 is an introductory invention kit you can use to build your own interactive machines. You can snap together Scratch programming blocks to interact with your LEGO WeDo creations and add animations on the screen.",
"wedo2.requirement": "The LEGO WeDo 2.0 extension is currently only available for Mac OSX. We plan to release a Windows version later in 2016.",
"wedo2.requirement": "The LEGO WeDo 2.0 extension is available for Mac OSX and Windows 10+.",
"wedo2.getStarted": "Getting Started with LEGO WeDo 2.0",
"wedo2.installTitle": "1. Install Device Manager",
"wedo2.installText": "The Device Manager lets you connect WeDo 2.0 to Scratch using Bluetooth <a href=\"https://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=1084869222&mt=12\">Download Here</a>",
"wedo2.installText": "The Device Manager lets you connect WeDo 2.0 to Scratch using Bluetooth",
"wedo2.downloadMac": "Download for Mac OSX",
"wedo2.downloadWin": "Download for Windows 10+",
"wedo2.setupTitle": "2. Setup & Help",
"wedo2.setupText": "Connect your WeDo 2.0 by following the steps in the <a href=\"/projects/editor/?tip_bar=ext2\">Tips Window</a>",
"wedo2.createTitle": "3. Create",

View file

@ -44,6 +44,14 @@ var Wedo2 = React.createClass({
</h4>
<p>
<FormattedHTMLMessage id='wedo2.installText' />
<br />
<a href="https://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=1084869222&mt=12">
<FormattedMessage id='wedo2.downloadMac' />
</a>
<br />
<a href="https://downloads.scratch.mit.edu/device-manager/ScratchDeviceManager-1.1.0.exe">
<FormattedMessage id='wedo2.downloadWin' />
</a>
</p>
</div>
<div className="column">

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB