Merge pull request #1822 from LLK/release/february-2018

February 2018 Release
This commit is contained in:
chrisgarrity 2018-03-01 16:46:25 -05:00 committed by GitHub
commit 770e1a2ebf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 92 additions and 63 deletions

View file

@ -88,7 +88,7 @@ const Footer = props => (
</a> </a>
</dd> </dd>
<dd> <dd>
<a href="http://wiki.scratch.mit.edu/wiki/Scratch_Press"> <a href="https://www.scratchfoundation.org/media-kit/">
<FormattedMessage id="general.press" /> <FormattedMessage id="general.press" />
</a> </a>
</dd> </dd>

View file

@ -65,6 +65,7 @@
"general.scratchJr": "ScratchJr", "general.scratchJr": "ScratchJr",
"general.scratchStore": "Scratch Store", "general.scratchStore": "Scratch Store",
"general.search": "Search", "general.search": "Search",
"general.searchEmpty": "Nothing found",
"general.signIn": "Sign in", "general.signIn": "Sign in",
"general.statistics": "Statistics", "general.statistics": "Statistics",
"general.studios": "Studios", "general.studios": "Studios",

View file

@ -3,6 +3,7 @@ const FormattedMessage = require('react-intl').FormattedMessage;
const React = require('react'); const React = require('react');
const render = require('../../../../lib/render.jsx'); const render = require('../../../../lib/render.jsx');
const Button = require('../../../../components/forms/button.jsx');
const FlexRow = require('../../../../components/flex-row/flex-row.jsx'); const FlexRow = require('../../../../components/flex-row/flex-row.jsx');
const Page = require('../../../../components/page/conference/2018/page.jsx'); const Page = require('../../../../components/page/conference/2018/page.jsx');
const TitleBanner = require('../../../../components/title-banner/title-banner.jsx'); const TitleBanner = require('../../../../components/title-banner/title-banner.jsx');
@ -19,9 +20,13 @@ const ConferenceSplash = () => (
<h3> <h3>
<FormattedMessage id="conference-2018.dateDesc" /> <FormattedMessage id="conference-2018.dateDesc" />
</h3> </h3>
<h3> <p>
<FormattedMessage id="conference-2018.registrationDate" /> <a href="https://scratch2018.eventbrite.com">
</h3> <Button className="mod-register">
<FormattedMessage id="conference-2018.registerNow" />
</Button>
</a>
</p>
</TitleBanner> </TitleBanner>
<div className="inner"> <div className="inner">
<section className="info"> <section className="info">
@ -69,7 +74,13 @@ const ConferenceSplash = () => (
<br /> <br />
<b><FormattedMessage id="conference-2018.registrationStandard" /></b> <b><FormattedMessage id="conference-2018.registrationStandard" /></b>
</p> </p>
<p><FormattedMessage id="conference-2018.registrationDate" /></p> <p>
<a href="https://scratch2018.eventbrite.com">
<Button className="mod-register">
<FormattedMessage id="conference-2018.registerNow" />
</Button>
</a>
</p>
<h3 id="questions"><FormattedMessage id="conference-2018.questionsTitle" /></h3> <h3 id="questions"><FormattedMessage id="conference-2018.questionsTitle" /></h3>
<div> <div>
<p className="conf2018-question"> <p className="conf2018-question">
@ -127,6 +138,11 @@ const ConferenceSplash = () => (
AC Hotel Boston Cambridge AC Hotel Boston Cambridge
</a> </a>
), ),
doubletreeLink: (
<a href="https://secure3.hilton.com/en_US/dt/reservation/book.htm?inputModule=HOTEL&ctyhocn=BOSCODT&spec_plan=CDTMIT&arrival=20180725&departure=20180728&cid=OM,WW,HILTONLINK,EN,DirectLink&fromId=HILTONLINKDIRECT">
DoubleTree by Hilton Hotel Boston - Downtown
</a>
),
hotelbostonLink: ( hotelbostonLink: (
<a href="https://www.hotelboston.com/"> <a href="https://www.hotelboston.com/">
Hotel Boston Hotel Boston
@ -152,18 +168,6 @@ const ConferenceSplash = () => (
}} }}
/> />
</p> </p>
<p className="conf2018-question">
<FormattedMessage id="conference-2018.apartment" />
</p>
<p className="conf2018-answer">
<FormattedMessage id="conference-2018.single" />
{' - $90.00'}
<FormattedMessage id="conference-2018.pp" />
<br />
<FormattedMessage id="conference-2018.double" />
{' - $65.00'}
<FormattedMessage id="conference-2018.pp" />
</p>
<p className="conf2018-question"> <p className="conf2018-question">
<FormattedMessage id="conference-2018.suite" /> <FormattedMessage id="conference-2018.suite" />
</p> </p>
@ -180,9 +184,9 @@ const ConferenceSplash = () => (
<FormattedMessage <FormattedMessage
id="conference-2018.accommodationsAns4" id="conference-2018.accommodationsAns4"
values={{ values={{
emailLink: ( dormrequestLink: (
<a href="mailto:conference@scratch.mit.edu"> <a href="https://docs.google.com/forms/d/e/1FAIpQLSd8LRQyz9ZLXcpvjmYrnpAlN0_RVyYsgObUXQveI9_WpoDabw/viewform?usp=sf_link">
conference@scratch.mit.edu <FormattedMessage id="conference-2018.dormRequestText" />
</a> </a>
) )
}} }}

View file

@ -37,9 +37,7 @@
a { a {
button { button {
background-color: $ui-white;
color: $ui-blue;
font-size: 1rem;
} }
} }
} }
@ -148,14 +146,14 @@ td {
height: 1rem; height: 1rem;
} }
.button.mod-2018-panel {
display: block; .button.mod-register {
margin: 2rem auto 0; padding: .75em 3.5em;
background-color: $ui-orange;
padding: 1rem 0;
width: 13.75rem;
text-align: center; text-align: center;
color: $type-white; color: $type-white;
font-size: 1rem;
font-weight: 500;
} }
@media only screen and (max-width: $mobile - 1) { @media only screen and (max-width: $mobile - 1) {
@ -221,8 +219,8 @@ td {
max-width: 18.75rem; max-width: 18.75rem;
} }
.button.mod-2018-panel { .button.mod-register {
width: 5.75rem; padding: .75em 2em;
} }
} }
@ -245,7 +243,7 @@ td {
font-size: 1.1rem; font-size: 1.1rem;
} }
.button.mod-2018-panel { .button.mod-register {
width: 8.75rem; padding: .75em 1.25em;
} }
} }

View file

@ -12,7 +12,7 @@
"conference-2018.desc1": "Join us for the Scratch@MIT conference, a playful gathering of educators, researchers, developers, and other members of the worldwide Scratch community.", "conference-2018.desc1": "Join us for the Scratch@MIT conference, a playful gathering of educators, researchers, developers, and other members of the worldwide Scratch community.",
"conference-2018.desc2": "We're planning a very participatory conference, with an entire day of hands-on workshops and lots of opportunities for peer-to-peer discussion and collaboration. The conference is intended primarily for adults who support young people learning Scratch.", "conference-2018.desc2": "We're planning a very participatory conference, with an entire day of hands-on workshops and lots of opportunities for peer-to-peer discussion and collaboration. The conference is intended primarily for adults who support young people learning Scratch.",
"conference-2018.registrationDate": "Registration opens March 1, 2018.", "conference-2018.registrationDate": "Registration opens March 1, 2018.",
"conference-2018.registerNow": "Register Now!",
"conference-2018.sessionDesc": "Interested in offering a session? We invite four types of proposals:", "conference-2018.sessionDesc": "Interested in offering a session? We invite four types of proposals:",
"conference-2018.sessionItem1Title": "Poster/demonstration (90 minutes).", "conference-2018.sessionItem1Title": "Poster/demonstration (90 minutes).",
"conference-2018.sessionItem1Desc": "Show off your project in an exhibition setting, alongside other presenters. You will be provided with display space for a poster and table space for a computer or handouts.", "conference-2018.sessionItem1Desc": "Show off your project in an exhibition setting, alongside other presenters. You will be provided with display space for a poster and table space for a computer or handouts.",
@ -35,20 +35,20 @@
"conference-2018.questions": "Questions? Contact the Scratch Team at {emailLink}", "conference-2018.questions": "Questions? Contact the Scratch Team at {emailLink}",
"conference-2018.questionsTitle": "Questions:", "conference-2018.questionsTitle": "Questions:",
"conference-2018.submissionQ": "I missed the submission deadline. Can I still submit a proposal for the conference?", "conference-2018.submissionQ": "I missed the submission deadline. Can I still submit a proposal for the conference?",
"conference-2018.submissionAns": "We are no longer accepting proposal submissions. We will send out proposal acceptance notifications on February 28.", "conference-2018.submissionAns": "We are no longer accepting proposal submissions.",
"conference-2018.regQ": "I can only attend one day of the conference. Do you offer single-day registration?", "conference-2018.regQ": "I can only attend one day of the conference. Do you offer single-day registration?",
"conference-2018.regAns": "Sorry, we are not offering single-day tickets.", "conference-2018.regAns": "Sorry, we are not offering single-day tickets.",
"conference-2018.accommodationsQ": "I want to plan my visit. Do you have suggestions for accommodations?", "conference-2018.accommodationsQ": "I want to plan my visit. Do you have suggestions for accommodations?",
"conference-2018.accommodationsAns1": "Yes, MIT partners with several hotels in the area who offer discounts to participants attending MIT events, including: {marriottLink} (0.4 miles from the MIT Media Lab), {holidayinnLink} (1.6 miles), {residenceinnLink} (0.3 miles), and {lemeridienLink} (0.9 miles). To reserve a room at one of these hotels, call the hotel and request the MIT discount. Advance booking is strongly recommended, as summer is a busy time in Boston. All MIT rates are subject to availability.", "conference-2018.accommodationsAns1": "Yes, MIT partners with several hotels in the area who offer discounts to participants attending MIT events, including: {marriottLink} (0.4 miles from the MIT Media Lab), {holidayinnLink} (1.6 miles), {residenceinnLink} (0.3 miles), and {lemeridienLink} (0.9 miles). To reserve a room at one of these hotels, call the hotel and request the MIT discount. Advance booking is strongly recommended, as summer is a busy time in Boston. All MIT rates are subject to availability.",
"conference-2018.accommodationsAns2": "If you are looking for lower-cost accommodations, we also recommend the {acLink} (7.1 miles). You might also consider home-share options such as Airbnb. Find an extended list of accommodations {mitLink}.", "conference-2018.accommodationsAns2": "If you are looking for additional accommodation options, we also recommend the {acLink} (7.1 miles), {doubletreeLink} (3.3 miles), and {hotelbostonLink} with the code MITSC2018 (5.3 mile). You might also consider home-share options such as Airbnb. Find an extended list of accommodations {mitLink}.",
"conference-2018.here": "here", "conference-2018.here": "here",
"conference-2018.accommodationsAns3": "Limited lodging is available in {neuLink} dorms rooms at the following rates:", "conference-2018.accommodationsAns3": "Limited lodging is available in {neuLink} dorm rooms at the following rates:",
"conference-2018.apartment": "Apartment",
"conference-2018.suite": "Suite", "conference-2018.suite": "Suite",
"conference-2018.single": "Single", "conference-2018.single": "Single",
"conference-2018.double": "Double", "conference-2018.double": "Double",
"conference-2018.pp": "/person/night", "conference-2018.pp": "/person/night",
"conference-2018.accommodationsAns4": "To request a dorm room, please email us at {emailLink} with the subject line “Dorm room.” Please note that Northeastern is located in Boston, two miles from the conference site at MIT. It is a half-hour commute via public transportation, accessible by subway via the Green Line (the Northeastern stop on the E line) or the Orange Line (Ruggles Station stop).", "conference-2018.accommodationsAns4": "Northeastern University dorms are open ONLY to individuals over 18 years of age. To request a dorm room, please complete the {dormrequestLink}. Northeastern is located in Boston, two miles from the conference site at MIT. It is a half-hour commute via public transportation, accessible by subway via the Green Line (the Northeastern stop on the E line) or the Orange Line (Ruggles Station stop).",
"conference-2018.dormRequestText": "Dorm Room Request Form",
"conference-2018.letterQ": "Can I get a visa letter?", "conference-2018.letterQ": "Can I get a visa letter?",
"conference-2018.letterAns": "Yes. Contact us at {emailLink}, and we can email you a letter.", "conference-2018.letterAns": "Yes. Contact us at {emailLink}, and we can email you a letter.",
"conference-2018.preConfQ": "In previous years, there was an event on Wednesday evening before the conference. Will you be hosting something similar this year?", "conference-2018.preConfQ": "In previous years, there was an event on Wednesday evening before the conference. Will you be hosting something similar this year?",

View file

@ -30,6 +30,7 @@ class Search extends React.Component {
this.state.loaded = []; this.state.loaded = [];
this.state.loadNumber = 16; this.state.loadNumber = 16;
this.state.offset = 0; this.state.offset = 0;
this.state.loadMore = false;
} }
componentDidMount () { componentDidMount () {
const query = window.location.search; const query = window.location.search;
@ -80,10 +81,12 @@ class Search extends React.Component {
const loadedSoFar = this.state.loaded; const loadedSoFar = this.state.loaded;
Array.prototype.push.apply(loadedSoFar, body); Array.prototype.push.apply(loadedSoFar, body);
const currentOffset = this.state.offset + this.state.loadNumber; const currentOffset = this.state.offset + this.state.loadNumber;
const willLoadMore = body.length === this.state.loadNumber;
this.setState({ this.setState({
loaded: loadedSoFar, loaded: loadedSoFar,
offset: currentOffset offset: currentOffset,
loadMore: willLoadMore
}); });
}); });
} }
@ -115,6 +118,41 @@ class Search extends React.Component {
} }
return allTab; return allTab;
} }
getProjectBox () {
const results = (
<Grid
cards
showAvatar
itemType={this.state.tab}
items={this.state.loaded}
showFavorites={false}
showLoves={false}
showViews={false}
/>
);
let searchAction = null;
if (this.state.loaded.length === 0 && this.state.offset !== 0) {
searchAction = <h2 className="search-prompt"><FormattedMessage id="general.searchEmpty" /></h2>;
} else if (this.state.loadMore) {
searchAction = (
<Button
className="white"
onClick={this.handleGetSearchMore}
>
<FormattedMessage id="general.loadMore" />
</Button>
);
}
return (
<div
id="projectBox"
key="projectBox"
>
{results}
{searchAction}
</div>
);
}
render () { render () {
return ( return (
<div> <div>
@ -130,26 +168,7 @@ class Search extends React.Component {
{this.getTab('projects')} {this.getTab('projects')}
{this.getTab('studios')} {this.getTab('studios')}
</Tabs> </Tabs>
<div {this.getProjectBox()}
id="projectBox"
key="projectBox"
>
<Grid
cards
showAvatar
itemType={this.state.tab}
items={this.state.loaded}
showFavorites={false}
showLoves={false}
showViews={false}
/>
<Button
className="white"
onClick={this.handleGetSearchMore}
>
<FormattedMessage id="general.loadMore" />
</Button>
</div>
</div> </div>
</div> </div>
); );

View file

@ -132,6 +132,13 @@ $base-bg: $ui-white;
display: block; display: block;
margin: 0 auto; margin: 0 auto;
} }
.search-prompt {
margin: 0 auto;
padding: 30px;
max-width: 500px;
text-align: center;
}
} }
} }

View file

@ -113,7 +113,7 @@ tap.test('clickJobsLink', options, t => {
// PRESS // PRESS
tap.test('clickPressLink', options, t => { tap.test('clickPressLink', options, t => {
const linkText = 'Press'; const linkText = 'Press';
const expectedUrl = 'https://wiki.scratch.mit.edu/wiki/Scratch_Press'; const expectedUrl = 'https://www.scratchfoundation.org/media-kit/';
clickFooterLinks(linkText).then(url => { clickFooterLinks(linkText).then(url => {
t.equal(url, expectedUrl); t.equal(url, expectedUrl);
t.end(); t.end();
@ -145,7 +145,7 @@ tap.test('clickDiscussionForumsLink', options, t => {
// SCRATCH WIKI // SCRATCH WIKI
tap.test('clickScratchWikiLink', options, t => { tap.test('clickScratchWikiLink', options, t => {
const linkText = 'Scratch Wiki'; const linkText = 'Scratch Wiki';
const expectedUrl = 'https://wiki.scratch.mit.edu/wiki/Scratch_Wiki_Home'; const expectedUrl = 'https://en.scratch-wiki.info/wiki/Scratch_Wiki_Home';
clickFooterLinks(linkText).then(url => { clickFooterLinks(linkText).then(url => {
t.equal(url, expectedUrl); t.equal(url, expectedUrl);
t.end(); t.end();

View file

@ -67,7 +67,7 @@ routes.forEach(function (route) {
// Config // Config
module.exports = { module.exports = {
entry: entry, entry: entry,
devtool: 'eval', devtool: process.env.NODE_ENV === 'production' ? 'none' : 'eval',
output: { output: {
path: path.resolve(__dirname, 'build'), path: path.resolve(__dirname, 'build'),
filename: 'js/[name].bundle.js' filename: 'js/[name].bundle.js'