mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2025-02-17 00:21:20 -05:00
Merge pull request #1134 from LLK/release/2.2.16
[Develop] Release 2.2.16
This commit is contained in:
commit
9e1c985ae5
14 changed files with 35 additions and 210 deletions
|
@ -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);
|
||||
}
|
||||
|
@ -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 />
|
||||
|
|
|
@ -62,10 +62,10 @@
|
|||
&.demographics-step {
|
||||
.radio {
|
||||
margin: 1.5rem 1.5rem 0 0;
|
||||
}
|
||||
|
||||
input {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
input[type="radio"] {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.demographics-step-input-other {
|
||||
|
|
|
@ -110,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",
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
{
|
||||
"name": "splash-redirect",
|
||||
"pattern": "^///?$",
|
||||
"routeAlias": "/?$",
|
||||
"redirect": "/"
|
||||
},
|
||||
{
|
||||
|
|
|
@ -135,7 +135,7 @@
|
|||
"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>"
|
||||
|
|
|
@ -1,115 +0,0 @@
|
|||
var FormattedMessage = require('react-intl').FormattedMessage;
|
||||
var injectIntl = require('react-intl').injectIntl;
|
||||
var MediaQuery = require('react-responsive');
|
||||
var React = require('react');
|
||||
|
||||
var FlexRow = require('../../../components/flex-row/flex-row.jsx');
|
||||
var TitleBanner = require('../../../components/title-banner/title-banner.jsx');
|
||||
var TTTModal = require('../../../components/modal/ttt/modal.jsx');
|
||||
var TTTTile = require('../../../components/ttt-tile/ttt-tile.jsx');
|
||||
|
||||
var frameless = require('../../../lib/frameless');
|
||||
var tiles = require('../../thingstotry/ttt');
|
||||
|
||||
require('../../../components/forms/button.scss');
|
||||
require('./hoc-banner.scss');
|
||||
|
||||
var HocBanner = injectIntl(React.createClass({
|
||||
getInitialState: function () {
|
||||
return {
|
||||
currentTile: tiles[1],
|
||||
TTTModalOpen: false
|
||||
};
|
||||
},
|
||||
showTTTModal: function (tile) {
|
||||
return this.setState({
|
||||
currentTile: tile,
|
||||
TTTModalOpen: true
|
||||
});
|
||||
},
|
||||
hideTTTModal: function () {
|
||||
return this.setState({TTTModalOpen: false});
|
||||
},
|
||||
renderTTTTiles: function () {
|
||||
var formatMessage = this.props.intl.formatMessage;
|
||||
|
||||
var tileObjects = {
|
||||
nameTile: {
|
||||
title: formatMessage({id: tiles[0].title}),
|
||||
description: formatMessage({id: tiles[0].description}),
|
||||
tutorialLoc: tiles[0].tutorialLoc,
|
||||
activityLoc: formatMessage({id: tiles[0].activityLoc}),
|
||||
guideLoc: formatMessage({id: tiles[0].guideLoc}),
|
||||
thumbUrl: tiles[0].thumbUrl,
|
||||
bannerUrl: tiles[0].bannerUrl
|
||||
},
|
||||
flyTile: {
|
||||
title: formatMessage({id: tiles[1].title}),
|
||||
description: formatMessage({id: tiles[1].description}),
|
||||
tutorialLoc: tiles[1].tutorialLoc,
|
||||
activityLoc: formatMessage({id: tiles[1].activityLoc}),
|
||||
guideLoc: formatMessage({id: tiles[1].guideLoc}),
|
||||
thumbUrl: tiles[1].thumbUrl,
|
||||
bannerUrl: tiles[1].bannerUrl
|
||||
},
|
||||
musicTile: {
|
||||
title: formatMessage({id: tiles[2].title}),
|
||||
description: formatMessage({id: tiles[2].description}),
|
||||
tutorialLoc: tiles[2].tutorialLoc,
|
||||
activityLoc: formatMessage({id: tiles[2].activityLoc}),
|
||||
guideLoc: formatMessage({id: tiles[2].guideLoc}),
|
||||
thumbUrl: tiles[2].thumbUrl,
|
||||
bannerUrl: tiles[2].bannerUrl
|
||||
}
|
||||
};
|
||||
|
||||
return [
|
||||
<TTTTile
|
||||
key={0}
|
||||
className="mod-banner"
|
||||
onGuideClick={this.showTTTModal.bind(this, tileObjects.nameTile)}
|
||||
{...tileObjects.nameTile}
|
||||
/>,
|
||||
<TTTTile
|
||||
key={1}
|
||||
className="mod-banner"
|
||||
onGuideClick={this.showTTTModal.bind(this, tileObjects.flyTile)}
|
||||
{...tileObjects.flyTile}
|
||||
/>,
|
||||
<TTTTile
|
||||
key={2}
|
||||
className="mod-banner"
|
||||
onGuideClick={this.showTTTModal.bind(this, tileObjects.musicTile)}
|
||||
{...tileObjects.musicTile}
|
||||
/>
|
||||
];
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<TitleBanner className="mod-splash-hoc">
|
||||
<div className="hoc-banner inner">
|
||||
<FlexRow className="mod-hoc-banner-header">
|
||||
<h1 className="hoc-banner-header-h1">
|
||||
<FormattedMessage id="hoc-banner.header" />
|
||||
</h1>
|
||||
<a href="/go" className="button mod-ttt-try-button">
|
||||
<FormattedMessage id="hoc-banner.ttt" />
|
||||
</a>
|
||||
</FlexRow>
|
||||
<MediaQuery minWidth={frameless.desktop}>
|
||||
<FlexRow className="mod-hoc-banner-tiles">
|
||||
{this.renderTTTTiles()}
|
||||
</FlexRow>
|
||||
<TTTModal
|
||||
isOpen={this.state.TTTModalOpen}
|
||||
onRequestClose={this.hideTTTModal}
|
||||
{...this.state.currentTile}
|
||||
/>
|
||||
</MediaQuery>
|
||||
</div>
|
||||
</TitleBanner>
|
||||
);
|
||||
}
|
||||
}));
|
||||
|
||||
module.exports = HocBanner;
|
|
@ -1,48 +0,0 @@
|
|||
@import "../../../colors";
|
||||
@import "../../../frameless";
|
||||
|
||||
.title-banner.mod-splash-hoc {
|
||||
background: url("/images/blocks-pattern.png");
|
||||
background-color: $ui-blue;
|
||||
background-repeat: repeat;
|
||||
background-size: 180px 180px;
|
||||
}
|
||||
|
||||
.flex-row.mod-hoc-banner-header,
|
||||
.flex-row.mod-hoc-banner-tiles {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.flex-row.mod-hoc-banner-header {
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
.hoc-banner-header-h1 {
|
||||
color: $type-white;
|
||||
}
|
||||
|
||||
.button.mod-ttt-try-button {
|
||||
padding: .75rem 2rem;
|
||||
}
|
||||
|
||||
.button.mod-ttt-try-button,
|
||||
.button.mod-ttt-try-button:hover {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.button.mod-ttt-try-button:link,
|
||||
.button.mod-ttt-try-button:visited,
|
||||
.button.mod-ttt-try-button:active
|
||||
.button.mod-ttt-try-button:hover {
|
||||
color: $type-white;
|
||||
}
|
||||
|
||||
.ttt-tile.mod-banner {
|
||||
background-color: $background-color;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: $tablet) and (max-width: $desktop - 1) {
|
||||
.flex-row.mod-hoc-banner-header {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"ttt.MakeItFlyActivityLoc": "/pdfs/cards/FlyCards.pdf",
|
||||
"ttt.MakeItFlyGuideLoc": "/pdfs/guides/FlyGuide.pdf",
|
||||
"ttt.AnimateYourNameActivityLoc": "/pdfs/cards/AnimateYourNameCards.pdf",
|
||||
"ttt.AnimateYourNameGuideLoc": "/pdfs/guides/NameGuide.pdf",
|
||||
"ttt.MakeMusicActivityLoc": "/pdfs/cards/MusicCards.pdf",
|
||||
"ttt.MakeMusicGuideLoc": "/pdfs/guides/MusicGuide.pdf"
|
||||
}
|
|
@ -28,23 +28,6 @@
|
|||
"teacherbanner.classesButton": "My Classes",
|
||||
"teacherbanner.faqButton": "Teacher Account FAQ",
|
||||
|
||||
"hoc-banner.header": "Get Creative with Coding",
|
||||
"hoc-banner.ttt": "See things to try",
|
||||
"ttt.tutorialTitle": "Tutorial",
|
||||
"ttt.tutorialSubtitle": "Find out how to make this project using a step-by-step tutorial in Scratch.",
|
||||
"ttt.activityTitle": "Activity Cards",
|
||||
"ttt.activitySubtitle": "Explore new coding ideas using this set of illustrated cards you can print out.",
|
||||
"ttt.educatorTitle": "Educator Guide",
|
||||
"ttt.educatorSubtitle": "Use this educator guide to plan and lead a one-hour Scratch workshop.",
|
||||
"ttt.tryIt": "Try It",
|
||||
"ttt.open": "Open",
|
||||
"ttt.download": "Download",
|
||||
"ttt.MakeItFlyTitle": "Make It Fly",
|
||||
"ttt.MakeItFlyDescription": "Animate the Scratch Cat, The Powerpuff Girls, or even a taco!",
|
||||
"ttt.AnimateYourNameTitle": "Animate Your Name",
|
||||
"ttt.AnimateYourNameDescription": "Animate the letters of your name, initials, or favorite word.",
|
||||
"ttt.MakeMusicTitle": "Make Music",
|
||||
"ttt.MakeMusicDescription": "Choose instruments, add sounds, and press keys to play music.",
|
||||
"hocevent.dismiss": "Dismiss",
|
||||
"hocevent.title": "Design and share your own character",
|
||||
"hocevent.studioLink": "See the studio",
|
||||
|
|
|
@ -14,7 +14,6 @@ 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 HocBanner = require('./hoc-banner/hoc-banner.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');
|
||||
|
@ -376,7 +375,6 @@ var Splash = injectIntl(React.createClass({
|
|||
{this.props.permissions.educator ? [
|
||||
<TeacherBanner key="teacherbanner" messages={messages} />
|
||||
] : []}
|
||||
<HocBanner />
|
||||
<div key="inner" className="inner mod-splash">
|
||||
{this.props.session.status === sessionActions.Status.FETCHED ? (
|
||||
this.props.session.session.user ? [
|
||||
|
|
|
@ -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 () {
|
||||
|
|
|
@ -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 () {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
"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, no student demographic data is required for account setup.",
|
||||
"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.",
|
||||
|
||||
|
|
Loading…
Reference in a new issue