зеркало из https://github.com/mozilla/CSOL-site.git
Merge branch 'master' into guardians
Conflicts: openbadger.js
This commit is contained in:
Коммит
ab9cb3b7f8
|
@ -168,4 +168,11 @@ aestimia.defaultOptions = {
|
|||
}
|
||||
};
|
||||
|
||||
module.exports = aestimia;
|
||||
module.exports = aestimia;
|
||||
module.exports.healthCheck = function(cb) {
|
||||
// A random email should guarantee we bust through any caches.
|
||||
var email = 'healthCheck_test_' +
|
||||
Math.floor(Math.random() * 100000) + '@mozilla.org';
|
||||
|
||||
aestimia.get('/submissions?learner=' + encodeURIComponent(email), cb);
|
||||
};
|
||||
|
|
36
app.js
36
app.js
|
@ -1,6 +1,7 @@
|
|||
if ( process.env.NEW_RELIC_HOME ) {
|
||||
require( 'newrelic' );
|
||||
}
|
||||
const colors = require('colors');
|
||||
const path = require('path');
|
||||
const http = require('http');
|
||||
const express = require('express');
|
||||
|
@ -9,16 +10,28 @@ const middleware = require('./middleware');
|
|||
const helpers = require('./helpers');
|
||||
const flash = require('connect-flash');
|
||||
const logger = require('./logger');
|
||||
const healthCheck = require('./controllers/health-check');
|
||||
|
||||
const port = parseInt(process.env.PORT || '3000');
|
||||
const app = express();
|
||||
const env = new nunjucks.Environment(new nunjucks.FileSystemLoader(path.join(__dirname, 'views')), {autoescape: false});
|
||||
env.express(app);
|
||||
const healthChecker = healthCheck({
|
||||
auth: express.basicAuth('health_check', process.env.COOKIE_SECRET),
|
||||
checks: {
|
||||
s3: healthCheck.checker(require('./s3').healthCheck),
|
||||
database: healthCheck.checker(require('./db').healthCheck),
|
||||
openbadger: healthCheck.checker(require('./openbadger').healthCheck),
|
||||
aestimia: healthCheck.checker(require('./aestimia').healthCheck)
|
||||
}
|
||||
});
|
||||
|
||||
app.use(express.cookieParser());
|
||||
app.use(middleware.session());
|
||||
app.use(middleware.csrf({
|
||||
whitelist: [
|
||||
'/applications'
|
||||
'/applications',
|
||||
'/health_check'
|
||||
]
|
||||
}));
|
||||
app.use(express.logger({stream:{
|
||||
|
@ -44,9 +57,28 @@ require('./controllers/program')(app);
|
|||
require('./controllers/learn')(app);
|
||||
require('./controllers/challenges')(app);
|
||||
|
||||
app.get('/health_check', healthChecker);
|
||||
require('./lib/errors')(app, env);
|
||||
|
||||
if (!module.parent)
|
||||
app.listen(3000);
|
||||
app.listen(port, function(err) {
|
||||
if (err) throw err;
|
||||
console.log("Listening on port " + port + ".");
|
||||
console.log("Performing health check.\n");
|
||||
|
||||
healthChecker.runChecks(function(results) {
|
||||
var consoleStr = healthCheck.resultsToConsoleString(results);
|
||||
console.log("Health check results:\n");
|
||||
if (results.status != "OK") {
|
||||
console.error(consoleStr + "\n");
|
||||
console.error(("One or more critical services are down or " +
|
||||
"misconfigured. Please fix them!").red.bold);
|
||||
} else {
|
||||
console.log(consoleStr);
|
||||
console.log(("\nHealth check indicates all systems are " +
|
||||
"functional.").green);
|
||||
}
|
||||
});
|
||||
});
|
||||
else
|
||||
module.exports = http.createServer(app);
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
// TODO: Separate this module out into its own npm module/git repo.
|
||||
|
||||
var async = require('async');
|
||||
var colors = require('colors');
|
||||
|
||||
const CHECKMARK = "\u2713";
|
||||
|
||||
function checker(fn) {
|
||||
return function check(cb) {
|
||||
var timeout = setTimeout(function() {
|
||||
timeout = null;
|
||||
cb(null, {status: "FAILED", reason: "TIMEOUT"});
|
||||
}, module.exports.TIMEOUT);
|
||||
|
||||
try {
|
||||
fn(function(err) {
|
||||
if (timeout === null) return;
|
||||
clearTimeout(timeout);
|
||||
timeout = null;
|
||||
if (err)
|
||||
return cb(null, {status: "FAILED", reason: err.toString()});
|
||||
cb(null, {status: "OK"});
|
||||
});
|
||||
} catch (e) {
|
||||
clearTimeout(timeout);
|
||||
timeout = null;
|
||||
cb(null, {status: "FAILED", reason: e.toString()});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function sessionStorageChecker(sessionStore) {
|
||||
return checker(function checkSessionStorage(cb) {
|
||||
var randomNumber = Math.floor(Math.random() * 10000000);
|
||||
var sid = "healthCheck_sessionStorage_" + randomNumber;
|
||||
var session = {
|
||||
n: randomNumber,
|
||||
cookie: {maxAge: 3600}
|
||||
};
|
||||
|
||||
async.series([
|
||||
sessionStore.set.bind(sessionStore, sid, session),
|
||||
function(cb) {
|
||||
sessionStore.get(sid, function(err, val) {
|
||||
if (err) return cb(err);
|
||||
if (!(val && val.n == randomNumber))
|
||||
return cb(new Error("session store read/write failure"));
|
||||
cb();
|
||||
});
|
||||
},
|
||||
sessionStore.destroy.bind(sessionStore, sid)
|
||||
], cb);
|
||||
});
|
||||
}
|
||||
|
||||
function runChecks(checks, cb) {
|
||||
async.parallel(checks, function(err, results) {
|
||||
if (err !== null)
|
||||
// This should never happen b/c checkers should catch all errors.
|
||||
return cb({
|
||||
status: "FAILED",
|
||||
reason: "a checker threw an error: " + err
|
||||
});
|
||||
|
||||
Object.keys(results).forEach(function(checkName) {
|
||||
if (results[checkName].status != "OK")
|
||||
results.status = "FAILED";
|
||||
});
|
||||
if (results.status != "FAILED")
|
||||
results.status = "OK";
|
||||
cb(results);
|
||||
});
|
||||
}
|
||||
|
||||
function resultsToConsoleString(results) {
|
||||
var lines = [];
|
||||
|
||||
Object.keys(results).forEach(function(name) {
|
||||
var info = results[name];
|
||||
|
||||
if (info && typeof(info) == "object" && info.status) {
|
||||
if (info.status == "OK") {
|
||||
lines.push(CHECKMARK.green + " " + name.grey);
|
||||
} else {
|
||||
lines.push("x".red + " " + name.grey + " " +
|
||||
(info.reason ? info.reason : ""));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
module.exports = function healthCheck(options) {
|
||||
var authenticate = options.auth || function(req, res, next) { next(); };
|
||||
var checks = options.checks;
|
||||
|
||||
var healthChecker = function healthChecker(req, res, next) {
|
||||
if (req.query['elb'] == 'true')
|
||||
return res.send(200, {status: "OK"});
|
||||
|
||||
authenticate(req, res, function(err) {
|
||||
if (err) return next(err);
|
||||
|
||||
runChecks(checks, function(results) {
|
||||
var statusCode = results.status == "OK" ? 200 : 500;
|
||||
return res.json(statusCode, results);
|
||||
});
|
||||
});
|
||||
};
|
||||
healthChecker.runChecks = runChecks.bind(null, checks);
|
||||
return healthChecker;
|
||||
};
|
||||
|
||||
module.exports.TIMEOUT = 15000;
|
||||
module.exports.resultsToConsoleString = resultsToConsoleString;
|
||||
module.exports.runChecks = runChecks;
|
||||
module.exports.sessionStorageChecker = sessionStorageChecker;
|
||||
module.exports.checker = checker;
|
|
@ -218,9 +218,11 @@ module.exports = function (app) {
|
|||
});
|
||||
});
|
||||
|
||||
app.get('/earn/:badgeName', function (req, res, next) {
|
||||
app.get('/earn/:badgeName', badger.middleware('getBadgeRecommendations'), function (req, res, next) {
|
||||
var data = req.remote;
|
||||
res.render('badges/single.html', {
|
||||
badge: req.params.badge
|
||||
badge: req.params.badge,
|
||||
relatedBadges: data.badges
|
||||
});
|
||||
});
|
||||
|
||||
|
|
8
db.js
8
db.js
|
@ -97,4 +97,12 @@ db.model = function(name) {
|
|||
}
|
||||
|
||||
db.type = Sequelize;
|
||||
db.healthCheck = function(cb) {
|
||||
db.model('Claim').find({
|
||||
where: {id: 1234}
|
||||
}).complete(function(err, claim) {
|
||||
if (err) return cb(err);
|
||||
cb();
|
||||
});
|
||||
};
|
||||
module.exports = db;
|
||||
|
|
|
@ -323,6 +323,7 @@ var openbadger = new Api(ENDPOINT, {
|
|||
});
|
||||
},
|
||||
|
||||
|
||||
claim: function claim (query, callback) {
|
||||
var email = query.email;
|
||||
var code = query.code;
|
||||
|
@ -335,6 +336,22 @@ var openbadger = new Api(ENDPOINT, {
|
|||
return callback(err, data);
|
||||
});
|
||||
},
|
||||
|
||||
getBadgeRecommendations: function getBadgeRecommendations (query, callback) {
|
||||
var id = query.badgeName;
|
||||
|
||||
if (!id)
|
||||
return callback(new errors.BadRequest('Invalid badge key'));
|
||||
|
||||
this.get('/badge/' + id + '/recommendations', function(err, data) {
|
||||
if (err)
|
||||
return callback(err, data);
|
||||
|
||||
return callback(null, {
|
||||
badges: _.map(data.badges, normalizeBadge)
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
updateOrgs();
|
||||
|
@ -370,3 +387,14 @@ module.exports.getFilters = function getFilters () {
|
|||
};
|
||||
}
|
||||
module.exports.updateOrgs = updateOrgs;
|
||||
|
||||
module.exports.healthCheck = function(cb) {
|
||||
// Use a privileged API call to ensure we're testing the JWT secret.
|
||||
// A random email should guarantee we bust through any caches.
|
||||
var email = 'healthCheck_test_' +
|
||||
Math.floor(Math.random() * 100000) + '@mozilla.org';
|
||||
|
||||
openbadger.getUserBadges({
|
||||
session: {user: {email: email}}
|
||||
}, cb);
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "CSOL-site",
|
||||
"version": "0.9.0",
|
||||
"version": "0.9.14",
|
||||
"description": "The website for the Chicago Summer of Learning, developed by Ocupop and Mozilla.",
|
||||
"main": "app.js",
|
||||
"dependencies": {
|
||||
|
@ -19,12 +19,12 @@
|
|||
"underscore": "~1.4.4",
|
||||
"winston": "~0.7.1",
|
||||
"newrelic": "~0.9.19",
|
||||
"colors": "~0.6.0",
|
||||
"jwt-simple": "~0.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"sinon": "~1.7.2",
|
||||
"injectr": "~0.4.0",
|
||||
"colors": "~0.6.0",
|
||||
"optimist": "~0.5.2",
|
||||
"up": "~0.2.2"
|
||||
},
|
||||
|
|
23
s3-fake.js
23
s3-fake.js
|
@ -47,11 +47,26 @@ FakeS3.prototype.get = function(urlPath) {
|
|||
var abspath = this._toFilePath(urlPath);
|
||||
var result = new EventEmitter();
|
||||
|
||||
process.nextTick(function() {
|
||||
result.emit('response', fs.createReadStream(abspath));
|
||||
});
|
||||
|
||||
result.end = function() {
|
||||
process.nextTick(function() {
|
||||
result.emit('response', fs.createReadStream(abspath));
|
||||
});
|
||||
};
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
FakeS3.prototype.deleteFile = function(urlPath, cb) {
|
||||
var abspath = this._toFilePath(urlPath);
|
||||
|
||||
if (fs.existsSync(abspath))
|
||||
fs.unlinkSync(abspath);
|
||||
|
||||
process.nextTick(function() {
|
||||
// We don't currently do anything w/ the response, so we won't bother
|
||||
// passing it in as the second param to the callback.
|
||||
cb(null);
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = FakeS3;
|
||||
|
|
27
s3.js
27
s3.js
|
@ -24,4 +24,31 @@ if (process.env["CSOL_AWS_FAKE_S3_DIR"]) {
|
|||
});
|
||||
}
|
||||
|
||||
s3.healthCheck = function(cb) {
|
||||
var async = require('async');
|
||||
var rnd = Math.floor(Math.random() * 100000).toString();
|
||||
var url = '/healthChecker_test_' + rnd;
|
||||
|
||||
async.series([
|
||||
s3.putBuffer.bind(s3, new Buffer(rnd), url, {
|
||||
'Content-Type': 'text/plain'
|
||||
}),
|
||||
function(cb) {
|
||||
s3.get(url).on('response', function(proxy) {
|
||||
var chunks = [];
|
||||
proxy.on('data', function(chunk) {
|
||||
chunks.push(chunk);
|
||||
});
|
||||
proxy.on('end', function() {
|
||||
var buf = Buffer.concat(chunks);
|
||||
if (buf.toString('ascii') != rnd)
|
||||
return cb("expected " + rnd + ", got " + buf.toString('ascii'));
|
||||
cb();
|
||||
});
|
||||
}).end();
|
||||
},
|
||||
s3.deleteFile.bind(s3, url)
|
||||
], cb);
|
||||
};
|
||||
|
||||
module.exports = s3;
|
||||
|
|
|
@ -85,6 +85,7 @@ ol {
|
|||
}
|
||||
.navbar .navbar-inner {
|
||||
background-image: url('../img/chalkboard_bg.jpg');
|
||||
background-repeat: repeat;
|
||||
}
|
||||
.navbar form.navbar-inner {
|
||||
padding: 7px;
|
||||
|
@ -107,24 +108,24 @@ ol {
|
|||
background: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
.navbar .nav-wrap ul {
|
||||
.navbar .nav-wrap ul.nav {
|
||||
display: inline-block;
|
||||
margin: 0 0 0 0;
|
||||
}
|
||||
.navbar .nav-wrap ul > li {
|
||||
.navbar .nav-wrap ul.nav > li {
|
||||
float: none;
|
||||
display: inline-block;
|
||||
}
|
||||
.navbar .nav-wrap ul > li > a {
|
||||
.navbar .nav-wrap ul.nav > li > a {
|
||||
text-shadow: none;
|
||||
color: #333333;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.navbar .nav-wrap ul > li > a:focus,
|
||||
.navbar .nav-wrap ul > li > a:hover {
|
||||
.navbar .nav-wrap ul.nav > li > a:focus,
|
||||
.navbar .nav-wrap ul.nav > li > a:hover {
|
||||
color: #c0c0c0;
|
||||
}
|
||||
.navbar .nav-wrap ul > li:last-child {
|
||||
.navbar .nav-wrap ul.nav > li:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
.navbar .brand {
|
||||
|
@ -154,6 +155,7 @@ nav.pagination ul li a {
|
|||
-webkit-box-shadow: inset 0px 10px 20px 0px rgba(0, 0, 0, 0.25);
|
||||
-moz-box-shadow: inset 0px 10px 20px 0px rgba(0, 0, 0, 0.25);
|
||||
box-shadow: inset 0px 10px 20px 0px rgba(0, 0, 0, 0.25);
|
||||
background-repeat: repeat;
|
||||
}
|
||||
.footer a {
|
||||
color: #fff;
|
||||
|
@ -236,8 +238,110 @@ nav.pagination ul li a {
|
|||
.wrapper.secondary {
|
||||
position: relative;
|
||||
color: #fff;
|
||||
overflow: hidden;
|
||||
}
|
||||
/*mobile*/
|
||||
@media only screen and (min-width: 320px) and (max-width: 599px) {
|
||||
.container p,
|
||||
.container h1,
|
||||
.container h2,
|
||||
.footer .upper p {
|
||||
width: inherit;
|
||||
}
|
||||
#main {
|
||||
padding-top: 15px;
|
||||
}
|
||||
.form-search label,
|
||||
.form-inline label,
|
||||
.form-search .btn-group,
|
||||
.form-inline .btn-group {
|
||||
display: block;
|
||||
}
|
||||
.filter label {
|
||||
display: none;
|
||||
}
|
||||
.navbar .nav-wrap,
|
||||
.container,
|
||||
.navbar-static-top .container,
|
||||
.navbar-fixed-top .container,
|
||||
.navbar-fixed-bottom .container,
|
||||
.navbar .brand {
|
||||
width: 95%;
|
||||
margin: 0 0 0 0;
|
||||
padding: 0 0 0 0;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.form-horizontal .control-label {
|
||||
text-align: left;
|
||||
float: none;
|
||||
}
|
||||
.form-horizontal .controls {
|
||||
margin-left: 0px;
|
||||
}
|
||||
.span6 {
|
||||
width: inherit;
|
||||
}
|
||||
/*mobile navbar*/
|
||||
.navbar div.navbar-inner {
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
border: none;
|
||||
}
|
||||
.navbar .nav-wrap {
|
||||
width: 90%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.navbar .nav-wrap ul.nav li {
|
||||
display: block;
|
||||
}
|
||||
.navbar .nav-wrap ul.nav li a {
|
||||
padding: 5px 0;
|
||||
}
|
||||
.navbar .nav-wrap ul.nav li:nth-child(even),
|
||||
.navbar .nav-wrap ul.nav > .active > a,
|
||||
.navbar .nav-wrap ul.nav > .active > a:hover {
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
/*mobile footer*/
|
||||
.footer .upper {
|
||||
padding-top: 15px;
|
||||
}
|
||||
.footer .upper p {
|
||||
width: inherit;
|
||||
background-image: none;
|
||||
padding-left: 0px;
|
||||
}
|
||||
.footer .upper ul.pull-right {
|
||||
width: 270px;
|
||||
display: block;
|
||||
float: none;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.footer .upper ul.pull-right li {
|
||||
width: 90px;
|
||||
float: left;
|
||||
}
|
||||
.footer .upper ul.pull-right li a {
|
||||
margin: 0 auto;
|
||||
}
|
||||
.footer .lower {
|
||||
border-top: none;
|
||||
}
|
||||
.footer .lower ul.pull-left {
|
||||
display: none;
|
||||
}
|
||||
.footer .lower ul.pull-right {
|
||||
float: none;
|
||||
text-align: center;
|
||||
}
|
||||
.footer .lower ul.pull-right li {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
/*CSOL-site specific*/
|
||||
.poster a,
|
||||
.poster img {
|
||||
display: block;
|
||||
|
@ -495,20 +599,62 @@ input[type="password"].metered:focus:invalid + .password-meter {
|
|||
input[type="password"].metered:focus:invalid:focus + .password-meter {
|
||||
border-color: #e9322d;
|
||||
}
|
||||
/*landing page specific*/
|
||||
body.home {
|
||||
background-image: url('../img/background-chalkboard-green.jpg');
|
||||
background-repeat: no-repeat;
|
||||
-webkit-background-size: cover;
|
||||
-moz-background-size: cover;
|
||||
-o-background-size: cover;
|
||||
background-size: cover;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../img/background-chalkboard-green.jpg', sizingMethod='scale');
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../img/background-chalkboard-green.jpg', sizingMethod='scale')";
|
||||
overflow: visible;
|
||||
/* ------------------------------ */
|
||||
/* Mobile : width > iphone ------ */
|
||||
/* ------------------------------ */
|
||||
@media only screen and (min-width: 321px) and (max-width: 940px) {
|
||||
.navbar .brand {
|
||||
background-image: url('../img/csol_logo_480.png');
|
||||
height: 166px;
|
||||
}
|
||||
}
|
||||
body.home .container {
|
||||
width: 960px;
|
||||
/* ------------------------------ */
|
||||
/* Mobile : width <= iphone ----- */
|
||||
/* ------------------------------ */
|
||||
@media only screen and (max-width: 320px) {
|
||||
.navbar .brand {
|
||||
background-image: url('../img/csol_logo_320.png');
|
||||
height: 116px;
|
||||
}
|
||||
}
|
||||
/* ------------------------------ */
|
||||
/* CSOL-site SPECIFIC ----------- */
|
||||
/* ------------------------------ */
|
||||
/* ------------------------------ */
|
||||
/* Mobile : width <= iphone ---- */
|
||||
/* ------------------------------ */
|
||||
@media only screen and (max-width: 320px) {
|
||||
.span3 {
|
||||
width: 150px;
|
||||
}
|
||||
ul.thumbnails li figure.thumbnail > a img {
|
||||
width: 140px;
|
||||
}
|
||||
ul.thumbnails li figure.thumbnail {
|
||||
margin: 0 0 0 0;
|
||||
}
|
||||
ul.thumbnails li figure.thumbnail > a img {
|
||||
display: block;
|
||||
width: 140px;
|
||||
height: 140px;
|
||||
background-image: url('../img/badge-default-320.png');
|
||||
}
|
||||
ul.thumbnails li:nth-child(2n+2) figure.thumbnail > a img {
|
||||
background-position: 0 -140px;
|
||||
}
|
||||
ul.thumbnails li:nth-child(3n+3) figure.thumbnail > a img {
|
||||
background-position: -140px 0px;
|
||||
}
|
||||
ul.thumbnails li:nth-child(4n+4) figure.thumbnail > a img {
|
||||
background-position: -140px -140px;
|
||||
}
|
||||
}
|
||||
/* ------------------------------ */
|
||||
/* Landing page ---------------- */
|
||||
/* ------------------------------ */
|
||||
body.home #main {
|
||||
padding: 0 0 0 0;
|
||||
display: none;
|
||||
}
|
||||
body.home .navbar {
|
||||
-webkit-box-shadow: 0px 10px 20px 0px rgba(0, 0, 0, 0.25);
|
||||
|
@ -516,24 +662,9 @@ body.home .navbar {
|
|||
box-shadow: 0px 10px 20px 0px rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
body.home .navbar .navbar-inner {
|
||||
background-image: url('../img/spacedimg.jpg');
|
||||
background-repeat: no-repeat;
|
||||
background-position: top center;
|
||||
-webkit-background-size: cover;
|
||||
-moz-background-size: cover;
|
||||
-o-background-size: cover;
|
||||
background-size: cover;
|
||||
padding-top: 0px;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../img/spacedimg.png', sizingMethod='scale');
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../img/spacedimg.png', sizingMethod='scale')";
|
||||
overflow: visible;
|
||||
max-height: 515px;
|
||||
}
|
||||
body.home .navbar .navbar-inner > .container {
|
||||
background-image: url('../img/home_drawing.png');
|
||||
background-position: top center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
body.home .navbar .nav > li.dropdown.open > .dropdown-toggle {
|
||||
color: #fff;
|
||||
}
|
||||
|
@ -541,7 +672,7 @@ body.home .navbar .brand {
|
|||
background-image: url('../img/csol_logo_sm.png');
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
margin-left: -102px;
|
||||
margin-left: -93px;
|
||||
z-index: 2;
|
||||
top: 50px;
|
||||
width: 189px;
|
||||
|
@ -552,36 +683,35 @@ body.home .navbar .nav-wrap {
|
|||
width: inherit;
|
||||
margin-bottom: 0px;
|
||||
height: 600px;
|
||||
width: 310px;
|
||||
width: 314px;
|
||||
margin: 0 auto;
|
||||
background: none;
|
||||
background-image: url('../img/banner300.png');
|
||||
background-image: url('../img/banner314.png');
|
||||
background-position: top center;
|
||||
background-repeat: no-repeat;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
box-shadow: none;
|
||||
}
|
||||
body.home .navbar .nav-wrap ul {
|
||||
body.home .navbar .nav-wrap ul.nav {
|
||||
padding-top: 200px;
|
||||
left: -6px;
|
||||
}
|
||||
body.home .navbar .nav-wrap ul > li {
|
||||
body.home .navbar .nav-wrap ul.nav > li {
|
||||
text-align: left;
|
||||
display: block;
|
||||
line-height: 9px;
|
||||
}
|
||||
body.home .navbar .nav-wrap ul > li > a {
|
||||
body.home .navbar .nav-wrap ul.nav > li > a {
|
||||
text-transform: inherit;
|
||||
font-size: 22px;
|
||||
color: #f4fc00;
|
||||
text-transform: lowercase;
|
||||
}
|
||||
body.home .navbar .nav-wrap ul > li.learn > a:first-letter {
|
||||
body.home .navbar .nav-wrap ul.nav > li.learn > a:first-letter {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
body.home .navbar .nav-wrap ul > li.log-in > a,
|
||||
body.home .navbar .nav-wrap ul > li.about > a {
|
||||
body.home .navbar .nav-wrap ul.nav > li.log-in > a,
|
||||
body.home .navbar .nav-wrap ul.nav > li.about > a {
|
||||
font-size: 18px;
|
||||
color: #fff;
|
||||
text-transform: lowercase;
|
||||
|
@ -589,19 +719,19 @@ body.home .navbar .nav-wrap ul > li.about > a {
|
|||
text-align: center;
|
||||
line-height: 24px;
|
||||
}
|
||||
body.home .navbar .nav-wrap ul > li.claim > a {
|
||||
body.home .navbar .nav-wrap ul.nav > li.claim > a {
|
||||
text-align: center;
|
||||
text-transform: capitalize;
|
||||
margin-top: 5px;
|
||||
}
|
||||
body.home .navbar .nav-wrap ul > li.claim > a:before,
|
||||
body.home .navbar .nav-wrap ul > li.claim > a:after {
|
||||
body.home .navbar .nav-wrap ul.nav > li.claim > a:before,
|
||||
body.home .navbar .nav-wrap ul.nav > li.claim > a:after {
|
||||
content: '-';
|
||||
}
|
||||
body.home .navbar .nav-wrap ul > li.video {
|
||||
body.home .navbar .nav-wrap ul.nav > li.video {
|
||||
margin: 30px 0;
|
||||
}
|
||||
body.home .navbar .nav-wrap ul > li.video a {
|
||||
body.home .navbar .nav-wrap ul.nav > li.video a {
|
||||
color: #fff;
|
||||
border-radius: 7px;
|
||||
margin: auto;
|
||||
|
@ -618,140 +748,207 @@ body.home .navbar .nav-wrap ul > li.video a {
|
|||
background: linear-gradient(to bottom, #e82202 0%, #e5381d 44%, #e56854 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#e82202', endColorstr='#e56854', GradientType=0);
|
||||
}
|
||||
body.home .navbar .nav-wrap ul > li span {
|
||||
body.home .navbar .nav-wrap ul.nav > li span {
|
||||
color: #fff;
|
||||
}
|
||||
body.home .navbar .nav-wrap ul > li:nth-child(even) {
|
||||
body.home .navbar .nav-wrap ul.nav > li:nth-child(even) {
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
body.home #main {
|
||||
padding: 0 0 0 0;
|
||||
display: none;
|
||||
/* ------------------------------ */
|
||||
/* Landing page : larger displays */
|
||||
/* ------------------------------ */
|
||||
@media screen and (min-width: 600px) {
|
||||
body.home {
|
||||
background-image: url('../img/background-chalkboard-green.jpg');
|
||||
background-repeat: no-repeat;
|
||||
-webkit-background-size: cover;
|
||||
-moz-background-size: cover;
|
||||
-o-background-size: cover;
|
||||
background-size: cover;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../img/background-chalkboard-green.jpg', sizingMethod='scale');
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../img/background-chalkboard-green.jpg', sizingMethod='scale')";
|
||||
overflow: visible;
|
||||
}
|
||||
body.home .navbar .navbar-inner {
|
||||
background-image: url('../img/spacedimg.jpg');
|
||||
background-repeat: no-repeat;
|
||||
background-position: top center;
|
||||
-webkit-background-size: cover;
|
||||
-moz-background-size: cover;
|
||||
-o-background-size: cover;
|
||||
background-size: cover;
|
||||
padding-top: 0px;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../img/spacedimg.png', sizingMethod='scale');
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../img/spacedimg.png', sizingMethod='scale')";
|
||||
}
|
||||
body.home .navbar .navbar-inner > .container {
|
||||
background-image: url('../img/home_drawing.png');
|
||||
background-position: top center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
body.home .container {
|
||||
width: 960px;
|
||||
}
|
||||
body.home .navbar-static-top .container {
|
||||
width: inherit;
|
||||
}
|
||||
body.home .secondary .upper {
|
||||
padding-top: 15px;
|
||||
position: relative;
|
||||
}
|
||||
body.home .secondary .upper > p.pull-left {
|
||||
display: none;
|
||||
}
|
||||
body.home .secondary .upper > .pull-right {
|
||||
float: left;
|
||||
text-align: center;
|
||||
width: 340px;
|
||||
padding-top: 55px;
|
||||
position: relative;
|
||||
}
|
||||
body.home .secondary .upper > .pull-right li:nth-child(even) {
|
||||
margin: 12px;
|
||||
}
|
||||
body.home .secondary .lower {
|
||||
border-top: none;
|
||||
}
|
||||
body.home .secondary .lower .pull-right li:first-child {
|
||||
display: none;
|
||||
}
|
||||
body.home .secondary .lower .pull-right li:nth-child(2) {
|
||||
border-left: none;
|
||||
}
|
||||
body.home .footer {
|
||||
-webkit-box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
body.home #rahm {
|
||||
position: relative;
|
||||
width: 210px;
|
||||
padding-left: 100px;
|
||||
padding-top: 15px;
|
||||
background-image: url('../img/rahm.png');
|
||||
background-repeat: no-repeat;
|
||||
background-position: center left;
|
||||
float: left;
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
body.home #bubbles {
|
||||
float: left;
|
||||
background-image: url('../img/bubbles.png');
|
||||
width: 310px;
|
||||
height: 140px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 18px 0px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
body.home #bubbles span {
|
||||
color: #000;
|
||||
display: block;
|
||||
width: 100px;
|
||||
}
|
||||
body.home #bubbles span.lt {
|
||||
float: left;
|
||||
margin-left: 34px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
body.home #bubbles span.lt a {
|
||||
color: #3B5998;
|
||||
}
|
||||
body.home #bubbles span.rt {
|
||||
margin-top: 52px;
|
||||
margin-right: 7px;
|
||||
float: right;
|
||||
font-size: 24px;
|
||||
line-height: 20px;
|
||||
}
|
||||
body.home .footer {
|
||||
background-image: none;
|
||||
}
|
||||
body.home #bkg_fade {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url('../img/65pb.png');
|
||||
margin: 0 0 0 0;
|
||||
padding: 0 0 0 0;
|
||||
z-index: 3;
|
||||
}
|
||||
body.home #i_vid_wrap {
|
||||
width: 640px;
|
||||
height: 360px;
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-top: -204px;
|
||||
margin-left: -348px;
|
||||
z-index: 4;
|
||||
background-color: #000;
|
||||
padding: 28px;
|
||||
border-radius: 7px;
|
||||
}
|
||||
body.home #cl_i_vid {
|
||||
background-image: url('../img/close.png');
|
||||
position: absolute;
|
||||
top: -7px;
|
||||
right: -7px;
|
||||
display: block;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
text-indent: -9000px;
|
||||
}
|
||||
}
|
||||
body.home .navbar-static-top .container {
|
||||
width: inherit;
|
||||
}
|
||||
body.home .secondary .upper {
|
||||
padding-top: 15px;
|
||||
position: relative;
|
||||
}
|
||||
body.home .secondary .upper > p.pull-left {
|
||||
display: none;
|
||||
}
|
||||
body.home .secondary .upper > .pull-right {
|
||||
float: left;
|
||||
text-align: center;
|
||||
width: 340px;
|
||||
padding-top: 55px;
|
||||
position: relative;
|
||||
left: -7px;
|
||||
}
|
||||
body.home .secondary .upper > .pull-right li:nth-child(even) {
|
||||
margin: 12px;
|
||||
}
|
||||
body.home .secondary .lower {
|
||||
border-top: none;
|
||||
}
|
||||
body.home .secondary .lower .pull-right li:first-child {
|
||||
display: none;
|
||||
}
|
||||
body.home .secondary .lower .pull-right li:nth-child(2) {
|
||||
border-left: none;
|
||||
}
|
||||
body.home .footer {
|
||||
-webkit-box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
body.home #rahm {
|
||||
position: relative;
|
||||
width: 210px;
|
||||
padding-left: 100px;
|
||||
padding-top: 15px;
|
||||
background-image: url('../img/rahm.png');
|
||||
background-repeat: no-repeat;
|
||||
background-position: center left;
|
||||
float: left;
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
body.home #bubbles {
|
||||
float: left;
|
||||
background-image: url('../img/bubbles.png');
|
||||
width: 310px;
|
||||
height: 140px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 18px 0px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
body.home #bubbles span {
|
||||
color: #000;
|
||||
display: block;
|
||||
width: 100px;
|
||||
}
|
||||
body.home #bubbles span.lt {
|
||||
float: left;
|
||||
margin-left: 34px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
body.home #bubbles span.lt a {
|
||||
color: #3B5998;
|
||||
}
|
||||
body.home #bubbles span.rt {
|
||||
margin-top: 52px;
|
||||
margin-right: 7px;
|
||||
float: right;
|
||||
font-size: 24px;
|
||||
line-height: 20px;
|
||||
}
|
||||
body.home .footer {
|
||||
background-image: none;
|
||||
}
|
||||
body.home #bkg_fade {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url('../img/65pb.png');
|
||||
margin: 0 0 0 0;
|
||||
padding: 0 0 0 0;
|
||||
z-index: 3;
|
||||
}
|
||||
body.home #i_vid_wrap {
|
||||
width: 640px;
|
||||
height: 360px;
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-top: -204px;
|
||||
margin-left: -348px;
|
||||
z-index: 4;
|
||||
background-color: #000;
|
||||
padding: 28px;
|
||||
border-radius: 7px;
|
||||
}
|
||||
body.home #cl_i_vid {
|
||||
background-image: url('../img/close.png');
|
||||
position: absolute;
|
||||
top: -7px;
|
||||
right: -7px;
|
||||
display: block;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
text-indent: -9000px;
|
||||
}
|
||||
.filter {
|
||||
color: #EEE;
|
||||
}
|
||||
.filter select {
|
||||
margin-right: 10px;
|
||||
width: 115px;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
.filter input {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
.filter .navbar-inner {
|
||||
padding-left: 10px;
|
||||
/* ------------------------------ */
|
||||
/* Landing page : mobile -------- */
|
||||
/* ------------------------------ */
|
||||
@media only screen and (min-width: 320px) and (max-width: 599px) {
|
||||
body.home {
|
||||
background-image: url('../img/chalkboard_bg.jpg');
|
||||
}
|
||||
body.home .navbar {
|
||||
-webkit-box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
body.home .navbar div.navbar-inner {
|
||||
padding-top: 0px;
|
||||
background-image: none;
|
||||
background: none;
|
||||
border: none;
|
||||
-webkit-box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
body.home .navbar .nav-wrap ul.nav li {
|
||||
display: block;
|
||||
}
|
||||
body.home .navbar .nav-wrap ul.nav li a {
|
||||
padding: 10px 15px 10px;
|
||||
}
|
||||
body.home .footer {
|
||||
background-image: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
body.home .footer .upper {
|
||||
padding-top: 70px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
body.home .footer .upper p,
|
||||
body.home .footer .upper div {
|
||||
display: none;
|
||||
}
|
||||
body.home .footer .upper ul {
|
||||
width: 90%;
|
||||
display: block;
|
||||
}
|
||||
body.home .footer .upper ul li {
|
||||
width: 32%;
|
||||
}
|
||||
body.home .footer .upper ul li a {
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 6.6 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 17 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 20 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 35 KiB |
|
@ -1,6 +1,12 @@
|
|||
$(document).ready(function(){
|
||||
|
||||
var mob = 0;
|
||||
|
||||
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent) ) mob = 1
|
||||
|
||||
$('.show-tooltip').tooltip();
|
||||
if($('body.home').length != 0) {
|
||||
|
||||
var vidLink = $('<a href="#">watch video</a>').click(function(){
|
||||
if($('#i_vid').length == 0) {
|
||||
var bkgFade = $('<div id="bkg_fade" style="display:none;"></div>');
|
||||
|
@ -23,6 +29,11 @@ $(document).ready(function(){
|
|||
/*landing page menu rearrange*/
|
||||
$('<p id="rahm">This summer Mayor Rahm Emanuel is challenging all Chicago youth to participate in the Summer of Learning. School stops for the summer, but learning never should.</p>').prependTo('.footer .upper');
|
||||
$('<div id="bubbles"><span class="lt">join the conversation on <a href="#">Facebook</a>.</span><span class="rt">share stories</span></div>').appendTo('.footer .upper');
|
||||
|
||||
if(mob) {
|
||||
vidLink = '<a href="http://www.youtube.com/v/6WwpwtYNsNk">watch video</a>';
|
||||
}
|
||||
|
||||
$('li.claim').after($('<li class="video"></li>').append(vidLink));
|
||||
$('li.log-in').before($('.about'));
|
||||
|
||||
|
|
|
@ -93,6 +93,7 @@ ol {
|
|||
}
|
||||
.navbar-inner {
|
||||
background-image:url('../img/chalkboard_bg.jpg');
|
||||
background-repeat:repeat;
|
||||
}
|
||||
form.navbar-inner {
|
||||
padding:7px;
|
||||
|
@ -114,8 +115,8 @@ ol {
|
|||
box-shadow:0 0 8px 3px rgba(0, 0, 0, 0.25);
|
||||
background:#fff;
|
||||
text-align:center;
|
||||
ul {
|
||||
display:inline-block;
|
||||
ul.nav {
|
||||
display:inline-block;
|
||||
margin:0 0 0 0;
|
||||
& > li {
|
||||
float:none;
|
||||
|
@ -170,6 +171,7 @@ nav.pagination {
|
|||
-webkit-box-shadow:inset 0px 10px 20px 0px rgba(0, 0, 0, 0.25);
|
||||
-moz-box-shadow:inset 0px 10px 20px 0px rgba(0, 0, 0, 0.25);
|
||||
box-shadow:inset 0px 10px 20px 0px rgba(0, 0, 0, 0.25);
|
||||
background-repeat:repeat;
|
||||
a {
|
||||
color: #fff;
|
||||
}
|
||||
|
@ -261,12 +263,123 @@ nav.pagination {
|
|||
}
|
||||
|
||||
&.secondary {
|
||||
position:relative;
|
||||
position:relative;
|
||||
color:#fff;
|
||||
overflow:hidden;
|
||||
}
|
||||
}
|
||||
|
||||
/*mobile*/
|
||||
@media only screen
|
||||
and (min-width : 320px)
|
||||
and (max-width : 599px) {
|
||||
.container p, .container h1, .container h2, .footer .upper p {
|
||||
width:inherit;
|
||||
}
|
||||
#main {
|
||||
padding-top:15px;
|
||||
}
|
||||
.form-search label, .form-inline label, .form-search .btn-group, .form-inline .btn-group {
|
||||
display:block;
|
||||
}
|
||||
.filter label {
|
||||
display:none;
|
||||
}
|
||||
.navbar .nav-wrap,
|
||||
.container,
|
||||
.navbar-static-top .container,
|
||||
.navbar-fixed-top .container,
|
||||
.navbar-fixed-bottom .container,
|
||||
.navbar .brand {
|
||||
width:95%;
|
||||
margin:0 0 0 0;
|
||||
padding:0 0 0 0;
|
||||
margin-left:auto;
|
||||
margin-right:auto;
|
||||
}
|
||||
.form-horizontal {
|
||||
.control-label {
|
||||
text-align:left;
|
||||
float:none;
|
||||
}
|
||||
.controls {
|
||||
margin-left:0px;
|
||||
}
|
||||
}
|
||||
.span6 {
|
||||
width:inherit;
|
||||
}
|
||||
|
||||
|
||||
/*mobile navbar*/
|
||||
.navbar {
|
||||
div.navbar-inner {
|
||||
padding-left:0px;
|
||||
padding-right:0px;
|
||||
padding-top:10px;
|
||||
padding-bottom:10px;
|
||||
border:none;
|
||||
}
|
||||
.nav-wrap {
|
||||
width:90%;
|
||||
margin:0 auto;
|
||||
ul.nav {
|
||||
li {
|
||||
display:block;
|
||||
a {
|
||||
padding: 5px 0;
|
||||
}
|
||||
}
|
||||
li:nth-child(even),
|
||||
& > .active > a,
|
||||
& > .active > a:hover,
|
||||
{
|
||||
border-left:none;
|
||||
border-right:none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*mobile footer*/
|
||||
.footer {
|
||||
.upper {
|
||||
padding-top:15px;
|
||||
p {
|
||||
width:inherit;
|
||||
background-image:none;
|
||||
padding-left:0px;
|
||||
}
|
||||
ul.pull-right {
|
||||
width:270px;
|
||||
display:block;
|
||||
float:none;
|
||||
margin:0 auto;
|
||||
li {
|
||||
width:90px;
|
||||
float:left;
|
||||
a {
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.lower {
|
||||
border-top:none;
|
||||
ul.pull-left {
|
||||
display:none;
|
||||
}
|
||||
ul.pull-right {
|
||||
float:none;
|
||||
text-align:center;
|
||||
li {
|
||||
display:inline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*CSOL-site specific*/
|
||||
.poster a,
|
||||
.poster img {
|
||||
display: block;
|
||||
|
@ -591,43 +704,96 @@ input[type="password"].metered {
|
|||
}
|
||||
}
|
||||
|
||||
/*landing page specific*/
|
||||
body.home {
|
||||
background-image:url('../img/background-chalkboard-green.jpg');
|
||||
background-repeat:no-repeat;
|
||||
-webkit-background-size:cover;
|
||||
-moz-background-size:cover;
|
||||
-o-background-size:cover;
|
||||
background-size:cover;
|
||||
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../img/background-chalkboard-green.jpg', sizingMethod='scale');
|
||||
-ms-filter:"progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../img/background-chalkboard-green.jpg', sizingMethod='scale')";
|
||||
overflow:visible;
|
||||
.container {
|
||||
width:960px;
|
||||
/* ------------------------------ */
|
||||
/* Mobile : width > iphone ------ */
|
||||
/* ------------------------------ */
|
||||
@media only screen
|
||||
and (min-width : 321px)
|
||||
and (max-width : 940px ) {
|
||||
.navbar .brand {
|
||||
background-image: url('../img/csol_logo_480.png');
|
||||
height:166px;
|
||||
}
|
||||
.navbar {
|
||||
-webkit-box-shadow:0px 10px 20px 0px rgba(0, 0, 0, 0.25);
|
||||
-moz-box-shadow:0px 10px 20px 0px rgba(0, 0, 0, 0.25);
|
||||
box-shadow:0px 10px 20px 0px rgba(0, 0, 0, 0.25);
|
||||
.navbar-inner {
|
||||
background-image:url('../img/spacedimg.jpg');
|
||||
background-repeat:no-repeat;
|
||||
background-position:top center;
|
||||
-webkit-background-size:cover;
|
||||
-moz-background-size:cover;
|
||||
-o-background-size:cover;
|
||||
background-size:cover;
|
||||
padding-top:0px;
|
||||
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../img/spacedimg.png', sizingMethod='scale');
|
||||
-ms-filter:"progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../img/spacedimg.png', sizingMethod='scale')";
|
||||
overflow:visible;
|
||||
max-height:515px;
|
||||
}
|
||||
|
||||
/* ------------------------------ */
|
||||
/* Mobile : width <= iphone ----- */
|
||||
/* ------------------------------ */
|
||||
@media only screen
|
||||
and (max-width : 320px) {
|
||||
.navbar .brand {
|
||||
background-image: url('../img/csol_logo_320.png');
|
||||
height:116px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------ */
|
||||
/* CSOL-site SPECIFIC ----------- */
|
||||
/* ------------------------------ */
|
||||
|
||||
/* ------------------------------ */
|
||||
/* Mobile : width <= iphone ---- */
|
||||
/* ------------------------------ */
|
||||
@media only screen
|
||||
and (max-width : 320px) {
|
||||
.span3 {
|
||||
width:150px;
|
||||
}
|
||||
ul.thumbnails li figure.thumbnail > a img {
|
||||
width:140px;
|
||||
}
|
||||
ul.thumbnails {
|
||||
li {
|
||||
figure.thumbnail {
|
||||
margin:0 0 0 0;
|
||||
& > a img {
|
||||
display:block;
|
||||
width:140px;
|
||||
height:140px;
|
||||
background-image:url('../img/badge-default-320.png');
|
||||
}
|
||||
}
|
||||
}
|
||||
li:nth-child(2n+2) {
|
||||
figure.thumbnail {
|
||||
& > a img {
|
||||
background-position:0 -140px;
|
||||
}
|
||||
}
|
||||
}
|
||||
li:nth-child(3n+3) {
|
||||
figure.thumbnail {
|
||||
& > a img {
|
||||
background-position:-140px 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
li:nth-child(4n+4) {
|
||||
figure.thumbnail {
|
||||
& > a img {
|
||||
background-position:-140px -140px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------ */
|
||||
/* Landing page ---------------- */
|
||||
/* ------------------------------ */
|
||||
body.home {
|
||||
#main {
|
||||
padding:0 0 0 0;
|
||||
display:none;
|
||||
}
|
||||
.navbar {
|
||||
-webkit-box-shadow:0px 10px 20px 0px rgba(0, 0, 0, 0.25);
|
||||
-moz-box-shadow:0px 10px 20px 0px rgba(0, 0, 0, 0.25);
|
||||
box-shadow:0px 10px 20px 0px rgba(0, 0, 0, 0.25);
|
||||
.navbar-inner {
|
||||
overflow:visible;
|
||||
max-height:515px;
|
||||
|
||||
& > .container {
|
||||
background-image:url('../img/home_drawing.png');
|
||||
background-position:top center;
|
||||
background-repeat:no-repeat;
|
||||
}
|
||||
}
|
||||
.nav {
|
||||
& > li {
|
||||
|
@ -640,7 +806,7 @@ body.home {
|
|||
background-image:url('../img/csol_logo_sm.png');
|
||||
position:absolute;
|
||||
left:50%;
|
||||
margin-left:-102px;
|
||||
margin-left:-93px;
|
||||
z-index:2;
|
||||
top:50px;
|
||||
width:189px;
|
||||
|
@ -651,18 +817,17 @@ body.home {
|
|||
width:inherit;
|
||||
margin-bottom:0px;
|
||||
height:600px;
|
||||
width:310px;
|
||||
width:314px;
|
||||
margin:0 auto;
|
||||
background:none;
|
||||
background-image:url('../img/banner300.png');
|
||||
background-image:url('../img/banner314.png');
|
||||
background-position:top center;
|
||||
background-repeat:no-repeat;
|
||||
position:relative;
|
||||
z-index:1;
|
||||
box-shadow:none;
|
||||
ul {
|
||||
ul.nav {
|
||||
padding-top:200px;
|
||||
left:-6px;
|
||||
& > li {
|
||||
text-align:left;
|
||||
display:block;
|
||||
|
@ -723,145 +888,217 @@ body.home {
|
|||
}
|
||||
}
|
||||
}
|
||||
#main {
|
||||
padding:0 0 0 0;
|
||||
display:none;
|
||||
}
|
||||
|
||||
}
|
||||
.navbar-static-top {
|
||||
.container {
|
||||
width:inherit;
|
||||
}
|
||||
}
|
||||
.secondary {
|
||||
.upper {
|
||||
padding-top:15px;
|
||||
position:relative;
|
||||
> p.pull-left {
|
||||
display:none;
|
||||
}
|
||||
> .pull-right {
|
||||
float:left;
|
||||
text-align:center;
|
||||
width:340px;
|
||||
padding-top:55px;
|
||||
position:relative;
|
||||
left:-7px;
|
||||
li:nth-child(even){
|
||||
margin:12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.lower {
|
||||
border-top:none;
|
||||
.pull-right {
|
||||
li:first-child {
|
||||
display:none;
|
||||
}
|
||||
li:nth-child(2) {
|
||||
border-left:none;
|
||||
}
|
||||
/* ------------------------------ */
|
||||
/* Landing page : larger displays */
|
||||
/* ------------------------------ */
|
||||
@media screen and (min-width: 600px) {
|
||||
body.home {
|
||||
.navbar {
|
||||
.navbar-inner {
|
||||
background-image:url('../img/spacedimg.jpg');
|
||||
background-repeat:no-repeat;
|
||||
background-position:top center;
|
||||
-webkit-background-size:cover;
|
||||
-moz-background-size:cover;
|
||||
-o-background-size:cover;
|
||||
background-size:cover;
|
||||
padding-top:0px;
|
||||
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../img/spacedimg.png', sizingMethod='scale');
|
||||
-ms-filter:"progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../img/spacedimg.png', sizingMethod='scale')";
|
||||
& > .container {
|
||||
background-image:url('../img/home_drawing.png');
|
||||
background-position:top center;
|
||||
background-repeat:no-repeat;
|
||||
}
|
||||
}
|
||||
}
|
||||
background-image:url('../img/background-chalkboard-green.jpg');
|
||||
background-repeat:no-repeat;
|
||||
-webkit-background-size:cover;
|
||||
-moz-background-size:cover;
|
||||
-o-background-size:cover;
|
||||
background-size:cover;
|
||||
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../img/background-chalkboard-green.jpg', sizingMethod='scale');
|
||||
-ms-filter:"progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../img/background-chalkboard-green.jpg', sizingMethod='scale')";
|
||||
overflow:visible;
|
||||
.container {
|
||||
width:960px;
|
||||
}
|
||||
.navbar-static-top {
|
||||
.container {
|
||||
width:inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
.footer {
|
||||
-webkit-box-shadow:none;
|
||||
-moz-box-shadow:none;
|
||||
box-shadow:none;
|
||||
}
|
||||
#rahm {
|
||||
position:relative;
|
||||
width:210px;
|
||||
padding-left:100px;
|
||||
padding-top:15px;
|
||||
background-image:url('../img/rahm.png');
|
||||
background-repeat:no-repeat;
|
||||
background-position:center left;
|
||||
float:left;
|
||||
-webkit-hyphens:none;
|
||||
-moz-hyphens:none;
|
||||
hyphens:none;
|
||||
}
|
||||
#bubbles {
|
||||
float:left;
|
||||
background-image:url('../img/bubbles.png');
|
||||
width:310px;
|
||||
height:140px;
|
||||
background-repeat:no-repeat;
|
||||
background-position:18px 0px;
|
||||
margin-top:15px;
|
||||
span {
|
||||
color:#000;
|
||||
display:block;
|
||||
width:100px;
|
||||
&.lt {
|
||||
float:left;
|
||||
margin-left:34px;
|
||||
margin-top:12px;
|
||||
a {
|
||||
color:#3B5998;
|
||||
}
|
||||
}
|
||||
&.rt {
|
||||
margin-top:52px;
|
||||
margin-right:7px;
|
||||
float:right;
|
||||
font-size:24px;
|
||||
line-height:20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.footer {
|
||||
background-image: none;
|
||||
}
|
||||
#bkg_fade {
|
||||
position:fixed;
|
||||
width:100%;
|
||||
height:100%;
|
||||
background-image:url('../img/65pb.png');
|
||||
margin:0 0 0 0;
|
||||
padding:0 0 0 0;
|
||||
z-index:3;
|
||||
}
|
||||
#i_vid_wrap {
|
||||
width:640px;
|
||||
height:360px;
|
||||
position:fixed;
|
||||
top:50%;
|
||||
left:50%;
|
||||
margin-top:-204px;
|
||||
margin-left:-348px;
|
||||
z-index:4;
|
||||
background-color:#000;
|
||||
padding:28px;
|
||||
border-radius:7px;
|
||||
}
|
||||
#cl_i_vid {
|
||||
background-image:url('../img/close.png');
|
||||
position:absolute;
|
||||
top:-7px;
|
||||
right:-7px;
|
||||
display:block;
|
||||
width:25px;
|
||||
height:25px;
|
||||
text-indent:-9000px;
|
||||
}
|
||||
}
|
||||
|
||||
.filter {
|
||||
color: #EEE;
|
||||
|
||||
select {
|
||||
margin-right: 10px;
|
||||
width: 115px;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
input {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
.navbar-inner {
|
||||
padding-left: 10px;
|
||||
}
|
||||
.secondary {
|
||||
.upper {
|
||||
padding-top:15px;
|
||||
position:relative;
|
||||
> p.pull-left {
|
||||
display:none;
|
||||
}
|
||||
> .pull-right {
|
||||
float:left;
|
||||
text-align:center;
|
||||
width:340px;
|
||||
padding-top:55px;
|
||||
position:relative;
|
||||
li:nth-child(even){
|
||||
margin:12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.lower {
|
||||
border-top:none;
|
||||
.pull-right {
|
||||
li:first-child {
|
||||
display:none;
|
||||
}
|
||||
li:nth-child(2) {
|
||||
border-left:none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.footer {
|
||||
-webkit-box-shadow:none;
|
||||
-moz-box-shadow:none;
|
||||
box-shadow:none;
|
||||
}
|
||||
#rahm {
|
||||
position:relative;
|
||||
width:210px;
|
||||
padding-left:100px;
|
||||
padding-top:15px;
|
||||
background-image:url('../img/rahm.png');
|
||||
background-repeat:no-repeat;
|
||||
background-position:center left;
|
||||
float:left;
|
||||
-webkit-hyphens:none;
|
||||
-moz-hyphens:none;
|
||||
hyphens:none;
|
||||
}
|
||||
#bubbles {
|
||||
float:left;
|
||||
background-image:url('../img/bubbles.png');
|
||||
width:310px;
|
||||
height:140px;
|
||||
background-repeat:no-repeat;
|
||||
background-position:18px 0px;
|
||||
margin-top:15px;
|
||||
span {
|
||||
color:#000;
|
||||
display:block;
|
||||
width:100px;
|
||||
&.lt {
|
||||
float:left;
|
||||
margin-left:34px;
|
||||
margin-top:12px;
|
||||
a {
|
||||
color:#3B5998;
|
||||
}
|
||||
}
|
||||
&.rt {
|
||||
margin-top:52px;
|
||||
margin-right:7px;
|
||||
float:right;
|
||||
font-size:24px;
|
||||
line-height:20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.footer {
|
||||
background-image: none;
|
||||
}
|
||||
#bkg_fade {
|
||||
position:fixed;
|
||||
width:100%;
|
||||
height:100%;
|
||||
background-image:url('../img/65pb.png');
|
||||
margin:0 0 0 0;
|
||||
padding:0 0 0 0;
|
||||
z-index:3;
|
||||
}
|
||||
#i_vid_wrap {
|
||||
width:640px;
|
||||
height:360px;
|
||||
position:fixed;
|
||||
top:50%;
|
||||
left:50%;
|
||||
margin-top:-204px;
|
||||
margin-left:-348px;
|
||||
z-index:4;
|
||||
background-color:#000;
|
||||
padding:28px;
|
||||
border-radius:7px;
|
||||
}
|
||||
#cl_i_vid {
|
||||
background-image:url('../img/close.png');
|
||||
position:absolute;
|
||||
top:-7px;
|
||||
right:-7px;
|
||||
display:block;
|
||||
width:25px;
|
||||
height:25px;
|
||||
text-indent:-9000px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------ */
|
||||
/* Landing page : mobile -------- */
|
||||
/* ------------------------------ */
|
||||
@media only screen
|
||||
and (min-width : 320px)
|
||||
and (max-width : 599px) {
|
||||
body.home {
|
||||
background-image:url('../img/chalkboard_bg.jpg');
|
||||
.navbar {
|
||||
-webkit-box-shadow:none;
|
||||
-moz-box-shadow:none;
|
||||
box-shadow:none;
|
||||
div.navbar-inner {
|
||||
padding-top:0px;
|
||||
background-image:none;
|
||||
background:none;
|
||||
border:none;
|
||||
-webkit-box-shadow:none;
|
||||
-moz-box-shadow:none;
|
||||
box-shadow:none;
|
||||
}
|
||||
.nav-wrap {
|
||||
ul.nav {
|
||||
li {
|
||||
display:block;
|
||||
a {
|
||||
padding: 10px 15px 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.footer {
|
||||
background-image:none;
|
||||
box-shadow:none;
|
||||
.upper {
|
||||
padding-top:70px;
|
||||
padding-bottom:20px;
|
||||
p, div {
|
||||
display:none;
|
||||
}
|
||||
ul {
|
||||
width:90%;
|
||||
display:block;
|
||||
li {
|
||||
width:32%;
|
||||
a {
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ const FAKE_S3_DIR = path.join(__dirname, 's3-fake-storage-test');
|
|||
|
||||
function removeFakeS3Dir(t) {
|
||||
var root = FAKE_S3_DIR;
|
||||
var pathParts = ['', 'evidence', 'lol.txt'];
|
||||
var pathParts = ['', 'evidence'];
|
||||
|
||||
for (var i = pathParts.length; i > 0; i--) {
|
||||
var relpath = pathParts.slice(0, i).join(path.sep);
|
||||
|
@ -27,7 +27,8 @@ test('FakeS3 works', function(t) {
|
|||
removeFakeS3Dir();
|
||||
s3.putBuffer(new Buffer('hai2u', 'binary'), '/evidence/lol.txt', {
|
||||
'Content-Type': 'text/plain'
|
||||
}, function() {
|
||||
}, function(err) {
|
||||
t.equal(err, null);
|
||||
s3.get('/evidence/lol.txt').on('response', function(proxy) {
|
||||
var chunks = [];
|
||||
proxy.on('data', function(chunk) {
|
||||
|
@ -36,9 +37,12 @@ test('FakeS3 works', function(t) {
|
|||
proxy.on('end', function() {
|
||||
var buf = Buffer.concat(chunks);
|
||||
t.equal(buf.toString('ascii'), 'hai2u');
|
||||
removeFakeS3Dir(t);
|
||||
t.end();
|
||||
s3.deleteFile('/evidence/lol.txt', function(err) {
|
||||
t.equal(err, null);
|
||||
removeFakeS3Dir(t);
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
});
|
||||
}).end();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
{% extends 'layout.html' %}
|
||||
{% set navItem = 'programs' %}
|
||||
{% set navItem = 'badges' %}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{% extends 'filter.html' %}
|
||||
{% set pageTitle = 'Badges' %}
|
||||
{% set navItem = 'badges' %}
|
||||
|
||||
{% block content %}
|
||||
<p>The City of Chicago Summer of Learning badges recognize the cool things you do over the summer. When you learn something new, you can earn a badge. As you earn more badges you can do more cool things. When you go back to school in the fall, you can show off all the badges you earned to your teachers, parents, potential employers and friends!</p>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
<p class="text-right">
|
||||
{% if badge.activityType == 'offline' %}
|
||||
<a href="{{ badge.url }}/claim" class="btn">Claim this badge</a>
|
||||
<a href="/claim" class="btn">Claim this badge</a>
|
||||
{% else %}
|
||||
<a href="{{ badge.url }}/apply" class="btn">Apply</a>
|
||||
{% endif %}
|
||||
|
@ -22,56 +22,23 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<h3><a href="/badges">Similar or Related Badges</a></h3>
|
||||
<p>If you're interested in this badge, you might be interested in these too. These are badges on similar STEAM topics or ones that can take you to the next level.</p>
|
||||
<ul class="thumbnails">
|
||||
<li class="span3">
|
||||
<figure class="thumbnail">
|
||||
<a href="/badges/ae784f"><img src="/media/images/badge.png"></a>
|
||||
<figcaption class="caption">
|
||||
<p>Badge blah in voluptate velit...</p>
|
||||
<p class="text-right">
|
||||
<a href="/badges/ae784f" class="btn">Details</a>
|
||||
<a class="btn show-tooltip" title="Save this badge to your favorites" href="/badges/ae784f/favorite"><i class="icon-heart"></i></a>
|
||||
</p>
|
||||
</figcaption>
|
||||
</figure>
|
||||
</li>
|
||||
<li class="span3">
|
||||
<figure class="thumbnail">
|
||||
<a href="/badges/ae784f"><img src="/media/images/badge.png"></a>
|
||||
<figcaption class="caption">
|
||||
<p>Badge blah in voluptate velit...</p>
|
||||
<p class="text-right">
|
||||
<a href="/badges/ae784f" class="btn">Details</a>
|
||||
<a class="btn show-tooltip" title="Save this badge to your favorites" href="/badges/ae784f/favorite"><i class="icon-heart"></i></a>
|
||||
</p>
|
||||
</figcaption>
|
||||
</figure>
|
||||
</li>
|
||||
<li class="span3">
|
||||
<figure class="thumbnail">
|
||||
<a href="/badges/ae784f"><img src="/media/images/badge.png"></a>
|
||||
<figcaption class="caption">
|
||||
<p>Badge blah in voluptate velit...</p>
|
||||
<p class="text-right">
|
||||
<a href="/badges/ae784f" class="btn">Details</a>
|
||||
<a class="btn show-tooltip" title="Save this badge to your favorites" href="/badges/ae784f/favorite"><i class="icon-heart"></i></a>
|
||||
</p>
|
||||
</figcaption>
|
||||
</figure>
|
||||
</li>
|
||||
<li class="span3">
|
||||
<figure class="thumbnail">
|
||||
<a href="/badges/ae784f"><img src="/media/images/badge.png"></a>
|
||||
<figcaption class="caption">
|
||||
<p>Badge blah in voluptate velit...</p>
|
||||
<p class="text-right">
|
||||
<a href="/badges/ae784f" class="btn">Details</a>
|
||||
<a class="btn show-tooltip" title="Save this badge to your favorites" href="/badges/ae784f/favorite"><i class="icon-heart"></i></a>
|
||||
</p>
|
||||
</figcaption>
|
||||
</figure>
|
||||
</li>
|
||||
</ul>
|
||||
{% if relatedBadges and relatedBadges|length > 0 %}
|
||||
<h3><a href="/badges">Similar or Related Badges</a></h3>
|
||||
<p>If you're interested in this badge, you might be interested in these too. These are badges on similar STEAM topics or ones that can take you to the next level.</p>
|
||||
<ul class="thumbnails">
|
||||
{% for relatedBadge in relatedBadges %}
|
||||
<li class="span3">
|
||||
<figure class="thumbnail">
|
||||
<a href=""><img src="{{relatedBadge.image}}"></a>
|
||||
<figcaption class="caption">
|
||||
<p>{{relatedBadge.description}}</p>
|
||||
<p class="text-right">
|
||||
<a href="" class="btn">Details</a>
|
||||
</p>
|
||||
</figcaption>
|
||||
</figure>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -24,7 +24,8 @@
|
|||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
|
||||
<p>To claim the badge you've earned, enter the "claim code" written on the paper badge you received from your teacher, counselor or mentor.</p>
|
||||
<p>Then hit the "Claim This Badge" button on your screen. Once you do this, the badge will be added to your dashboard and you can throw the piece of paper away (better yet, recycle it!).</p>
|
||||
|
||||
<h3>Already have a claim code?</h3>
|
||||
<form method="get" class="form-horizontal well span6 offset3">
|
||||
|
@ -37,10 +38,10 @@
|
|||
</div>
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<button type="submit" class="btn">Claim this badge</button>
|
||||
<button type="submit" class="btn">Claim this Badge</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<img src="{{program.imageUrl}}">
|
||||
</div>
|
||||
<div class="span8">
|
||||
<p><strong>From <a href="/orgs/some-organization">Some Organization</a>.</strong></p>
|
||||
<p><strong>From <a href="/orgs/some-organization">{{program.issuer.name}}</a>.</strong></p>
|
||||
{% if program.description %}
|
||||
<p>{{program.description}}</p>
|
||||
{% endif %}
|
||||
|
@ -19,27 +19,18 @@
|
|||
</div>
|
||||
<h3><a href="/badges">Badges</a></h3>
|
||||
<ul class="thumbnails">
|
||||
{% for shortname,badge in program.earnableBadges %}
|
||||
<li class="span3">
|
||||
<figure class="thumbnail">
|
||||
<a href="/badges/ae784f"><img src="/media/images/badge.png"></a>
|
||||
<a href="/earn/{{shortname}}"><img src="{{badge.image}}"></a>
|
||||
<figcaption class="caption">
|
||||
<p>Badge blah in voluptate velit...</p>
|
||||
<p>{{badge.description}}</p>
|
||||
<p class="text-right">
|
||||
<a href="/badges/ae784f" class="btn">Details</a>
|
||||
</p>
|
||||
</figcaption>
|
||||
</figure>
|
||||
</li>
|
||||
<li class="span3">
|
||||
<figure class="thumbnail">
|
||||
<a href="/badges/ae784f"><img src="/media/images/badge.png"></a>
|
||||
<figcaption class="caption">
|
||||
<p>Badge blah in voluptate velit...</p>
|
||||
<p class="text-right">
|
||||
<a href="/badges/ae784f" class="btn">Details</a>
|
||||
<a href="/earn/{{shortname}}" class="btn">Details</a>
|
||||
</p>
|
||||
</figcaption>
|
||||
</figure>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock %}
|
Загрузка…
Ссылка в новой задаче