Added i18n to courses

This commit is contained in:
Imperadeiro98 2015-09-25 20:51:51 +01:00
parent 17a24bbcba
commit 446b193f8c
5 changed files with 224 additions and 111 deletions

View file

@ -844,6 +844,90 @@
last_played: "Last played"
leagues_explanation: "Play in a league against other clan members in these multiplayer arena instances."
courses:
course: "Course"
courses: "courses"
not_enrolled: "You are not enrolled in this course."
visit_pref: "Please visit the"
visit_suf: "page to enroll."
select_class: "Select one of your classes"
unnamed: "*unnamed*"
select: "Select"
unnamed_class: "Unnamed Class"
edit_settings: "edit class settings"
edit_settings1: "Edit Class Settings"
progress: "Class Progress"
add_students: "Add Students"
stats: "Statistics"
total_students: "Total students:"
average_time: "Average level play time:"
total_time: "Total play time:"
average_levels: "Average levels completed:"
total_levels: "Total levels completed:"
furthest_level: "Furthest level completed:"
concepts_covered: "Concepts Covered"
students: "Students"
students1: "students"
expand_details: "Expand details"
concepts: "Concepts"
levels: "levels"
played: "Played"
play_time: "Play time:"
completed: "Completed:"
invite_students: "Invite students to join this class."
enter_emails: "Enter student emails to invite, one per line"
send_invites: "Send Invites"
title: "Title"
description: "Description"
languages_available: "Select programming languages available to the class:"
all_lang: "All Languages"
show_progress: "Show student progress to everyone in the class"
creating_class: "Creating class..."
purchasing_course: "Purchasing course..."
buy_course: "Buy Course"
buy_course1: "Buy this course"
create_class: "Create Class"
select_all_courses: "Select 'All Courses' for a 50% discount!"
all_courses: "All Courses"
number_students: "Number of students"
enter_number_students: "Enter the number of students you need for this class."
name_class: "Name your class"
displayed_course_page: "This will be displayed on the course page for you and your students. It can be changed later."
buy: "Buy"
purchasing_for: "You are purchasing a license for"
creating_for: "You are creating a class for"
for: "for" # Like in 'for 30 students'
receive_code: "Afterwards you will receive an unlock code to distribute to your students, which they can use to enroll in your class."
free_trial: "Free trial for teachers!"
get_access: "to get individual access to all courses for evalutaion purposes."
questions: "Questions?"
faq: "Courses FAQ"
question: "Q:" # Like in 'Question'
question1: "What's the difference between these courses and the single player game?"
answer: "A:" # Like in 'Answer'
answer1: "The single player game is designed for individuals, while the courses are designed for classes."
answer2: "The single player game has items, gems, hero selection, leveling up, and in-app purchases. Courses have classroom management features and streamlined student-focused level pacing."
teachers_click: "Teachers Click Here"
students_click: "Students Click Here"
courses_on_coco: "Courses on CodeCombat"
designed_to: "Courses are designed to introduce computer science concepts using CodeCombat's fun and engaging environment. CodeCombat levels are organized around key topics to encourage progressive learning, over the course of 5 hours."
more_in_less: "Learn more in less time"
no_experience: "No coding experience necesssary"
easy_monitor: "Easily monitor student progress"
purchase_for_class: "Purchase a course for your entire class. It's easy to sign up your students!"
see_the: "See the"
more_info: "for more information."
choose_course: "Choose Your Course:"
enter_code: "Enter an unlock code"
enter_code1: "Enter unlock code"
enroll: "Enroll"
pick_from_classes: "Pick from your current classes"
enter: "Enter"
or: "Or"
topics: "Topics"
hours_content: "Hours of content:"
get_free: "Get FREE course"
classes:
archmage_title: "Archmage"
archmage_title_description: "(Coder)"
@ -1180,6 +1264,7 @@
bad_input: "Bad input."
server_error: "Server error."
unknown: "Unknown error."
error: "ERROR"
resources:
sessions: "Sessions"

View file

@ -10,13 +10,13 @@ block content
if (noCourseInstance || noCourseInstanceSelected) && course
h1= course.get('name')
if noCourseInstance
p You are not enrolled in this course.
p(data-i18n="courses.not_enrolled")
p
span.spr Please visit the
a.spr(href="/courses") courses
span page to enroll.
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 Select one of your classes
p(data-i18n="courses.select_class")
.container-fluid
.row
.col-md-6
@ -25,13 +25,13 @@ block content
if courseInstance.get('name')
option(value="#{courseInstance.id}")= courseInstance.get('name')
else
option(value="#{courseInstance.id}") *unnamed*
option(value="#{courseInstance.id}", data-i18n="courses.unnamed")
.col-md-6
button.btn.btn-success.btn-select-instance Select
button.btn.btn-success.btn-select-instance(data-i18n="courses.select")
else if !course || !courseInstance
h1 Loading...
h1(data-i18n="common.loading") Loading...
else
h1= courseInstance.get('name') || 'Unnamed Class'
h1= courseInstance.get('name') || ($.i18n.t 'courses.unnamed_class')
small.spl (#{course.get('name')})
p
@ -41,17 +41,17 @@ block content
if adminMode && courseInstance
+settings-dialog
p
button.btn.btn-xs(data-toggle='modal', data-target='#settingsModal') edit class settings
button.btn.btn-xs(data-toggle='modal', data-target='#settingsModal', data-i18n="courses.edit_settings")
div.well.well-sm(role='tabpanel')
ul.nav.nav-pills(role='tablist')
li.active(role='presentation')
a(href='#progress', aria-controls='progress', role='tab', data-toggle='tab') Class Progress
a(href='#progress', aria-controls='progress', role='tab', data-toggle='tab', data-i18n="courses.progress")
if adminMode
li(role='presentation')
a(href='#invite', aria-controls='invite', role='tab', data-toggle='tab') Add Students
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') Levels
a(href='#levels', aria-controls='levels', role='tab', data-toggle='tab', data-i18n="nav.play")
.tab-content
.tab-pane.active#progress(role='tabpanel')
+progress-tab
@ -71,38 +71,38 @@ mixin progress-tab
+progress-members
mixin progress-summary-stats
h3 Statistics
h3(data-i18n="courses.stats")
table.progress-stats-container
tr
td Total students:
td(data-i18n="courses.total_students")
td
if courseInstance
div #{courseInstance.get('members').length}
if instanceStats
tr
td Average level play time:
td(data-i18n="courses.average_time")
if instanceStats.averageLevelPlaytime > 0
td= moment.duration(instanceStats.averageLevelPlaytime, "seconds").humanize()
else
td 0
tr
td Total play time:
td(data-i18n="courses.total_time")
if instanceStats.totalPlayTime > 0
td= moment.duration(instanceStats.totalPlayTime, "seconds").humanize()
else
td 0
tr
td Average levels completed:
td(data-i18n="courses.average_levels")
td #{instanceStats.averageLevelsCompleted.toFixed(2)}
tr
td Total levels completed:
td(data-i18n="courses.total_levels")
td= instanceStats.totalLevelsCompleted
tr
td Furthest level completed:
td(data-i18n="courses.furthest_level")
td= instanceStats.furthestLevelCompleted.replace('Course: ', '')
mixin progress-summary-concepts
h3 Concepts Covered
h3(data-i18n="courses.concepts_covered")
if course && courseInstance && conceptsCompleted
table.progress-concepts-container
each concept in course.get('concepts')
@ -116,29 +116,29 @@ mixin progress-summary-concepts
span - #{conceptCompletion}%
mixin progress-members
h3 Students
h3(data-i18n="courses.students")
table.table.table-condensed
thead
tr
th
span.progress-member-header.spr Name
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 Progress
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 complete
span.progress-key.progress-key-started started
span.progress-key not started
span.progress-key.progress-key-complete(data-i18n="clans.complete_1")
span.progress-key.progress-key-started(data-i18n="clans.started_1")
span.progress-key(data-i18n="clans.not_started_1")
input.progress-expand-checkbox(type='checkbox')
span.spl.progress-expand-label Expand details
span.spl.progress-expand-label(data-i18n="courses.expand_details")
tbody
each memberID in sortedMembers
tr
@ -146,19 +146,19 @@ mixin progress-members
+progress-members-individual(memberID)
td.progress-cell
if showExpandedProgress
.progress-concepts-label Concepts
.progress-concepts-label(data-i18n="courses.concepts")
+progress-members-concepts(memberID)
.progess-levels-label Levels
.progess-levels-label(data-i18n="nav.play")
+progress-members-levels-expanded(memberID)
else
table
tbody
tr
td.progress-concepts-label Concepts
td.progress-concepts-label(data-i18n="courses.concepts")
td.progress-condensed-cell
+progress-members-concepts(memberID)
tr
td.progess-levels-label Levels
td.progess-levels-label(data-i18n="nav.play")
td.progress-condensed-cell
+progress-members-levels-condensed(memberID)
@ -166,8 +166,12 @@ 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 #{memberStats[memberID].totalLevelsCompleted} levels
div Played #{moment.duration(memberStats[memberID].totalPlayTime, "seconds").humanize()}
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]
@ -215,41 +219,49 @@ mixin progress-members-levels-condensed(memberID)
mixin progress-members-popup-completed(i, level)
.progress-popup-container
h3 #{i + 1}. #{level.name.replace('Course: ', '')}
p Play time: #{moment.duration(level.playtime, "seconds").humanize()}
p Completed: #{moment(level.changed).format('MMMM Do YYYY, h:mm:ss a')}
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
strong Click to view solution.
strong(data-i18n="clans.view_solution")
mixin progress-members-popup-started(i, level)
.progress-popup-container
h3 #{i + 1}. #{level.name.replace('Course: ', '')}
p Play time: #{moment.duration(level.playtime, "seconds").humanize()}
p Last played: #{moment(level.changed).format('MMMM Do YYYY, h:mm:ss a')}
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
strong Click to view solution.
strong(data-i18n="clans.view_solution")
mixin invite-tab
p Invite students to join this class.
p(data-i18n="courses.invite_students")
p TODO: Student unlock code
p TODO: Class capacity
textarea.invite-emails(rows=3, placeholder="Enter student emails to invite, one per line")
textarea.invite-emails(rows=3, data-i18n="[placeholder]courses.enter_emails", placeholder="Enter student emails to invite, one per line")
div(style='margin-top:10px;')
button.btn.btn-success.btn-invite Send Invites
button.btn.btn-success.btn-invite(data-i18n="courses.send_invites")
mixin levels-tab
table.table.table-striped.table-condensed
thead
tr
th
th Status
th Level
th Concepts
th(data-i18n="clans.status")
th(data-i18n="resources.level")
th(data-i18n="courses.concepts")
tbody
if campaign
each level, levelID in campaign.get('levels')
tr
td
button.btn.btn-success.btn-play-level(data-level-slug=level.slug) Play
button.btn.btn-success.btn-play-level(data-level-slug=level.slug, data-i18n="home.play")
td
if userLevelStateMap[me.id]
div= userLevelStateMap[me.id][levelID]
@ -266,24 +278,24 @@ mixin settings-dialog
.modal-header
button.close(data-dismiss='modal')
span ×
h3.modal-title Edit Class Settings
h3.modal-title(data-i18n="courses.edit_settings1")
.modal-body
p
strong Title
strong(data-i18n="courses.title")
p
input.settings-name-input(type='text', value="#{courseInstance.get('name') || ''}")
p
strong Description
strong(data-i18n="courses.description")
p
textarea.settings-description-input(rows=2)= courseInstance.get('description')
p Select programming languages available to the class:
p(data-i18n="courses.languages_available")
p
select.form-control.settings-language-select
option(value="Python") Python
option(value="JavaScript") JavaScript
option(value="All Languages") All Languages
option(value="All Languages", data-i18n="courses.all_lang")
p
input.settings-public-progress(type='checkbox', checked)
span.spl Show student progress to everyone in the class
span.spl(data-i18n="courses.show_progress")
.modal-footer
button.btn.btn-save-settings(data-i18n="common.save_changes")

View file

@ -9,67 +9,81 @@ block content
if state === 'declined' || state === 'unknown_error'
p
.alert.alert-danger ERROR #{stateMessage}
.alert.alert-danger
span.spr(data-i18n="loading_error.error")
span #{stateMessage}
if state === 'creating'
p
.alert.alert-info Creating class...
.alert.alert-info(data-i18n="courses.creating_class")
else if state === 'purchasing'
p
.alert.alert-info Purchasing course...
.alert.alert-info(data-i18n="courses.purchasing_course")
else
.well.well-lg.enroll-container
if price > 0
h1.center Buy Course
h1.center(data-i18n="courses.buy_course")
else
h1.center Create Class
h3 1. Course
h1.center(data-i18n="courses.create_class")
h3
span 1.
span.spl(data-i18n="courses.course")
if courses.length > 2
p Select 'All Courses' for a 50% discount!
p(data-i18n="courses.select_all_courses")
.form-group
select.form-control.course-select
each course in courses
option(value="#{course.id}")= course.get('name')
if courses.length > 1
option(value="All Courses") All Courses
option(value="All Courses", data-i18n="courses.all_courses")
h3 2. Number of students
p Enter the number of students you need for this class.
h3
span 2.
span.spl(data-i18n="courses.number_students")
p(data-i18n="courses.enter_number_students")
input.input-seats(type='text', value="#{seats}")
h3 3. Name your class
p This will be displayed on the course page for you and your students. It can be changed later.
h3
span 3.
span.spl(data-i18n="courses.name_class")
p(data-i18n="courses.displayed_course_page")
input.class-name(type='text', placeholder="Mrs. Smith's 4th Period", value="#{className ? className : ''}")
if price > 0
h3 4. Buy
h3
span 4.
span.spl(data-i18n="courses.buy") Buy
else
h3 4. Create Class
h3
span 4.
span.spl(data-i18n="courses.create_class")
p
if price > 0
span.spr You are purchasing a license for
span.spr(data-i18n="courses.purchasing_for")
else
span.spr You are creating a class for
span.spr(data-i18n="courses.creating_for")
strong.spr #{selectedCourseTitle}
span.spr for
strong #{seats} students
| .
p Afterwards you will receive an unlock code to distribute to your students, which they can use to enroll in your class.
span.spr(data-i18n="courses.for")
strong
span #{seats}
span.spl(data-i18n="courses.students1")
span .
p(data-i18n="courses.receive_code")
p.center
if price > 0
button.btn.btn-success.btn-lg.btn-buy $#{(price / 100.0).toFixed(2)}
else
button.btn.btn-success.btn-lg.btn-buy Create Class
button.btn.btn-success.btn-lg.btn-buy(data-i18n="courses.create_class")
+trial-and-questions
mixin trial-and-questions
h3 Free trial for teachers!
h3(data-i18n="courses.free_trial")
p
span.spr Please fill out our
span.spr(data-i18n="teachers.teacher_subs_1")
a(href='/teachers/freetrial', data-i18n="teachers.teacher_subs_2")
span.spl to get individual access to all courses for evalutaion purposes.
span.spl(data-i18n="courses.get_access")
h3 Questions?
h3(data-i18n="courses.questions")
p
span Please contact
span(data-i18n="teachers_survey.contact_1")
a.spl(href='mailto:team@codecombat.com') team@codecombat.com

View file

@ -22,34 +22,34 @@ block content
- i++
mixin student-main
button.btn.btn-warning.btn-teacher Teachers Click Here
h1.center Courses on CodeCombat
button.btn.btn-warning.btn-teacher(data-i18n="courses.teachers_click")
h1.center(data-i18n="courses.courses_on_coco")
mixin teacher-main
button.btn.btn-warning.btn-student Students Click Here
h1.center Courses on CodeCombat
button.btn.btn-warning.btn-student(data-i18n="courses.students_click")
h1.center(data-i18n="courses.courses_on_coco")
.info-container
p Courses are designed to introduce computer science concepts using CodeCombat's fun and engaging environment. CodeCombat levels are organized around key topics to encourage progressive learning, over the course of 5 hours.
p(data-i18n="courses.designed_to")
.container-fluid
.row
.col-md-6
ul
li Learn more in less time
li No coding experience necesssary
li Easily monitor student progress
p Purchase a course for your entire class. It's easy to sign up your students!
li(data-i18n="courses.more_in_less")
li(data-i18n="courses.no_experience")
li(data-i18n="courses.easy_monitor")
p(data-i18n="courses.purchase_for_class")
p.faq-blurb
span.spr See the courses
a.spr.courses-faq FAQ
span for more information.
span.spr(data-i18n="courses.see_the")
a.courses-faq(data-i18n="courses.faq")
span.spl(data-i18n="courses.more_info")
.col-md-6
img.img-quote(src="/images/pages/courses/coco_complab.png")
p
.well.well-sm
div.praise-quote "#{praise.quote}"
div.praise-caption - #{praise.source}
h2.center Choose Your Course:
h2.center(data-i18n="courses.choose_course")
mixin student-dialog(course)
.modal.continue-dialog(id="continueModal#{course.id}")
@ -64,13 +64,13 @@ mixin student-dialog(course)
.col-md-12
.well.well-sm
p
div.instruction-label Enter an unlock code
div.instruction-label(data-i18n="courses.enter_code")
.container-fluid
.row
.col-md-8
input.code-input(type='text', placeholder="Enter unlock code")
input.code-input(type='text', data-i18n="[placeholder]courses.enter_code1", placeholder="Enter unlock code")
.col-md-4
button.btn.btn-success.btn-enroll Enroll
button.btn.btn-success.btn-enroll(data-i18n="courses.enroll")
mixin teacher-dialog(course)
.modal.continue-dialog(id="continueModal#{course.id}")
@ -86,7 +86,7 @@ mixin teacher-dialog(course)
.col-md-12
.well.well-sm
p
div.instruction-label Pick from your current classes
div.instruction-label(data-i18n="courses.pick_from_classes")
.container-fluid
.row
.col-md-8
@ -96,15 +96,15 @@ mixin teacher-dialog(course)
if inst.get('name')
option(value="#{inst.id}")= inst.get('name')
else
option(value="#{inst.id}") *unnamed*
option(value="#{inst.id}", data-i18n="courses.unnamed")
.col-md-4
button.btn.btn-success.btn-enter(data-course-id="#{course.id}") Enter
button.btn.btn-success.btn-enter(data-course-id="#{course.id}", data-i18n="courses.enter")
.row.button-row.center.row-pick-class
.col-md-12
div.or Or
div.or(data-i18n="courses.or")
.row.button-row.center
.col-md-12
button.btn.btn-success.btn-lg.btn-buy(data-course-id="#{course.id}") Buy this course
button.btn.btn-success.btn-lg.btn-buy(data-course-id="#{course.id}", data-i18n="courses.buy_course1")
mixin course-block(course)
if studentMode
@ -125,18 +125,20 @@ mixin course-block(course)
img.course-image(src="#{course.get('screenshot')}")
.row.button-row
.col-md-6
strong Topics
strong(data-i18n="courses.topics")
ul
each concept in course.get('concepts')
li(data-i18n="concepts." + concept)
strong Hours of content: #{course.get('duration')}
strong
span.spr(data-i18n="courses.hours_content")
span #{course.get('duration')}
.col-md-6.center(style='margin-top: 40px;')
if studentMode
if enrolledCourses[course.id]
a.btn.btn-lg.btn-success.btn-continue(href="/courses/#{course.id}?student=true") Continue
a.btn.btn-lg.btn-success.btn-continue(href="/courses/#{course.id}?student=true", data-i18n="common.continue")
else
button.btn.btn-lg.btn-success.btn-continue(data-toggle='modal', data-target="#continueModal#{course.id}") Enter
button.btn.btn-lg.btn-success.btn-continue(data-toggle='modal', data-target="#continueModal#{course.id}", data-i18n="courses.enter") Enter
else if enrolledCourses[course.id]
button.btn.btn-lg.btn-success.btn-continue(data-toggle='modal', data-target="#continueModal#{course.id}") Continue
button.btn.btn-lg.btn-success.btn-continue(data-toggle='modal', data-target="#continueModal#{course.id}", data-i18n="common.continue")
else
button.btn.btn-lg.btn-success.btn-buy(data-course-id="#{course.id}") #{course.get('pricePerSeat') === 0 ? 'Get FREE course' : 'Buy course'}
button.btn.btn-lg.btn-success.btn-buy(data-course-id="#{course.id}") #{course.get('pricePerSeat') === 0 ? $.i18n.t('courses.get_free') : $.i18n.t('courses.buy_course')}

View file

@ -45,10 +45,10 @@ module.exports = class CoursesView extends RootView
@enrolledCourses[courseInstance.get('courseID')] = true for courseInstance in @courseInstances.models
setupCoursesFAQPopover: ->
popoverTitle = "<h3>Courses FAQ<button type='button' class='close' onclick='$(&#39;.courses-faq&#39;).popover(&#39;hide&#39;);'>&times;</button></h3>"
popoverContent = "<p><strong>Q:</strong> What's the difference between these courses and the single player game?</p>"
popoverContent += "<p><strong>A:</strong> The single player game is designed for individuals, while the courses are designed for classes.</p>"
popoverContent += "<p>The single player game has items, gems, hero selection, leveling up, and in-app purchases. Courses have classroom management features and streamlined student-focused level pacing.</p>"
popoverTitle = "<h3>" + $.i18n.t('courses.faq') + "<button type='button' class='close' onclick='$(&#39;.courses-faq&#39;).popover(&#39;hide&#39;);'>&times;</button></h3>"
popoverContent = "<p><strong>" + $.i18n.t('courses.question') + "</strong> " + $.i18n.t('courses.question1') + "</p>"
popoverContent += "<p><strong>" + $.i18n.t('courses.answer') + "</strong> " + $.i18n.t('courses.answer1') + "</p>"
popoverContent += "<p>" + $.i18n.t('courses.answer2') + "</p>"
@$el.find('.courses-faq').popover(
animation: true
html: true