codecombat/app/templates/courses/course-details.jade

333 lines
13 KiB
Text
Raw Normal View History

extends /templates/base
block content
div
span *UNDER CONSTRUCTION, send feedback to
a.spl(href='mailto:team@codecombat.com') team@codecombat.com
div(style='border-bottom: 1px solid black;')
if (noCourseInstance || noCourseInstanceSelected) && course
h1= course.get('name')
if noCourseInstance
2015-09-25 15:51:51 -04:00
p(data-i18n="courses.not_enrolled")
p
2015-09-25 15:51:51 -04:00
span.spr(data-i18n="courses.visit_pref")
a(href="/courses", data-i18n="courses.courses")
span.spl(data-i18n="courses.visit_suf")
else if noCourseInstanceSelected
2015-09-25 15:51:51 -04:00
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
2015-09-25 15:51:51 -04:00
option(value="#{courseInstance.id}", data-i18n="courses.unnamed")
.col-md-6
2015-09-25 15:51:51 -04:00
button.btn.btn-success.btn-select-instance(data-i18n="courses.select")
2015-09-13 01:01:59 -04:00
else if !course || !courseInstance
2015-09-25 15:51:51 -04:00
h1(data-i18n="common.loading") Loading...
else
2015-10-27 20:47:48 -04:00
h1
if courseInstance.get('name')
| #{courseInstance.get('name')}
else
span(data-i18n='courses.unnamed_class')
2015-10-27 20:47:48 -04:00
small.spl (#{course.get('name')})
if !view.owner.isNew()
p
span.spr Creator:
a(href="/user/#{view.owner.id}")
strong= view.getOwnerName()
p
2015-09-13 01:01:59 -04:00
if courseInstance.get('description')
each line in courseInstance.get('description').split('\n')
div= line
if adminMode && courseInstance
+settings-dialog
p
2015-09-25 15:51:51 -04:00
button.btn.btn-xs(data-toggle='modal', data-target='#settingsModal', data-i18n="courses.edit_settings")
2015-09-13 01:01:59 -04:00
div.well.well-sm(role='tabpanel')
ul.nav.nav-pills(role='tablist')
if adminMode
li.active(role='presentation')
a(href='#progress', aria-controls='progress', role='tab', data-toggle='tab', data-i18n="courses.progress")
2015-09-13 01:01:59 -04:00
li(role='presentation')
2015-09-25 15:51:51 -04:00
a(href='#invite', aria-controls='invite', role='tab', data-toggle='tab', data-i18n="courses.add_students")
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")
2015-09-13 01:01:59 -04:00
.tab-content
if adminMode
.tab-pane.active#progress(role='tabpanel')
+progress-tab
2015-09-13 01:01:59 -04:00
.tab-pane#invite(role='tabpanel')
+invite-tab
.tab-pane#levels(role='tabpanel')
+levels-tab
else
.tab-pane.active#levels(role='tabpanel')
+levels-tab
.tab-pane#progress(role='tabpanel')
+progress-tab
2015-09-13 01:01:59 -04:00
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
2015-09-25 15:51:51 -04:00
h3(data-i18n="courses.stats")
2015-09-13 01:01:59 -04:00
table.progress-stats-container
tr
2015-09-25 15:51:51 -04:00
td(data-i18n="courses.total_students")
2015-09-13 01:01:59 -04:00
td
if courseInstance
div #{courseInstance.get('members').length}
2015-09-24 10:28:43 -04:00
if instanceStats
tr
2015-09-25 15:51:51 -04:00
td(data-i18n="courses.average_time")
2015-09-24 10:28:43 -04:00
if instanceStats.averageLevelPlaytime > 0
td= moment.duration(instanceStats.averageLevelPlaytime, "seconds").humanize()
else
td 0
tr
2015-09-25 15:51:51 -04:00
td(data-i18n="courses.total_time")
2015-09-24 10:28:43 -04:00
if instanceStats.totalPlayTime > 0
td= moment.duration(instanceStats.totalPlayTime, "seconds").humanize()
else
td 0
tr
2015-09-25 15:51:51 -04:00
td(data-i18n="courses.average_levels")
2015-09-24 10:28:43 -04:00
td #{instanceStats.averageLevelsCompleted.toFixed(2)}
tr
2015-09-25 15:51:51 -04:00
td(data-i18n="courses.total_levels")
2015-09-24 10:28:43 -04:00
td= instanceStats.totalLevelsCompleted
tr
2015-09-25 15:51:51 -04:00
td(data-i18n="courses.furthest_level")
2015-09-24 10:28:43 -04:00
td= instanceStats.furthestLevelCompleted.replace('Course: ', '')
2015-09-13 01:01:59 -04:00
mixin progress-summary-concepts
2015-09-25 15:51:51 -04:00
h3(data-i18n="courses.concepts_covered")
2015-09-13 01:01:59 -04:00
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
2015-09-25 15:51:51 -04:00
h3(data-i18n="courses.students")
2015-09-13 01:01:59 -04:00
table.table.table-condensed
thead
tr
th
2015-09-25 15:51:51 -04:00
span.progress-member-header.spr(data-i18n="clans.name")
2015-09-13 01:01:59 -04:00
if memberSort === 'nameAsc'
span.progress-member-header.glyphicon.glyphicon-chevron-up
else if memberSort === 'nameDesc'
span.progress-member-header.glyphicon.glyphicon-chevron-down
th
2015-09-25 15:51:51 -04:00
span.progress-header.spr(data-i18n="clans.progress")
2015-09-13 01:01:59 -04:00
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;')
2015-09-25 15:51:51 -04:00
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")
2015-09-13 01:01:59 -04:00
input.progress-expand-checkbox(type='checkbox')
2015-09-25 15:51:51 -04:00
span.spl.progress-expand-label(data-i18n="courses.expand_details")
2015-09-13 01:01:59 -04:00
tbody
each memberID in sortedMembers
tr
td.progress-member-cell
+progress-members-individual(memberID)
td.progress-cell
if showExpandedProgress
2015-09-25 15:51:51 -04:00
.progress-concepts-label(data-i18n="courses.concepts")
2015-09-13 01:01:59 -04:00
+progress-members-concepts(memberID)
2015-09-25 15:51:51 -04:00
.progess-levels-label(data-i18n="nav.play")
2015-09-13 01:01:59 -04:00
+progress-members-levels-expanded(memberID)
else
table
tbody
tr
2015-09-25 15:51:51 -04:00
td.progress-concepts-label(data-i18n="courses.concepts")
2015-09-13 01:01:59 -04:00
td.progress-condensed-cell
+progress-members-concepts(memberID)
tr
2015-09-25 15:51:51 -04:00
td.progess-levels-label(data-i18n="nav.play")
2015-09-13 01:01:59 -04:00
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'
2015-09-24 10:28:43 -04:00
if memberStats && memberStats[memberID]
2015-09-25 15:51:51 -04:00
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()}
2015-09-13 01:01:59 -04:00
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}
2015-09-13 01:01:59 -04:00
span.spl= level.name.replace('Course: ', '')
+progress-members-popup-completed(i, level)
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: ', '')}
2015-09-13 01:01:59 -04:00
+progress-members-popup-started(i, level)
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}
2015-09-13 01:01:59 -04:00
+progress-members-popup-completed(i, level)
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}
2015-09-13 01:01:59 -04:00
+progress-members-popup-started(i, level)
else
break
- i++
mixin progress-members-popup-completed(i, level)
.progress-popup-container
h3 #{i + 1}. #{level.name.replace('Course: ', '')}
2015-09-25 15:51:51 -04:00
p
span.spr(data-i18n="courses.play_time")
span #{moment.duration(level.playtime, "seconds").humanize()}
p
span.spr(data-i18n="courses.completed")
span #{moment(level.changed).format('MMMM Do YYYY, h:mm:ss a')}
if adminMode
2015-09-25 15:51:51 -04:00
strong(data-i18n="clans.view_solution")
2015-09-13 01:01:59 -04:00
mixin progress-members-popup-started(i, level)
.progress-popup-container
h3 #{i + 1}. #{level.name.replace('Course: ', '')}
2015-09-25 15:51:51 -04:00
p
span.spr(data-i18n="courses.play_time")
span #{moment.duration(level.playtime, "seconds").humanize()}
p
span.spr(data-i18n="clans.last_played")
span #{moment(level.changed).format('MMMM Do YYYY, h:mm:ss a')}
if adminMode
2015-09-25 15:51:51 -04:00
strong(data-i18n="clans.view_solution")
2015-09-13 01:01:59 -04:00
mixin invite-tab
2015-09-25 15:51:51 -04:00
p(data-i18n="courses.invite_students")
2015-10-05 19:00:47 -04:00
h3(data-i18n="courses.invite_link_header")
p(data-i18n="courses.invite_link_p_1")
.alert.alert-info
strong= document.location.origin + "/courses/students?_ppc=" + view.prepaid.get('code')
2015-10-05 19:00:47 -04:00
p(data-i18n="courses.invite_link_p_2")
.form
.form-group
textarea#invite-emails-textarea.form-control
.help-block(data-i18n="courses.enter_emails")
2015-10-05 19:00:47 -04:00
.form-group
button#invite-btn.btn.btn-success(data-i18n="courses.send_invites")
#invite-emails-sending-alert.alert.alert-info.hide(data-i18n="common.sending")
#invite-emails-success-alert.alert.alert-success.hide(data-i18n="play_level.done")
if view.prepaid.loaded && pricePerSeat > 0
h3 Class Capacity
p
2015-10-05 19:00:47 -04:00
span.spr(data-i18n="courses.capacity_used")
span #{view.prepaid.get('redeemers').length} / #{view.prepaid.get('maxRedeemers')}.
2015-09-13 01:01:59 -04:00
mixin levels-tab
table.table.table-striped.table-condensed
thead
tr
th
2015-09-25 15:51:51 -04:00
th(data-i18n="clans.status")
th(data-i18n="resources.level")
th(data-i18n="courses.concepts")
2015-09-13 01:01:59 -04:00
tbody
if campaign
- var lastLevelCompleted = true;
2015-09-13 01:01:59 -04:00
each level, levelID in campaign.get('levels')
tr
td
if lastLevelCompleted || adminMode
button.btn.btn-success.btn-play-level(data-level-slug=level.slug, data-i18n="home.play")
2015-09-13 01:01:59 -04:00
td
if userLevelStateMap[me.id]
div= userLevelStateMap[me.id][levelID]
- lastLevelCompleted = userLevelStateMap[me.id][levelID] === 'complete'
else
- lastLevelCompleted = false
2015-09-13 01:01:59 -04:00
td= 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)
mixin settings-dialog
.modal#settingsModal
.modal-dialog
.modal-header
button.close(data-dismiss='modal')
span ×
2015-09-25 15:51:51 -04:00
h3.modal-title(data-i18n="courses.edit_settings1")
2015-09-13 01:01:59 -04:00
.modal-body
p
2015-09-25 15:51:51 -04:00
strong(data-i18n="courses.title")
2015-09-13 01:01:59 -04:00
p
input.settings-name-input(type='text', value="#{courseInstance.get('name') || ''}")
p
2015-09-25 15:51:51 -04:00
strong(data-i18n="courses.description")
2015-09-13 01:01:59 -04:00
p
textarea.settings-description-input(rows=2)= courseInstance.get('description')
.modal-footer
button.btn.btn-save-settings(data-i18n="common.save_changes")