Merge branch 'master' into production
BIN
app/assets/images/pages/about/bracket_left.png
Executable file
After Width: | Height: | Size: 2.7 KiB |
BIN
app/assets/images/pages/about/bracket_right.png
Executable file
After Width: | Height: | Size: 2.7 KiB |
BIN
app/assets/images/pages/about/character_silouhette.png
Executable file
After Width: | Height: | Size: 7.8 KiB |
Before Width: | Height: | Size: 77 KiB |
BIN
app/assets/images/pages/about/codebackground_zoom_compressed.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
app/assets/images/pages/about/desert.png
Executable file
After Width: | Height: | Size: 344 KiB |
BIN
app/assets/images/pages/about/dungeon.png
Executable file
After Width: | Height: | Size: 455 KiB |
BIN
app/assets/images/pages/about/forest.png
Executable file
After Width: | Height: | Size: 765 KiB |
BIN
app/assets/images/pages/about/github.png
Executable file
After Width: | Height: | Size: 6.5 KiB |
BIN
app/assets/images/pages/about/github_avatars.png
Normal file
After Width: | Height: | Size: 294 KiB |
BIN
app/assets/images/pages/about/glacier.png
Executable file
After Width: | Height: | Size: 1,018 KiB |
BIN
app/assets/images/pages/about/globe_green.png
Executable file
After Width: | Height: | Size: 11 KiB |
BIN
app/assets/images/pages/about/globe_white.png
Executable file
After Width: | Height: | Size: 7.9 KiB |
BIN
app/assets/images/pages/about/languages.png
Executable file
After Width: | Height: | Size: 24 KiB |
BIN
app/assets/images/pages/about/languages_group1.png
Executable file
After Width: | Height: | Size: 12 KiB |
BIN
app/assets/images/pages/about/languages_group2.png
Executable file
After Width: | Height: | Size: 12 KiB |
BIN
app/assets/images/pages/about/screenshot_desert.png
Executable file
After Width: | Height: | Size: 90 KiB |
BIN
app/assets/images/pages/about/screenshot_dungeon.png
Executable file
After Width: | Height: | Size: 89 KiB |
BIN
app/assets/images/pages/about/screenshot_forest.png
Executable file
After Width: | Height: | Size: 144 KiB |
BIN
app/assets/images/pages/about/screenshot_glacier.png
Executable file
After Width: | Height: | Size: 147 KiB |
BIN
app/assets/images/pages/about/sketch.png
Executable file
After Width: | Height: | Size: 192 KiB |
|
@ -83,8 +83,8 @@ module.exports.setErrorToProperty = setErrorToProperty = (el, property, message,
|
||||||
setErrorToField input, message, warning
|
setErrorToField input, message, warning
|
||||||
|
|
||||||
module.exports.scrollToFirstError = ($el=$('body')) ->
|
module.exports.scrollToFirstError = ($el=$('body')) ->
|
||||||
$first = $el.find('.has-error, .alert-danger, .error-help-block, .has-warning, .alert-warning, .warning-help-block').first()
|
$first = $el.find('.has-error, .alert-danger, .error-help-block, .has-warning, .alert-warning, .warning-help-block').filter(':visible').first()
|
||||||
$('body').animate({ scrollTop: $first.offset().top - 20 }, 300)
|
$('html, body').animate({ scrollTop: $first.offset().top - 20 }, 300)
|
||||||
|
|
||||||
module.exports.clearFormAlerts = (el) ->
|
module.exports.clearFormAlerts = (el) ->
|
||||||
$('.has-error', el).removeClass('has-error')
|
$('.has-error', el).removeClass('has-error')
|
||||||
|
|
|
@ -25,7 +25,7 @@ module.exports = class LevelSetupManager extends CocoClass
|
||||||
loadLevel: ->
|
loadLevel: ->
|
||||||
levelURL = "/db/level/#{@options.levelID}"
|
levelURL = "/db/level/#{@options.levelID}"
|
||||||
@level = new Level().setURL levelURL
|
@level = new Level().setURL levelURL
|
||||||
@level = @supermodel.loadModel(@level, 'level').model
|
@level = @supermodel.loadModel(@level).model
|
||||||
if @level.loaded then @onLevelSync() else @listenToOnce @level, 'sync', @onLevelSync
|
if @level.loaded then @onLevelSync() else @listenToOnce @level, 'sync', @onLevelSync
|
||||||
|
|
||||||
loadSession: ->
|
loadSession: ->
|
||||||
|
@ -33,7 +33,7 @@ module.exports = class LevelSetupManager extends CocoClass
|
||||||
#sessionURL += "?team=#{@team}" if @options.team # TODO: figure out how to get the teams for multiplayer PVP hero style
|
#sessionURL += "?team=#{@team}" if @options.team # TODO: figure out how to get the teams for multiplayer PVP hero style
|
||||||
sessionURL += "?course=#{@options.courseID}" if @options.courseID
|
sessionURL += "?course=#{@options.courseID}" if @options.courseID
|
||||||
@session = new LevelSession().setURL sessionURL
|
@session = new LevelSession().setURL sessionURL
|
||||||
@session = @supermodel.loadModel(@session, 'level_session').model
|
@session = @supermodel.loadModel(@session).model
|
||||||
if @session.loaded then @onSessionSync() else @listenToOnce @session, 'sync', @onSessionSync
|
if @session.loaded then @onSessionSync() else @listenToOnce @session, 'sync', @onSessionSync
|
||||||
|
|
||||||
onLevelSync: ->
|
onLevelSync: ->
|
||||||
|
|
|
@ -286,6 +286,7 @@ module.exports.thangNames = thangNames =
|
||||||
'Gom'
|
'Gom'
|
||||||
'Grek'
|
'Grek'
|
||||||
'Gror'
|
'Gror'
|
||||||
|
'Grue'
|
||||||
'Il\'Du\'duka'
|
'Il\'Du\'duka'
|
||||||
'Makas'
|
'Makas'
|
||||||
'Mogadishu'
|
'Mogadishu'
|
||||||
|
|
|
@ -545,19 +545,11 @@
|
||||||
editor_config_behaviors_description: "Autocompletes brackets, braces, and quotes."
|
editor_config_behaviors_description: "Autocompletes brackets, braces, and quotes."
|
||||||
|
|
||||||
about:
|
about:
|
||||||
why_codecombat: "Why CodeCombat?"
|
mission_title: "Our mission: make programming accessible to every student on Earth."
|
||||||
why_paragraph_1: "If you want to learn to program, you don't need lessons. You need to write a lot of code and have a great time doing it."
|
mission_description_1: "Programming is magic. It's the ability to create things from pure imagination. We started CodeCombat to give learners the feeling of wizardly power at their fingertips by using typed code."
|
||||||
why_paragraph_2_prefix: "That's what programming is about. It's gotta be fun. Not fun like"
|
mission_description_2: "As it turns out, that enables them to learn faster too. WAY faster. It's like having a conversation instead of reading a manual. We want to bring that conversation to every school and to every student, because everyone should have the chance to learn the magic of programming."
|
||||||
why_paragraph_2_italic: "yay a badge"
|
team_title: "Meet the CodeCombat team"
|
||||||
why_paragraph_2_center: "but fun like"
|
team_values: "We value open and respectful dialog, where the best idea wins. Our decisions are grounded in customer research and our process is focused on delivering tangible results for them. Everyone is hands-on, from our CEO to our Github contributors, because we value growth and learning in our team."
|
||||||
why_paragraph_2_italic_caps: "NO MOM I HAVE TO FINISH THE LEVEL!"
|
|
||||||
why_paragraph_2_suffix: "That's why CodeCombat is a multiplayer game, not a gamified lesson course. We won't stop until you can't stop--but this time, that's a good thing."
|
|
||||||
why_paragraph_3: "If you're going to get addicted to some game, get addicted to this one and become one of the wizards of the tech age."
|
|
||||||
press_title: "Bloggers/Press"
|
|
||||||
press_paragraph_1_prefix: "Want to write about us? Feel free to download and use all of the resources included in our"
|
|
||||||
press_paragraph_1_link: "press packet"
|
|
||||||
press_paragraph_1_suffix: ". All logos and images may be used without contacting us directly."
|
|
||||||
team: "Team"
|
|
||||||
nick_title: "Cofounder, CEO"
|
nick_title: "Cofounder, CEO"
|
||||||
nick_blurb: "Motivation Guru"
|
nick_blurb: "Motivation Guru"
|
||||||
matt_title: "Cofounder, CTO"
|
matt_title: "Cofounder, CTO"
|
||||||
|
@ -582,6 +574,49 @@
|
||||||
jose_blurb: "Taking Off"
|
jose_blurb: "Taking Off"
|
||||||
carlos_title: "Region Manager, Brazil"
|
carlos_title: "Region Manager, Brazil"
|
||||||
carlos_blurb: "Celery Man"
|
carlos_blurb: "Celery Man"
|
||||||
|
community_title: "...and our open-source community"
|
||||||
|
community_subtitle: "Over 450 contributors have helped build CodeCombat, with more joining every week!"
|
||||||
|
community_description_1: "CodeCombat is a community project, with hundreds of players volunteering to create levels, contribute to our code to add features, fix bugs, playtest, and even translate the game into 50 languages so far. Employees, contributors and the site gain by sharing ideas and pooling effort, as does the open source community in general. The site is built on numerous open source projects, and we are open sourced to give back to the community and provide code-curious players a familiar project to explore and experiment with. Anyone can join the CodeCombat community! Check out our "
|
||||||
|
community_description_link: "contribute page "
|
||||||
|
community_description_2: "for more info."
|
||||||
|
story_title: "Our story so far"
|
||||||
|
story_subtitle: "Since 2013, CodeCombat has grown from a mere set of sketches to a living, thriving game."
|
||||||
|
story_statistic_1a: "5,000,000+"
|
||||||
|
story_statistic_1b: "total players"
|
||||||
|
story_statistic_2a: "We’ve been translated into over 50 languages — our players hail from"
|
||||||
|
story_statistic_2b: "200+ countries"
|
||||||
|
story_statistic_3a: "Together, they have written"
|
||||||
|
story_statistic_3b: "1 billion lines of code and counting"
|
||||||
|
story_statistic_3c: "across six different programming languages"
|
||||||
|
story_long_way_1: "Though we've come a long way..."
|
||||||
|
story_sketch_caption: "Nick's very first sketch depicting a programming game in action."
|
||||||
|
story_long_way_2: "we still have much to do before we complete our quest, so..."
|
||||||
|
jobs_title: "Come work with us and help write CodeCombat history!"
|
||||||
|
jobs_subtitle: """Don't see a good fit but interested in keeping in touch? See our "Create Your Own" listing."""
|
||||||
|
jobs_benefits: "Employee Benefits"
|
||||||
|
jobs_benefit_1: "Competitive salary and options"
|
||||||
|
jobs_benefit_2: "15 day minimum vacation policy, excluding company holidays"
|
||||||
|
jobs_benefit_3: "Work from home flexibility"
|
||||||
|
jobs_benefit_4: "Unlimited sick/personal days"
|
||||||
|
jobs_benefit_5: "Professional development and continuing education support"
|
||||||
|
jobs_benefit_6: "Medical/dental/vision insurance"
|
||||||
|
jobs_custom_title: "Create Your Own"
|
||||||
|
jobs_custom_description: "Are you passionate about CodeCombat but don't see a job listed that matches your qualifications? Write us and show how you think you can contribute to our team. We'd love to hear from you!"
|
||||||
|
jobs_custom_contact_1: "Send us a note at "
|
||||||
|
jobs_custom_contact_2: "introducing yourself and we might get in touch in the future!"
|
||||||
|
contact_title: "Press & Contact"
|
||||||
|
contact_subtitle: "Need more information? Get in touch with us at "
|
||||||
|
screenshots_title: "Game Screenshots"
|
||||||
|
screenshots_hint: "(click to view full size)"
|
||||||
|
downloads_title: "Download Assets & Information"
|
||||||
|
about_codecombat: "About CodeCombat"
|
||||||
|
logo: "Logo"
|
||||||
|
screenshots: "Screenshots"
|
||||||
|
character_art: "Character Art"
|
||||||
|
download_all: "Download All"
|
||||||
|
location_title: "We're located in downtown SF:"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
teachers:
|
teachers:
|
||||||
who_for_title: "Who is CodeCombat for?"
|
who_for_title: "Who is CodeCombat for?"
|
||||||
|
|
|
@ -85,11 +85,11 @@ module.exports = class SuperModel extends Backbone.Model
|
||||||
trackModel: (model, value) ->
|
trackModel: (model, value) ->
|
||||||
res = @addModelResource(collection, '', {}, value)
|
res = @addModelResource(collection, '', {}, value)
|
||||||
res.listen()
|
res.listen()
|
||||||
|
|
||||||
trackCollection: (collection, value) ->
|
trackCollection: (collection, value) ->
|
||||||
res = @addModelResource(collection, '', {}, value)
|
res = @addModelResource(collection, '', {}, value)
|
||||||
res.listen()
|
res.listen()
|
||||||
|
|
||||||
# replace or overwrite
|
# replace or overwrite
|
||||||
shouldSaveBackups: (model) -> false
|
shouldSaveBackups: (model) -> false
|
||||||
|
|
||||||
|
@ -285,7 +285,7 @@ class ModelResource extends Resource
|
||||||
fetchModel: ->
|
fetchModel: ->
|
||||||
@jqxhr = @model.fetch(@fetchOptions) unless @model.loading
|
@jqxhr = @model.fetch(@fetchOptions) unless @model.loading
|
||||||
@listen()
|
@listen()
|
||||||
|
|
||||||
listen: ->
|
listen: ->
|
||||||
@listenToOnce @model, 'sync', -> @markLoaded()
|
@listenToOnce @model, 'sync', -> @markLoaded()
|
||||||
@listenToOnce @model, 'error', -> @markFailed()
|
@listenToOnce @model, 'error', -> @markFailed()
|
||||||
|
|
|
@ -1,36 +1,327 @@
|
||||||
|
@import "app/styles/bootstrap/variables"
|
||||||
|
@import "app/styles/mixins"
|
||||||
|
@import "app/styles/style-flat"
|
||||||
|
|
||||||
#about-view
|
#about-view
|
||||||
|
|
||||||
@import "bootstrap/variables"
|
overflow: hidden
|
||||||
|
|
||||||
.team-column
|
#nav-container
|
||||||
padding-left: 0
|
min-height: 55px
|
||||||
|
nav
|
||||||
|
background: $gold
|
||||||
|
&.affix
|
||||||
|
z-index: 1
|
||||||
|
position: fixed
|
||||||
|
top: 0
|
||||||
|
width: 100%
|
||||||
|
ul
|
||||||
|
margin-top: 5px
|
||||||
|
padding-left: 0
|
||||||
|
list-style: none
|
||||||
|
li
|
||||||
|
height: 22pt
|
||||||
|
display: inline-block
|
||||||
|
margin: 10px 18px 0 18px
|
||||||
|
a
|
||||||
|
color: white
|
||||||
|
text-transform: uppercase
|
||||||
|
text-decoration: none
|
||||||
|
li.active
|
||||||
|
.label
|
||||||
|
padding-left: 0
|
||||||
|
padding-right: 0
|
||||||
|
padding-bottom: 0
|
||||||
|
margin-left: 0.6em
|
||||||
|
margin-right: 0.6em
|
||||||
|
border-bottom: 4px solid white
|
||||||
|
border-radius: 0
|
||||||
|
|
||||||
|
#jumbotron
|
||||||
|
background-color: $navy
|
||||||
|
background-image: url("/images/pages/about/codebackground_zoom_compressed.png")
|
||||||
|
background-size: cover
|
||||||
|
background-repeat: no-repeat
|
||||||
|
|
||||||
|
h1
|
||||||
|
color: white
|
||||||
|
margin-top: 100px
|
||||||
|
|
||||||
|
h2
|
||||||
|
color: white
|
||||||
|
margin-bottom: 100px
|
||||||
|
|
||||||
|
.responsive-side-margins, h3, h4, p
|
||||||
|
max-width: 460px
|
||||||
|
margin-left: auto
|
||||||
|
margin-right: auto
|
||||||
|
@media (min-width: $screen-sm-min)
|
||||||
|
max-width: inherit
|
||||||
|
|
||||||
|
h3
|
||||||
|
margin-top: 60px
|
||||||
|
@media (min-width: $screen-sm-min)
|
||||||
|
margin-top: 150px
|
||||||
|
|
||||||
|
#about-container
|
||||||
|
@media (min-width: $screen-sm-min)
|
||||||
|
margin-top: 85px
|
||||||
|
background-color: white
|
||||||
|
|
||||||
|
#mission-text
|
||||||
|
margin-top: 30px
|
||||||
|
@media (min-width: $screen-sm-min)
|
||||||
|
margin-top: 45px
|
||||||
|
|
||||||
|
#mission-graphic, #community-graphic
|
||||||
|
padding: 30px 40px
|
||||||
|
position: relative
|
||||||
|
min-height: 320px
|
||||||
|
@media (min-width: $screen-sm-min)
|
||||||
|
min-height: 250px
|
||||||
|
|
||||||
ul.thumbnails
|
h2
|
||||||
margin-left: 40px
|
color: white
|
||||||
|
width: 50%
|
||||||
|
|
||||||
|
#mission-graphic
|
||||||
|
margin-top: 30px
|
||||||
|
@media (min-width: $screen-sm-min)
|
||||||
|
margin-top: 45px
|
||||||
|
background: $navy
|
||||||
|
|
||||||
|
h2
|
||||||
|
float: right
|
||||||
|
|
||||||
|
img
|
||||||
|
position: absolute
|
||||||
|
bottom: 0
|
||||||
|
left: 0
|
||||||
|
|
||||||
|
#mission-graphic-filler
|
||||||
|
background: $navy
|
||||||
|
height: 100%
|
||||||
|
width: 2000px
|
||||||
|
position: absolute
|
||||||
|
right: 100%
|
||||||
|
top: 0
|
||||||
|
|
||||||
|
#team
|
||||||
|
ul
|
||||||
|
text-align: center
|
||||||
|
margin-top: 40px
|
||||||
padding: 0
|
padding: 0
|
||||||
|
|
||||||
li
|
li
|
||||||
list-style-type: none
|
width: 200px
|
||||||
|
height: 230px
|
||||||
|
list-style: none
|
||||||
|
display: inline-block
|
||||||
|
text-align: center
|
||||||
|
color: black
|
||||||
|
small
|
||||||
|
display: block
|
||||||
|
white-space: nowrap
|
||||||
|
.img-thumbnail
|
||||||
|
border-radius: 50%
|
||||||
|
padding: 0
|
||||||
|
background-color: $burgandy
|
||||||
|
border: 5px solid $gold
|
||||||
|
|
||||||
|
// #community
|
||||||
|
// margin-top: 100px
|
||||||
|
|
||||||
|
#community-row-1
|
||||||
|
#community-avatars
|
||||||
|
width: 90%
|
||||||
|
margin: 20px 5%
|
||||||
|
|
||||||
|
#community-row-2
|
||||||
|
margin-top: 35px
|
||||||
|
@media (min-width: $screen-sm-min)
|
||||||
|
margin-top: 70px
|
||||||
|
|
||||||
|
#community-graphic
|
||||||
|
background: $burgandy
|
||||||
|
|
||||||
img.img-thumbnail
|
img
|
||||||
background-color: transparent
|
position: absolute
|
||||||
&:hover
|
right: 0
|
||||||
background-color: rgba(200, 244, 255, 0.2)
|
bottom: 0
|
||||||
float: left
|
|
||||||
width: 80px
|
|
||||||
height: 80px
|
|
||||||
margin: 0px 10px 22px 0px
|
|
||||||
|
|
||||||
.team_name
|
#community-graphic-filler
|
||||||
font-size: 20px
|
background: $burgandy
|
||||||
margin-top: 0
|
height: 100%
|
||||||
|
width: 2000px
|
||||||
|
position: absolute
|
||||||
|
left: 100%
|
||||||
|
top: 0
|
||||||
|
|
||||||
.team_bio
|
#story
|
||||||
width: 150px
|
// margin-top: 150px
|
||||||
float: left
|
font-family: $headline-font
|
||||||
|
font-variant: normal
|
||||||
|
#story-graphic-1
|
||||||
|
max-width: 580px
|
||||||
|
margin-top: 50px
|
||||||
|
@media (min-width: $screen-sm-min)
|
||||||
|
margin-top: 80px
|
||||||
|
margin-left: auto
|
||||||
|
margin-right: auto
|
||||||
|
.media-heading
|
||||||
|
color: $burgandy
|
||||||
|
#story-graphic-2
|
||||||
|
//TODO: Fix left-margin of this
|
||||||
|
margin-top: 50px
|
||||||
|
@media (min-width: $screen-sm-min)
|
||||||
|
margin-top: 80px
|
||||||
|
margin-left: auto
|
||||||
|
margin-right: auto
|
||||||
|
max-width: 390px
|
||||||
|
.media-heading
|
||||||
|
color: $forest
|
||||||
|
#story-graphic-3
|
||||||
|
margin-top: 50px
|
||||||
|
@media (min-width: $screen-sm-min)
|
||||||
|
margin-top: 80px
|
||||||
|
p
|
||||||
|
margin-top: 30px
|
||||||
|
img
|
||||||
|
margin-top: 20px
|
||||||
|
#story-bracketed-text
|
||||||
|
width: 100%
|
||||||
|
max-width: 640px
|
||||||
|
margin: 0 auto
|
||||||
|
.text-h1
|
||||||
|
display: inline-block
|
||||||
|
margin: auto 0
|
||||||
|
color: $navy
|
||||||
|
width: 80%
|
||||||
|
vertical-align: bottom
|
||||||
|
img
|
||||||
|
margin: auto 0
|
||||||
|
#left-bracket
|
||||||
|
width: 10%
|
||||||
|
display: inline-block
|
||||||
|
#right-bracket
|
||||||
|
width: 10%
|
||||||
|
display: inline-block
|
||||||
|
#story-languages
|
||||||
|
margin-top: 50px
|
||||||
|
#language-icons
|
||||||
|
display: inline-block
|
||||||
|
padding-left: auto
|
||||||
|
padding-right: auto
|
||||||
|
|
||||||
|
#story-graphic-4
|
||||||
|
margin-left: auto
|
||||||
|
margin-right: auto
|
||||||
|
margin-top: 50px
|
||||||
|
@media (min-width: $screen-sm-min)
|
||||||
|
margin-top: 150px
|
||||||
|
p
|
||||||
|
margin-top: 20px
|
||||||
|
figure
|
||||||
|
img
|
||||||
|
display: block
|
||||||
|
margin: 0 auto
|
||||||
|
#jobs
|
||||||
|
// margin-top: 50px
|
||||||
|
// @media (min-width: $screen-sm-min)
|
||||||
|
// margin-top: 100px
|
||||||
|
#jobs-row
|
||||||
|
#benefits, .job-listing
|
||||||
|
margin-top: 65px
|
||||||
|
border: thin solid $navy
|
||||||
|
border-radius: 8px
|
||||||
|
padding: 50px
|
||||||
|
width: 370px
|
||||||
|
height: 420px
|
||||||
|
margin-left: auto
|
||||||
|
margin-right: auto
|
||||||
|
h5
|
||||||
|
text-align: center
|
||||||
|
color: inherit
|
||||||
|
li
|
||||||
|
padding-bottom: 7px
|
||||||
|
#benefits
|
||||||
|
color: white
|
||||||
|
background: $navy
|
||||||
|
ul
|
||||||
|
margin-top: 20px
|
||||||
|
.job-listing
|
||||||
|
color: $navy
|
||||||
|
background: white
|
||||||
|
// centering hack
|
||||||
|
position: relative
|
||||||
|
.label
|
||||||
|
text-transform: uppercase
|
||||||
|
color: grey
|
||||||
|
a.job-link
|
||||||
|
width: 170px
|
||||||
|
bottom: 45px
|
||||||
|
// centering hack
|
||||||
|
position: absolute
|
||||||
|
left: 50%
|
||||||
|
margin-left: -85px
|
||||||
|
p
|
||||||
|
margin-top: 15px
|
||||||
|
|
||||||
|
#files
|
||||||
|
padding: 30px 0
|
||||||
|
margin-top: 50px
|
||||||
|
border: thin solid gray
|
||||||
|
border-radius: 8px
|
||||||
|
.label
|
||||||
|
color: black
|
||||||
|
display: block
|
||||||
|
#screenshots
|
||||||
|
text-align: center
|
||||||
|
#screenshot-grid
|
||||||
|
img
|
||||||
|
display: inline-block
|
||||||
|
margin: 6.5px
|
||||||
|
|
||||||
|
#downloads-container
|
||||||
|
position: relative
|
||||||
|
height: 250px
|
||||||
|
#downloads
|
||||||
|
//TODO: How do I center this in small view?
|
||||||
|
margin: 20px auto 0
|
||||||
|
width: 260px
|
||||||
|
ul
|
||||||
|
width: 260px
|
||||||
|
margin-top: 10px
|
||||||
|
margin-bottom: 20px
|
||||||
|
margin-left: -25px
|
||||||
|
a
|
||||||
|
color: black
|
||||||
|
#download-button
|
||||||
|
margin: 0 auto
|
||||||
|
color: $navy
|
||||||
|
.glyphicon-download-alt
|
||||||
|
margin-right: 15px
|
||||||
|
vertical-align: middle
|
||||||
|
font-size: 1.5em
|
||||||
|
|
||||||
|
#screenshot-lightbox
|
||||||
|
.modal-dialog
|
||||||
|
width: auto
|
||||||
|
max-width: 1024px
|
||||||
|
|
||||||
div
|
#location
|
||||||
font-size: 12px
|
margin-top: 75px
|
||||||
line-height: 14px
|
margin-bottom: 100px
|
||||||
padding-bottom: 5px
|
text-align: center
|
||||||
|
p b
|
||||||
|
margin-top: 40px
|
||||||
|
a
|
||||||
|
color: inherit
|
||||||
|
text-decoration: underline
|
||||||
|
iframe
|
||||||
|
border: 2px solid lightgray
|
||||||
|
|
||||||
|
.anchor::before
|
||||||
|
content: ""
|
||||||
|
display: block
|
||||||
|
height: 55px
|
||||||
|
margin: -55px 0 0 0
|
|
@ -1,205 +1,6 @@
|
||||||
@import "app/styles/bootstrap/variables"
|
@import "app/styles/bootstrap/variables"
|
||||||
@import "app/styles/mixins"
|
@import "app/styles/mixins"
|
||||||
|
@import "app/styles/style-flat"
|
||||||
// TODO: Move flat style into probably several files and Bootstrap variables
|
|
||||||
|
|
||||||
// Variables
|
|
||||||
|
|
||||||
$headline-font: 'Arvo', serif
|
|
||||||
$body-font: 'Open Sans', sans-serif
|
|
||||||
|
|
||||||
$burgandy: #7D0101
|
|
||||||
$gold: #F2BE19
|
|
||||||
$navy: #0E4C60
|
|
||||||
$forest: #20572B
|
|
||||||
|
|
||||||
.style-flat
|
|
||||||
background: white
|
|
||||||
|
|
||||||
// Fonts
|
|
||||||
h1, h2, h3, h4, h5, h6
|
|
||||||
// Unsetting game styles
|
|
||||||
font-variant: normal
|
|
||||||
color: black
|
|
||||||
margin: 0
|
|
||||||
|
|
||||||
h1
|
|
||||||
font-family: $headline-font
|
|
||||||
font-weight: normal
|
|
||||||
font-size: 46px
|
|
||||||
line-height: 62px
|
|
||||||
|
|
||||||
h2
|
|
||||||
font-family: $body-font
|
|
||||||
font-weight: lighter
|
|
||||||
font-size: 30px
|
|
||||||
line-height: 42px
|
|
||||||
|
|
||||||
h3
|
|
||||||
font-family: $headline-font
|
|
||||||
font-weight: normal
|
|
||||||
font-size: 33px
|
|
||||||
line-height: 45px
|
|
||||||
|
|
||||||
h4
|
|
||||||
font-family: $body-font
|
|
||||||
font-weight: lighter
|
|
||||||
font-size: 22px
|
|
||||||
line-height: 32px
|
|
||||||
|
|
||||||
h5
|
|
||||||
font-family: $headline-font
|
|
||||||
font-weight: bold
|
|
||||||
font-size: 20px
|
|
||||||
line-height: 31px
|
|
||||||
|
|
||||||
h6
|
|
||||||
font-family: $body-font
|
|
||||||
font-weight: bold
|
|
||||||
font-size: 14px
|
|
||||||
line-height: 20px
|
|
||||||
|
|
||||||
p
|
|
||||||
margin: 0 0 14px
|
|
||||||
|
|
||||||
.small
|
|
||||||
font-weight: normal
|
|
||||||
font-size: 14px
|
|
||||||
line-height: 20px
|
|
||||||
|
|
||||||
font-family: $body-font
|
|
||||||
font-size: 18px
|
|
||||||
line-height: 29px
|
|
||||||
|
|
||||||
blockquote
|
|
||||||
border: none
|
|
||||||
|
|
||||||
&:before
|
|
||||||
font-family: "Monaco"
|
|
||||||
content: "\201C"
|
|
||||||
position: absolute
|
|
||||||
left: 0px
|
|
||||||
top: 20px
|
|
||||||
font-size: 40px
|
|
||||||
opacity: 0.5
|
|
||||||
|
|
||||||
// Navbar
|
|
||||||
|
|
||||||
.navbar
|
|
||||||
background: white
|
|
||||||
margin-bottom: 0
|
|
||||||
white-space: nowrap // prevent home icon from going under brand
|
|
||||||
|
|
||||||
a.navbar-brand
|
|
||||||
#logo-img
|
|
||||||
width: 230px
|
|
||||||
height: 65px
|
|
||||||
margin-right: 10px
|
|
||||||
|
|
||||||
color: $burgandy
|
|
||||||
&:hover
|
|
||||||
color: white
|
|
||||||
background: $burgandy
|
|
||||||
|
|
||||||
.glyphicon-home
|
|
||||||
position: relative
|
|
||||||
top: 3px
|
|
||||||
|
|
||||||
.navbar-toggle
|
|
||||||
color: black
|
|
||||||
margin: 30px 25px 0
|
|
||||||
|
|
||||||
.nav > li > a
|
|
||||||
// TODO: Move this to bootstrap variables for navbars
|
|
||||||
font-weight: bold
|
|
||||||
font-family: $body-font
|
|
||||||
font-size: 16px
|
|
||||||
padding: 38px 15px 37px
|
|
||||||
color: $burgandy
|
|
||||||
text-shadow: 0 0 0
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
background: $burgandy
|
|
||||||
color: white
|
|
||||||
|
|
||||||
#language-dropdown-wrapper
|
|
||||||
display: inline-block
|
|
||||||
padding: 30px 10px
|
|
||||||
width: 100%
|
|
||||||
|
|
||||||
@media (max-width: $screen-sm-min)
|
|
||||||
.nav > li > a
|
|
||||||
padding: 10px 20px
|
|
||||||
#language-dropdown-wrapper
|
|
||||||
display: inline-block
|
|
||||||
padding: 10px 10px
|
|
||||||
.language-dropdown
|
|
||||||
width: 150px
|
|
||||||
|
|
||||||
.img-circle
|
|
||||||
border: $gold 8px solid
|
|
||||||
width: 98px
|
|
||||||
height: 98px // Includes the border
|
|
||||||
|
|
||||||
.user-level
|
|
||||||
position: absolute
|
|
||||||
top: 76px
|
|
||||||
right: 42px
|
|
||||||
color: $gold
|
|
||||||
text-shadow: 1px 1px black, -1px -1px 0 black, 1px -1px 0 black, -1px 1px 0 black
|
|
||||||
|
|
||||||
// Buttons
|
|
||||||
|
|
||||||
.btn
|
|
||||||
border: none
|
|
||||||
border-radius: 5px
|
|
||||||
font-family: $body-font
|
|
||||||
font-weight: normal
|
|
||||||
background-image: none // overrides legacy buttons
|
|
||||||
|
|
||||||
.btn-primary, .btn-navy
|
|
||||||
background-color: $navy
|
|
||||||
color: white
|
|
||||||
|
|
||||||
.btn-primary-alt, .btn-navy-alt
|
|
||||||
background-color: white
|
|
||||||
border: 1px solid $navy
|
|
||||||
color: $navy
|
|
||||||
|
|
||||||
.btn-forest
|
|
||||||
background-color: $forest
|
|
||||||
color: white
|
|
||||||
|
|
||||||
.btn-forest-alt
|
|
||||||
background-color: white
|
|
||||||
border: 1px solid $forest
|
|
||||||
color: $forest
|
|
||||||
|
|
||||||
.btn-gold
|
|
||||||
background-color: $gold
|
|
||||||
color: white
|
|
||||||
|
|
||||||
.btn-gold-alt
|
|
||||||
background-color: white
|
|
||||||
border: 1px solid $gold
|
|
||||||
color: $gold
|
|
||||||
|
|
||||||
.btn-lg
|
|
||||||
font-size: 18px
|
|
||||||
|
|
||||||
// Classes
|
|
||||||
|
|
||||||
.text-navy
|
|
||||||
color: $navy
|
|
||||||
|
|
||||||
.bg-navy
|
|
||||||
background-color: $navy
|
|
||||||
color: white
|
|
||||||
h1, h2, h3, h4, h5, h6, a
|
|
||||||
color: white
|
|
||||||
a.btn-primary-alt
|
|
||||||
color: $navy
|
|
||||||
|
|
||||||
|
|
||||||
#new-home-view
|
#new-home-view
|
||||||
|
|
||||||
|
@ -464,40 +265,3 @@ $forest: #20572B
|
||||||
img
|
img
|
||||||
margin-bottom: 20px
|
margin-bottom: 20px
|
||||||
|
|
||||||
#footer
|
|
||||||
background-image: url("/images/pages/home/footer_background.png")
|
|
||||||
height: 229px
|
|
||||||
margin: -22px auto 0
|
|
||||||
color: white
|
|
||||||
|
|
||||||
@media (max-width: $screen-sm-min)
|
|
||||||
background-color: #201a15
|
|
||||||
background-image: none
|
|
||||||
height: auto
|
|
||||||
|
|
||||||
ul
|
|
||||||
margin: 30px
|
|
||||||
li:first-child
|
|
||||||
border-bottom: 1px solid white
|
|
||||||
margin-bottom: 10px
|
|
||||||
a
|
|
||||||
color: white
|
|
||||||
|
|
||||||
#final-footer
|
|
||||||
position: absolute
|
|
||||||
left: 0
|
|
||||||
right: 0
|
|
||||||
height: 60px
|
|
||||||
color: white
|
|
||||||
background-color: #463a2c
|
|
||||||
@media (max-width: $screen-sm-min)
|
|
||||||
position: inherit
|
|
||||||
padding: 20px
|
|
||||||
height: auto
|
|
||||||
|
|
||||||
a
|
|
||||||
color: white
|
|
||||||
|
|
||||||
img
|
|
||||||
width: 150px
|
|
||||||
margin: 0 10px
|
|
|
@ -1,27 +1,32 @@
|
||||||
#request-quote-view
|
#request-quote-view
|
||||||
|
#site-content-area
|
||||||
label
|
//TODO: Maybe this should go in style-flat
|
||||||
margin-bottom: 2px
|
margin: 50px 10px 100px
|
||||||
|
|
||||||
.row
|
|
||||||
margin: 10px 0
|
|
||||||
|
|
||||||
|
.section
|
||||||
|
margin-top: 80px
|
||||||
|
margin-bottom: 50px
|
||||||
|
|
||||||
|
.form-group
|
||||||
|
label
|
||||||
|
margin-bottom: 0
|
||||||
|
|
||||||
|
label.checkbox
|
||||||
|
font-weight: normal
|
||||||
|
|
||||||
.help-block
|
.help-block
|
||||||
margin: 0
|
margin: -4px 0 2px
|
||||||
|
|
||||||
p
|
p
|
||||||
margin: 0 0 20px
|
margin: 0 0 20px
|
||||||
|
|
||||||
hr
|
|
||||||
margin: 30px 0
|
|
||||||
|
|
||||||
.checkbox, .checkbox-inline
|
.checkbox, .checkbox-inline
|
||||||
margin: 0
|
input
|
||||||
|
margin-top: 8px
|
||||||
#anything-else-row
|
|
||||||
margin: 50px 0 20px
|
|
||||||
|
|
||||||
#other-education-level-input
|
#other-education-level-input
|
||||||
|
label
|
||||||
|
display: inline-block
|
||||||
display: inline-block
|
display: inline-block
|
||||||
width: 200px
|
width: 200px
|
||||||
margin-left: 5px
|
margin-left: 5px
|
||||||
|
|
239
app/styles/style-flat.sass
Normal file
|
@ -0,0 +1,239 @@
|
||||||
|
@import "app/styles/bootstrap/variables"
|
||||||
|
@import "app/styles/mixins"
|
||||||
|
|
||||||
|
// TODO: Move flat style into probably several files and Bootstrap variables
|
||||||
|
|
||||||
|
// Variables
|
||||||
|
|
||||||
|
$headline-font: 'Arvo', serif
|
||||||
|
$body-font: 'Open Sans', sans-serif
|
||||||
|
|
||||||
|
$burgandy: #7D0101
|
||||||
|
$gold: #F2BE19
|
||||||
|
$navy: #0E4C60
|
||||||
|
$forest: #20572B
|
||||||
|
|
||||||
|
.style-flat
|
||||||
|
background: white
|
||||||
|
|
||||||
|
// Fonts
|
||||||
|
h1, h2, h3, h4, h5, h6
|
||||||
|
// Unsetting game styles
|
||||||
|
font-variant: normal
|
||||||
|
color: black
|
||||||
|
margin: 0
|
||||||
|
|
||||||
|
h1, .text-h1
|
||||||
|
font-family: $headline-font
|
||||||
|
font-weight: normal
|
||||||
|
font-size: 46px
|
||||||
|
line-height: 62px
|
||||||
|
|
||||||
|
h2, .text-h2
|
||||||
|
font-family: $body-font
|
||||||
|
font-weight: lighter
|
||||||
|
font-size: 30px
|
||||||
|
line-height: 42px
|
||||||
|
|
||||||
|
h3, .text-h3
|
||||||
|
font-family: $headline-font
|
||||||
|
font-weight: normal
|
||||||
|
font-size: 33px
|
||||||
|
line-height: 45px
|
||||||
|
|
||||||
|
h4, .text-h4
|
||||||
|
font-family: $body-font
|
||||||
|
font-weight: lighter
|
||||||
|
font-size: 22px
|
||||||
|
line-height: 32px
|
||||||
|
|
||||||
|
h5, .text-h5
|
||||||
|
font-family: $headline-font
|
||||||
|
font-weight: bold
|
||||||
|
font-size: 20px
|
||||||
|
line-height: 31px
|
||||||
|
|
||||||
|
h6, .text-h6
|
||||||
|
font-family: $body-font
|
||||||
|
font-weight: bold
|
||||||
|
font-size: 14px
|
||||||
|
line-height: 20px
|
||||||
|
|
||||||
|
p
|
||||||
|
margin: 0 0 14px
|
||||||
|
|
||||||
|
.small
|
||||||
|
font-weight: normal
|
||||||
|
font-size: 14px
|
||||||
|
line-height: 20px
|
||||||
|
|
||||||
|
font-family: $body-font
|
||||||
|
font-size: 18px
|
||||||
|
line-height: 29px
|
||||||
|
|
||||||
|
blockquote
|
||||||
|
border: none
|
||||||
|
|
||||||
|
&:before
|
||||||
|
font-family: "Monaco"
|
||||||
|
content: "\201C"
|
||||||
|
position: absolute
|
||||||
|
left: 0px
|
||||||
|
top: 20px
|
||||||
|
font-size: 40px
|
||||||
|
opacity: 0.5
|
||||||
|
|
||||||
|
// Navbar
|
||||||
|
|
||||||
|
.navbar
|
||||||
|
background: white
|
||||||
|
margin-bottom: 0
|
||||||
|
white-space: nowrap // prevent home icon from going under brand
|
||||||
|
|
||||||
|
a.navbar-brand
|
||||||
|
#logo-img
|
||||||
|
width: 230px
|
||||||
|
height: 65px
|
||||||
|
margin-right: 10px
|
||||||
|
|
||||||
|
color: $burgandy
|
||||||
|
&:hover
|
||||||
|
color: white
|
||||||
|
background: $burgandy
|
||||||
|
|
||||||
|
.glyphicon-home
|
||||||
|
position: relative
|
||||||
|
top: 3px
|
||||||
|
|
||||||
|
.navbar-toggle
|
||||||
|
color: black
|
||||||
|
margin: 30px 25px 0
|
||||||
|
|
||||||
|
.nav > li > a
|
||||||
|
// TODO: Move this to bootstrap variables for navbars
|
||||||
|
font-weight: bold
|
||||||
|
font-family: $body-font
|
||||||
|
font-size: 16px
|
||||||
|
padding: 38px 15px 37px
|
||||||
|
color: $burgandy
|
||||||
|
text-shadow: 0 0 0
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background: $burgandy
|
||||||
|
color: white
|
||||||
|
|
||||||
|
#language-dropdown-wrapper
|
||||||
|
display: inline-block
|
||||||
|
padding: 30px 10px
|
||||||
|
width: 100%
|
||||||
|
|
||||||
|
@media (max-width: $screen-sm-min)
|
||||||
|
.nav > li > a
|
||||||
|
padding: 10px 20px
|
||||||
|
#language-dropdown-wrapper
|
||||||
|
display: inline-block
|
||||||
|
padding: 10px 10px
|
||||||
|
.language-dropdown
|
||||||
|
width: 150px
|
||||||
|
|
||||||
|
.img-circle
|
||||||
|
border: $gold 8px solid
|
||||||
|
width: 98px
|
||||||
|
height: 98px // Includes the border
|
||||||
|
|
||||||
|
.user-level
|
||||||
|
position: absolute
|
||||||
|
top: 76px
|
||||||
|
right: 42px
|
||||||
|
color: $gold
|
||||||
|
text-shadow: 1px 1px black, -1px -1px 0 black, 1px -1px 0 black, -1px 1px 0 black
|
||||||
|
|
||||||
|
// Buttons
|
||||||
|
|
||||||
|
.btn
|
||||||
|
border: none
|
||||||
|
border-radius: 5px
|
||||||
|
font-family: $body-font
|
||||||
|
font-weight: normal
|
||||||
|
background-image: none // overrides legacy buttons
|
||||||
|
|
||||||
|
.btn-primary, .btn-navy
|
||||||
|
background-color: $navy
|
||||||
|
color: white
|
||||||
|
|
||||||
|
.btn-primary-alt, .btn-navy-alt
|
||||||
|
background-color: white
|
||||||
|
border: 1px solid $navy
|
||||||
|
color: $navy
|
||||||
|
|
||||||
|
.btn-forest
|
||||||
|
background-color: $forest
|
||||||
|
color: white
|
||||||
|
|
||||||
|
.btn-forest-alt
|
||||||
|
background-color: white
|
||||||
|
border: 1px solid $forest
|
||||||
|
color: $forest
|
||||||
|
|
||||||
|
.btn-gold
|
||||||
|
background-color: $gold
|
||||||
|
color: white
|
||||||
|
|
||||||
|
.btn-gold-alt
|
||||||
|
background-color: white
|
||||||
|
border: 1px solid $gold
|
||||||
|
color: $gold
|
||||||
|
|
||||||
|
.btn-lg
|
||||||
|
font-size: 18px
|
||||||
|
|
||||||
|
// Classes
|
||||||
|
|
||||||
|
.text-navy
|
||||||
|
color: $navy
|
||||||
|
|
||||||
|
.bg-navy
|
||||||
|
background-color: $navy
|
||||||
|
color: white
|
||||||
|
h1, h2, h3, h4, h5, h6, a
|
||||||
|
color: white
|
||||||
|
a.btn-primary-alt
|
||||||
|
color: $navy
|
||||||
|
|
||||||
|
#footer
|
||||||
|
background-image: url("/images/pages/home/footer_background.png")
|
||||||
|
height: 229px
|
||||||
|
margin: -22px auto 0
|
||||||
|
color: white
|
||||||
|
|
||||||
|
@media (max-width: $screen-sm-min)
|
||||||
|
background-color: #201a15
|
||||||
|
background-image: none
|
||||||
|
height: auto
|
||||||
|
|
||||||
|
ul
|
||||||
|
margin: 30px
|
||||||
|
li:first-child
|
||||||
|
border-bottom: 1px solid white
|
||||||
|
margin-bottom: 10px
|
||||||
|
a
|
||||||
|
color: white
|
||||||
|
|
||||||
|
#final-footer
|
||||||
|
position: absolute
|
||||||
|
left: 0
|
||||||
|
right: 0
|
||||||
|
height: 60px
|
||||||
|
color: white
|
||||||
|
background-color: #463a2c
|
||||||
|
@media (max-width: $screen-sm-min)
|
||||||
|
position: inherit
|
||||||
|
padding: 20px
|
||||||
|
height: auto
|
||||||
|
|
||||||
|
a
|
||||||
|
color: white
|
||||||
|
|
||||||
|
img
|
||||||
|
width: 150px
|
||||||
|
margin: 0 10px
|
|
@ -1,188 +1,441 @@
|
||||||
extends /templates/base
|
extends /templates/base-flat
|
||||||
|
|
||||||
block content
|
block content
|
||||||
|
.style-flat(data-spy="scroll", data-target="#nav-container")
|
||||||
|
.container-fluid#jumbotron
|
||||||
|
.container
|
||||||
|
.row
|
||||||
|
//TODO: Size these correctly
|
||||||
|
.col-xs-10
|
||||||
|
h1 If you want to learn to program, you need to write (a lot of) code.
|
||||||
|
.row
|
||||||
|
.col-xs-8
|
||||||
|
h2 At CodeCombat, our job is to make sure you're doing that with a smile on your face.
|
||||||
|
|
||||||
|
#nav-container
|
||||||
|
nav#fixed-nav.nav.navbar
|
||||||
|
.container-fluid.text-center
|
||||||
|
ul.center-block
|
||||||
|
li.active
|
||||||
|
a(href="#mission")#mission-link
|
||||||
|
small.label(data-i18n="about.mission_link")
|
||||||
|
| Mission
|
||||||
|
li
|
||||||
|
a(href="#team")#team-link
|
||||||
|
small.label(data-i18n="about.team_link")
|
||||||
|
| Team
|
||||||
|
li
|
||||||
|
a(href="#community")#community-link
|
||||||
|
small.label(data-i18n="about.community_link")
|
||||||
|
| Community
|
||||||
|
li
|
||||||
|
a(href="#story")#story-link
|
||||||
|
small.label(data-i18n="about.story_link")
|
||||||
|
| Story
|
||||||
|
li
|
||||||
|
a(href="#jobs")#jobs-link
|
||||||
|
small.label(data-i18n="about.jobs_link")
|
||||||
|
| Careers
|
||||||
|
li
|
||||||
|
a(href="#contact")#contact-link
|
||||||
|
small.label(data-i18n="about.contact_link")
|
||||||
|
| Press
|
||||||
|
|
||||||
|
#about-container.container
|
||||||
|
#mission.anchor.row
|
||||||
|
.col-sm-6#mission-graphic.responsive-side-margins
|
||||||
|
img(src="/images/pages/about/globe_white.png")
|
||||||
|
h2(data-i18n="about.mission_title")
|
||||||
|
| Our mission: make programming accessible to every student on Earth.
|
||||||
|
#mission-graphic-filler
|
||||||
|
.col-sm-5.col-sm-offset-1
|
||||||
|
#mission-text.responsive-side-margins
|
||||||
|
p(data-i18n="about.mission_description_1")
|
||||||
|
| Programming is magic. It's the ability to create things from pure imagination. We started CodeCombat to give learners the feeling of wizardly power at their fingertips by using typed code.
|
||||||
|
p(data-i18n="about.mission_description_2")
|
||||||
|
| As it turns out, that enables them to learn faster too. WAY faster. It's like having a conversation instead of reading a manual. We want to bring that conversation to every school and to every student, because everyone should have the chance to learn the magic of programming.
|
||||||
|
|
||||||
img(src="/images/pages/about/coco_comic.jpg")
|
#team.anchor
|
||||||
|
.text-center
|
||||||
.row
|
h3(data-i18n="about.team_title")
|
||||||
|
| Meet the CodeCombat team
|
||||||
.col-sm-6
|
h4.responsive-side-margins(data-i18n="about.team_values")
|
||||||
|
| We value open and respectful dialog, where the best idea wins. Our decisions are grounded in customer research and our process is focused on delivering tangible results for them. Everyone is hands-on, from our CEO to our Github contributors, because we value growth and learning in our team.
|
||||||
h2(data-i18n="about.why_codecombat")
|
ul
|
||||||
| Why CodeCombat?
|
|
||||||
|
|
||||||
p(data-i18n="about.why_paragraph_1")
|
|
||||||
| If you want to learn to program, you don't need lessons.
|
|
||||||
| You need to write a lot of code and have a great time doing it.
|
|
||||||
|
|
||||||
p
|
|
||||||
span(data-i18n="about.why_paragraph_2_prefix")
|
|
||||||
| That's what programming is about. It's gotta be fun.
|
|
||||||
| Not fun like
|
|
||||||
span
|
|
||||||
i(data-i18n="about.why_paragraph_2_italic")
|
|
||||||
| yay a badge
|
|
||||||
span
|
|
||||||
span(data-i18n="about.why_paragraph_2_center")
|
|
||||||
| but fun like
|
|
||||||
span
|
|
||||||
i(data-i18n="about.why_paragraph_2_italic_caps")
|
|
||||||
| NO MOM I HAVE TO FINISH THE LEVEL!
|
|
||||||
span
|
|
||||||
span(data-i18n="about.why_paragraph_2_suffix")
|
|
||||||
| That's why CodeCombat is a multiplayer game,
|
|
||||||
| not a gamified lesson course. We won't stop
|
|
||||||
| until you can't stop--but this time, that's a good thing.
|
|
||||||
|
|
||||||
p(data-i18n="about.why_paragraph_3")
|
|
||||||
| If you're going to get addicted to some game,
|
|
||||||
| get addicted to this one and become one of the wizards of the tech age.
|
|
||||||
|
|
||||||
h2(data-i18n="about.press_title")
|
|
||||||
| Bloggers/Press
|
|
||||||
|
|
||||||
p
|
|
||||||
span.spr(data-i18n="about.press_paragraph_1_prefix")
|
|
||||||
| Want to write about us? Feel free to download and use all of the resources included in our
|
|
||||||
a(href="https://s3.amazonaws.com/CodeCombatMisc/press_packet.zip", data-i18n="about.press_paragraph_1_link") press packet
|
|
||||||
span(data-i18n="about.press_paragraph_1_suffix")
|
|
||||||
| . All logos and images may be used without contacting us directly.
|
|
||||||
|
|
||||||
h2(data-i18n="nav.contact")
|
|
||||||
| Contact
|
|
||||||
p
|
|
||||||
span CodeCombat Inc.
|
|
||||||
br
|
|
||||||
span 360 3rd St Suite 700 (Livefyre)
|
|
||||||
br
|
|
||||||
span San Francisco, CA 94107
|
|
||||||
br
|
|
||||||
a(href='mailto:team@codecombat.com') team@codecombat.com
|
|
||||||
if me.get('preferredLanguage') == 'pt-BR'
|
|
||||||
span CodeCombat, Brazil
|
|
||||||
br
|
|
||||||
span Rua 1814 Militão Chaves
|
|
||||||
br
|
|
||||||
span Natal, Brazil, RN 59064-500
|
|
||||||
|
|
||||||
ul.col-sm-6.team-column
|
|
||||||
|
|
||||||
ul.thumbnails
|
|
||||||
|
|
||||||
li.row
|
|
||||||
|
|
||||||
h2(data-i18n="about.team") Team
|
|
||||||
|
|
||||||
// Full time
|
// Full time
|
||||||
|
li
|
||||||
|
a(href="http://www.nickwinter.net" rel="external")
|
||||||
|
img(src="/images/pages/about/nick_small.png").img-thumbnail
|
||||||
|
.team-bio
|
||||||
|
h6.label.team-name
|
||||||
|
a(href="http://www.nickwinter.net" rel="external") Nick Winter
|
||||||
|
small(data-i18n="about.nick_title")
|
||||||
|
small(data-i18n="about.nick_blurb")
|
||||||
|
|
||||||
a(href="http://www.nickwinter.net")
|
li
|
||||||
img(src="/images/pages/about/nick_small.png").img-thumbnail
|
a(href="http://www.mattlott.com/" rel="external")
|
||||||
.team_bio
|
img(src="/images/pages/about/matt_small.png").img-thumbnail
|
||||||
h4.team_name
|
.team-bio
|
||||||
a(href="http://www.nickwinter.net") Nick Winter
|
h6.label.team-name
|
||||||
div(data-i18n="about.nick_title")
|
a(href="http://www.mattlott.com/" rel="external") Matt Lott
|
||||||
div(data-i18n="about.nick_blurb")
|
small(data-i18n="about.matt_title")
|
||||||
|
small(data-i18n="about.matt_blurb")
|
||||||
|
|
||||||
a(href="http://www.mattlott.com/")
|
li
|
||||||
img(src="/images/pages/about/matt_small.png").img-thumbnail
|
a(href="http://cat.zdh.com/" rel="external")
|
||||||
.team_bio
|
img(src="/images/pages/about/cat_small.png").img-thumbnail
|
||||||
h4.team_name
|
.team-bio
|
||||||
a(href="http://www.mattlott.com/") Matt Lott
|
h6.label.team-name
|
||||||
div(data-i18n="about.matt_title")
|
a(href="http://cat.zdh.com/" rel="external") Catherine Weresow
|
||||||
div(data-i18n="about.matt_blurb")
|
small(data-i18n="about.cat_title")
|
||||||
|
small(data-i18n="about.cat_blurb")
|
||||||
|
|
||||||
li.row
|
li
|
||||||
|
img(src="/images/pages/about/scott_small.png").img-thumbnail
|
||||||
|
.team-bio
|
||||||
|
h6.label.team-name Scott Erickson
|
||||||
|
small(data-i18n="about.scott_title")
|
||||||
|
small(data-i18n="about.scott_blurb")
|
||||||
|
|
||||||
a(href="http://cat.zdh.com/")
|
li
|
||||||
img(src="/images/pages/about/cat_small.png").img-thumbnail
|
img(src="/images/pages/about/maka_small.png").img-thumbnail
|
||||||
.team_bio
|
.team-bio
|
||||||
h4.team_name
|
h6.label.team-name Michael 'Maka' Gradin
|
||||||
a(href="http://cat.zdh.com/") Catherine Weresow
|
small(data-i18n="about.maka_title")
|
||||||
div(data-i18n="about.cat_title")
|
small(data-i18n="about.maka_blurb")
|
||||||
div(data-i18n="about.cat_blurb")
|
|
||||||
|
|
||||||
img(src="/images/pages/about/scott_small.png").img-thumbnail
|
a(href="http://basicer.com/" rel="external")
|
||||||
.team_bio
|
|
||||||
h4.team_name Scott Erickson
|
li
|
||||||
div(data-i18n="about.scott_title")
|
a(href="http://basicer.com/" rel="external")
|
||||||
div(data-i18n="about.scott_blurb")
|
img(src="/images/pages/about/rob_small.png").img-thumbnail
|
||||||
|
.team-bio
|
||||||
|
h6.label.team-name
|
||||||
|
a(href="http://basicer.com/" rel="external") Rob Blanckaert
|
||||||
|
small(data-i18n="about.rob_title")
|
||||||
|
small(data-i18n="about.rob_blurb")
|
||||||
|
|
||||||
li.row
|
li
|
||||||
|
img(src="/images/pages/about/josh_c_small.png").img-thumbnail
|
||||||
|
.team-bio
|
||||||
|
h6.label.team-name Josh Callebaut
|
||||||
|
small(data-i18n="about.josh_c_title")
|
||||||
|
small(data-i18n="about.josh_c_blurb")
|
||||||
|
|
||||||
img(src="/images/pages/about/maka_small.png").img-thumbnail
|
a(href="http://robinyang.com/" rel="external")
|
||||||
.team_bio
|
|
||||||
h4.team_name Michael 'Maka' Gradin
|
li
|
||||||
div(data-i18n="about.maka_title")
|
a(href="http://robinyang.com/" rel="external")
|
||||||
div(data-i18n="about.maka_blurb")
|
img(src="/images/pages/about/robin_small.png").img-thumbnail
|
||||||
|
.team-bio
|
||||||
a(href="http://basicer.com/")
|
h6.label.team-name
|
||||||
img(src="/images/pages/about/rob_small.png").img-thumbnail
|
a(href="http://robinyang.com/" rel="external") Robin Yang
|
||||||
.team_bio
|
small(data-i18n="about.robin_title")
|
||||||
h4.team_name
|
small(data-i18n="about.robin_blurb")
|
||||||
a(href="http://basicer.com/") Rob Blanckaert
|
|
||||||
div(data-i18n="about.rob_title")
|
|
||||||
div(data-i18n="about.rob_blurb")
|
|
||||||
|
|
||||||
li.row
|
|
||||||
|
|
||||||
img(src="/images/pages/about/josh_c_small.png").img-thumbnail
|
|
||||||
.team_bio
|
|
||||||
h4.team_name Josh Callebaut
|
|
||||||
div(data-i18n="about.josh_c_title")
|
|
||||||
div(data-i18n="about.josh_c_blurb")
|
|
||||||
|
|
||||||
a(href="http://robinyang.com/")
|
|
||||||
img(src="/images/pages/about/robin_small.png").img-thumbnail
|
|
||||||
.team_bio
|
|
||||||
h4.team_name
|
|
||||||
a(href="http://robinyang.com/") Robin Yang
|
|
||||||
div(data-i18n="about.robin_title")
|
|
||||||
div(data-i18n="about.robin_blurb")
|
|
||||||
|
|
||||||
|
|
||||||
// Part time / contract
|
// Part time / contract
|
||||||
|
|
||||||
li.row
|
li
|
||||||
|
a(href="http://floor.is/lava/" rel="external")
|
||||||
|
img(src="/images/pages/about/josh_small.png").img-thumbnail
|
||||||
|
.team-bio
|
||||||
|
h6.label.team-name
|
||||||
|
a(href="http://floor.is/lava/" rel="external") Josh Lee
|
||||||
|
small(data-i18n="about.josh_title")
|
||||||
|
small(data-i18n="about.josh_blurb")
|
||||||
|
|
||||||
a(href="http://floor.is/lava/")
|
li
|
||||||
img(src="/images/pages/about/josh_small.png").img-thumbnail
|
a(href="https://soundcloud.com/taking-off" rel="external")
|
||||||
.team_bio
|
img(src="/images/pages/about/jose_small.png").img-thumbnail
|
||||||
h4.team_name
|
.team-bio
|
||||||
a(href="http://floor.is/lava/") Josh Lee
|
h6.label.team-name
|
||||||
div(data-i18n="about.josh_title")
|
a(href="https://soundcloud.com/taking-off" rel="external") Jose Antonini
|
||||||
div(data-i18n="about.josh_blurb")
|
small(data-i18n="about.jose_title")
|
||||||
|
small(data-i18n="about.jose_blurb")
|
||||||
|
|
||||||
a(href="https://soundcloud.com/taking-off")
|
li
|
||||||
img(src="/images/pages/about/jose_small.png").img-thumbnail
|
a(href="http://retrostylegames.com/" rel="external")
|
||||||
.team_bio
|
img(src="/images/pages/about/pavel_small.png").img-thumbnail
|
||||||
h4.team_name
|
.team-bio
|
||||||
a(href="https://soundcloud.com/taking-off") Jose Antonini
|
h6.label.team-name
|
||||||
div(data-i18n="about.jose_title")
|
a(href="http://retrostylegames.com/" rel="external") Pavel Konstantinov
|
||||||
div(data-i18n="about.jose_blurb")
|
small(data-i18n="about.retrostyle_title")
|
||||||
|
small(data-i18n="about.retrostyle_blurb")
|
||||||
|
|
||||||
li.row
|
li
|
||||||
|
a(href="http://retrostylegames.com/" rel="external")
|
||||||
a(href="http://retrostylegames.com/")
|
img(src="/images/pages/about/oleg_small.png").img-thumbnail
|
||||||
img(src="/images/pages/about/pavel_small.png").img-thumbnail
|
.team-bio
|
||||||
.team_bio
|
h6.label.team-name
|
||||||
h4.team_name
|
a(href="http://retrostylegames.com/" rel="external") Oleg Ulyanickiy
|
||||||
a(href="http://retrostylegames.com/") Pavel Konstantinov
|
small(data-i18n="about.retrostyle_title")
|
||||||
div(data-i18n="about.retrostyle_title")
|
small(data-i18n="about.retrostyle_blurb")
|
||||||
div(data-i18n="about.retrostyle_blurb")
|
|
||||||
|
|
||||||
a(href="http://retrostylegames.com/")
|
|
||||||
img(src="/images/pages/about/oleg_small.png").img-thumbnail
|
|
||||||
.team_bio
|
|
||||||
h4.team_name
|
|
||||||
a(href="http://retrostylegames.com/") Oleg Ulyanickiy
|
|
||||||
div(data-i18n="about.retrostyle_title")
|
|
||||||
div(data-i18n="about.retrostyle_blurb")
|
|
||||||
|
|
||||||
li.row
|
|
||||||
|
|
||||||
img(src="/images/pages/about/carlos_small.png").img-thumbnail
|
|
||||||
.team_bio
|
|
||||||
h4.team_name Carlos Maia
|
|
||||||
div(data-i18n="about.carlos_title")
|
|
||||||
div(data-i18n="about.carlos_blurb")
|
|
||||||
|
|
||||||
|
li
|
||||||
|
img(src="/images/pages/about/carlos_small.png").img-thumbnail
|
||||||
|
.team-bio
|
||||||
|
h6.label.team-name Carlos Maia
|
||||||
|
small(data-i18n="about.carlos_title")
|
||||||
|
small(data-i18n="about.carlos_blurb")
|
||||||
|
|
||||||
|
#community.anchor
|
||||||
|
#community-row-1.row.text-center
|
||||||
|
.col-sm-12
|
||||||
|
.text-center
|
||||||
|
h3(data-i18n="about.community_title")
|
||||||
|
| ...and our open-source community
|
||||||
|
h4(data-i18n="about.community_subtitle")
|
||||||
|
| Over 450 contributors have helped build CodeCombat, with more joining every week!
|
||||||
|
img(src="/images/pages/about/github_avatars.png")#community-avatars
|
||||||
|
|
||||||
|
#community-row-2.row
|
||||||
|
.col-sm-5
|
||||||
|
p.responsive-side-margins
|
||||||
|
span(data-i18n="about.community_description_1")
|
||||||
|
| CodeCombat is a community project, with hundreds of players volunteering to create levels, contribute to our code to add features, fix bugs, playtest, and even translate the game into 50 languages so far. Employees, contributors and the site gain by sharing ideas and pooling effort, as does the open source community in general. The site is built on numerous open source projects, and we are open sourced to give back to the community and provide code-curious players a familiar project to explore and experiment with. Anyone can join the CodeCombat community! Check out our
|
||||||
|
a(href="/contribute")
|
||||||
|
span(data-i18n="about.community_description_link")
|
||||||
|
| contribute page
|
||||||
|
span(data-i18n="about.community_description_2")
|
||||||
|
| for more info.
|
||||||
|
.col-sm-6.col-sm-offset-1#community-graphic.responsive-side-margins
|
||||||
|
h2 Over 450 contributors have lent their support and time to this project.
|
||||||
|
img(src="/images/pages/about/github.png")
|
||||||
|
#community-graphic-filler
|
||||||
|
|
||||||
|
#story.anchor
|
||||||
|
.text-center
|
||||||
|
h3(data-i18n="about.story_title")
|
||||||
|
| Our story so far
|
||||||
|
h4.responsive-side-margins(data-i18n="about.story_subtitle")
|
||||||
|
| Since 2013, CodeCombat has grown from a mere set of sketches to a living, thriving game.
|
||||||
|
.row
|
||||||
|
#story-graphic-1.col-lg-6
|
||||||
|
.media
|
||||||
|
.pull-left
|
||||||
|
img.media-object#story-image-1(src="/images/pages/about/Character_Silouhette.png")
|
||||||
|
.media-body
|
||||||
|
.media-heading.text-h1
|
||||||
|
span(data-i18n="about.story_statistic_1a")
|
||||||
|
| 5,000,000+
|
||||||
|
br
|
||||||
|
span(data-i18n="about.story_statistic_1b")
|
||||||
|
| total players
|
||||||
|
p.text-h5 have started their programming journey through CodeCombat
|
||||||
|
|
||||||
|
.col-lg-5.col-lg-offset-1
|
||||||
|
#story-graphic-2
|
||||||
|
.media
|
||||||
|
p.text-h5(data-i18n="about.story_statistic_2a")
|
||||||
|
| We’ve been translated into over 50 languages — our players hail from
|
||||||
|
.pull-right
|
||||||
|
img(src="/images/pages/about/globe_green.png")
|
||||||
|
.media-body
|
||||||
|
.media-heading.text-h1(data-i18n="about.story_statistic_2b")
|
||||||
|
| 200+ countries
|
||||||
|
|
||||||
|
#story-graphic-3.text-center
|
||||||
|
p
|
||||||
|
div.text-h5(data-i18n="about.story_statistic_3a")
|
||||||
|
| Together, they have written
|
||||||
|
#story-bracketed-text
|
||||||
|
div#left-bracket
|
||||||
|
img(src="/images/pages/about/bracket_left.png")
|
||||||
|
div.text-h1(data-i18n="about.story_statistic_3b")
|
||||||
|
| 1 billion lines of code and counting
|
||||||
|
div#right-bracket
|
||||||
|
img(src="/images/pages/about/bracket_right.png")
|
||||||
|
#story-languages
|
||||||
|
.text-center
|
||||||
|
.text-h5(data-i18n="about.story_statistic_3c")
|
||||||
|
| across six different programming languages
|
||||||
|
#language-icons.text-center
|
||||||
|
img.hidden-xs(src="/images/pages/about/Languages.png")
|
||||||
|
img.hidden-sm.hidden-md.hidden-lg(src="/images/pages/about/Languages_group1.png")
|
||||||
|
img.hidden-sm.hidden-md.hidden-lg(src="/images/pages/about/Languages_group2.png")
|
||||||
|
|
||||||
|
#story-graphic-4.text-center
|
||||||
|
p
|
||||||
|
div.text-h5(data-i18n="about.story_long_way_1")
|
||||||
|
| Though we've come a long way...
|
||||||
|
figure
|
||||||
|
img(src="/images/pages/about/sketch.png")
|
||||||
|
figcaption
|
||||||
|
small(data-i18n="about.story_sketch_caption")
|
||||||
|
| Nick's very first sketch depicting a programming game in action.
|
||||||
|
p
|
||||||
|
.text-h5(data-i18n="about.story_long_way_2")
|
||||||
|
| we still have much to do before we complete our quest, so...
|
||||||
|
|
||||||
|
#jobs.anchor
|
||||||
|
.text-center
|
||||||
|
h3(data-i18n="about.jobs_title")
|
||||||
|
| Come work with us and help write CodeCombat history!
|
||||||
|
h4(data-i18n="about.jobs_subtitle")
|
||||||
|
| Don't see a good fit but interested in keeping in touch? See our "Create Your Own" listing.
|
||||||
|
#jobs-row.row
|
||||||
|
.col-sm-6.col-md-5.col-md-offset-1.col-lg-4.col-lg-offset-0
|
||||||
|
#benefits
|
||||||
|
h5(data-i18n="about.jobs_benefits")
|
||||||
|
| Employee Benefits
|
||||||
|
ul
|
||||||
|
li.small(data-i18n="about.jobs_benefit_1")
|
||||||
|
| Competitive salary and options
|
||||||
|
li.small(data-i18n="about.jobs_benefit_2")
|
||||||
|
| 15 day minimum vacation policy, excluding company holidays
|
||||||
|
li.small(data-i18n="about.jobs_benefit_3")
|
||||||
|
| Work from home flexibility
|
||||||
|
li.small(data-i18n="about.jobs_benefit_4")
|
||||||
|
| Unlimited sick/personal days
|
||||||
|
li.small(data-i18n="about.jobs_benefit_5")
|
||||||
|
| Professional development and continuing education support
|
||||||
|
li.small(data-i18n="about.jobs_benefit_6")
|
||||||
|
| Medical/dental/vision insurance
|
||||||
|
.col-sm-6.col-md-5.col-lg-4
|
||||||
|
.job-listing
|
||||||
|
h5 Software Engineer, iOS
|
||||||
|
.text-center
|
||||||
|
small.label
|
||||||
|
| San Francisco • Fulltime
|
||||||
|
p.small Want to write the first iPad app for CodeCombat? We’re looking for a product-focused engineer to translate our core gameplay and educational tools into an experience that feels like it was born on the iPad.
|
||||||
|
a.job-link.btn.btn-lg.btn-navy(href="https://jobs.lever.co/codecombat/eb190007-7195-49ee-a322-893b0d1cdcb4" rel="external")
|
||||||
|
| Learn More
|
||||||
|
.col-sm-6.col-md-5.col-md-offset-1.col-lg-4.col-lg-offset-0
|
||||||
|
.job-listing
|
||||||
|
h5 Head of Sales
|
||||||
|
.text-center
|
||||||
|
small.label
|
||||||
|
| San Francisco • Fulltime
|
||||||
|
p.small School districts are scrambling to offer computer science classes to all their students as a core subject. They have had no solution, because they can't afford to hire enough programming teachers – until now.
|
||||||
|
a.job-link.btn.btn-lg.btn-navy(href="https://jobs.lever.co/codecombat/2d0194ed-7c69-4aab-b1f9-363ca4b9f04b" rel="external")
|
||||||
|
| Learn More
|
||||||
|
.col-sm-6.col-md-5.col-lg-4
|
||||||
|
.job-listing
|
||||||
|
h5 Sales Representative
|
||||||
|
.text-center
|
||||||
|
small.label
|
||||||
|
| San Francisco • Fulltime
|
||||||
|
p.small School districts are scrambling to offer computer science classes to all their students as a core subject. They have had no solution, because they can't afford to hire enough programming teachers – until now.
|
||||||
|
a.job-link.btn.btn-lg.btn-navy(href="https://jobs.lever.co/codecombat/3f6ff123-16ce-4ecb-aba3-dcf4e8927c47" rel="external")
|
||||||
|
| Learn More
|
||||||
|
.col-sm-6.col-md-5.col-md-offset-1.col-lg-4.col-lg-offset-0
|
||||||
|
.job-listing
|
||||||
|
h5(data-i18n="about.jobs_custom_title")
|
||||||
|
| Create Your Own
|
||||||
|
p.small(data-i18n="about.jobs_custom_description")
|
||||||
|
| Are you passionate about CodeCombat but don't see a job listed that matches your qualifications? Write us and show how you think you can contribute to our team. We'd love to hear from you!
|
||||||
|
p.small
|
||||||
|
span(data-i18n="about.jobs_custom_contact_1")
|
||||||
|
| Send us a note at
|
||||||
|
a(href="mailto:team@codecombat.com")
|
||||||
|
| team@codecombat.com
|
||||||
|
span(data-i18n="about.jobs_custom_contact_2")
|
||||||
|
| introducing yourself and we might get in touch in the future!
|
||||||
|
|
||||||
|
#contact.anchor
|
||||||
|
.text-center
|
||||||
|
h3(data-i18n="about.contact_title")
|
||||||
|
| Press & Contact
|
||||||
|
h4(data-i18n="about.contact_subtitle")
|
||||||
|
| Need more information? Get in touch with us at
|
||||||
|
a(href="mailto:team@codecombat.com") team@codecombat.com
|
||||||
|
|
||||||
|
#files
|
||||||
|
.row
|
||||||
|
.col-md-6.col-lg-8
|
||||||
|
#screenshots
|
||||||
|
span.label(data-i18n="about.screenshots_title")
|
||||||
|
| Game Screenshots
|
||||||
|
.hidden-sm.hidden-md.hidden-lg
|
||||||
|
small(data-i18n="about.screenshots_hint")
|
||||||
|
| (click to view full size)
|
||||||
|
#screenshot-grid
|
||||||
|
a.screen-thumbnail(data-toggle="modal", data-target="#screenshot-lightbox", data-index='0')
|
||||||
|
img(src="/images/pages/about/screenshot_desert.png")
|
||||||
|
a.screen-thumbnail(data-toggle="modal", data-target="#screenshot-lightbox", data-index='1')
|
||||||
|
img(src="/images/pages/about/screenshot_forest.png")
|
||||||
|
a.screen-thumbnail(data-toggle="modal", data-target="#screenshot-lightbox", data-index='2')
|
||||||
|
img(src="/images/pages/about/screenshot_dungeon.png")
|
||||||
|
a.screen-thumbnail(data-toggle="modal", data-target="#screenshot-lightbox", data-index='3')
|
||||||
|
img(src="/images/pages/about/screenshot_glacier.png")
|
||||||
|
.clearfix.hidden-xs
|
||||||
|
small(data-i18n="about.screenshots_hint")
|
||||||
|
| (click to view full size)
|
||||||
|
.col-md-6.col-lg-4
|
||||||
|
#downloads-container
|
||||||
|
#downloads
|
||||||
|
.label(data-i18n="about.downloads_title")
|
||||||
|
| Download Assets & Information
|
||||||
|
ul
|
||||||
|
li
|
||||||
|
a.small(href="http://files.codecombat.com/presspack/AboutCodeCombat.pdf")
|
||||||
|
span(data-i18n="about.about_codecombat")
|
||||||
|
| About CodeCombat
|
||||||
|
| (.pdf)
|
||||||
|
li
|
||||||
|
a.small(href="http://files.codecombat.com/presspack/CodeCombat-Logo.ai")
|
||||||
|
span(data-i18n="about.logo")
|
||||||
|
| Logo
|
||||||
|
| (.ai)
|
||||||
|
li
|
||||||
|
a.small(href="http://files.codecombat.com/presspack/CodeCombat-Logo.png")
|
||||||
|
span(data-i18n="about.logo")
|
||||||
|
| Logo
|
||||||
|
| (.png)
|
||||||
|
li
|
||||||
|
a.small(href="http://files.codecombat.com/presspack/GameImages.zip")
|
||||||
|
span(data-i18n="about.screenshots")
|
||||||
|
| Screenshots
|
||||||
|
| (.zip)
|
||||||
|
li
|
||||||
|
a.small(href="http://files.codecombat.com/presspack/gameimages/CodeCombat_Splash.png")
|
||||||
|
span(data-i18n="about.character_art")
|
||||||
|
| Character Art
|
||||||
|
| (.png)
|
||||||
|
.text-center
|
||||||
|
a.btn.btn-lg.btn-primary-alt#download-button(href="http://files.codecombat.com/presspack/CodeCombat_PressPack.zip")
|
||||||
|
span.glyphicon.glyphicon-download-alt
|
||||||
|
span(data-i18n="about.download_all")
|
||||||
|
| Download All
|
||||||
|
|
||||||
|
#screenshot-lightbox.modal.fade(data-show="false")
|
||||||
|
.modal-dialog
|
||||||
|
.modal-content
|
||||||
|
#screenshot-carousel.carousel
|
||||||
|
ol.carousel-indicators
|
||||||
|
li(data-target=".screenshot-display", data-slide-to="0").active
|
||||||
|
li(data-target=".screenshot-display", data-slide-to="1")
|
||||||
|
li(data-target=".screenshot-display", data-slide-to="2")
|
||||||
|
li(data-target=".screenshot-display", data-slide-to="3")
|
||||||
|
|
||||||
|
.carousel-inner
|
||||||
|
.item.active
|
||||||
|
img#screenshot-desert(src="/images/pages/about/Desert.png")
|
||||||
|
.item
|
||||||
|
img#screenshot-forest(src="/images/pages/about/Forest.png")
|
||||||
|
.item
|
||||||
|
img#screenshot-dungeon(src="/images/pages/about/Dungeon.png")
|
||||||
|
.item
|
||||||
|
img#screenshot-glacier(src="/images/pages/about/Glacier.png")
|
||||||
|
a#carousel-left.left.carousel-control(href="#screenshot-carousel", role="button")
|
||||||
|
span.glyphicon.glyphicons-chevron-left.glyphicon-chevron-left(aria-hidden="true")
|
||||||
|
span.sr-only Previous
|
||||||
|
a#carousel-right.right.carousel-control(href="#screenshot-carousel", role="button")
|
||||||
|
span.glyphicon.glyphicons-chevron-right.glyphicon-chevron-right(aria-hidden="true")
|
||||||
|
span.sr-only Next
|
||||||
|
|
||||||
|
#location
|
||||||
|
.row
|
||||||
|
.col-sm-4.col-sm-offset-2
|
||||||
|
p
|
||||||
|
b CodeCombat Inc.
|
||||||
|
p 360 3rd St.
|
||||||
|
p Suite 700 (Livefyre)
|
||||||
|
p San Francisco, CA 94107
|
||||||
|
a(href="mailto:team@codecombat.com") team@codecombat.com
|
||||||
|
.col-sm-4
|
||||||
|
p
|
||||||
|
b(data-i18n="about.location_title")
|
||||||
|
| We're located in downtown SF:
|
||||||
|
iframe(width="370", height="280", frameBorder="2", src="https://www.google.com/maps/embed/v1/place?key=AIzaSyAIGQz3OMbv5YWivScUM86-zESjEgJR2Xo&q=360+3rd+St+Suite+700,+San+Francisco,+CA+94107")
|
||||||
|
|
|
@ -20,11 +20,12 @@ block content
|
||||||
th Location
|
th Location
|
||||||
th Age / Level
|
th Age / Level
|
||||||
th Students
|
th Students
|
||||||
th How Found / Notes
|
th Role
|
||||||
|
th Phone
|
||||||
th Status
|
th Status
|
||||||
tbody
|
tbody
|
||||||
- var numReviewed = 0
|
- var numReviewed = 0
|
||||||
- var maxReviewedShown = 100
|
- var maxReviewedShown = 1000
|
||||||
each trialRequest in trialRequests
|
each trialRequest in trialRequests
|
||||||
if trialRequest.get('status') !== 'submitted'
|
if trialRequest.get('status') !== 'submitted'
|
||||||
- numReviewed++
|
- numReviewed++
|
||||||
|
@ -42,7 +43,8 @@ block content
|
||||||
td= props.location || trialRequest.locationString()
|
td= props.location || trialRequest.locationString()
|
||||||
td= props.age || trialRequest.educationLevelString()
|
td= props.age || trialRequest.educationLevelString()
|
||||||
td= props.numStudents
|
td= props.numStudents
|
||||||
td= props.heardAbout || props.notes
|
td= props.role
|
||||||
|
td= props.phoneNumber
|
||||||
td.status-cell
|
td.status-cell
|
||||||
if trialRequest.get('status') === 'submitted'
|
if trialRequest.get('status') === 'submitted'
|
||||||
button.btn.btn-xs.btn-success.btn-approve(data-trial-request-id=trialRequest.id) Approve
|
button.btn.btn-xs.btn-success.btn-approve(data-trial-request-id=trialRequest.id) Approve
|
||||||
|
@ -51,3 +53,10 @@ block content
|
||||||
span= trialRequest.get('prepaidCode')
|
span= trialRequest.get('prepaidCode')
|
||||||
else
|
else
|
||||||
span= trialRequest.get('status')
|
span= trialRequest.get('status')
|
||||||
|
if props.heardAbout || props.notes
|
||||||
|
tr
|
||||||
|
td(colspan=2)
|
||||||
|
td(colspan=7)
|
||||||
|
strong #{trialRequest.nameString()} notes:
|
||||||
|
div= props.heardAbout || props.notes
|
||||||
|
td
|
||||||
|
|
144
app/templates/base-flat.jade
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
.style-flat
|
||||||
|
block header
|
||||||
|
.container-fluid.text-center
|
||||||
|
.alert.alert-danger.lt-ie9
|
||||||
|
strong(data-i18n="home.no_ie") The CodeCombat game does not run in Internet Explorer 8 or older. Sorry!
|
||||||
|
|
||||||
|
if view.isIPadBrowser() || view.isMobile()
|
||||||
|
.alert.alert-danger.mobile
|
||||||
|
strong(data-i18n="home.no_mobile") CodeCombat gameplay was not designed for mobile devices and may not work!
|
||||||
|
else if view.isOldBrowser()
|
||||||
|
.alert.alert-danger.old-browser
|
||||||
|
strong(data-i18n="home.old_browser") Uh oh, your browser is too old to play CodeCombat. Sorry!
|
||||||
|
br
|
||||||
|
span(data-i18n="home.old_browser_suffix") You can try anyway, but it probably won't work.
|
||||||
|
|
||||||
|
nav.navbar.navbar-default
|
||||||
|
.container
|
||||||
|
.row
|
||||||
|
.col-md-3.col-sm-4
|
||||||
|
.navbar-header
|
||||||
|
button.navbar-toggle.collapsed(data-toggle='collapse', data-target='#navbar-collapse' aria-expanded='false')
|
||||||
|
span.sr-only Toggle navigation
|
||||||
|
span.icon-bar
|
||||||
|
span.icon-bar
|
||||||
|
span.icon-bar
|
||||||
|
a.navbar-brand(href="/")
|
||||||
|
img#logo-img(src="/images/pages/base/logo.png")
|
||||||
|
span.glyphicon.glyphicon-home
|
||||||
|
|
||||||
|
.col-md-9.col-sm-8
|
||||||
|
#navbar-collapse.collapse.navbar-collapse
|
||||||
|
ul.nav.navbar-nav.pull-left
|
||||||
|
li
|
||||||
|
a(href="/about") About
|
||||||
|
li
|
||||||
|
a(href="/courses") Courses
|
||||||
|
li
|
||||||
|
a(href="/courses/teachers") Teachers
|
||||||
|
li
|
||||||
|
a(href="https://discourse.codecombat.com/") Forum
|
||||||
|
if me.isAnonymous()
|
||||||
|
li
|
||||||
|
a#create-account-link.signup-button Create Account
|
||||||
|
li
|
||||||
|
a#login-link.login-button Login
|
||||||
|
else
|
||||||
|
li.dropdown
|
||||||
|
a.dropdown-toggle(href="#", data-toggle="dropdown" role="button" aroa-haspopup="true" aria-expanded="false")
|
||||||
|
span.spr My Account
|
||||||
|
ul.dropdown-menu
|
||||||
|
li.user-dropdown-header.text-center
|
||||||
|
span.user-level= me.level()
|
||||||
|
a(href="/user/#{me.getSlugOrID()}")
|
||||||
|
img.img-circle(src=me.getPhotoURL())
|
||||||
|
h5=me.displayName()
|
||||||
|
li
|
||||||
|
a(href="/user/#{me.getSlugOrID()}" data-i18n="nav.profile")
|
||||||
|
li
|
||||||
|
a(href="/account/settings", data-i18n="play.settings")
|
||||||
|
li
|
||||||
|
a(href="/account/payments", data-i18n="account.payments")
|
||||||
|
li
|
||||||
|
a(href="/account/subscription", data-i18n="account.subscription")
|
||||||
|
li
|
||||||
|
a(href="/account/prepaid", data-i18n="account.prepaid_codes") Prepaid Codes
|
||||||
|
li
|
||||||
|
a#logout-button(data-i18n="login.log_out")
|
||||||
|
|
||||||
|
li
|
||||||
|
#language-dropdown-wrapper
|
||||||
|
select.language-dropdown.form-control
|
||||||
|
|
||||||
|
|
||||||
|
block outer_content
|
||||||
|
#site-content-area
|
||||||
|
block content
|
||||||
|
p If this is showing, you dun goofed
|
||||||
|
|
||||||
|
block footer
|
||||||
|
#character-lineup.text-center
|
||||||
|
img(src="/images/pages/home/character_lineup.png")
|
||||||
|
.container-fluid
|
||||||
|
#footer.small
|
||||||
|
.container
|
||||||
|
.row
|
||||||
|
.col-sm-3
|
||||||
|
ul.list-unstyled
|
||||||
|
li
|
||||||
|
strong CodeCombat
|
||||||
|
li
|
||||||
|
a(href="/about") About
|
||||||
|
li
|
||||||
|
a(href="/Careers") Jobs
|
||||||
|
li
|
||||||
|
a(href="http://blog.codecombat.com/", data-i18n="nav.blog")
|
||||||
|
li
|
||||||
|
a(href="/legal") Legal
|
||||||
|
|
||||||
|
.col-sm-3
|
||||||
|
ul.list-unstyled
|
||||||
|
li
|
||||||
|
strong Schools
|
||||||
|
li
|
||||||
|
a(href="/courses/teachers") Teachers
|
||||||
|
li
|
||||||
|
a(href="https://sites.google.com/a/codecombat.com/teacher-guides/") Educator Wiki
|
||||||
|
li
|
||||||
|
a(href="/teachers/quote") Request a Quote
|
||||||
|
|
||||||
|
.col-sm-3
|
||||||
|
ul.list-unstyled
|
||||||
|
li
|
||||||
|
strong Get Involved
|
||||||
|
li
|
||||||
|
a(href='/community', data-i18n="nav.community")
|
||||||
|
li
|
||||||
|
a(href="/contribute") Contribute
|
||||||
|
li
|
||||||
|
a(href=view.forumLink(), data-i18n="nav.forum")
|
||||||
|
li
|
||||||
|
a(href="/play/ladder") Multiplayer
|
||||||
|
li
|
||||||
|
a(href="https://github.com/codecombat/codecombat") Open source (GitHub)
|
||||||
|
.col-sm-3
|
||||||
|
ul.list-unstyled
|
||||||
|
li
|
||||||
|
strong Support
|
||||||
|
li
|
||||||
|
a(href="https://discourse.codecombat.com/t/faq-check-before-posting/1027") FAQs
|
||||||
|
li
|
||||||
|
a(tabindex=-1, data-toggle="coco-modal", data-target="core/ContactModal", data-i18n="nav.contact")
|
||||||
|
li
|
||||||
|
a(href="https://www.facebook.com/codecombat", data-i18n="nav.facebook")
|
||||||
|
li
|
||||||
|
a(href="https://twitter.com/codecombat", data-i18n="nav.twitter")
|
||||||
|
|
||||||
|
#final-footer.small.text-center
|
||||||
|
| Copyright ©2016 CodeCombat. All Rights Reserved.
|
||||||
|
br.hidden-lg.hidden-md
|
||||||
|
img(src="/images/pages/base/logo.png" alt="CodeCombat")
|
||||||
|
br.hidden-lg.hidden-md
|
||||||
|
span.spr Need help? Email
|
||||||
|
a(href="mailto:team@codecombat.com") team@codecombat.com
|
||||||
|
span.spl and we'll get in touch!
|
|
@ -1,388 +1,253 @@
|
||||||
.container-fluid.text-center
|
extends /templates/base-flat
|
||||||
.alert.alert-danger.lt-ie9
|
|
||||||
strong(data-i18n="home.no_ie") The CodeCombat game does not run in Internet Explorer 8 or older. Sorry!
|
|
||||||
|
|
||||||
if view.isIPadBrowser() || view.isMobile()
|
block content
|
||||||
.alert.alert-danger.mobile
|
.container-fluid#jumbotron-container-fluid(class=view.jumbotron === 'student' ? 'alt-image' : '')
|
||||||
strong(data-i18n="home.no_mobile") CodeCombat gameplay was not designed for mobile devices and may not work!
|
|
||||||
else if view.isOldBrowser()
|
|
||||||
.alert.alert-danger.old-browser
|
|
||||||
strong(data-i18n="home.old_browser") Uh oh, your browser is too old to play CodeCombat. Sorry!
|
|
||||||
br
|
|
||||||
span(data-i18n="home.old_browser_suffix") You can try anyway, but it probably won't work.
|
|
||||||
|
|
||||||
nav.navbar.navbar-default
|
|
||||||
.container
|
|
||||||
.row
|
|
||||||
.col-md-3.col-sm-4
|
|
||||||
.navbar-header
|
|
||||||
button.navbar-toggle.collapsed(data-toggle='collapse', data-target='#navbar-collapse' aria-expanded='false')
|
|
||||||
span.sr-only Toggle navigation
|
|
||||||
span.icon-bar
|
|
||||||
span.icon-bar
|
|
||||||
span.icon-bar
|
|
||||||
a.navbar-brand(href="/")
|
|
||||||
img#logo-img(src="/images/pages/base/logo.png")
|
|
||||||
span.glyphicon.glyphicon-home
|
|
||||||
|
|
||||||
.col-md-9.col-sm-8
|
|
||||||
#navbar-collapse.collapse.navbar-collapse
|
|
||||||
ul.nav.navbar-nav.pull-left
|
|
||||||
li
|
|
||||||
a(href="/about") About
|
|
||||||
li
|
|
||||||
a(href="/courses") Courses
|
|
||||||
li
|
|
||||||
a(href="/courses/teachers") Teachers
|
|
||||||
li
|
|
||||||
a(href="https://discourse.codecombat.com/") Forum
|
|
||||||
if me.isAnonymous()
|
|
||||||
li
|
|
||||||
a#create-account-link.signup-button Create Account
|
|
||||||
li
|
|
||||||
a#login-link.login-button Login
|
|
||||||
else
|
|
||||||
li.dropdown
|
|
||||||
a.dropdown-toggle(href="#", data-toggle="dropdown" role="button" aroa-haspopup="true" aria-expanded="false")
|
|
||||||
span.spr My Account
|
|
||||||
ul.dropdown-menu
|
|
||||||
li.user-dropdown-header.text-center
|
|
||||||
span.user-level= me.level()
|
|
||||||
a(href="/user/#{me.getSlugOrID()}")
|
|
||||||
img.img-circle(src=me.getPhotoURL())
|
|
||||||
h5=me.displayName()
|
|
||||||
li
|
|
||||||
a(href="/user/#{me.getSlugOrID()}" data-i18n="nav.profile")
|
|
||||||
li
|
|
||||||
a(href="/account/settings", data-i18n="play.settings")
|
|
||||||
li
|
|
||||||
a(href="/account/payments", data-i18n="account.payments")
|
|
||||||
li
|
|
||||||
a(href="/account/subscription", data-i18n="account.subscription")
|
|
||||||
li
|
|
||||||
a(href="/account/prepaid", data-i18n="account.prepaid_codes") Prepaid Codes
|
|
||||||
li
|
|
||||||
a#logout-button(data-i18n="login.log_out")
|
|
||||||
|
|
||||||
li
|
|
||||||
#language-dropdown-wrapper
|
|
||||||
select.language-dropdown.form-control
|
|
||||||
|
|
||||||
.container-fluid#jumbotron-container-fluid(class=view.jumbotron === 'student' ? 'alt-image' : '')
|
|
||||||
.container
|
|
||||||
.row
|
|
||||||
.col-lg-7.col-md-8
|
|
||||||
h1 The most engaging game for learning programming.
|
|
||||||
|
|
||||||
.col-lg-3.col-lg-offset-2.col-md-4
|
|
||||||
.well.text-center.hidden-md.hidden-lg
|
|
||||||
.row
|
|
||||||
.col-xs-8
|
|
||||||
h6 Classroom Edition:
|
|
||||||
.col-xs-4
|
|
||||||
h6 Learn to code:
|
|
||||||
.row
|
|
||||||
.col-xs-4
|
|
||||||
button#teacher-btn.btn.btn-primary.btn-lg.btn-block Teacher
|
|
||||||
.col-xs-4
|
|
||||||
a.btn.btn-forest.btn-lg.btn-block(href="/courses") Student
|
|
||||||
.col-xs-4
|
|
||||||
a.btn.btn-gold.btn-lg.btn-block(href=view.playURL) Play Now
|
|
||||||
|
|
||||||
.well.text-center.hidden-xs.hidden-sm
|
|
||||||
h6#classroom-edition-header Classroom Edition:
|
|
||||||
div
|
|
||||||
button#teacher-btn.btn.btn-primary.btn-lg.btn-block I'm a Teacher
|
|
||||||
div
|
|
||||||
a.btn.btn-forest.btn-lg.btn-block(href="/courses") I'm a Student
|
|
||||||
|
|
||||||
h6#learn-to-code-header Learn to code:
|
|
||||||
a.btn.btn-gold.btn-lg.btn-block(href=view.playURL) Play Now
|
|
||||||
.row#learn-more-row
|
|
||||||
.col-xs-12.text-center
|
|
||||||
a#learn-more-link
|
|
||||||
h6 Learn more
|
|
||||||
h2
|
|
||||||
span.glyphicon.glyphicon-chevron-down
|
|
||||||
|
|
||||||
|
|
||||||
.container#classroom-in-box-container
|
|
||||||
#classroom-in-box-row.row
|
|
||||||
.col-sm-6
|
|
||||||
h2.text-navy A classroom in-a-box for teaching computer science.
|
|
||||||
.col-sm-6
|
|
||||||
p CodeCombat is a platform for students to learn computer science while playing through a real game.
|
|
||||||
p Our courses have been specifically playtested to excel in a classroom setting, even by teachers with little to no prior programming experience.
|
|
||||||
|
|
||||||
#feature-spread-row.row.text-center
|
|
||||||
h3 Designed with teachers in mind
|
|
||||||
.col-sm-4
|
|
||||||
img.img-circle(src="/images/pages/home/F1_typedcode.png")
|
|
||||||
h4
|
|
||||||
| Real, typed code
|
|
||||||
br
|
|
||||||
| from the first level
|
|
||||||
p.small Getting students to typed code as quickly as possible is critical to learning programming syntax and proper structure.
|
|
||||||
|
|
||||||
.col-sm-4
|
|
||||||
img.img-circle(src="/images/pages/home/F2_teacherguides.png")
|
|
||||||
h4
|
|
||||||
| Educator resources
|
|
||||||
br
|
|
||||||
| and course guides
|
|
||||||
p.small Teaching computer science does not require a costly degree, because we provide tools to support educators of all backgrounds.
|
|
||||||
|
|
||||||
.col-sm-4
|
|
||||||
img.img-circle(src="/images/pages/home/F3_accessible.png")
|
|
||||||
h4
|
|
||||||
| Accessible to
|
|
||||||
br
|
|
||||||
| everyone
|
|
||||||
p.small Democratizing the process of learning coding is at the core of our philosophy. Everyone should be able to learn to code.
|
|
||||||
|
|
||||||
.testimonials-rows
|
|
||||||
.testimonials-filler-left
|
|
||||||
.testimonials-filler-right
|
|
||||||
.row
|
|
||||||
.col-lg-offset-2.col-lg-7.col-sm-8
|
|
||||||
blockquote
|
|
||||||
h3 I think they actually forgot that they were actually learning something.
|
|
||||||
|
|
||||||
.col-lg-2.col-sm-3.text-center
|
|
||||||
img.img-circle(src="/images/pages/home/timmaki.png")
|
|
||||||
h6 Tim Maki
|
|
||||||
.small Director of Technology, Tilton School
|
|
||||||
|
|
||||||
.row
|
|
||||||
.col-lg-7.col-sm-8.col-sm-push-4.col-lg-push-3
|
|
||||||
blockquote
|
|
||||||
h3 Coding is something I've always wanted to do, and I never thought I would be able to learn it in school.
|
|
||||||
|
|
||||||
.col-lg-2.col-sm-3.col-lg-offset-1.text-center.col-sm-pull-8.col-lg-pull-7
|
|
||||||
img.img-circle(src="/images/pages/home/dylan.png")
|
|
||||||
h6 Dylan
|
|
||||||
.small 3rd Grader
|
|
||||||
|
|
||||||
|
|
||||||
h3.text-center Why is learning through games important?
|
|
||||||
|
|
||||||
#benefit-row-1.row
|
|
||||||
#benefit-graphic-1.col-sm-6.col-sm-offset-1.col-sm-push-6
|
|
||||||
h2 Games reward the productive struggle.
|
|
||||||
img(src="/images/pages/home/G1_reward.png")
|
|
||||||
#benefit-graphic-1-filler
|
|
||||||
|
|
||||||
.col-sm-5.col-sm-pull-6
|
|
||||||
p
|
|
||||||
| Gaming is a medium that encourages interaction, discovery, and trial-and-error.
|
|
||||||
| A good game challenges the player to master skills over time,
|
|
||||||
| which is the same critical process students go through as they learn.
|
|
||||||
p
|
|
||||||
| Games excel at rewarding “
|
|
||||||
a(href="http://blog.mindresearch.org/blog/game-based-learning-infographic-strong-math-practices" target="_blank") productive struggle
|
|
||||||
span.spr ” - the kind of struggle that results in learning that’s engaging and
|
|
||||||
a(href="http://www.gamesandlearning.org/2014/06/09/teachers-on-using-games-in-class/" target="_blank") motivating
|
|
||||||
| , not tedious.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#benefit-row-2.row
|
|
||||||
#benefit-graphic-2.col-sm-6
|
|
||||||
h2 Studies suggest gaming is good for children’s brains. (it’s true!)
|
|
||||||
img(src="/images/pages/home/G2_brains.png")
|
|
||||||
#benefit-graphic-2-filler
|
|
||||||
|
|
||||||
.col-sm-5.col-sm-offset-1
|
|
||||||
p
|
|
||||||
span.spr When game-based learning systems are
|
|
||||||
a(href="http://schoolsweek.co.uk/gaming-is-good-for-childrens-brains-study-suggests/" target="_blank") compared
|
|
||||||
span.spl.spr against conventional assessment methods, the difference is clear: games are better at helping students retain knowledge, concentrate and
|
|
||||||
a(href="http://dev.k-12techdecisions.com/article/game_based_learning_is_where_vygotsky_meets_dweck/P3" target="_blank") perform at a higher level of achievement
|
|
||||||
| .
|
|
||||||
p
|
|
||||||
| Games also provide real-time feedback that allows students to adjust their solution path and understand concepts more holistically, instead of being limited to just “correct” or “incorrect” answers.
|
|
||||||
|
|
||||||
#benefit-row-3.row
|
|
||||||
#benefit-graphic-3.col-sm-6.col-sm-offset-1.col-sm-push-6
|
|
||||||
h2 A real game, played with real coding.
|
|
||||||
img(src="/images/pages/home/G3_game.png")
|
|
||||||
#benefit-graphic-3-filler
|
|
||||||
|
|
||||||
.col-sm-5.col-sm-pull-6
|
|
||||||
p
|
|
||||||
| A great game is more than just badges and achievements - it’s about a player’s journey, well-designed puzzles, and the ability to tackle challenges with agency and confidence.
|
|
||||||
p
|
|
||||||
| CodeCombat is a game that gives players that agency and confidence with our robust typed code engine, which helps beginner and advanced students alike write proper, valid code.
|
|
||||||
|
|
||||||
|
|
||||||
.request-demo-row.text-center
|
|
||||||
h3 Curious? Request a demo and we'll show you the ropes
|
|
||||||
h4 Or create a class and see it for yourself!
|
|
||||||
div
|
|
||||||
a.btn.btn-primary.btn-lg(href="/teachers/freetrial") Request a Demo
|
|
||||||
a.btn.btn-primary-alt.btn-lg(href="/courses/teachers") Create a Class
|
|
||||||
div
|
|
||||||
if me.isAnonymous()
|
|
||||||
span.spr Already have an account?
|
|
||||||
a.login-button Login
|
|
||||||
else
|
|
||||||
span.spr You are currently logged in as #{me.broadName()}.
|
|
||||||
a(href="/courses/teachers") View my classes
|
|
||||||
span.spr.spl or
|
|
||||||
a#logout-button logout
|
|
||||||
|
|
||||||
h3.text-center Computer science courses for all ages
|
|
||||||
h4.text-center
|
|
||||||
span#school-level-label Show me lesson time estimates for:
|
|
||||||
select#school-level-dropdown.form-control.text-navy
|
|
||||||
option(value='elementary') Elementary School
|
|
||||||
option(value='middle', selected=true) Middle School
|
|
||||||
option(value='high') High School
|
|
||||||
h5.text-center#total-hours-header
|
|
||||||
span.spr Total curriculum hours:
|
|
||||||
span#semester-duration
|
|
||||||
#courses-row.row
|
|
||||||
- var conceptsSeen = {};
|
|
||||||
- var lastScreenshot = "";
|
|
||||||
for course, courseIndex in view.courses.models
|
|
||||||
.col-md-3.col-sm-4
|
|
||||||
.media.course-details(data-course-slug=course.get('slug'))
|
|
||||||
if courseIndex === 0
|
|
||||||
.free-course
|
|
||||||
h6 Free for all students
|
|
||||||
.media-body(title=course.get('description'))
|
|
||||||
h6.course-name= course.get('name') + ':'
|
|
||||||
p.small
|
|
||||||
- var total = 0;
|
|
||||||
each concept in course.get('concepts')
|
|
||||||
- if (conceptsSeen[concept]) continue;
|
|
||||||
- conceptsSeen[concept] = true;
|
|
||||||
if total === 3
|
|
||||||
- total += 1;
|
|
||||||
span ...
|
|
||||||
- continue;
|
|
||||||
else if total > 3
|
|
||||||
- continue;
|
|
||||||
else if total > 0
|
|
||||||
span.spr ,
|
|
||||||
- total += 1;
|
|
||||||
span(data-i18n="concepts." + concept)
|
|
||||||
img.media-object(src="/images/pages/home/course"+(courseIndex+1)+".png")
|
|
||||||
- lastScreenshot = course.get('screenshot');
|
|
||||||
h6.course-duration
|
|
||||||
span.spr Lesson time:
|
|
||||||
span.course-hours= course.get('duration') || 0
|
|
||||||
span.spl.unit(data-i18n="units.hours")
|
|
||||||
for upcomingCourse in ['Computer Science 6', 'Computer Science 7', 'Computer Science 8']
|
|
||||||
.col-md-3.col-sm-4
|
|
||||||
.media.disabled
|
|
||||||
.media-body
|
|
||||||
h6.course-name= upcomingCourse + ':'
|
|
||||||
p.small Coming soon!
|
|
||||||
img.media-object(src="/images/pages/home/inprogress.png")
|
|
||||||
|
|
||||||
.clearfix
|
|
||||||
.text-center
|
|
||||||
h4
|
|
||||||
img(src="/images/pages/home/course_languages.png")
|
|
||||||
div Courses are available in JavaScript, Python, and Java (coming soon!)
|
|
||||||
|
|
||||||
.testimonials-rows
|
|
||||||
.testimonials-filler-left
|
|
||||||
.testimonials-filler-right
|
|
||||||
.row
|
|
||||||
.col-lg-offset-2.col-lg-7.col-sm-8
|
|
||||||
blockquote
|
|
||||||
h3 Boasts riddles that are complex enough to fascinate gamers and coders alike.
|
|
||||||
|
|
||||||
.col-lg-2.col-sm-3.text-center
|
|
||||||
img.img-circle(src="/images/pages/home/opensource.png")
|
|
||||||
h6 Open Source
|
|
||||||
.small opensource.com
|
|
||||||
|
|
||||||
.row
|
|
||||||
.col-lg-7.col-sm-8.col-sm-push-4.col-lg-push-3
|
|
||||||
blockquote
|
|
||||||
h3 A winning combination of RPG gameplay and programming homework that pulls off making kid-friendly education legitimately enjoyable.
|
|
||||||
|
|
||||||
.col-lg-2.col-sm-3.col-lg-offset-1.text-center.col-sm-pull-8.col-lg-pull-7
|
|
||||||
img.img-circle(src="/images/pages/home/pcmag.png")
|
|
||||||
h6 PC Mag
|
|
||||||
.small pcmag.com
|
|
||||||
|
|
||||||
|
|
||||||
.request-demo-row.text-center
|
|
||||||
h3 Everything you need to run a computer science class in your school today, no CS background required.
|
|
||||||
p
|
|
||||||
a.btn.btn-primary.btn-lg(href="/teachers/freetrial") Request a Demo
|
|
||||||
a.btn.btn-primary-alt.btn-lg(href="/courses/teachers") Create a Class
|
|
||||||
|
|
||||||
|
|
||||||
.text-center
|
|
||||||
img(src="/images/pages/home/character_lineup.png")
|
|
||||||
|
|
||||||
|
|
||||||
.container-fluid
|
|
||||||
#footer.small
|
|
||||||
.container
|
.container
|
||||||
.row
|
.row
|
||||||
.col-sm-3
|
.col-lg-7.col-md-8
|
||||||
ul.list-unstyled
|
h1 The most engaging game for learning programming.
|
||||||
li
|
|
||||||
strong CodeCombat
|
.col-lg-3.col-lg-offset-2.col-md-4
|
||||||
li
|
.well.text-center.hidden-md.hidden-lg
|
||||||
a(href="/about") About
|
.row
|
||||||
li
|
.col-xs-8
|
||||||
a(href="/Careers") Jobs
|
h6 Classroom Edition:
|
||||||
li
|
.col-xs-4
|
||||||
a(href="http://blog.codecombat.com/", data-i18n="nav.blog")
|
h6 Learn to code:
|
||||||
li
|
.row
|
||||||
a(href="/legal") Legal
|
.col-xs-4
|
||||||
|
button#teacher-btn.btn.btn-primary.btn-lg.btn-block Teacher
|
||||||
|
.col-xs-4
|
||||||
|
a.btn.btn-forest.btn-lg.btn-block(href="/courses") Student
|
||||||
|
.col-xs-4
|
||||||
|
a.btn.btn-gold.btn-lg.btn-block(href=view.playURL) Play Now
|
||||||
|
|
||||||
|
.well.text-center.hidden-xs.hidden-sm
|
||||||
|
h6#classroom-edition-header Classroom Edition:
|
||||||
|
div
|
||||||
|
button#teacher-btn.btn.btn-primary.btn-lg.btn-block I'm a Teacher
|
||||||
|
div
|
||||||
|
a.btn.btn-forest.btn-lg.btn-block(href="/courses") I'm a Student
|
||||||
|
|
||||||
.col-sm-3
|
h6#learn-to-code-header Learn to code:
|
||||||
ul.list-unstyled
|
a.btn.btn-gold.btn-lg.btn-block(href=view.playURL) Play Now
|
||||||
li
|
.row#learn-more-row
|
||||||
strong Schools
|
.col-xs-12.text-center
|
||||||
li
|
a#learn-more-link
|
||||||
a(href="/courses/teachers") Teachers
|
h6 Learn more
|
||||||
li
|
h2
|
||||||
a(href="https://sites.google.com/a/codecombat.com/teacher-guides/") Educator Wiki
|
span.glyphicon.glyphicon-chevron-down
|
||||||
li
|
|
||||||
a(href="/teachers/quote") Request a Quote
|
|
||||||
|
.container#classroom-in-box-container
|
||||||
|
#classroom-in-box-row.row
|
||||||
|
.col-sm-6
|
||||||
|
h2.text-navy A classroom in-a-box for teaching computer science.
|
||||||
|
.col-sm-6
|
||||||
|
p CodeCombat is a platform for students to learn computer science while playing through a real game.
|
||||||
|
p Our courses have been specifically playtested to excel in a classroom setting, even by teachers with little to no prior programming experience.
|
||||||
|
|
||||||
|
#feature-spread-row.row.text-center
|
||||||
|
h3 Designed with teachers in mind
|
||||||
|
.col-sm-4
|
||||||
|
img.img-circle(src="/images/pages/home/F1_typedcode.png")
|
||||||
|
h4
|
||||||
|
| Real, typed code
|
||||||
|
br
|
||||||
|
| from the first level
|
||||||
|
p.small Getting students to typed code as quickly as possible is critical to learning programming syntax and proper structure.
|
||||||
|
|
||||||
|
.col-sm-4
|
||||||
|
img.img-circle(src="/images/pages/home/F2_teacherguides.png")
|
||||||
|
h4
|
||||||
|
| Educator resources
|
||||||
|
br
|
||||||
|
| and course guides
|
||||||
|
p.small Teaching computer science does not require a costly degree, because we provide tools to support educators of all backgrounds.
|
||||||
|
|
||||||
|
.col-sm-4
|
||||||
|
img.img-circle(src="/images/pages/home/F3_accessible.png")
|
||||||
|
h4
|
||||||
|
| Accessible to
|
||||||
|
br
|
||||||
|
| everyone
|
||||||
|
p.small Democratizing the process of learning coding is at the core of our philosophy. Everyone should be able to learn to code.
|
||||||
|
|
||||||
|
.testimonials-rows
|
||||||
|
.testimonials-filler-left
|
||||||
|
.testimonials-filler-right
|
||||||
|
.row
|
||||||
|
.col-lg-offset-2.col-lg-7.col-sm-8
|
||||||
|
blockquote
|
||||||
|
h3 I think they actually forgot that they were actually learning something.
|
||||||
|
|
||||||
|
.col-lg-2.col-sm-3.text-center
|
||||||
|
img.img-circle(src="/images/pages/home/timmaki.png")
|
||||||
|
h6 Tim Maki
|
||||||
|
.small Director of Technology, Tilton School
|
||||||
|
|
||||||
|
.row
|
||||||
|
.col-lg-7.col-sm-8.col-sm-push-4.col-lg-push-3
|
||||||
|
blockquote
|
||||||
|
h3 Coding is something I've always wanted to do, and I never thought I would be able to learn it in school.
|
||||||
|
|
||||||
.col-sm-3
|
.col-lg-2.col-sm-3.col-lg-offset-1.text-center.col-sm-pull-8.col-lg-pull-7
|
||||||
ul.list-unstyled
|
img.img-circle(src="/images/pages/home/dylan.png")
|
||||||
li
|
h6 Dylan
|
||||||
strong Get Involved
|
.small 3rd Grader
|
||||||
li
|
|
||||||
a(href='/community', data-i18n="nav.community")
|
|
||||||
li
|
h3.text-center Why is learning through games important?
|
||||||
a(href="/contribute") Contribute
|
|
||||||
li
|
#benefit-row-1.row
|
||||||
a(href=view.forumLink(), data-i18n="nav.forum")
|
#benefit-graphic-1.col-sm-6.col-sm-offset-1.col-sm-push-6
|
||||||
li
|
h2 Games reward the productive struggle.
|
||||||
a(href="/play/ladder") Multiplayer
|
img(src="/images/pages/home/G1_reward.png")
|
||||||
li
|
#benefit-graphic-1-filler
|
||||||
a(href="https://github.com/codecombat/codecombat") Open source (GitHub)
|
|
||||||
.col-sm-3
|
.col-sm-5.col-sm-pull-6
|
||||||
ul.list-unstyled
|
p
|
||||||
li
|
| Gaming is a medium that encourages interaction, discovery, and trial-and-error.
|
||||||
strong Support
|
| A good game challenges the player to master skills over time,
|
||||||
li
|
| which is the same critical process students go through as they learn.
|
||||||
a(href="https://discourse.codecombat.com/t/faq-check-before-posting/1027") FAQs
|
p
|
||||||
li
|
| Games excel at rewarding “
|
||||||
a(tabindex=-1, data-toggle="coco-modal", data-target="core/ContactModal", data-i18n="nav.contact")
|
a(href="http://blog.mindresearch.org/blog/game-based-learning-infographic-strong-math-practices" target="_blank") productive struggle
|
||||||
li
|
span.spr ” - the kind of struggle that results in learning that’s engaging and
|
||||||
a(href="https://www.facebook.com/codecombat", data-i18n="nav.facebook")
|
a(href="http://www.gamesandlearning.org/2014/06/09/teachers-on-using-games-in-class/" target="_blank") motivating
|
||||||
li
|
| , not tedious.
|
||||||
a(href="https://twitter.com/codecombat", data-i18n="nav.twitter")
|
|
||||||
|
|
||||||
#final-footer.small.text-center
|
|
||||||
| Copyright ©2016 CodeCombat. All Rights Reserved.
|
#benefit-row-2.row
|
||||||
br.hidden-lg.hidden-md
|
#benefit-graphic-2.col-sm-6
|
||||||
img(src="/images/pages/base/logo.png" alt="CodeCombat")
|
h2 Studies suggest gaming is good for children’s brains. (it’s true!)
|
||||||
br.hidden-lg.hidden-md
|
img(src="/images/pages/home/G2_brains.png")
|
||||||
span.spr Need help? Email
|
#benefit-graphic-2-filler
|
||||||
a(href="mailto:team@codecombat.com") team@codecombat.com
|
|
||||||
span.spl and we'll get in touch!
|
.col-sm-5.col-sm-offset-1
|
||||||
|
p
|
||||||
|
span.spr When game-based learning systems are
|
||||||
|
a(href="http://schoolsweek.co.uk/gaming-is-good-for-childrens-brains-study-suggests/" target="_blank") compared
|
||||||
|
span.spl.spr against conventional assessment methods, the difference is clear: games are better at helping students retain knowledge, concentrate and
|
||||||
|
a(href="http://dev.k-12techdecisions.com/article/game_based_learning_is_where_vygotsky_meets_dweck/P3" target="_blank") perform at a higher level of achievement
|
||||||
|
| .
|
||||||
|
p
|
||||||
|
| Games also provide real-time feedback that allows students to adjust their solution path and understand concepts more holistically, instead of being limited to just “correct” or “incorrect” answers.
|
||||||
|
|
||||||
|
#benefit-row-3.row
|
||||||
|
#benefit-graphic-3.col-sm-6.col-sm-offset-1.col-sm-push-6
|
||||||
|
h2 A real game, played with real coding.
|
||||||
|
img(src="/images/pages/home/G3_game.png")
|
||||||
|
#benefit-graphic-3-filler
|
||||||
|
|
||||||
|
.col-sm-5.col-sm-pull-6
|
||||||
|
p
|
||||||
|
| A great game is more than just badges and achievements - it’s about a player’s journey, well-designed puzzles, and the ability to tackle challenges with agency and confidence.
|
||||||
|
p
|
||||||
|
| CodeCombat is a game that gives players that agency and confidence with our robust typed code engine, which helps beginner and advanced students alike write proper, valid code.
|
||||||
|
|
||||||
|
|
||||||
|
.request-demo-row.text-center
|
||||||
|
h3 Curious? Request a demo and we'll show you the ropes
|
||||||
|
h4 Or create a class and see it for yourself!
|
||||||
|
div
|
||||||
|
a.btn.btn-primary.btn-lg(href="/teachers/freetrial") Request a Demo
|
||||||
|
a.btn.btn-primary-alt.btn-lg(href="/courses/teachers") Create a Class
|
||||||
|
div
|
||||||
|
if me.isAnonymous()
|
||||||
|
span.spr Already have an account?
|
||||||
|
a.login-button Login
|
||||||
|
else
|
||||||
|
span.spr You are currently logged in as #{me.broadName()}.
|
||||||
|
a(href="/courses/teachers") View my classes
|
||||||
|
span.spr.spl or
|
||||||
|
a#logout-button logout
|
||||||
|
|
||||||
|
h3.text-center Computer science courses for all ages
|
||||||
|
h4.text-center
|
||||||
|
span#school-level-label Show me lesson time estimates for:
|
||||||
|
select#school-level-dropdown.form-control.text-navy
|
||||||
|
option(value='elementary') Elementary School
|
||||||
|
option(value='middle', selected=true) Middle School
|
||||||
|
option(value='high') High School
|
||||||
|
h5.text-center#total-hours-header
|
||||||
|
span.spr Total curriculum hours:
|
||||||
|
span#semester-duration
|
||||||
|
#courses-row.row
|
||||||
|
- var conceptsSeen = {};
|
||||||
|
- var lastScreenshot = "";
|
||||||
|
for course, courseIndex in view.courses.models
|
||||||
|
.col-md-3.col-sm-4
|
||||||
|
.media.course-details(data-course-slug=course.get('slug'))
|
||||||
|
if courseIndex === 0
|
||||||
|
.free-course
|
||||||
|
h6 Free for all students
|
||||||
|
.media-body(title=course.get('description'))
|
||||||
|
h6.course-name= course.get('name') + ':'
|
||||||
|
p.small
|
||||||
|
- var total = 0;
|
||||||
|
each concept in course.get('concepts')
|
||||||
|
- if (conceptsSeen[concept]) continue;
|
||||||
|
- conceptsSeen[concept] = true;
|
||||||
|
if total === 3
|
||||||
|
- total += 1;
|
||||||
|
span ...
|
||||||
|
- continue;
|
||||||
|
else if total > 3
|
||||||
|
- continue;
|
||||||
|
else if total > 0
|
||||||
|
span.spr ,
|
||||||
|
- total += 1;
|
||||||
|
span(data-i18n="concepts." + concept)
|
||||||
|
img.media-object(src="/images/pages/home/course"+(courseIndex+1)+".png")
|
||||||
|
- lastScreenshot = course.get('screenshot');
|
||||||
|
h6.course-duration
|
||||||
|
span.spr Lesson time:
|
||||||
|
span.course-hours= course.get('duration') || 0
|
||||||
|
span.spl.unit(data-i18n="units.hours")
|
||||||
|
for upcomingCourse in ['Computer Science 6', 'Computer Science 7', 'Computer Science 8']
|
||||||
|
.col-md-3.col-sm-4
|
||||||
|
.media.disabled
|
||||||
|
.media-body
|
||||||
|
h6.course-name= upcomingCourse + ':'
|
||||||
|
p.small Coming soon!
|
||||||
|
img.media-object(src="/images/pages/home/inprogress.png")
|
||||||
|
|
||||||
|
.clearfix
|
||||||
|
.text-center
|
||||||
|
h4
|
||||||
|
img(src="/images/pages/home/course_languages.png")
|
||||||
|
div Courses are available in JavaScript, Python, and Java (coming soon!)
|
||||||
|
|
||||||
|
.testimonials-rows
|
||||||
|
.testimonials-filler-left
|
||||||
|
.testimonials-filler-right
|
||||||
|
.row
|
||||||
|
.col-lg-offset-2.col-lg-7.col-sm-8
|
||||||
|
blockquote
|
||||||
|
h3 Boasts riddles that are complex enough to fascinate gamers and coders alike.
|
||||||
|
|
||||||
|
.col-lg-2.col-sm-3.text-center
|
||||||
|
img.img-circle(src="/images/pages/home/opensource.png")
|
||||||
|
h6 Open Source
|
||||||
|
.small opensource.com
|
||||||
|
|
||||||
|
.row
|
||||||
|
.col-lg-7.col-sm-8.col-sm-push-4.col-lg-push-3
|
||||||
|
blockquote
|
||||||
|
h3 A winning combination of RPG gameplay and programming homework that pulls off making kid-friendly education legitimately enjoyable.
|
||||||
|
|
||||||
|
.col-lg-2.col-sm-3.col-lg-offset-1.text-center.col-sm-pull-8.col-lg-pull-7
|
||||||
|
img.img-circle(src="/images/pages/home/pcmag.png")
|
||||||
|
h6 PC Mag
|
||||||
|
.small pcmag.com
|
||||||
|
|
||||||
|
|
||||||
|
.request-demo-row.text-center
|
||||||
|
h3 Everything you need to run a computer science class in your school today, no CS background required.
|
||||||
|
p
|
||||||
|
a.btn.btn-primary.btn-lg(href="/teachers/freetrial") Request a Demo
|
||||||
|
a.btn.btn-primary-alt.btn-lg(href="/courses/teachers") Create a Class
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,155 +1,152 @@
|
||||||
extends /templates/base
|
extends /templates/base-flat
|
||||||
|
|
||||||
block content
|
block content
|
||||||
form.form(class=view.trialRequest.isNew() ? '' : 'hide')
|
.container
|
||||||
h1.text-center(data-i18n="teachers_quote.title")
|
form.form(class=view.trialRequest.isNew() ? '' : 'hide')
|
||||||
p.text-center(data-i18n="teachers_quote.subtitle")
|
h1.text-center(data-i18n="teachers_quote.title")
|
||||||
|
h2.text-center(data-i18n="teachers_quote.subtitle")
|
||||||
|
|
||||||
.row
|
#form-teacher-info.section
|
||||||
.col-sm-offset-2.col-sm-4
|
.row
|
||||||
.form-group
|
.col-sm-offset-2.col-sm-4
|
||||||
label.control-label(data-i18n="general.name")
|
.form-group
|
||||||
- var name = me.get('name') || '';
|
label.control-label(data-i18n="general.name")
|
||||||
input.form-control(name="name" value=name, disabled=!!name)
|
- var name = me.get('name') || '';
|
||||||
|
input.form-control(name="name" value=name, disabled=!!name)
|
||||||
.col-sm-4
|
|
||||||
#email-form-group.form-group
|
|
||||||
label.control-label(data-i18n="general.email")
|
|
||||||
- var email = me.get('email') || '';
|
|
||||||
input.form-control(name="email" type="email", value=email, disabled=!!email)
|
|
||||||
|
|
||||||
|
|
||||||
.row
|
|
||||||
.col-sm-offset-2.col-sm-4
|
|
||||||
.form-group
|
|
||||||
label.control-label
|
|
||||||
span(data-i18n="teachers_quote.phone_number")
|
|
||||||
span.spl.text-muted(data-i18n="signup.optional")
|
|
||||||
.help-block
|
|
||||||
em.text-info(data-i18n="teachers_quote.phone_number_help")
|
|
||||||
input.form-control(name="phoneNumber")
|
|
||||||
|
|
||||||
.col-sm-4
|
|
||||||
.form-group
|
|
||||||
label.control-label(data-i18n="teachers_quote.role_label")
|
|
||||||
.help-block
|
|
||||||
em.text-info(data-i18n="teachers_quote.role_help")
|
|
||||||
select.form-control(name="role")
|
|
||||||
option
|
|
||||||
option(data-i18n="courses.teacher", value="Teacher")
|
|
||||||
option(data-i18n="teachers_quote.tech_coordinator", value="Technology coordinator")
|
|
||||||
option(data-i18n="teachers_quote.advisor", value="Advisor")
|
|
||||||
option(data-i18n="teachers_quote.principal", value="Principal")
|
|
||||||
option(data-i18n="teachers_quote.superintendent", value="Superintendent")
|
|
||||||
option(data-i18n="teachers_quote.parent", value="Parent")
|
|
||||||
|
|
||||||
.row
|
|
||||||
.col-sm-offset-2.col-sm-8
|
|
||||||
hr
|
|
||||||
|
|
||||||
.row
|
|
||||||
.col-sm-offset-2.col-sm-4
|
|
||||||
.form-group
|
|
||||||
label.control-label(data-i18n="teachers_quote.organization_label")
|
|
||||||
input.form-control(name="organization")
|
|
||||||
|
|
||||||
.col-sm-4
|
|
||||||
.form-group
|
|
||||||
label.control-label(data-i18n="teachers_quote.city")
|
|
||||||
input.form-control(name="city")
|
|
||||||
|
|
||||||
.row
|
|
||||||
.col-sm-offset-2.col-sm-4
|
|
||||||
.form-group
|
|
||||||
label.control-label(data-i18n="teachers_quote.state")
|
|
||||||
input.form-control(name="state")
|
|
||||||
|
|
||||||
.col-sm-4
|
|
||||||
.form-group
|
|
||||||
label.control-labellabel.control-label(data-i18n="teachers_quote.country")
|
|
||||||
input.form-control(name="country")
|
|
||||||
|
|
||||||
.row
|
|
||||||
.col-sm-offset-2.col-sm-8
|
|
||||||
hr
|
|
||||||
|
|
||||||
.row
|
|
||||||
.col-sm-offset-2.col-sm-5
|
|
||||||
.form-group
|
|
||||||
label.control-label(data-i18n="courses.number_students")
|
|
||||||
.help-block
|
|
||||||
em.text-info(data-i18n="teachers_quote.num_students_help")
|
|
||||||
select.form-control(name="numStudents")
|
|
||||||
option
|
|
||||||
option 1-10
|
|
||||||
option 11-50
|
|
||||||
option 51-100
|
|
||||||
option 101-200
|
|
||||||
option 201-500
|
|
||||||
option 501-1000
|
|
||||||
option 1000+
|
|
||||||
|
|
||||||
.form-group
|
|
||||||
|
|
||||||
.row
|
|
||||||
.col-sm-offset-2.col-sm-4
|
|
||||||
label.control-label(data-i18n="teachers_quote.education_level_label")
|
|
||||||
.help-block
|
|
||||||
em.text-info(data-i18n="teachers_quote.education_level_help")
|
|
||||||
|
|
||||||
.row
|
.col-sm-4
|
||||||
.col-sm-offset-2.col-sm-2
|
#email-form-group.form-group
|
||||||
label.control-label.checkbox
|
label.control-label(data-i18n="general.email")
|
||||||
input(type="checkbox" name="educationLevel" value="Elementary")
|
- var email = me.get('email') || '';
|
||||||
span(data-i18n="teachers_quote.elementary_school")
|
input.form-control(name="email" type="email", value=email, disabled=!!email)
|
||||||
.col-sm-2
|
|
||||||
label.control-label.checkbox
|
|
||||||
input(type="checkbox" name="educationLevel" value="High")
|
|
||||||
span(data-i18n="teachers_quote.high_school")
|
|
||||||
.col-sm-6
|
|
||||||
// Other field uses custom logic, so no name field is included in either input.
|
|
||||||
// That way the forms library ignores it.
|
|
||||||
.checkbox-inline
|
|
||||||
label.control-label
|
|
||||||
input#other-education-level-checkbox(type="checkbox")
|
|
||||||
span(data-i18n="nav.other")
|
|
||||||
br
|
|
||||||
span(data-i18n="teachers_quote.please_explain")
|
|
||||||
input#other-education-level-input.form-control
|
|
||||||
|
|
||||||
.row
|
.row
|
||||||
.col-sm-offset-2.col-sm-2
|
.col-sm-offset-2.col-sm-4
|
||||||
label.control-label.checkbox
|
.form-group
|
||||||
input(type="checkbox" name="educationLevel" value="Middle")
|
label.control-label
|
||||||
span(data-i18n="teachers_quote.middle_school")
|
span(data-i18n="teachers_quote.phone_number")
|
||||||
.col-sm-2
|
span.spl.text-muted(data-i18n="signup.optional")
|
||||||
label.control-label.checkbox
|
.help-block.small
|
||||||
input(type="checkbox" name="educationLevel" value="College+")
|
em.text-info(data-i18n="teachers_quote.phone_number_help")
|
||||||
span(data-i18n="teachers_quote.college_plus")
|
input.form-control(name="phoneNumber")
|
||||||
|
|
||||||
#anything-else-row.row
|
.col-sm-4
|
||||||
.col-sm-offset-2.col-sm-8
|
.form-group
|
||||||
label.control-label
|
label.control-label(data-i18n="teachers_quote.role_label")
|
||||||
span(data-i18n="teachers_quote.anything_else")
|
.help-block.small
|
||||||
span.spl.text-muted(data-i18n="signup.optional")
|
em.text-info(data-i18n="teachers_quote.role_help")
|
||||||
|
select.form-control(name="role")
|
||||||
textarea.form-control(rows=8, name="notes")
|
option
|
||||||
|
option(data-i18n="courses.teacher", value="Teacher")
|
||||||
#buttons-row.row.text-center
|
option(data-i18n="teachers_quote.tech_coordinator", value="Technology coordinator")
|
||||||
input#submit-request-btn.btn.btn-primary(type="submit" data-i18n="[value]common.send")
|
option(data-i18n="teachers_quote.advisor", value="Advisor")
|
||||||
|
option(data-i18n="teachers_quote.principal", value="Principal")
|
||||||
|
option(data-i18n="teachers_quote.superintendent", value="Superintendent")
|
||||||
|
option(data-i18n="teachers_quote.parent", value="Parent")
|
||||||
|
|
||||||
|
#form-school-info.section
|
||||||
#form-submit-success.text-center(class=view.trialRequest.isNew() ? 'hide' : '')
|
.row
|
||||||
h1.text-center(data-i18n="teachers_quote.thanks_header")
|
.col-sm-offset-2.col-sm-4
|
||||||
p.text-center
|
.form-group
|
||||||
span.spr(data-i18n="teachers_quote.thanks_p")
|
label.control-label(data-i18n="teachers_quote.organization_label")
|
||||||
a.spl(href="mailto:team@codecombat.com") team@codecombat.com
|
input.form-control(name="organization")
|
||||||
|
|
||||||
|
.col-sm-4
|
||||||
|
.form-group
|
||||||
|
label.control-label(data-i18n="teachers_quote.city")
|
||||||
|
input.form-control(name="city")
|
||||||
|
|
||||||
|
.row
|
||||||
|
.col-sm-offset-2.col-sm-4
|
||||||
|
.form-group
|
||||||
|
label.control-label(data-i18n="teachers_quote.state")
|
||||||
|
input.form-control(name="state")
|
||||||
|
|
||||||
|
.col-sm-4
|
||||||
|
.form-group
|
||||||
|
label.control-labellabel.control-label(data-i18n="teachers_quote.country")
|
||||||
|
input.form-control(name="country")
|
||||||
|
|
||||||
|
#form-students-info.section
|
||||||
|
.row
|
||||||
|
.col-sm-offset-2.col-sm-5
|
||||||
|
.form-group
|
||||||
|
label.control-label(data-i18n="courses.number_students")
|
||||||
|
.help-block.small
|
||||||
|
em.text-info(data-i18n="teachers_quote.num_students_help")
|
||||||
|
select.form-control(name="numStudents")
|
||||||
|
option
|
||||||
|
option 1-10
|
||||||
|
option 11-50
|
||||||
|
option 51-100
|
||||||
|
option 101-200
|
||||||
|
option 201-500
|
||||||
|
option 501-1000
|
||||||
|
option 1000+
|
||||||
|
|
||||||
|
.form-group
|
||||||
|
|
||||||
if me.isAnonymous()
|
.row
|
||||||
p.text-center(data-i18n="teachers_quote.thanks_anon")
|
.col-sm-offset-2.col-sm-4
|
||||||
|
label.control-label(data-i18n="teachers_quote.education_level_label")
|
||||||
|
.help-block.small
|
||||||
|
em.text-info(data-i18n="teachers_quote.education_level_help")
|
||||||
|
|
||||||
|
.row
|
||||||
|
.col-sm-offset-2.col-sm-2
|
||||||
|
label.control-label.checkbox
|
||||||
|
input(type="checkbox" name="educationLevel" value="Elementary")
|
||||||
|
span(data-i18n="teachers_quote.elementary_school")
|
||||||
|
.col-sm-2
|
||||||
|
label.control-label.checkbox
|
||||||
|
input(type="checkbox" name="educationLevel" value="High")
|
||||||
|
span(data-i18n="teachers_quote.high_school")
|
||||||
|
.col-sm-2
|
||||||
|
label.control-label.checkbox
|
||||||
|
input(type="checkbox" name="educationLevel" value="Middle")
|
||||||
|
span(data-i18n="teachers_quote.middle_school")
|
||||||
|
.col-sm-2
|
||||||
|
label.control-label.checkbox
|
||||||
|
input(type="checkbox" name="educationLevel" value="College+")
|
||||||
|
span(data-i18n="teachers_quote.college_plus")
|
||||||
|
|
||||||
|
.row
|
||||||
|
.col-sm-offset-2.col-sm-6
|
||||||
|
// Other field uses custom logic, so no name field is included in either input.
|
||||||
|
// That way the forms library ignores it.
|
||||||
|
.form-group
|
||||||
|
label.control-label.checkbox
|
||||||
|
input#other-education-level-checkbox(type="checkbox")
|
||||||
|
span(data-i18n="nav.other")
|
||||||
|
|
|
||||||
|
span(data-i18n="teachers_quote.please_explain")
|
||||||
|
input#other-education-level-input.form-control
|
||||||
|
|
||||||
|
#anything-else-row.section
|
||||||
|
.row
|
||||||
|
.col-sm-offset-2.col-sm-8
|
||||||
|
label.control-label
|
||||||
|
span(data-i18n="teachers_quote.anything_else")
|
||||||
|
span.spl.text-muted(data-i18n="signup.optional")
|
||||||
|
|
||||||
|
textarea.form-control(rows=8, name="notes")
|
||||||
|
|
||||||
|
#buttons-row.row.text-center
|
||||||
|
input#submit-request-btn.btn.btn-lg.btn-primary(type="submit" data-i18n="[value]common.send")
|
||||||
|
|
||||||
|
|
||||||
|
#form-submit-success.text-center(class=view.trialRequest.isNew() ? 'hide' : '')
|
||||||
|
h1.text-center(data-i18n="teachers_quote.thanks_header")
|
||||||
p.text-center
|
p.text-center
|
||||||
button#login-btn.btn.btn-info(data-i18n="login.log_in")
|
span.spr(data-i18n="teachers_quote.thanks_p")
|
||||||
button#signup-btn.btn.btn-info(data-i18n="login.sign_up")
|
a.spl(href="mailto:team@codecombat.com") team@codecombat.com
|
||||||
else
|
|
||||||
p.text-center(data-i18n="teachers_quote.thanks_logged_in")
|
if me.isAnonymous()
|
||||||
|
p.text-center(data-i18n="teachers_quote.thanks_anon")
|
||||||
|
|
||||||
|
p.text-center
|
||||||
|
button#login-btn.btn.btn-info(data-i18n="login.log_in")
|
||||||
|
button#signup-btn.btn.btn-info(data-i18n="login.sign_up")
|
||||||
|
else
|
||||||
|
p.text-center(data-i18n="teachers_quote.thanks_logged_in")
|
|
@ -5,4 +5,86 @@ module.exports = class AboutView extends RootView
|
||||||
id: 'about-view'
|
id: 'about-view'
|
||||||
template: template
|
template: template
|
||||||
|
|
||||||
logoutRedirectURL: false
|
logoutRedirectURL: false
|
||||||
|
|
||||||
|
events:
|
||||||
|
'click #mission-link': 'onClickMissionLink'
|
||||||
|
'click #team-link': 'onClickTeamLink'
|
||||||
|
'click #community-link': 'onClickCommunityLink'
|
||||||
|
'click #story-link': 'onClickStoryLink'
|
||||||
|
'click #jobs-link': 'onClickJobsLink'
|
||||||
|
'click #contact-link': 'onClickContactLink'
|
||||||
|
'click .screen-thumbnail': 'onClickScreenThumbnail'
|
||||||
|
'click #carousel-left': 'onLeftPressed'
|
||||||
|
'click #carousel-right': 'onRightPressed'
|
||||||
|
|
||||||
|
shortcuts:
|
||||||
|
'right': 'onRightPressed'
|
||||||
|
'left': 'onLeftPressed'
|
||||||
|
'esc': 'onEscapePressed'
|
||||||
|
|
||||||
|
afterRender: ->
|
||||||
|
super(arguments...)
|
||||||
|
@$('#fixed-nav').affix({
|
||||||
|
offset:
|
||||||
|
top: ->
|
||||||
|
$('#nav-container').offset().top
|
||||||
|
})
|
||||||
|
#TODO: Maybe cache top value between page resizes to save CPU
|
||||||
|
$('body').scrollspy(
|
||||||
|
target: '#nav-container'
|
||||||
|
offset: 150
|
||||||
|
)
|
||||||
|
@$('#screenshot-lightbox').modal()
|
||||||
|
|
||||||
|
@$('#screenshot-carousel').carousel({
|
||||||
|
interval: 0
|
||||||
|
keyboard: false
|
||||||
|
})
|
||||||
|
|
||||||
|
onClickMissionLink: (event) ->
|
||||||
|
event.preventDefault()
|
||||||
|
@scrollToLink('#mission')
|
||||||
|
|
||||||
|
onClickTeamLink: (event) ->
|
||||||
|
event.preventDefault()
|
||||||
|
@scrollToLink('#team')
|
||||||
|
|
||||||
|
onClickCommunityLink: (event) ->
|
||||||
|
event.preventDefault()
|
||||||
|
@scrollToLink('#community')
|
||||||
|
|
||||||
|
onClickStoryLink: (event) ->
|
||||||
|
event.preventDefault()
|
||||||
|
@scrollToLink('#story')
|
||||||
|
|
||||||
|
onClickJobsLink: (event) ->
|
||||||
|
event.preventDefault()
|
||||||
|
@scrollToLink('#jobs')
|
||||||
|
|
||||||
|
onClickContactLink: (event) ->
|
||||||
|
event.preventDefault()
|
||||||
|
@scrollToLink('#contact')
|
||||||
|
|
||||||
|
onRightPressed: (event) ->
|
||||||
|
if $('#screenshot-lightbox').data('bs.modal')?.isShown
|
||||||
|
event.preventDefault()
|
||||||
|
$('#screenshot-carousel').carousel('next')
|
||||||
|
|
||||||
|
onLeftPressed: (event) ->
|
||||||
|
if $('#screenshot-lightbox').data('bs.modal')?.isShown
|
||||||
|
event.preventDefault()
|
||||||
|
$('#screenshot-carousel').carousel('prev')
|
||||||
|
|
||||||
|
onEscapePressed: (event) ->
|
||||||
|
if $('#screenshot-lightbox').data('bs.modal')?.isShown
|
||||||
|
event.preventDefault()
|
||||||
|
$('#screenshot-lightbox').modal('hide')
|
||||||
|
|
||||||
|
onClickScreenThumbnail: (event) ->
|
||||||
|
unless $('#screenshot-lightbox').data('bs.modal')?.isShown
|
||||||
|
event.preventDefault()
|
||||||
|
# Modal opening happens automatically from bootstrap
|
||||||
|
$('#screenshot-carousel').carousel($(event.currentTarget).data("index"))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -41,16 +41,6 @@ module.exports = class HomeView extends RootView
|
||||||
afterInsert: ->
|
afterInsert: ->
|
||||||
super(arguments...)
|
super(arguments...)
|
||||||
|
|
||||||
isOldBrowser: ->
|
|
||||||
if $.browser
|
|
||||||
majorVersion = $.browser.versionNumber
|
|
||||||
return true if $.browser.mozilla && majorVersion < 25
|
|
||||||
return true if $.browser.chrome && majorVersion < 31 # Noticed Gems in the Deep not loading with 30
|
|
||||||
return true if $.browser.safari && majorVersion < 6 # 6 might have problems with Aether, or maybe just old minors of 6: https://errorception.com/projects/51a79585ee207206390002a2/errors/547a202e1ead63ba4e4ac9fd
|
|
||||||
else
|
|
||||||
console.warn 'no more jquery browser version...'
|
|
||||||
return false
|
|
||||||
|
|
||||||
justPlaysCourses: ->
|
justPlaysCourses: ->
|
||||||
# This heuristic could be better, but currently we don't add to me.get('courseInstances') for single-player anonymous intro courses, so they have to beat a level without choosing a hero.
|
# This heuristic could be better, but currently we don't add to me.get('courseInstances') for single-player anonymous intro courses, so they have to beat a level without choosing a hero.
|
||||||
return me.get('stats')?.gamesCompleted and not me.get('heroConfig')
|
return me.get('stats')?.gamesCompleted and not me.get('heroConfig')
|
||||||
|
|
|
@ -75,14 +75,5 @@ module.exports = class NewHomeView extends RootView
|
||||||
onClickTeacherButton: ->
|
onClickTeacherButton: ->
|
||||||
@scrollToLink('.request-demo-row', 600)
|
@scrollToLink('.request-demo-row', 600)
|
||||||
|
|
||||||
isOldBrowser: ->
|
|
||||||
if $.browser
|
|
||||||
majorVersion = $.browser.versionNumber
|
|
||||||
return true if $.browser.mozilla && majorVersion < 25
|
|
||||||
return true if $.browser.chrome && majorVersion < 31 # Noticed Gems in the Deep not loading with 30
|
|
||||||
return true if $.browser.safari && majorVersion < 6 # 6 might have problems with Aether, or maybe just old minors of 6: https://errorception.com/projects/51a79585ee207206390002a2/errors/547a202e1ead63ba4e4ac9fd
|
|
||||||
else
|
|
||||||
console.warn 'no more jquery browser version...'
|
|
||||||
return false
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -105,6 +105,7 @@ module.exports = class RequestQuoteView extends RootView
|
||||||
.addClass('has-error')
|
.addClass('has-error')
|
||||||
.append($("<div class='help-block error-help-block'>#{userExists} <a id='email-exists-login-link'>#{logIn}</a>"))
|
.append($("<div class='help-block error-help-block'>#{userExists} <a id='email-exists-login-link'>#{logIn}</a>"))
|
||||||
@$('#submit-request-btn').text('Submit').attr('disabled', false)
|
@$('#submit-request-btn').text('Submit').attr('disabled', false)
|
||||||
|
forms.scrollToFirstError()
|
||||||
|
|
||||||
onClickEmailExistsLoginLink: ->
|
onClickEmailExistsLoginLink: ->
|
||||||
modal = new AuthModal({
|
modal = new AuthModal({
|
||||||
|
|
|
@ -14,7 +14,7 @@ module.exports = class AdministerUserModal extends ModalView
|
||||||
|
|
||||||
constructor: (options, @userHandle) ->
|
constructor: (options, @userHandle) ->
|
||||||
super(options)
|
super(options)
|
||||||
@user = @supermodel.loadModel(new User({_id:@userHandle}), 'user', {cache: false}).model
|
@user = @supermodel.loadModel(new User({_id:@userHandle}), {cache: false}).model
|
||||||
options = {cache: false, url: '/stripe/coupons'}
|
options = {cache: false, url: '/stripe/coupons'}
|
||||||
options.success = (@coupons) =>
|
options.success = (@coupons) =>
|
||||||
@couponsResource = @supermodel.addRequestResource('coupon', options)
|
@couponsResource = @supermodel.addRequestResource('coupon', options)
|
||||||
|
|
|
@ -30,7 +30,7 @@ module.exports = class TrialRequestsView extends RootView
|
||||||
-1
|
-1
|
||||||
else
|
else
|
||||||
1
|
1
|
||||||
@trialRequests = new CocoCollection([], { url: '/db/trial.request?conditions[sort]=-created&conditions[limit]=500', model: TrialRequest, comparator: sortRequests })
|
@trialRequests = new CocoCollection([], { url: '/db/trial.request?conditions[sort]=-created&conditions[limit]=1000', model: TrialRequest, comparator: sortRequests })
|
||||||
@supermodel.loadCollection(@trialRequests, 'trial-requests', {cache: false})
|
@supermodel.loadCollection(@trialRequests, 'trial-requests', {cache: false})
|
||||||
|
|
||||||
getRenderData: ->
|
getRenderData: ->
|
||||||
|
|
|
@ -60,8 +60,8 @@ module.exports = class ClanDetailsView extends RootView
|
||||||
@listenTo @memberAchievements, 'sync', @onMemberAchievementsSync
|
@listenTo @memberAchievements, 'sync', @onMemberAchievementsSync
|
||||||
@listenTo @memberSessions, 'sync', @onMemberSessionsSync
|
@listenTo @memberSessions, 'sync', @onMemberSessionsSync
|
||||||
|
|
||||||
@supermodel.loadModel @campaigns, 'campaigns', cache: false
|
@supermodel.loadModel @campaigns, cache: false
|
||||||
@supermodel.loadModel @clan, 'clan', cache: false
|
@supermodel.loadModel @clan, cache: false
|
||||||
@supermodel.loadCollection(@members, 'members', {cache: false})
|
@supermodel.loadCollection(@members, 'members', {cache: false})
|
||||||
@supermodel.loadCollection(@memberAchievements, 'member_achievements', {cache: false})
|
@supermodel.loadCollection(@memberAchievements, 'member_achievements', {cache: false})
|
||||||
|
|
||||||
|
@ -204,7 +204,7 @@ module.exports = class ClanDetailsView extends RootView
|
||||||
unless @owner?
|
unless @owner?
|
||||||
@owner = new User _id: @clan.get('ownerID')
|
@owner = new User _id: @clan.get('ownerID')
|
||||||
@listenTo @owner, 'sync', => @render?()
|
@listenTo @owner, 'sync', => @render?()
|
||||||
@supermodel.loadModel @owner, 'owner', cache: false
|
@supermodel.loadModel @owner, cache: false
|
||||||
if @clan.get("dashboardType") is "premium"
|
if @clan.get("dashboardType") is "premium"
|
||||||
@supermodel.loadCollection(@memberSessions, 'member_sessions', {cache: false})
|
@supermodel.loadCollection(@memberSessions, 'member_sessions', {cache: false})
|
||||||
@render?()
|
@render?()
|
||||||
|
|
|
@ -13,7 +13,7 @@ module.exports = class LevelSessionCodeView extends CocoView
|
||||||
@session = options.session
|
@session = options.session
|
||||||
@level = LevelSession.getReferencedModel(@session.get('level'), LevelSession.schema.properties.level)
|
@level = LevelSession.getReferencedModel(@session.get('level'), LevelSession.schema.properties.level)
|
||||||
@level.setProjection ['employerDescription', 'name', 'icon', 'banner', 'slug']
|
@level.setProjection ['employerDescription', 'name', 'icon', 'banner', 'slug']
|
||||||
@supermodel.loadModel @level, 'level'
|
@supermodel.loadModel @level
|
||||||
|
|
||||||
getRenderData: ->
|
getRenderData: ->
|
||||||
c = super()
|
c = super()
|
||||||
|
|
|
@ -17,7 +17,7 @@ module.exports = class UserView extends RootView
|
||||||
@user = me
|
@user = me
|
||||||
@onLoaded()
|
@onLoaded()
|
||||||
@user = new User _id: @userID
|
@user = new User _id: @userID
|
||||||
@supermodel.loadModel @user, 'user', cache: false
|
@supermodel.loadModel @user, cache: false
|
||||||
|
|
||||||
getRenderData: ->
|
getRenderData: ->
|
||||||
context = super()
|
context = super()
|
||||||
|
|
|
@ -171,5 +171,15 @@ module.exports = class RootView extends CocoView
|
||||||
console.warn 'Error saving language:', errors
|
console.warn 'Error saving language:', errors
|
||||||
res.success (model, response, options) ->
|
res.success (model, response, options) ->
|
||||||
#console.log 'Saved language:', newLang
|
#console.log 'Saved language:', newLang
|
||||||
|
|
||||||
|
isOldBrowser: ->
|
||||||
|
if $.browser
|
||||||
|
majorVersion = $.browser.versionNumber
|
||||||
|
return true if $.browser.mozilla && majorVersion < 25
|
||||||
|
return true if $.browser.chrome && majorVersion < 31 # Noticed Gems in the Deep not loading with 30
|
||||||
|
return true if $.browser.safari && majorVersion < 6 # 6 might have problems with Aether, or maybe just old minors of 6: https://errorception.com/projects/51a79585ee207206390002a2/errors/547a202e1ead63ba4e4ac9fd
|
||||||
|
else
|
||||||
|
console.warn 'no more jquery browser version...'
|
||||||
|
return false
|
||||||
|
|
||||||
logoutRedirectURL: '/'
|
logoutRedirectURL: '/'
|
||||||
|
|
|
@ -31,7 +31,7 @@ module.exports = class CourseDetailsView extends RootView
|
||||||
if @course.loaded
|
if @course.loaded
|
||||||
@onCourseSync()
|
@onCourseSync()
|
||||||
else
|
else
|
||||||
@supermodel.loadModel @course, 'course'
|
@supermodel.loadModel @course
|
||||||
|
|
||||||
getRenderData: ->
|
getRenderData: ->
|
||||||
context = super()
|
context = super()
|
||||||
|
@ -67,7 +67,7 @@ module.exports = class CourseDetailsView extends RootView
|
||||||
if @campaign.loaded
|
if @campaign.loaded
|
||||||
@onCampaignSync()
|
@onCampaignSync()
|
||||||
else
|
else
|
||||||
@supermodel.loadModel @campaign, 'campaign'
|
@supermodel.loadModel @campaign
|
||||||
@render()
|
@render()
|
||||||
|
|
||||||
onCampaignSync: ->
|
onCampaignSync: ->
|
||||||
|
@ -106,7 +106,7 @@ module.exports = class CourseDetailsView extends RootView
|
||||||
if @courseInstance.loaded
|
if @courseInstance.loaded
|
||||||
@onCourseInstanceSync()
|
@onCourseInstanceSync()
|
||||||
else
|
else
|
||||||
@courseInstance = @supermodel.loadModel(@courseInstance, 'course_instance').model
|
@courseInstance = @supermodel.loadModel(@courseInstance).model
|
||||||
|
|
||||||
onCourseInstancesSync: ->
|
onCourseInstancesSync: ->
|
||||||
return if @destroyed
|
return if @destroyed
|
||||||
|
@ -128,14 +128,14 @@ module.exports = class CourseDetailsView extends RootView
|
||||||
# console.log 'onCourseInstanceSync'
|
# console.log 'onCourseInstanceSync'
|
||||||
if @courseInstance.get('classroomID')
|
if @courseInstance.get('classroomID')
|
||||||
@classroom = new Classroom({_id: @courseInstance.get('classroomID')})
|
@classroom = new Classroom({_id: @courseInstance.get('classroomID')})
|
||||||
@supermodel.loadModel @classroom, 'classroom'
|
@supermodel.loadModel @classroom
|
||||||
@singlePlayerMode = @courseInstance.get('name') is 'Single Player'
|
@singlePlayerMode = @courseInstance.get('name') is 'Single Player'
|
||||||
@teacherMode = @courseInstance.get('ownerID') is me.id and not @singlePlayerMode
|
@teacherMode = @courseInstance.get('ownerID') is me.id and not @singlePlayerMode
|
||||||
@levelSessions = new CocoCollection([], { url: "/db/course_instance/#{@courseInstance.id}/level_sessions", model: LevelSession, comparator: '_id' })
|
@levelSessions = new CocoCollection([], { url: "/db/course_instance/#{@courseInstance.id}/level_sessions", model: LevelSession, comparator: '_id' })
|
||||||
@listenToOnce @levelSessions, 'sync', @onLevelSessionsSync
|
@listenToOnce @levelSessions, 'sync', @onLevelSessionsSync
|
||||||
@supermodel.loadCollection @levelSessions, 'level_sessions', cache: false
|
@supermodel.loadCollection @levelSessions, 'level_sessions', cache: false
|
||||||
@owner = new User({_id: @courseInstance.get('ownerID')})
|
@owner = new User({_id: @courseInstance.get('ownerID')})
|
||||||
@supermodel.loadModel @owner, 'user'
|
@supermodel.loadModel @owner
|
||||||
@render()
|
@render()
|
||||||
|
|
||||||
onLevelSessionsSync: ->
|
onLevelSessionsSync: ->
|
||||||
|
@ -192,7 +192,7 @@ module.exports = class CourseDetailsView extends RootView
|
||||||
if @nextCourseInstance
|
if @nextCourseInstance
|
||||||
nextCourseID = @nextCourseInstance.get('courseID')
|
nextCourseID = @nextCourseInstance.get('courseID')
|
||||||
@nextCourse = @supermodel.getModel(Course, nextCourseID) or new Course _id: nextCourseID
|
@nextCourse = @supermodel.getModel(Course, nextCourseID) or new Course _id: nextCourseID
|
||||||
@nextCourse = @supermodel.loadModel(@nextCourse, 'course').model
|
@nextCourse = @supermodel.loadModel(@nextCourse).model
|
||||||
else if @allCourses?.loaded
|
else if @allCourses?.loaded
|
||||||
@nextCourse = _.find @allCourses.models, (course) => course.id > @course.id
|
@nextCourse = _.find @allCourses.models, (course) => course.id > @course.id
|
||||||
else
|
else
|
||||||
|
|
|
@ -46,7 +46,7 @@ module.exports = class HourOfCodeView extends RootView
|
||||||
if @lastSession
|
if @lastSession
|
||||||
@lastLevel = new Level()
|
@lastLevel = new Level()
|
||||||
levelData = @lastSession.get('level')
|
levelData = @lastSession.get('level')
|
||||||
@supermodel.loadModel(@lastLevel, 'level', {
|
@supermodel.loadModel(@lastLevel, {
|
||||||
url: "/db/level/#{levelData.original}/version/#{levelData.majorVersion}"
|
url: "/db/level/#{levelData.original}/version/#{levelData.majorVersion}"
|
||||||
data: {
|
data: {
|
||||||
project: 'name,slug'
|
project: 'name,slug'
|
||||||
|
|
|
@ -36,7 +36,7 @@ module.exports = class DeltaView extends CocoView
|
||||||
@[modelName] = options[modelName]
|
@[modelName] = options[modelName]
|
||||||
continue unless @[modelName] and options.loadModels
|
continue unless @[modelName] and options.loadModels
|
||||||
if not @[modelName].isLoaded
|
if not @[modelName].isLoaded
|
||||||
@[modelName] = @supermodel.loadModel(@[modelName], 'document').model
|
@[modelName] = @supermodel.loadModel(@[modelName]).model
|
||||||
|
|
||||||
@buildDeltas() if @supermodel.finished()
|
@buildDeltas() if @supermodel.finished()
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ module.exports = class PatchModal extends ModalView
|
||||||
@originalSource = @targetModel.clone(false)
|
@originalSource = @targetModel.clone(false)
|
||||||
else
|
else
|
||||||
@originalSource = new @targetModel.constructor({_id:targetID})
|
@originalSource = new @targetModel.constructor({_id:targetID})
|
||||||
@supermodel.loadModel @originalSource, 'source_document'
|
@supermodel.loadModel @originalSource
|
||||||
|
|
||||||
applyDelta: ->
|
applyDelta: ->
|
||||||
@headModel = null
|
@headModel = null
|
||||||
|
|
|
@ -22,7 +22,7 @@ module.exports = class AchievementEditView extends RootView
|
||||||
super options
|
super options
|
||||||
@achievement = new Achievement(_id: @achievementID)
|
@achievement = new Achievement(_id: @achievementID)
|
||||||
@achievement.saveBackups = true
|
@achievement.saveBackups = true
|
||||||
@supermodel.loadModel @achievement, 'achievement'
|
@supermodel.loadModel @achievement
|
||||||
@pushChangesToPreview = _.throttle(@pushChangesToPreview, 500)
|
@pushChangesToPreview = _.throttle(@pushChangesToPreview, 500)
|
||||||
|
|
||||||
onLoaded: ->
|
onLoaded: ->
|
||||||
|
|
|
@ -20,7 +20,7 @@ module.exports = class ArticleEditView extends RootView
|
||||||
super options
|
super options
|
||||||
@article = new Article({_id: @articleID})
|
@article = new Article({_id: @articleID})
|
||||||
@article.saveBackups = true
|
@article.saveBackups = true
|
||||||
@supermodel.loadModel @article, 'article'
|
@supermodel.loadModel @article
|
||||||
@pushChangesToPreview = _.throttle(@pushChangesToPreview, 500)
|
@pushChangesToPreview = _.throttle(@pushChangesToPreview, 500)
|
||||||
|
|
||||||
onLoaded: ->
|
onLoaded: ->
|
||||||
|
|
|
@ -32,7 +32,7 @@ module.exports = class CampaignEditorView extends RootView
|
||||||
constructor: (options, @campaignHandle) ->
|
constructor: (options, @campaignHandle) ->
|
||||||
super(options)
|
super(options)
|
||||||
@campaign = new Campaign({_id:@campaignHandle})
|
@campaign = new Campaign({_id:@campaignHandle})
|
||||||
@supermodel.loadModel(@campaign, 'campaign')
|
@supermodel.loadModel(@campaign)
|
||||||
@listenToOnce @campaign, 'sync', (model, response, jqXHR) ->
|
@listenToOnce @campaign, 'sync', (model, response, jqXHR) ->
|
||||||
@campaign.set '_id', response._id
|
@campaign.set '_id', response._id
|
||||||
@campaign.url = -> '/db/campaign/' + @id
|
@campaign.url = -> '/db/campaign/' + @id
|
||||||
|
@ -72,7 +72,7 @@ module.exports = class CampaignEditorView extends RootView
|
||||||
thangType = new ThangType()
|
thangType = new ThangType()
|
||||||
thangType.setProjection(thangTypeProject)
|
thangType.setProjection(thangTypeProject)
|
||||||
thangType.setURL("/db/thang.type/#{original}/version")
|
thangType.setURL("/db/thang.type/#{original}/version")
|
||||||
@supermodel.loadModel(thangType, 'thang')
|
@supermodel.loadModel(thangType)
|
||||||
|
|
||||||
onFundamentalLoaded: ->
|
onFundamentalLoaded: ->
|
||||||
# Load any levels which haven't been denormalized into our campaign.
|
# Load any levels which haven't been denormalized into our campaign.
|
||||||
|
@ -82,7 +82,7 @@ module.exports = class CampaignEditorView extends RootView
|
||||||
model = new Level({})
|
model = new Level({})
|
||||||
model.setProjection Campaign.denormalizedLevelProperties
|
model.setProjection Campaign.denormalizedLevelProperties
|
||||||
model.setURL("/db/level/#{level.original}/version")
|
model.setURL("/db/level/#{level.original}/version")
|
||||||
@levels.add @supermodel.loadModel(model, 'level').model
|
@levels.add @supermodel.loadModel(model).model
|
||||||
achievements = new RelatedAchievementsCollection level.original
|
achievements = new RelatedAchievementsCollection level.original
|
||||||
achievements.setProjection achievementProject
|
achievements.setProjection achievementProject
|
||||||
@supermodel.loadCollection achievements, 'achievements'
|
@supermodel.loadCollection achievements, 'achievements'
|
||||||
|
@ -109,20 +109,20 @@ module.exports = class CampaignEditorView extends RootView
|
||||||
rewardObject.hero = reward
|
rewardObject.hero = reward
|
||||||
thangType = new ThangType({}, {project: thangTypeProject})
|
thangType = new ThangType({}, {project: thangTypeProject})
|
||||||
thangType.setURL("/db/thang.type/#{reward}/version")
|
thangType.setURL("/db/thang.type/#{reward}/version")
|
||||||
@supermodel.loadModel(thangType, 'thang')
|
@supermodel.loadModel(thangType)
|
||||||
|
|
||||||
if rewardType is 'levels'
|
if rewardType is 'levels'
|
||||||
rewardObject.level = reward
|
rewardObject.level = reward
|
||||||
if not @levels.findWhere({original: reward})
|
if not @levels.findWhere({original: reward})
|
||||||
level = new Level({}, {project: Campaign.denormalizedLevelProperties})
|
level = new Level({}, {project: Campaign.denormalizedLevelProperties})
|
||||||
level.setURL("/db/level/#{reward}/version")
|
level.setURL("/db/level/#{reward}/version")
|
||||||
@supermodel.loadModel(level, 'level')
|
@supermodel.loadModel(level)
|
||||||
|
|
||||||
if rewardType is 'items'
|
if rewardType is 'items'
|
||||||
rewardObject.item = reward
|
rewardObject.item = reward
|
||||||
thangType = new ThangType({}, {project: thangTypeProject})
|
thangType = new ThangType({}, {project: thangTypeProject})
|
||||||
thangType.setURL("/db/thang.type/#{reward}/version")
|
thangType.setURL("/db/thang.type/#{reward}/version")
|
||||||
@supermodel.loadModel(thangType, 'thang')
|
@supermodel.loadModel(thangType)
|
||||||
|
|
||||||
rewards.push rewardObject
|
rewards.push rewardObject
|
||||||
campaignLevel.rewards = rewards
|
campaignLevel.rewards = rewards
|
||||||
|
|
|
@ -71,7 +71,7 @@ module.exports = class ThangComponentsEditView extends CocoView
|
||||||
levelComponent = new LevelComponent(componentRef)
|
levelComponent = new LevelComponent(componentRef)
|
||||||
url = "/db/level.component/#{componentRef.original}/version/#{componentRef.majorVersion}"
|
url = "/db/level.component/#{componentRef.original}/version/#{componentRef.majorVersion}"
|
||||||
levelComponent.setURL(url)
|
levelComponent.setURL(url)
|
||||||
resource = @supermodel.loadModel levelComponent, 'component'
|
resource = @supermodel.loadModel levelComponent
|
||||||
continue unless resource.isLoading
|
continue unless resource.isLoading
|
||||||
@listenToOnce resource, 'loaded', ->
|
@listenToOnce resource, 'loaded', ->
|
||||||
return if @handlingChange
|
return if @handlingChange
|
||||||
|
|
|
@ -30,7 +30,7 @@ module.exports = class SystemsTabView extends CocoView
|
||||||
for system in @buildDefaultSystems()
|
for system in @buildDefaultSystems()
|
||||||
url = "/db/level.system/#{system.original}/version/#{system.majorVersion}"
|
url = "/db/level.system/#{system.original}/version/#{system.majorVersion}"
|
||||||
ls = new LevelSystem().setURL(url)
|
ls = new LevelSystem().setURL(url)
|
||||||
@supermodel.loadModel(ls, 'system')
|
@supermodel.loadModel(ls)
|
||||||
|
|
||||||
afterRender: ->
|
afterRender: ->
|
||||||
@buildSystemsTreema()
|
@buildSystemsTreema()
|
||||||
|
|
|
@ -30,7 +30,7 @@ module.exports = class VersionsModal extends ModalView
|
||||||
constructor: (options, @ID, @model) ->
|
constructor: (options, @ID, @model) ->
|
||||||
super options
|
super options
|
||||||
@original = new @model(_id: @ID)
|
@original = new @model(_id: @ID)
|
||||||
@original = @supermodel.loadModel(@original, 'document').model
|
@original = @supermodel.loadModel(@original).model
|
||||||
@listenToOnce(@original, 'sync', @onViewSync)
|
@listenToOnce(@original, 'sync', @onViewSync)
|
||||||
|
|
||||||
onViewSync: ->
|
onViewSync: ->
|
||||||
|
|
|
@ -25,7 +25,7 @@ module.exports = class PollEditView extends RootView
|
||||||
loadPoll: ->
|
loadPoll: ->
|
||||||
@poll = new Poll _id: @pollID
|
@poll = new Poll _id: @pollID
|
||||||
@poll.saveBackups = true
|
@poll.saveBackups = true
|
||||||
@supermodel.loadModel @poll, 'poll'
|
@supermodel.loadModel @poll
|
||||||
|
|
||||||
loadUserPollsRecord: ->
|
loadUserPollsRecord: ->
|
||||||
url = "/db/user.polls.record/-/user/#{me.id}"
|
url = "/db/user.polls.record/-/user/#{me.id}"
|
||||||
|
@ -34,7 +34,7 @@ module.exports = class PollEditView extends RootView
|
||||||
return if @destroyed
|
return if @destroyed
|
||||||
@userPollsRecord.url = -> '/db/user.polls.record/' + @id
|
@userPollsRecord.url = -> '/db/user.polls.record/' + @id
|
||||||
@listenToOnce @userPollsRecord, 'sync', onRecordSync
|
@listenToOnce @userPollsRecord, 'sync', onRecordSync
|
||||||
@userPollsRecord = @supermodel.loadModel(@userPollsRecord, 'user_polls_record').model
|
@userPollsRecord = @supermodel.loadModel(@userPollsRecord).model
|
||||||
onRecordSync.call @ if @userPollsRecord.loaded
|
onRecordSync.call @ if @userPollsRecord.loaded
|
||||||
|
|
||||||
onLoaded: ->
|
onLoaded: ->
|
||||||
|
|
|
@ -13,7 +13,7 @@ module.exports = class ThangTypeColorsTabView extends CocoView
|
||||||
|
|
||||||
constructor: (@thangType, options) ->
|
constructor: (@thangType, options) ->
|
||||||
super options
|
super options
|
||||||
@supermodel.loadModel @thangType, 'thang'
|
@supermodel.loadModel @thangType
|
||||||
@colorConfig = {hue: 0, saturation: 0.5, lightness: 0.5}
|
@colorConfig = {hue: 0, saturation: 0.5, lightness: 0.5}
|
||||||
@spriteBuilder = new SpriteBuilder(@thangType) if @thangType.get('raw')
|
@spriteBuilder = new SpriteBuilder(@thangType) if @thangType.get('raw')
|
||||||
f = =>
|
f = =>
|
||||||
|
|
|
@ -174,7 +174,7 @@ module.exports = class ThangTypeEditView extends RootView
|
||||||
super options
|
super options
|
||||||
@mockThang = $.extend(true, {}, @mockThang)
|
@mockThang = $.extend(true, {}, @mockThang)
|
||||||
@thangType = new ThangType(_id: @thangTypeID)
|
@thangType = new ThangType(_id: @thangTypeID)
|
||||||
@thangType = @supermodel.loadModel(@thangType, 'thang').model
|
@thangType = @supermodel.loadModel(@thangType).model
|
||||||
@thangType.saveBackups = true
|
@thangType.saveBackups = true
|
||||||
@listenToOnce @thangType, 'sync', ->
|
@listenToOnce @thangType, 'sync', ->
|
||||||
@files = @supermodel.loadCollection(new DocumentFiles(@thangType), 'files').model
|
@files = @supermodel.loadCollection(new DocumentFiles(@thangType), 'files').model
|
||||||
|
|
|
@ -19,7 +19,7 @@ module.exports = class I18NEditModelView extends RootView
|
||||||
constructor: (options, @modelHandle) ->
|
constructor: (options, @modelHandle) ->
|
||||||
super(options)
|
super(options)
|
||||||
@model = new @modelClass(_id: @modelHandle)
|
@model = new @modelClass(_id: @modelHandle)
|
||||||
@model = @supermodel.loadModel(@model, 'model').model
|
@model = @supermodel.loadModel(@model).model
|
||||||
@model.saveBackups = true
|
@model.saveBackups = true
|
||||||
@selectedLanguage = me.get('preferredLanguage', true)
|
@selectedLanguage = me.get('preferredLanguage', true)
|
||||||
|
|
||||||
|
@ -172,7 +172,7 @@ module.exports = class I18NEditModelView extends RootView
|
||||||
# Override PUT so we can trigger postNewVersion logic
|
# Override PUT so we can trigger postNewVersion logic
|
||||||
# or you're POSTing a Patch
|
# or you're POSTing a Patch
|
||||||
type = 'POST'
|
type = 'POST'
|
||||||
res = modelToSave.save(null, {type: type})
|
res = modelToSave.save(null, {type: type})
|
||||||
return button.text('Failed to Submit Changes') unless res
|
return button.text('Failed to Submit Changes') unless res
|
||||||
button.text('Submitting...')
|
button.text('Submitting...')
|
||||||
res.error => button.text('Error Submitting Changes')
|
res.error => button.text('Error Submitting Changes')
|
||||||
|
|
|
@ -41,7 +41,7 @@ module.exports = class LadderView extends RootView
|
||||||
|
|
||||||
constructor: (options, @levelID, @leagueType, @leagueID) ->
|
constructor: (options, @levelID, @leagueType, @leagueID) ->
|
||||||
super(options)
|
super(options)
|
||||||
@level = @supermodel.loadModel(new Level(_id: @levelID), 'level').model
|
@level = @supermodel.loadModel(new Level(_id: @levelID)).model
|
||||||
@sessions = @supermodel.loadCollection(new LevelSessionsCollection(@levelID), 'your_sessions', {cache: false}).model
|
@sessions = @supermodel.loadCollection(new LevelSessionsCollection(@levelID), 'your_sessions', {cache: false}).model
|
||||||
@teams = []
|
@teams = []
|
||||||
@loadLeague()
|
@loadLeague()
|
||||||
|
@ -51,8 +51,7 @@ module.exports = class LadderView extends RootView
|
||||||
@leagueID = @leagueType = null unless @leagueType in ['clan', 'course']
|
@leagueID = @leagueType = null unless @leagueType in ['clan', 'course']
|
||||||
return unless @leagueID
|
return unless @leagueID
|
||||||
modelClass = if @leagueType is 'clan' then Clan else CourseInstance
|
modelClass = if @leagueType is 'clan' then Clan else CourseInstance
|
||||||
resourceString = if @leagueType is 'clan' then 'clans.clan' else 'courses.course'
|
@league = @supermodel.loadModel(new modelClass(_id: @leagueID)).model
|
||||||
@league = @supermodel.loadModel(new modelClass(_id: @leagueID), resourceString).model
|
|
||||||
if @leagueType is 'course'
|
if @leagueType is 'course'
|
||||||
if @league.loaded
|
if @league.loaded
|
||||||
@onCourseInstanceLoaded @league
|
@onCourseInstanceLoaded @league
|
||||||
|
@ -62,7 +61,7 @@ module.exports = class LadderView extends RootView
|
||||||
onCourseInstanceLoaded: (courseInstance) ->
|
onCourseInstanceLoaded: (courseInstance) ->
|
||||||
return if @destroyed
|
return if @destroyed
|
||||||
course = new Course({_id: courseInstance.get('courseID')})
|
course = new Course({_id: courseInstance.get('courseID')})
|
||||||
@course = @supermodel.loadModel(course, 'courses.course').model
|
@course = @supermodel.loadModel(course).model
|
||||||
@listenToOnce @course, 'sync', @render
|
@listenToOnce @course, 'sync', @render
|
||||||
|
|
||||||
onLoaded: ->
|
onLoaded: ->
|
||||||
|
|
|
@ -13,7 +13,7 @@ module.exports = class ModelModal extends ModalView
|
||||||
super options
|
super options
|
||||||
@models = options.models
|
@models = options.models
|
||||||
for model in @models when not model.loaded
|
for model in @models when not model.loaded
|
||||||
@supermodel.loadModel model, 'source_document'
|
@supermodel.loadModel model
|
||||||
model.fetch cache: false
|
model.fetch cache: false
|
||||||
|
|
||||||
afterRender: ->
|
afterRender: ->
|
||||||
|
|
|
@ -82,7 +82,7 @@ module.exports = class CampaignView extends RootView
|
||||||
|
|
||||||
@campaign = new Campaign({_id:@terrain})
|
@campaign = new Campaign({_id:@terrain})
|
||||||
@campaign.saveBackups = @editorMode
|
@campaign.saveBackups = @editorMode
|
||||||
@campaign = @supermodel.loadModel(@campaign, 'campaign').model
|
@campaign = @supermodel.loadModel(@campaign).model
|
||||||
|
|
||||||
# Temporary attempt to make sure all earned rewards are accounted for. Figure out a better solution...
|
# Temporary attempt to make sure all earned rewards are accounted for. Figure out a better solution...
|
||||||
@earnedAchievements = new CocoCollection([], {url: '/db/earned_achievement', model:EarnedAchievement, project: ['earnedRewards']})
|
@earnedAchievements = new CocoCollection([], {url: '/db/earned_achievement', model:EarnedAchievement, project: ['earnedRewards']})
|
||||||
|
@ -442,11 +442,11 @@ module.exports = class CampaignView extends RootView
|
||||||
preloadLevel: (levelSlug) ->
|
preloadLevel: (levelSlug) ->
|
||||||
levelURL = "/db/level/#{levelSlug}"
|
levelURL = "/db/level/#{levelSlug}"
|
||||||
level = new Level().setURL levelURL
|
level = new Level().setURL levelURL
|
||||||
level = @supermodel.loadModel(level, 'level', null, 0).model
|
level = @supermodel.loadModel(level, null, 0).model
|
||||||
sessionURL = "/db/level/#{levelSlug}/session"
|
sessionURL = "/db/level/#{levelSlug}/session"
|
||||||
@preloadedSession = new LevelSession().setURL sessionURL
|
@preloadedSession = new LevelSession().setURL sessionURL
|
||||||
@listenToOnce @preloadedSession, 'sync', @onSessionPreloaded
|
@listenToOnce @preloadedSession, 'sync', @onSessionPreloaded
|
||||||
@preloadedSession = @supermodel.loadModel(@preloadedSession, 'level_session', {cache: false}).model
|
@preloadedSession = @supermodel.loadModel(@preloadedSession, {cache: false}).model
|
||||||
@preloadedSession.levelSlug = levelSlug
|
@preloadedSession.levelSlug = levelSlug
|
||||||
|
|
||||||
onSessionPreloaded: (session) ->
|
onSessionPreloaded: (session) ->
|
||||||
|
@ -604,7 +604,7 @@ module.exports = class CampaignView extends RootView
|
||||||
continue if @supermodel.getModel url
|
continue if @supermodel.getModel url
|
||||||
fullHero = new ThangType()
|
fullHero = new ThangType()
|
||||||
fullHero.setURL url
|
fullHero.setURL url
|
||||||
@supermodel.loadModel fullHero, 'thang'
|
@supermodel.loadModel fullHero
|
||||||
|
|
||||||
updateVolume: (volume) ->
|
updateVolume: (volume) ->
|
||||||
volume ?= me.get('volume') ? 1.0
|
volume ?= me.get('volume') ? 1.0
|
||||||
|
@ -675,7 +675,7 @@ module.exports = class CampaignView extends RootView
|
||||||
else
|
else
|
||||||
console.log 'Poll will be ready in', (22 * 60 * 60 * 1000 - interval) / (60 * 60 * 1000), 'hours.'
|
console.log 'Poll will be ready in', (22 * 60 * 60 * 1000 - interval) / (60 * 60 * 1000), 'hours.'
|
||||||
@listenToOnce @userPollsRecord, 'sync', onRecordSync
|
@listenToOnce @userPollsRecord, 'sync', onRecordSync
|
||||||
@userPollsRecord = @supermodel.loadModel(@userPollsRecord, 'user_polls_record', null, 0).model
|
@userPollsRecord = @supermodel.loadModel(@userPollsRecord, null, 0).model
|
||||||
onRecordSync.call @ if @userPollsRecord.loaded
|
onRecordSync.call @ if @userPollsRecord.loaded
|
||||||
|
|
||||||
loadPoll: ->
|
loadPoll: ->
|
||||||
|
@ -693,7 +693,7 @@ module.exports = class CampaignView extends RootView
|
||||||
delete @poll
|
delete @poll
|
||||||
@listenToOnce @poll, 'sync', onPollSync
|
@listenToOnce @poll, 'sync', onPollSync
|
||||||
@listenToOnce @poll, 'error', onPollError
|
@listenToOnce @poll, 'error', onPollError
|
||||||
@poll = @supermodel.loadModel(@poll, 'poll', null, 0).model
|
@poll = @supermodel.loadModel(@poll, null, 0).model
|
||||||
onPollSync.call @ if @poll.loaded
|
onPollSync.call @ if @poll.loaded
|
||||||
|
|
||||||
activatePoll: ->
|
activatePoll: ->
|
||||||
|
|
|
@ -17,7 +17,7 @@ module.exports = class CourseVictoryModal extends ModalView
|
||||||
template: template
|
template: template
|
||||||
closesOnClickOutside: false
|
closesOnClickOutside: false
|
||||||
|
|
||||||
|
|
||||||
initialize: (options) ->
|
initialize: (options) ->
|
||||||
@courseID = options.courseID
|
@courseID = options.courseID
|
||||||
@courseInstanceID = options.courseInstanceID
|
@courseInstanceID = options.courseInstanceID
|
||||||
|
@ -27,7 +27,7 @@ module.exports = class CourseVictoryModal extends ModalView
|
||||||
@level = options.level
|
@level = options.level
|
||||||
@newItems = new ThangTypes()
|
@newItems = new ThangTypes()
|
||||||
@newHeroes = new ThangTypes()
|
@newHeroes = new ThangTypes()
|
||||||
|
|
||||||
@achievements = options.achievements
|
@achievements = options.achievements
|
||||||
if not @achievements
|
if not @achievements
|
||||||
@achievements = new Achievements()
|
@achievements = new Achievements()
|
||||||
|
@ -36,18 +36,18 @@ module.exports = class CourseVictoryModal extends ModalView
|
||||||
@listenToOnce @achievements, 'sync', @onAchievementsLoaded
|
@listenToOnce @achievements, 'sync', @onAchievementsLoaded
|
||||||
else
|
else
|
||||||
@onAchievementsLoaded()
|
@onAchievementsLoaded()
|
||||||
|
|
||||||
@playSound 'victory'
|
@playSound 'victory'
|
||||||
@nextLevel = options.nextLevel
|
@nextLevel = options.nextLevel
|
||||||
if (nextLevel = @level.get('nextLevel')) and not @nextLevel
|
if (nextLevel = @level.get('nextLevel')) and not @nextLevel
|
||||||
@nextLevel = new Level().setURL "/db/level/#{nextLevel.original}/version/#{nextLevel.majorVersion}"
|
@nextLevel = new Level().setURL "/db/level/#{nextLevel.original}/version/#{nextLevel.majorVersion}"
|
||||||
@nextLevel = @supermodel.loadModel(@nextLevel, 'level').model
|
@nextLevel = @supermodel.loadModel(@nextLevel).model
|
||||||
|
|
||||||
@campaign = new Campaign()
|
@campaign = new Campaign()
|
||||||
@course = options.course
|
@course = options.course
|
||||||
if @courseID and not @course
|
if @courseID and not @course
|
||||||
@course = new Course().setURL "/db/course/#{@courseID}"
|
@course = new Course().setURL "/db/course/#{@courseID}"
|
||||||
@course = @supermodel.loadModel(@course, 'course').model
|
@course = @supermodel.loadModel(@course).model
|
||||||
if @course.loading
|
if @course.loading
|
||||||
@listenToOnce @course, 'sync', @onCourseLoaded
|
@listenToOnce @course, 'sync', @onCourseLoaded
|
||||||
else
|
else
|
||||||
|
@ -58,16 +58,16 @@ module.exports = class CourseVictoryModal extends ModalView
|
||||||
if @courseInstanceID
|
if @courseInstanceID
|
||||||
@levelSessions = new LevelSessions()
|
@levelSessions = new LevelSessions()
|
||||||
@levelSessions.fetchForCourseInstance(@courseInstanceID)
|
@levelSessions.fetchForCourseInstance(@courseInstanceID)
|
||||||
@levelSessions = @supermodel.loadCollection(@levelSessions, 'sessions', {
|
@levelSessions = @supermodel.loadCollection(@levelSessions, 'sessions', {
|
||||||
data: { project: 'state.complete level.original playtime changed' }
|
data: { project: 'state.complete level.original playtime changed' }
|
||||||
}).model
|
}).model
|
||||||
|
|
||||||
|
|
||||||
onCourseLoaded: ->
|
onCourseLoaded: ->
|
||||||
@campaign.set('_id', @course.get('campaignID'))
|
@campaign.set('_id', @course.get('campaignID'))
|
||||||
@campaign = @supermodel.loadModel(@campaign, 'campaign').model
|
@campaign = @supermodel.loadModel(@campaign).model
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
onAchievementsLoaded: ->
|
onAchievementsLoaded: ->
|
||||||
@achievements.models = _.filter @achievements.models, (m) -> not m.get('query')?.ladderAchievementDifficulty # Don't show higher AI difficulty achievements
|
@achievements.models = _.filter @achievements.models, (m) -> not m.get('query')?.ladderAchievementDifficulty # Don't show higher AI difficulty achievements
|
||||||
itemOriginals = []
|
itemOriginals = []
|
||||||
|
@ -89,9 +89,9 @@ module.exports = class CourseVictoryModal extends ModalView
|
||||||
thang= new ThangType()
|
thang= new ThangType()
|
||||||
thang.url = "/db/thang.type/#{original}/version"
|
thang.url = "/db/thang.type/#{original}/version"
|
||||||
thang.project = project
|
thang.project = project
|
||||||
@supermodel.loadModel(thang, 'thang')
|
@supermodel.loadModel(thang)
|
||||||
newThangTypeCollection.add(thang)
|
newThangTypeCollection.add(thang)
|
||||||
|
|
||||||
@newEarnedAchievements = []
|
@newEarnedAchievements = []
|
||||||
for achievement in @achievements.models
|
for achievement in @achievements.models
|
||||||
continue unless achievement.completed
|
continue unless achievement.completed
|
||||||
|
@ -108,25 +108,25 @@ module.exports = class CourseVictoryModal extends ModalView
|
||||||
model.sr.markLoaded()
|
model.sr.markLoaded()
|
||||||
if _.all((ea.id for ea in @newEarnedAchievements))
|
if _.all((ea.id for ea in @newEarnedAchievements))
|
||||||
unless me.loading
|
unless me.loading
|
||||||
@supermodel.loadModel(me, 'user', {cache: false})
|
@supermodel.loadModel(me, {cache: false})
|
||||||
@newEarnedAchievementsResource.markLoaded()
|
@newEarnedAchievementsResource.markLoaded()
|
||||||
|
|
||||||
|
|
||||||
# have to use a something resource because addModelResource doesn't handle models being upserted/fetched via POST like we're doing here
|
# have to use a something resource because addModelResource doesn't handle models being upserted/fetched via POST like we're doing here
|
||||||
@newEarnedAchievementsResource = @supermodel.addSomethingResource('earned achievements') if @newEarnedAchievements.length
|
@newEarnedAchievementsResource = @supermodel.addSomethingResource('earned achievements') if @newEarnedAchievements.length
|
||||||
|
|
||||||
|
|
||||||
onLoaded: ->
|
onLoaded: ->
|
||||||
super()
|
super()
|
||||||
@views = []
|
@views = []
|
||||||
|
|
||||||
# TODO: Add main victory view
|
# TODO: Add main victory view
|
||||||
# TODO: Add level up view
|
# TODO: Add level up view
|
||||||
# TODO: Add new hero view?
|
# TODO: Add new hero view?
|
||||||
|
|
||||||
for newItem in @newItems.models
|
for newItem in @newItems.models
|
||||||
@views.push(new NewItemView({item: newItem}))
|
@views.push(new NewItemView({item: newItem}))
|
||||||
|
|
||||||
progressView = new ProgressView({
|
progressView = new ProgressView({
|
||||||
level: @level
|
level: @level
|
||||||
nextLevel: @nextLevel
|
nextLevel: @nextLevel
|
||||||
|
@ -134,15 +134,15 @@ module.exports = class CourseVictoryModal extends ModalView
|
||||||
campaign: @campaign
|
campaign: @campaign
|
||||||
levelSessions: @levelSessions
|
levelSessions: @levelSessions
|
||||||
})
|
})
|
||||||
|
|
||||||
progressView.once 'done', @onDone, @
|
progressView.once 'done', @onDone, @
|
||||||
progressView.once 'next-level', @onNextLevel, @
|
progressView.once 'next-level', @onNextLevel, @
|
||||||
for view in @views
|
for view in @views
|
||||||
view.on 'continue', @onViewContinue, @
|
view.on 'continue', @onViewContinue, @
|
||||||
@views.push(progressView)
|
@views.push(progressView)
|
||||||
|
|
||||||
@showView(_.first(@views))
|
@showView(_.first(@views))
|
||||||
|
|
||||||
afterRender: ->
|
afterRender: ->
|
||||||
super()
|
super()
|
||||||
@showView(@currentView)
|
@showView(@currentView)
|
||||||
|
@ -166,5 +166,3 @@ module.exports = class CourseVictoryModal extends ModalView
|
||||||
onDone: ->
|
onDone: ->
|
||||||
link = "/courses/#{@courseID}/#{@courseInstanceID}"
|
link = "/courses/#{@courseID}/#{@courseInstanceID}"
|
||||||
application.router.navigate(link, {trigger: true})
|
application.router.navigate(link, {trigger: true})
|
||||||
|
|
||||||
|
|
|
@ -66,10 +66,10 @@ module.exports = class HeroVictoryModal extends ModalView
|
||||||
if @level.get('type', true) is 'course'
|
if @level.get('type', true) is 'course'
|
||||||
if nextLevel = @level.get('nextLevel')
|
if nextLevel = @level.get('nextLevel')
|
||||||
@nextLevel = new Level().setURL "/db/level/#{nextLevel.original}/version/#{nextLevel.majorVersion}"
|
@nextLevel = new Level().setURL "/db/level/#{nextLevel.original}/version/#{nextLevel.majorVersion}"
|
||||||
@nextLevel = @supermodel.loadModel(@nextLevel, 'level').model
|
@nextLevel = @supermodel.loadModel(@nextLevel).model
|
||||||
if @courseID
|
if @courseID
|
||||||
@course = new Course().setURL "/db/course/#{@courseID}"
|
@course = new Course().setURL "/db/course/#{@courseID}"
|
||||||
@course = @supermodel.loadModel(@course, 'course').model
|
@course = @supermodel.loadModel(@course).model
|
||||||
if @level.get('type', true) in ['course', 'course-ladder']
|
if @level.get('type', true) in ['course', 'course-ladder']
|
||||||
@saveReviewEventually = _.debounce(@saveReviewEventually, 2000)
|
@saveReviewEventually = _.debounce(@saveReviewEventually, 2000)
|
||||||
@loadExistingFeedback()
|
@loadExistingFeedback()
|
||||||
|
@ -123,7 +123,7 @@ module.exports = class HeroVictoryModal extends ModalView
|
||||||
thangType.url = "/db/thang.type/#{thangTypeOriginal}/version"
|
thangType.url = "/db/thang.type/#{thangTypeOriginal}/version"
|
||||||
#thangType.project = ['original', 'rasterIcon', 'name', 'soundTriggers', 'i18n'] # This is what we need, but the PlayHeroesModal needs more, and so we load more to fill up the supermodel.
|
#thangType.project = ['original', 'rasterIcon', 'name', 'soundTriggers', 'i18n'] # This is what we need, but the PlayHeroesModal needs more, and so we load more to fill up the supermodel.
|
||||||
thangType.project = ['original', 'rasterIcon', 'name', 'slug', 'soundTriggers', 'featureImages', 'gems', 'heroClass', 'description', 'components', 'extendedName', 'unlockLevelName', 'i18n']
|
thangType.project = ['original', 'rasterIcon', 'name', 'slug', 'soundTriggers', 'featureImages', 'gems', 'heroClass', 'description', 'components', 'extendedName', 'unlockLevelName', 'i18n']
|
||||||
@thangTypes[thangTypeOriginal] = @supermodel.loadModel(thangType, 'thang').model
|
@thangTypes[thangTypeOriginal] = @supermodel.loadModel(thangType).model
|
||||||
|
|
||||||
@newEarnedAchievements = []
|
@newEarnedAchievements = []
|
||||||
hadOneCompleted = false
|
hadOneCompleted = false
|
||||||
|
|
|
@ -170,7 +170,7 @@ module.exports = class CastButtonView extends CocoView
|
||||||
url = "/db/level/#{@options.level.get('slug') or @options.level.id}/session"
|
url = "/db/level/#{@options.level.get('slug') or @options.level.id}/session"
|
||||||
url += "?team=#{if me.team is 'humans' then 'ogres' else 'humans'}"
|
url += "?team=#{if me.team is 'humans' then 'ogres' else 'humans'}"
|
||||||
mirrorSession = new LevelSession().setURL url
|
mirrorSession = new LevelSession().setURL url
|
||||||
@mirrorSession = @supermodel.loadModel(mirrorSession, 'level_session', {cache: false}).model
|
@mirrorSession = @supermodel.loadModel(mirrorSession, {cache: false}).model
|
||||||
|
|
||||||
updateLadderSubmissionViews: ->
|
updateLadderSubmissionViews: ->
|
||||||
@removeSubView subview for key, subview of @subviews when subview instanceof LadderSubmissionView
|
@removeSubView subview for key, subview of @subviews when subview instanceof LadderSubmissionView
|
||||||
|
|
|
@ -21,7 +21,7 @@ module.exports = class LeaderboardModal extends ModalView
|
||||||
@levelSlug = @options.levelSlug
|
@levelSlug = @options.levelSlug
|
||||||
level = new Level({_id: @levelSlug})
|
level = new Level({_id: @levelSlug})
|
||||||
level.project = ['name', 'i18n', 'scoreType', 'original']
|
level.project = ['name', 'i18n', 'scoreType', 'original']
|
||||||
@level = @supermodel.loadModel(level, 'level').model
|
@level = @supermodel.loadModel(level).model
|
||||||
|
|
||||||
getRenderData: (c) ->
|
getRenderData: (c) ->
|
||||||
c = super c
|
c = super c
|
||||||
|
|
|
@ -139,7 +139,7 @@ module.exports = class PlayHeroesModal extends ModalView
|
||||||
return fullHero
|
return fullHero
|
||||||
fullHero = new ThangType()
|
fullHero = new ThangType()
|
||||||
fullHero.setURL url
|
fullHero.setURL url
|
||||||
fullHero = (@supermodel.loadModel fullHero, 'thang').model
|
fullHero = (@supermodel.loadModel fullHero).model
|
||||||
fullHero
|
fullHero
|
||||||
|
|
||||||
preloadHero: (heroIndex) ->
|
preloadHero: (heroIndex) ->
|
||||||
|
|
|
@ -27,14 +27,14 @@ describe 'SuperModel', ->
|
||||||
it 'starts loading the model if it isn\'t already loading', ->
|
it 'starts loading the model if it isn\'t already loading', ->
|
||||||
s = new SuperModel()
|
s = new SuperModel()
|
||||||
m = new User({_id: '12345'})
|
m = new User({_id: '12345'})
|
||||||
s.loadModel(m, 'user')
|
s.loadModel(m)
|
||||||
request = jasmine.Ajax.requests.mostRecent()
|
request = jasmine.Ajax.requests.mostRecent()
|
||||||
expect(request).toBeDefined()
|
expect(request).toBeDefined()
|
||||||
|
|
||||||
it 'also loads collections', ->
|
it 'also loads collections', ->
|
||||||
s = new SuperModel()
|
s = new SuperModel()
|
||||||
c = new ComponentsCollection()
|
c = new ComponentsCollection()
|
||||||
s.loadModel(c, 'collection')
|
s.loadModel(c)
|
||||||
request = jasmine.Ajax.requests.mostRecent()
|
request = jasmine.Ajax.requests.mostRecent()
|
||||||
expect(request).toBeDefined()
|
expect(request).toBeDefined()
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ describe 'SuperModel', ->
|
||||||
m = new User({_id: '12345'})
|
m = new User({_id: '12345'})
|
||||||
triggered = false
|
triggered = false
|
||||||
s.once 'loaded-all', -> triggered = true
|
s.once 'loaded-all', -> triggered = true
|
||||||
s.loadModel(m, 'user')
|
s.loadModel(m)
|
||||||
request = jasmine.Ajax.requests.mostRecent()
|
request = jasmine.Ajax.requests.mostRecent()
|
||||||
request.respondWith({status: 200, responseText: '{}'})
|
request.respondWith({status: 200, responseText: '{}'})
|
||||||
_.defer ->
|
_.defer ->
|
||||||
|
|