mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2024-11-27 09:35:56 -05:00
Merge pull request #1135 from LLK/release/2.2.16
[Master] Release 2.2.16
This commit is contained in:
commit
023d0d6368
25 changed files with 136 additions and 243 deletions
|
@ -5,6 +5,7 @@
|
|||
"ast": "Asturianu",
|
||||
"id": "Bahasa Indonesia",
|
||||
"ms": "Bahasa Melayu",
|
||||
"be": "Беларуская",
|
||||
"bg": "Български",
|
||||
"ca": "Català",
|
||||
"cs": "Česky",
|
||||
|
|
|
@ -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" />
|
||||
});
|
||||
|
|
|
@ -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
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -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,24 +360,24 @@ module.exports = {
|
|||
options={[
|
||||
{value: 'female', label: formatMessage({id: 'general.female'})},
|
||||
{value: 'male', label: formatMessage({id: 'general.male'})},
|
||||
{value: 'other', label: ''}
|
||||
{value: 'other', label: <Input
|
||||
className="demographics-step-input-other"
|
||||
name="user.genderOther"
|
||||
type="text"
|
||||
validations={{
|
||||
maxLength: 25
|
||||
}}
|
||||
validationErrors={{
|
||||
maxLength: formatMessage({
|
||||
id: 'registration.validationMaxLength'
|
||||
})
|
||||
}}
|
||||
disabled={this.state.otherDisabled}
|
||||
required={!this.state.otherDisabled}
|
||||
help={null}
|
||||
/>}
|
||||
]}
|
||||
required />
|
||||
<div className="gender-input">
|
||||
<Input name="user.genderOther"
|
||||
type="text"
|
||||
validations={{
|
||||
maxLength: 25
|
||||
}}
|
||||
validationErrors={{
|
||||
maxLength: formatMessage({
|
||||
id: 'registration.validationMaxLength'
|
||||
})
|
||||
}}
|
||||
disabled={this.state.otherDisabled}
|
||||
required={!this.state.otherDisabled}
|
||||
help={null} />
|
||||
</div>
|
||||
<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 />
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.gender-input,
|
||||
.other-input {
|
||||
float: right;
|
||||
width: 90%;
|
||||
|
@ -61,16 +60,19 @@
|
|||
}
|
||||
|
||||
&.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[type="radio"] {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
input {
|
||||
margin-right: 1rem;
|
||||
.demographics-step-input-other {
|
||||
display: inline-block;
|
||||
|
||||
.col-sm-9 {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
24
src/redux/navigation.js
Normal 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
|
||||
};
|
||||
};
|
|
@ -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;
|
||||
|
|
|
@ -6,6 +6,11 @@
|
|||
"view": "splash/splash",
|
||||
"title": "Imagine, Program, Share"
|
||||
},
|
||||
{
|
||||
"name": "splash-redirect",
|
||||
"pattern": "^///?$",
|
||||
"redirect": "/"
|
||||
},
|
||||
{
|
||||
"name": "about",
|
||||
"pattern": "^/about/?$",
|
||||
|
|
|
@ -137,7 +137,7 @@ var Explore = injectIntl(React.createClass({
|
|||
<div className='outer'>
|
||||
<TitleBanner className="masthead">
|
||||
<div className="inner">
|
||||
<h1 className="title-banner-h1">Explore</h1>
|
||||
<h1 className="title-banner-h1"><FormattedMessage id='general.explore' /></h1>
|
||||
</div>
|
||||
</TitleBanner>
|
||||
<Tabs>
|
||||
|
@ -156,9 +156,9 @@ var Explore = injectIntl(React.createClass({
|
|||
<Form className='sort-mode'>
|
||||
<Select name="sort"
|
||||
options={[
|
||||
{value: 'trending', label: 'Trending'},
|
||||
{value: 'popular', label: 'Popular'},
|
||||
{value: 'recent', label: 'Recent'}
|
||||
{value: 'trending', label: <FormattedMessage id='explore.trending' />},
|
||||
{value: 'popular', label: <FormattedMessage id='explore.popular' />},
|
||||
{value: 'recent', label: <FormattedMessage id='explore.recent' />}
|
||||
]}
|
||||
value={this.props.mode}
|
||||
onChange={this.changeSortMode}/>
|
||||
|
|
5
src/views/explore/l10n.json
Normal file
5
src/views/explore/l10n.json
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"explore.trending": "Trending",
|
||||
"explore.popular": "Popular",
|
||||
"explore.recent": "Recent"
|
||||
}
|
|
@ -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>
|
||||
|
|
|
@ -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 doesn’t 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 doesn’t 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>"
|
||||
}
|
||||
|
|
|
@ -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 className="title-banner-h1">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'));
|
||||
|
|
|
@ -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 () {
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -34,7 +34,11 @@
|
|||
"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?",
|
||||
"teacherfaq.commHiddenBody": "No. All content shared within your class will be accessible to the Scratch community.",
|
||||
|
|
Loading…
Reference in a new issue