mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2024-11-23 07:38:07 -05:00
commit
86b4e8aa66
14 changed files with 107 additions and 33 deletions
|
@ -17,7 +17,7 @@ env:
|
||||||
- SKIP_CLEANUP=true
|
- SKIP_CLEANUP=true
|
||||||
- BUILD_ARCHIVE=$TRAVIS_BUILD_ID.zip
|
- BUILD_ARCHIVE=$TRAVIS_BUILD_ID.zip
|
||||||
before_deploy:
|
before_deploy:
|
||||||
- zip -r $BUILD_ARCHIVE .
|
- zip -qr $BUILD_ARCHIVE .
|
||||||
deploy:
|
deploy:
|
||||||
- provider: elasticbeanstalk
|
- provider: elasticbeanstalk
|
||||||
access_key_id: $EB_AWS_ACCESS_KEY_ID
|
access_key_id: $EB_AWS_ACCESS_KEY_ID
|
||||||
|
|
4
en.json
4
en.json
|
@ -14,6 +14,7 @@
|
||||||
"general.forParents": "For Parents",
|
"general.forParents": "For Parents",
|
||||||
"general.forEducators": "For Educators",
|
"general.forEducators": "For Educators",
|
||||||
"general.guidelines": "Community Guidelines",
|
"general.guidelines": "Community Guidelines",
|
||||||
|
"general.help": "Help",
|
||||||
"general.jobs": "Jobs",
|
"general.jobs": "Jobs",
|
||||||
"general.joinScratch": "Join Scratch",
|
"general.joinScratch": "Join Scratch",
|
||||||
"general.legal": "Legal",
|
"general.legal": "Legal",
|
||||||
|
@ -27,11 +28,13 @@
|
||||||
"general.scratchEd": "ScratchEd",
|
"general.scratchEd": "ScratchEd",
|
||||||
"general.scratchFoundation": "Scratch Foundation",
|
"general.scratchFoundation": "Scratch Foundation",
|
||||||
"general.scratchJr": "ScratchJr",
|
"general.scratchJr": "ScratchJr",
|
||||||
|
"general.search": "Search",
|
||||||
"general.signIn": "Sign in",
|
"general.signIn": "Sign in",
|
||||||
"general.statistics": "Statistics",
|
"general.statistics": "Statistics",
|
||||||
"general.support": "Support",
|
"general.support": "Support",
|
||||||
"general.termsOfUse": "Terms of Use",
|
"general.termsOfUse": "Terms of Use",
|
||||||
"general.username": "Username",
|
"general.username": "Username",
|
||||||
|
"general.viewAll": "View All",
|
||||||
"general.whatsHappening": "What's Happening?",
|
"general.whatsHappening": "What's Happening?",
|
||||||
"general.wiki": "Scratch Wiki",
|
"general.wiki": "Scratch Wiki",
|
||||||
"footer.about": "About Scratch",
|
"footer.about": "About Scratch",
|
||||||
|
@ -47,6 +50,7 @@
|
||||||
"intro.tryItOut": "TRY IT OUT",
|
"intro.tryItOut": "TRY IT OUT",
|
||||||
"login.forgotPassword": "Forgot Password?",
|
"login.forgotPassword": "Forgot Password?",
|
||||||
"navigation.signOut": "Sign out",
|
"navigation.signOut": "Sign out",
|
||||||
|
"news.scratchNews": "Scratch News",
|
||||||
"parents.FaqAgeRangeA": "While Scratch is primarily designed for 8 to 16 year olds, it is also used by people of all ages, including younger children with their parents.",
|
"parents.FaqAgeRangeA": "While Scratch is primarily designed for 8 to 16 year olds, it is also used by people of all ages, including younger children with their parents.",
|
||||||
"parents.FaqAgeRangeQ": "What is the age range for Scratch?",
|
"parents.FaqAgeRangeQ": "What is the age range for Scratch?",
|
||||||
"parents.FaqResourcesQ": "What resources are available for learning Scratch?",
|
"parents.FaqResourcesQ": "What resources are available for learning Scratch?",
|
||||||
|
|
|
@ -7,11 +7,14 @@ module.exports = {
|
||||||
'and animations.',
|
'and animations.',
|
||||||
|
|
||||||
// Open graph
|
// Open graph
|
||||||
og_image: 'https://scratch.mit.edu/images/og_image.jpg',
|
og_image: 'https://scratch.mit.edu/images/scratch-og.png',
|
||||||
og_image_type: 'image/jpeg',
|
og_image_type: 'image/png',
|
||||||
og_image_width: 986,
|
og_image_width: 986,
|
||||||
og_image_height: 860,
|
og_image_height: 860,
|
||||||
|
|
||||||
// Analytics & Monitoring
|
// Analytics & Monitoring
|
||||||
ga_tracker: process.env.GA_TRACKER || ''
|
ga_tracker: process.env.GA_TRACKER || '',
|
||||||
|
|
||||||
|
// Use minified JS libraries
|
||||||
|
min: (process.env.NODE_ENV === 'production') ? '.min' : ''
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,9 +13,23 @@ var log = require('./log');
|
||||||
var proxies = require('./proxies.json');
|
var proxies = require('./proxies.json');
|
||||||
var routes = require('./routes.json');
|
var routes = require('./routes.json');
|
||||||
|
|
||||||
// Server setup
|
// Create server
|
||||||
var app = express();
|
var app = express();
|
||||||
app.disable('x-powered-by');
|
app.disable('x-powered-by');
|
||||||
|
|
||||||
|
// Block POST & PUT requests in production
|
||||||
|
if (process.env.NODE_ENV === 'production') {
|
||||||
|
app.use(function (req, res, next) {
|
||||||
|
if (req.method === 'GET') return next();
|
||||||
|
if (req.method === 'OPTIONS') return next();
|
||||||
|
if (req.method === 'HEAD') return next();
|
||||||
|
|
||||||
|
res.writeHead(405, {'content-type' : 'application/json'});
|
||||||
|
res.end('{"error": "Method not allowed"}');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Server setup
|
||||||
app.use(log());
|
app.use(log());
|
||||||
app.use(compression());
|
app.use(compression());
|
||||||
app.use(express.static(path.resolve(__dirname, '../build'), {
|
app.use(express.static(path.resolve(__dirname, '../build'), {
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
"/i18n/setlang/",
|
"/i18n/setlang/",
|
||||||
"/login_retry/",
|
"/login_retry/",
|
||||||
"/media/",
|
"/media/",
|
||||||
|
"/scratch_admin/homepage/clear-cache/",
|
||||||
"/session/",
|
"/session/",
|
||||||
"/site-api",
|
"/site-api",
|
||||||
"/static/"
|
"/static/"
|
||||||
|
|
|
@ -41,8 +41,8 @@
|
||||||
<div id="footer"></div>
|
<div id="footer"></div>
|
||||||
|
|
||||||
<!-- Scripts -->
|
<!-- Scripts -->
|
||||||
<script src="/js/lib/react.js"></script>
|
<script src="/js/lib/react{{min}}.js"></script>
|
||||||
<script src="/js/lib/react-dom.js"></script>
|
<script src="/js/lib/react-dom{{min}}.js"></script>
|
||||||
|
|
||||||
<script src="/js/main.bundle.js"></script>
|
<script src="/js/main.bundle.js"></script>
|
||||||
<script src="/js/{{view}}.bundle.js"></script>
|
<script src="/js/{{view}}.bundle.js"></script>
|
||||||
|
@ -59,7 +59,5 @@
|
||||||
});
|
});
|
||||||
ga('send', 'pageview');
|
ga('send', 'pageview');
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- @todo New Relic -->
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -58,8 +58,12 @@
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
background-color: $ui-dark-gray;
|
|
||||||
padding: .5rem 1rem;
|
padding: .5rem 1rem;
|
||||||
|
|
||||||
|
&.inprogress {
|
||||||
|
background-color: $ui-dark-gray;
|
||||||
|
color: $type-gray;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ $navigation-height: 50px;
|
||||||
.banner {
|
.banner {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: $navigation-height;
|
top: $navigation-height;
|
||||||
z-index: 99;
|
z-index: 9;
|
||||||
box-shadow: 0 1px 1px $ui-dark-gray;
|
box-shadow: 0 1px 1px $ui-dark-gray;
|
||||||
background-color: $ui-orange;
|
background-color: $ui-orange;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
@import "../../colors";
|
@import "../../colors";
|
||||||
|
|
||||||
$base-bg: $ui-white;
|
$base-bg: $ui-white;
|
||||||
|
$fail-bg: $ui-orange;
|
||||||
|
$pass-bg: $ui-aqua;
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
@ -15,12 +17,7 @@ $base-bg: $ui-white;
|
||||||
font-size: .8rem;
|
font-size: .8rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
||||||
&.white {
|
/* USER BUTTON STATES */
|
||||||
border-top: 1px inset $active-gray;
|
|
||||||
background-color: $base-bg;
|
|
||||||
color: $ui-blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
box-shadow: 0 2px 2px $box-shadow-gray;
|
box-shadow: 0 2px 2px $box-shadow-gray;
|
||||||
}
|
}
|
||||||
|
@ -32,4 +29,23 @@ $base-bg: $ui-white;
|
||||||
&:focus {
|
&:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* DATA BUTTON STATES */
|
||||||
|
&.white {
|
||||||
|
border-top: 1px inset $active-gray;
|
||||||
|
background-color: $base-bg;
|
||||||
|
color: $ui-blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.pass {
|
||||||
|
background-color: $pass-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.fail {
|
||||||
|
background-color: $fail-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,10 @@ var defaultMessages = defineMessages({
|
||||||
myStuff: {
|
myStuff: {
|
||||||
id: 'general.myStuff',
|
id: 'general.myStuff',
|
||||||
defaultMessage: 'My Stuff'
|
defaultMessage: 'My Stuff'
|
||||||
|
},
|
||||||
|
search: {
|
||||||
|
id: 'general.search',
|
||||||
|
defaultMessage: 'Search'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -222,7 +226,7 @@ var Navigation = React.createClass({
|
||||||
<li className="search">
|
<li className="search">
|
||||||
<form action="/search/google_results" method="get">
|
<form action="/search/google_results" method="get">
|
||||||
<Input type="submit" value="" />
|
<Input type="submit" value="" />
|
||||||
<Input type="text" placeholder="Search" name="q" />
|
<Input type="text" placeholder={formatMessage(defaultMessages.search)} name="q" />
|
||||||
<Input type="hidden" name="date" value="anytime" />
|
<Input type="hidden" name="date" value="anytime" />
|
||||||
<Input type="hidden" name="sort_by" value="datetime_shared" />
|
<Input type="hidden" name="sort_by" value="datetime_shared" />
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -68,10 +68,12 @@ a:hover {
|
||||||
}
|
}
|
||||||
|
|
||||||
#view {
|
#view {
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
/* NOTE: Margin should match height in navigation.scss */
|
/* NOTE: Margin should match height in navigation.scss */
|
||||||
margin-top: 50px;
|
margin-top: 50px;
|
||||||
background-color: $background-color;
|
background-color: $background-color;
|
||||||
|
padding: 20px 1px;
|
||||||
padding: 20px 0;
|
min-width: 100%;
|
||||||
min-height: 768px;
|
min-height: 768px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,8 @@ var Splash = injectIntl(React.createClass({
|
||||||
news: [],
|
news: [],
|
||||||
featuredCustom: {},
|
featuredCustom: {},
|
||||||
featuredGlobal: {},
|
featuredGlobal: {},
|
||||||
showEmailConfirmationModal: false
|
showEmailConfirmationModal: false,
|
||||||
|
refreshCacheStatus: 'notrequested'
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
componentDidUpdate: function (prevProps, prevState) {
|
componentDidUpdate: function (prevProps, prevState) {
|
||||||
|
@ -115,6 +116,36 @@ var Splash = injectIntl(React.createClass({
|
||||||
if (!err) this.setState({projectCount: body.count});
|
if (!err) this.setState({projectCount: body.count});
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
},
|
},
|
||||||
|
refreshHomepageCache: function () {
|
||||||
|
this.api({
|
||||||
|
host: '',
|
||||||
|
uri: '/scratch_admin/homepage/clear-cache/',
|
||||||
|
method: 'post',
|
||||||
|
useCsrf: true
|
||||||
|
}, function (err, body) {
|
||||||
|
if (err) return this.setState({refreshCacheStatus: 'fail'});
|
||||||
|
if (!body.success) return this.setState({refreshCacheStatus: 'inprogress'});
|
||||||
|
return this.setState({refreshCacheStatus: 'pass'});
|
||||||
|
}.bind(this));
|
||||||
|
},
|
||||||
|
getHomepageRefreshStatus: function () {
|
||||||
|
var status = {
|
||||||
|
status: this.state.refreshCacheStatus,
|
||||||
|
disabled: false,
|
||||||
|
content: 'Refresh'
|
||||||
|
};
|
||||||
|
if (this.state.refreshCacheStatus === 'inprogress') {
|
||||||
|
status.disabled = true;
|
||||||
|
status.content = 'In Progress';
|
||||||
|
} else if (this.state.refreshCacheStatus === 'pass') {
|
||||||
|
status.disabled = true;
|
||||||
|
status.content = 'Requested';
|
||||||
|
} else if (this.state.refreshCacheStatus == 'fail') {
|
||||||
|
status.disabled = false;
|
||||||
|
status.content = 'Error';
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
},
|
||||||
showEmailConfirmationModal: function () {
|
showEmailConfirmationModal: function () {
|
||||||
this.setState({emailConfirmationModalOpen: true});
|
this.setState({emailConfirmationModalOpen: true});
|
||||||
},
|
},
|
||||||
|
@ -286,6 +317,7 @@ var Splash = injectIntl(React.createClass({
|
||||||
render: function () {
|
render: function () {
|
||||||
var featured = this.renderHomepageRows();
|
var featured = this.renderHomepageRows();
|
||||||
var emailConfirmationStyle = {width: 500, height: 330, padding: 1};
|
var emailConfirmationStyle = {width: 500, height: 330, padding: 1};
|
||||||
|
var homepageCacheState = this.getHomepageRefreshStatus();
|
||||||
return (
|
return (
|
||||||
<div className="splash">
|
<div className="splash">
|
||||||
{this.shouldShowEmailConfirmation() ? [
|
{this.shouldShowEmailConfirmation() ? [
|
||||||
|
@ -340,18 +372,14 @@ var Splash = injectIntl(React.createClass({
|
||||||
<dd>
|
<dd>
|
||||||
<ul className="cache-list">
|
<ul className="cache-list">
|
||||||
<li>
|
<li>
|
||||||
<form
|
<div className="button-row">
|
||||||
id="homepage-refresh-form"
|
<span>Refresh row data:</span>
|
||||||
method="post"
|
<Button onClick={this.refreshHomepageCache}
|
||||||
action="/scratch_admin/homepage/clear-cache/">
|
className={homepageCacheState.status}
|
||||||
|
disabled={homepageCacheState.disabled}>
|
||||||
<div className="button-row">
|
<span>{homepageCacheState.content}</span>
|
||||||
<span>Refresh row data:</span>
|
</Button>
|
||||||
<Button type="submit">
|
</div>
|
||||||
<span>Refresh</span>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 212 KiB |
BIN
static/images/scratch-og.png
Normal file
BIN
static/images/scratch-og.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 33 KiB |
Loading…
Reference in a new issue