codecombat/app/templates/courses/course-details.jade
Nick Winter c77e1c0fa2 Add course complete visual state for student CourseDetailsView
Also including a few misc tweaks to CourseDetailsView and the end-of-course HeroVictoryModal state.
2015-12-02 09:52:52 -08:00

339 lines
14 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

extends /templates/base
block content
if (noCourseInstance || noCourseInstanceSelected) && course
h1= course.get('name')
if noCourseInstance
p(data-i18n="courses.not_enrolled")
p
span.spr(data-i18n="courses.visit_pref")
a(href="/courses", data-i18n="courses.courses")
span.spl(data-i18n="courses.visit_suf")
else if noCourseInstanceSelected
p(data-i18n="courses.select_class")
.container-fluid
.row
.col-md-6
select.form-control.select-instance
each courseInstance in courseInstances
if courseInstance.get('name')
option(value="#{courseInstance.id}")= courseInstance.get('name')
else
option(value="#{courseInstance.id}", data-i18n="courses.unnamed")
.col-md-6
button.btn.btn-success.btn-select-instance(data-i18n="courses.select")
else if !course || !courseInstance
h1(data-i18n="common.loading") Loading...
else
p
// TODO: format this text all good and stuff
strong
if courseInstance.get('name')
span= courseInstance.get('name')
else if view.classroom.get('name')
span= view.classroom.get('name')
else
span(data-i18n='courses.unnamed_class')
if !view.owner.isNew() && view.getOwnerName()
span.spl.spr - Teacher:
//a(href="/user/#{view.owner.id}") // Don't link to profiles until we improve them
span
strong= view.getOwnerName()
h1
| #{course.get('name')}
if view.courseComplete
span.spl - Complete!
p
if courseInstance.get('description')
each line in courseInstance.get('description').split('\n')
div= line
if view.courseComplete && !view.teacherMode
.jumbotron
.row
if view.singlePlayerMode && !me.isAnonymous()
.col-md-3
.col-md-6
a.btn.btn-lg.btn-success(href="/play")
h1 Play the Campaign
p Youre ready to take the next step! Explore hundreds of challenging levels, learn advanced programming skills, and compete in multiplayer arenas!
.col-md-3
else if view.singlePlayerMode && me.isAnonymous()
.col-md-6
a.btn.btn-lg.btn-success.signup-button
h1 Create an Account
p Sign up for a FREE CodeCombat account and gain access to more levels, more programming skills, and more fun!
.col-md-6
a.btn.btn-lg.btn-success(href="/play")
h1 Preview Campaign
p Take a sneak peek at all that CodeCombat has to offer before signing up for your FREE account.
else if !view.singlePlayerMode
.col-md-6
if view.arenaLevel
a.btn.btn-lg.btn-success.btn-play-level(data-level-slug=view.arenaLevel.slug, data-level-id=view.arenaLevel.original)
h1
span Arena
| :
span.spl= view.arenaLevel.name
p= view.arenaLevel.description.replace(/!\[.*?\)/, '')
else
a.btn.btn-lg.btn-success.disabled
h1 Arena Coming Soon
p We are working on a multiplayer arena for classrooms at the end of #{course.get('name')}.
.col-md-6
if view.nextCourseInstance
a.btn.btn-lg.btn-success(href="/courses/#{view.nextCourse.id}/#{view.nextCourseInstance.id}")
h1= view.nextCourse.get('name')
p= view.nextCourse.get('description')
else if view.nextCourse
a.btn.btn-lg.btn-success.disabled
h1= view.nextCourse.get('name')
p
em NOT ENROLLED
p Ask your teacher to enroll you in the next course.
else
a.btn.btn-lg.btn-success(disabled=!view.nextCourse ? "disabled" : "")
h1 Next Course
p
em COMING SOON
p We are hard at work making more courses for you!
if !me.isAnonymous()
div.well.well-sm(role='tabpanel')
ul.nav.nav-pills(role='tablist')
if view.teacherMode
li.active(role='presentation')
a(href='#progress', aria-controls='progress', role='tab', data-toggle='tab', data-i18n="courses.progress")
li(role='presentation')
a(href='#levels', aria-controls='levels', role='tab', data-toggle='tab', data-i18n="nav.play")
else
li.active(role='presentation')
a(href='#levels', aria-controls='levels', role='tab', data-toggle='tab', data-i18n="nav.play")
li(role='presentation')
a(href='#progress', aria-controls='progress', role='tab', data-toggle='tab', data-i18n="courses.progress")
.tab-content
if view.teacherMode
.tab-pane.active#progress(role='tabpanel')
+progress-tab
.tab-pane#levels(role='tabpanel')
+levels-tab
else
.tab-pane.active#levels(role='tabpanel')
+levels-tab
.tab-pane#progress(role='tabpanel')
+progress-tab
mixin progress-tab
.container-fluid.progress-summary-container
.row
.col-md-6
+progress-summary-stats
.col-md-6
+progress-summary-concepts
+progress-members
mixin progress-summary-stats
h3(data-i18n="courses.stats")
table.progress-stats-container
tr
td(data-i18n="courses.total_students")
td
if courseInstance
div #{courseInstance.get('members').length}
if instanceStats
tr
td(data-i18n="courses.average_time")
if instanceStats.averageLevelPlaytime > 0
td= moment.duration(instanceStats.averageLevelPlaytime, "seconds").humanize()
else
td 0
tr
td(data-i18n="courses.total_time")
if instanceStats.totalPlayTime > 0
td= moment.duration(instanceStats.totalPlayTime, "seconds").humanize()
else
td 0
tr
td(data-i18n="courses.average_levels")
td #{instanceStats.averageLevelsCompleted.toFixed(2)}
tr
td(data-i18n="courses.total_levels")
td= instanceStats.totalLevelsCompleted
tr
td(data-i18n="courses.furthest_level")
td= instanceStats.furthestLevelCompleted.replace('Course: ', '')
mixin progress-summary-concepts
h3(data-i18n="courses.concepts_covered")
if course && courseInstance && conceptsCompleted
table.progress-concepts-container
each concept in course.get('concepts')
- var conceptCompletion = Math.round(parseFloat(conceptsCompleted[concept]) / courseInstance.get('members').length * 100)
if isNaN(conceptCompletion)
- conceptCompletion = 0
tr
td.progress-concept-completion-container
span.progress-concept-summary(style="width:#{conceptCompletion}%;")
span.spr(data-i18n="concepts." + concept)
span - #{conceptCompletion}%
mixin progress-members
h3(data-i18n="courses.students")
table.table.table-condensed
thead
tr
th
span.progress-member-header.spr(data-i18n="clans.name")
if memberSort === 'nameAsc'
span.progress-member-header.glyphicon.glyphicon-chevron-up
else if memberSort === 'nameDesc'
span.progress-member-header.glyphicon.glyphicon-chevron-down
th
span.progress-header.spr(data-i18n="clans.progress")
if memberSort === 'progressAsc'
span.progress-header.glyphicon.glyphicon-chevron-up
else if memberSort === 'progressDesc'
span.progress-header.glyphicon.glyphicon-chevron-down
else
span(style='padding-left:16px;')
span.progress-key.progress-key-complete(data-i18n="clans.complete_1")
span.progress-key.progress-key-started(data-i18n="clans.started_1")
if showExpandedProgress
span.progress-key(data-i18n="clans.not_started_1")
input.progress-expand-checkbox(type='checkbox')
span.spl.progress-expand-label(data-i18n="courses.expand_details")
tbody
each memberID in sortedMembers
tr
td.progress-member-cell
+progress-members-individual(memberID)
td.progress-cell
if showExpandedProgress
.progress-concepts-label(data-i18n="courses.concepts")
+progress-members-concepts(memberID)
.progess-levels-label(data-i18n="nav.play")
+progress-members-levels-expanded(memberID)
else
table
tbody
tr
td.progress-concepts-label(data-i18n="courses.concepts")
td.progress-condensed-cell
+progress-members-concepts(memberID)
tr
td.progess-levels-label(data-i18n="nav.play")
td.progress-condensed-cell
+progress-members-levels-condensed(memberID)
mixin progress-members-individual(memberID)
- var name = memberUserMap[memberID] ? memberUserMap[memberID].get('name') : 'Anoner'
a(href="/user/#{memberID}")= name || 'Anoner'
if memberStats && memberStats[memberID]
div
span #{memberStats[memberID].totalLevelsCompleted}
span.spl(data-i18n="courses.levels")
div
span.spr(data-i18n="courses.played")
span #{moment.duration(memberStats[memberID].totalPlayTime, "seconds").humanize()}
mixin progress-members-concepts(memberID)
if course && userLevelStateMap[memberID]
each concept in course.get('concepts')
if userConceptStateMap[memberID][concept] === 'complete'
span.spr.progress-concept-cell.progress-concept-cell-complete(data-i18n="concepts." + concept)
else if userConceptStateMap[memberID][concept] === 'started'
span.spr.progress-concept-cell.progress-concept-cell-started(data-i18n="concepts." + concept)
else if showExpandedProgress
span.spr.progress-concept-cell.progress-concept-cell-not-started(data-i18n="concepts." + concept)
mixin progress-members-levels-expanded(memberID)
if campaign && userLevelStateMap[memberID]
- var i = 0
each level, levelID in campaign.get('levels')
if userLevelStateMap[memberID][levelID] === 'complete'
span.progress-level-cell.progress-level-cell-complete(data-level-id=levelID, data-level-slug=level.slug, data-user-id=memberID) #{i + 1}
span.spl= level.name.replace('Course: ', '')
+progress-members-popup-completed(i, level, (view.userLevelSessionMap[memberID] || {})[levelID])
else if userLevelStateMap[memberID][levelID] === 'started'
span.progress-level-cell.progress-level-cell-started(data-level-id=levelID, data-level-slug=level.slug, data-user-id=memberID) #{i + 1} #{level.name.replace('Course: ', '')}
+progress-members-popup-started(i, level, (view.userLevelSessionMap[memberID] || {})[levelID])
else
span.progress-level-cell #{i + 1} #{level.name.replace('Course: ', '')}
- i++
mixin progress-members-levels-condensed(memberID)
if campaign && userLevelStateMap[memberID]
- var numLevels = Object.keys(campaign.get('levels')).length
- var levelCellWidth = 100.00
if numLevels > 0
levelCellWidth = 100.00 / numLevels
- var i = 0
each level, levelID in campaign.get('levels')
if userLevelStateMap[memberID][levelID] === 'complete'
span.progress-level-cell.progress-level-cell-complete(style="width:#{levelCellWidth}%;", data-level-id=levelID, data-level-slug=level.slug, data-user-id=memberID) #{i + 1}
+progress-members-popup-completed(i, level, (view.userLevelSessionMap[memberID] || {})[levelID])
else if userLevelStateMap[memberID][levelID] === 'started'
span.progress-level-cell.progress-level-cell-started(style="width:#{levelCellWidth}%;", data-level-id=levelID, data-level-slug=level.slug, data-user-id=memberID) #{i + 1}
+progress-members-popup-started(i, level, (view.userLevelSessionMap[memberID] || {})[levelID])
else
break
- i++
mixin progress-members-popup-completed(i, level, session)
.progress-popup-container
h3 #{i + 1}. #{level.name.replace('Course: ', '')}
p
span.spr(data-i18n="courses.play_time")
span #{moment.duration(session.get('playtime'), "seconds").humanize()}
p
span.spr(data-i18n="courses.completed")
span #{moment(session.get('changed')).format('MMMM Do YYYY, h:mm:ss a')}
if view.teacherMode || me.isAdmin()
strong(data-i18n="clans.view_solution")
mixin progress-members-popup-started(i, level, session)
.progress-popup-container
h3 #{i + 1}. #{level.name.replace('Course: ', '')}
p
span.spr(data-i18n="courses.play_time")
span #{moment.duration(session.get('playtime'), "seconds").humanize()}
p
span.spr(data-i18n="clans.last_played")
span #{moment(session.get('changed')).format('MMMM Do YYYY, h:mm:ss a')}
if view.teacherMode || me.isAdmin()
strong(data-i18n="clans.view_solution")
mixin levels-tab
table.table.table-striped.table-condensed
thead
tr
th
th(data-i18n="clans.status")
th(data-i18n="resources.level")
th(data-i18n="courses.concepts")
tbody
if campaign
- var lastLevelCompleted = true;
- var levelCount = 0;
each level, levelID in campaign.get('levels')
tr
td
if lastLevelCompleted || view.teacherMode
- var i18n = level.type === 'course-ladder' ? 'play.compete' : 'home.play';
button.btn.btn-success.btn-play-level(data-level-slug=level.slug, data-i18n=i18n, data-level-id=levelID)
td
if userLevelStateMap[me.id]
div= userLevelStateMap[me.id][levelID]
- lastLevelCompleted = userLevelStateMap[me.id][levelID] === 'complete'
else
- lastLevelCompleted = false
td= ++levelCount + '. ' + level.name.replace('Course: ', '')
td
if levelConceptMap[levelID]
each concept in course.get('concepts')
if levelConceptMap[levelID][concept]
span.spr.progress-level-cell.progress-level-cell-not-started(data-i18n="concepts." + concept)