mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-23 23:58:02 -05:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
66650452b2
14 changed files with 224 additions and 172 deletions
|
@ -96,6 +96,8 @@ module.exports = class CocoRouter extends Backbone.Router
|
|||
|
||||
'github/*path': 'routeToServer'
|
||||
|
||||
'hoc': go('courses/CoursesView')
|
||||
|
||||
'i18n': go('i18n/I18NHomeView')
|
||||
'i18n/thang/:handle': go('i18n/I18NEditThangTypeView')
|
||||
'i18n/component/:handle': go('i18n/I18NEditComponentView')
|
||||
|
|
|
@ -913,7 +913,7 @@
|
|||
see_the: "See the"
|
||||
more_info: "for more information."
|
||||
choose_course: "Choose Your Course:"
|
||||
enter_code: "Enter an unlock code"
|
||||
enter_code: "Enter an unlock code to join an existing class" # {change}
|
||||
enter_code1: "Enter unlock code"
|
||||
enroll: "Enroll"
|
||||
pick_from_classes: "Pick from your current classes"
|
||||
|
|
|
@ -304,7 +304,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
|
|||
tip_morale_improves: "在士气提升之前会一直进行加载。"
|
||||
tip_all_species: "我们相信每一个人都有同等的机会学习编程"
|
||||
tip_reticulating: "网格状锯齿。(指Maxis开发的许多游戏,如《模拟城市》、《孢子》中,加载进程中跑动时出现的卡顿现象)"
|
||||
tip_harry: "巫师, "
|
||||
tip_harry: "你是一名巫师, "
|
||||
tip_great_responsibility: "更强的编程技巧也意味着有更高的责任来进行调试。"
|
||||
tip_munchkin: "如果您不吃掉您的蔬菜, 一个小矮人将在您睡着之后来找您。"
|
||||
tip_binary: "这个世界上只有10种人: 那些懂二进制的, 还有那些不懂二进制的。"
|
||||
|
@ -464,7 +464,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
|
|||
was_free_until: "您有过一个免费订阅,直到"
|
||||
managed_subs: "管理订阅"
|
||||
managed_subs_desc: "为其他玩家(学生、儿童等)添加订阅。"
|
||||
managed_subs_desc_2: "收件人必须有一个与您提供的电子邮件地址相关联的codecombat帐户。"
|
||||
managed_subs_desc_2: "收件人必须有一个与您提供的电子邮件地址相关联的CodeCombat帐户。"
|
||||
group_discounts: "团购价"
|
||||
group_discounts_1: "我们还为批量订阅提供团购价"
|
||||
group_discounts_1st: "1个订阅"
|
||||
|
@ -673,7 +673,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
|
|||
under: "低于"
|
||||
other: "其他:"
|
||||
amount_students: "请问您有多少学生需要教导?"
|
||||
hear_about: "您是怎么知道CodeComabat的?"
|
||||
hear_about: "您是怎么知道CodeCombat的?"
|
||||
fill_fields: "请填写所有问题。"
|
||||
thanks: "非常感谢!我们会很快寄给您设置说明。"
|
||||
|
||||
|
@ -1207,7 +1207,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
|
|||
recently_played: "最近玩过的关卡"
|
||||
no_recent_games: "最近两个星期没有玩过游戏。"
|
||||
payments: "支付方式"
|
||||
# prepaid: "Prepaid"
|
||||
prepaid: "预付费"
|
||||
purchased: "已购买"
|
||||
sale: "促销"
|
||||
subscription: "订阅"
|
||||
|
|
|
@ -602,7 +602,7 @@ module.exports = nativeDescription: "繁體中文", englishDescription: "Chinese
|
|||
intro_2: "無需經驗!"
|
||||
free_title: "要多少錢?"
|
||||
cost_china: "CodeCombat的前5個關卡在中國是免費的,在這之後需花費每月9.99美元來訪問我們架設在中國專屬服務器上的190多個關卡。" # Deprecated
|
||||
# cost_premium_server: "CodeCombat is free for the first five levels, after which it costs $9.99 USD per month for access to our other 190+ levels on our exclusive country-specific servers."
|
||||
cost_premium_server: "CodeCombat的前5個關卡在中國是免費的,在這之後需花費每月9.99美元來訪問我們架設在中國專屬服務器上的190多個關卡。"
|
||||
free_1: "有110多個覆蓋了所有理論的免費關卡。"
|
||||
free_2: "包月訂閱可以訪問視頻教程和額外的練習關卡。"
|
||||
teacher_subs_title: "教師可免費訂閱!"
|
||||
|
@ -673,7 +673,7 @@ module.exports = nativeDescription: "繁體中文", englishDescription: "Chinese
|
|||
under: "低於"
|
||||
other: "其他:"
|
||||
amount_students: "請問您有多少學生需要教導?"
|
||||
hear_about: "您是怎麼知道CodeComabat的?"
|
||||
hear_about: "您是怎麼知道CodeCombat的?"
|
||||
fill_fields: "請填寫所有問題。"
|
||||
thanks: "非常感謝!我們會很快寄給您設置說明。"
|
||||
|
||||
|
@ -835,93 +835,94 @@ module.exports = nativeDescription: "繁體中文", englishDescription: "Chinese
|
|||
last_played: "最後玩了"
|
||||
leagues_explanation: "在部落裡與其他成員組成聯盟一起參加下面的多人競技場。"
|
||||
|
||||
# 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."
|
||||
# invite_link_header: "Link to join course"
|
||||
# invite_link_p_1: "Give this link to students you would like to have join the course."
|
||||
# invite_link_p_2: "Or have us email them directly:"
|
||||
# capacity_used: "Course slots used:"
|
||||
# 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"
|
||||
|
||||
courses:
|
||||
course: "課程"
|
||||
courses: "課程"
|
||||
not_enrolled: "您没有註冊這一節課。"
|
||||
visit_pref: "請到這個"
|
||||
visit_suf: "網頁註冊。"
|
||||
select_class: "請選其中一門課堂"
|
||||
unnamed: "*未命名*"
|
||||
select: "選擇"
|
||||
unnamed_class: "課堂未命名"
|
||||
edit_settings: "編輯課堂設定"
|
||||
edit_settings1: "編輯課堂設定"
|
||||
progress: "課堂進度"
|
||||
add_students: "添加學生"
|
||||
stats: "統計"
|
||||
total_students: "學生人數:"
|
||||
average_time: "平均遊戲時間:"
|
||||
total_time: "總計遊戲時間:"
|
||||
average_levels: "平均完成關卡:"
|
||||
total_levels: "總共完成關卡:"
|
||||
furthest_level: "最高關卡完成:"
|
||||
concepts_covered: "課目覆蓋"
|
||||
students: "學生"
|
||||
students1: "個學生。"
|
||||
expand_details: "展開細節"
|
||||
concepts: "課目"
|
||||
levels: "關卡"
|
||||
played: "已通關"
|
||||
play_time: "遊戲時間:"
|
||||
completed: "遊戲時間:"
|
||||
invite_students: "邀請學生加入此課堂。"
|
||||
invite_link_header: "參與課堂的縺結"
|
||||
invite_link_p_1: "把這個參與課堂的連結發給你認可的學生。" # there has few problem of my translation
|
||||
invite_link_p_2: "或讓我們代你直接發送電郵:"
|
||||
capacity_used: "Course slots used:"
|
||||
enter_emails: "輸入學生電郵地址來邀請,每行一個"
|
||||
send_invites: "發送邀請"
|
||||
title: "發送邀請"
|
||||
description: "描述"
|
||||
languages_available: "選擇編程語言:"
|
||||
all_lang: "所有編程語言"
|
||||
show_progress: "向所有該課堂的人展示學生的進度"
|
||||
creating_class: "課堂創建中···"
|
||||
purchasing_course: "購買課程中···"
|
||||
buy_course: "購買課程"
|
||||
buy_course1: "購買這個課程"
|
||||
create_class: "創建課堂"
|
||||
select_all_courses: "可半價一次購買所有課程!"
|
||||
all_courses: "所有課程"
|
||||
number_students: "學生人數"
|
||||
enter_number_students: "輪入該課堂的學生上限人數"
|
||||
name_class: "命名您的課堂"
|
||||
displayed_course_page: "這將會在課程頁面顯示,可被修改。"
|
||||
buy: "購買"
|
||||
purchasing_for: "你正在購買許可證,課程為"
|
||||
creating_for: "您正在創建一個課程為"
|
||||
for: ",人數上限為" # Like in 'for 30 students'
|
||||
receive_code: "然後您會收到一個解鎖碼,把它分發給你的學生用來註冊你的課堂。"
|
||||
free_trial: "老師可免費試用!"
|
||||
get_access: "獲得個人使用權在評估目的下來使用所有課程。"
|
||||
questions: "有疑問?"
|
||||
faq: "課程FAQ"
|
||||
question: "問:" # Like in 'Question'
|
||||
question1: "這些課程和單人遊戲之間的有什麼區別?"
|
||||
answer: "答:" # Like in 'Answer'
|
||||
answer1: "單人遊戲是專為個人而設,而課程是專為課堂而設。"
|
||||
answer2: "在單人遊戲中有物品、寶石、英雄選擇、練級、和內購應用。課程有課堂管理功能,和老師可根據學生的水平而調整教學進度。"
|
||||
teachers_click: "老師點擊這裡"
|
||||
students_click: "學生點擊這裡"
|
||||
courses_on_coco: "CodeCombat上的課程"
|
||||
designed_to: "CodeCombat課程的宗旨是在使用CodeCombat生動有趣的環境下教授計算機科學的課目。整個CodeCombat的關卡是圍繞著計算機科學的重點並激勵學生們自主向上學習在5小時的過程。"
|
||||
more_in_less: "以最少的時間學習最多的知識"
|
||||
no_experience: "無需編程經驗"
|
||||
easy_monitor: "容易管理學生的進程"
|
||||
purchase_for_class: "為你的班級購買CodeCombat課程,讓簽到和管理變得更容易!"
|
||||
see_the: "詳細資訊請看"
|
||||
more_info: "。"
|
||||
choose_course: "選擇您的課程:"
|
||||
enter_code: "輸入一個解銷碼"
|
||||
enter_code1: "輸入解銷碼"
|
||||
enroll: "註冊"
|
||||
pick_from_classes: "從目前的課程選擇"
|
||||
enter: "輪入"
|
||||
or: "或"
|
||||
topics: "題目"
|
||||
hours_content: "內容時間:"
|
||||
get_free: "取得免費課程!"
|
||||
|
||||
classes:
|
||||
archmage_title: "大法師"
|
||||
|
@ -1207,7 +1208,7 @@ module.exports = nativeDescription: "繁體中文", englishDescription: "Chinese
|
|||
recently_played: "最近玩過"
|
||||
no_recent_games: "在過去兩個星期沒有玩過遊戲。"
|
||||
payments: "付款"
|
||||
# prepaid: "Prepaid"
|
||||
prepaid: "充值"
|
||||
purchased: "已購買"
|
||||
sale: "促銷"
|
||||
subscription: "訂閱"
|
||||
|
@ -1238,13 +1239,13 @@ module.exports = nativeDescription: "繁體中文", englishDescription: "Chinese
|
|||
retrying: "服務器錯誤,重試中。"
|
||||
success: "支付成功。謝謝!"
|
||||
|
||||
# account_prepaid:
|
||||
# purchase_code: "Purchase a Subscription Code"
|
||||
# purchase_amount: "Amount"
|
||||
# purchase_total: "Total"
|
||||
# purchase_button: "Submit Purchase"
|
||||
# your_codes: "Your Codes:"
|
||||
# redeem_codes: "Redeem a Subscription Code"
|
||||
account_prepaid:
|
||||
purchase_code: "購買訂閱碼"
|
||||
purchase_amount: "數量"
|
||||
purchase_total: "總共"
|
||||
purchase_button: "提交購買"
|
||||
your_codes: "你的訂閱碼:"
|
||||
redeem_codes: "兌換訂閱碼"
|
||||
|
||||
loading_error:
|
||||
could_not_load: "從伺服器載入失敗"
|
||||
|
@ -1258,7 +1259,7 @@ module.exports = nativeDescription: "繁體中文", englishDescription: "Chinese
|
|||
bad_input: "錯誤輸入。"
|
||||
server_error: "伺服器錯誤。"
|
||||
unknown: "未知錯誤。"
|
||||
# error: "ERROR"
|
||||
error: "錯誤"
|
||||
|
||||
resources:
|
||||
sessions: "會話"
|
||||
|
|
|
@ -25,9 +25,6 @@
|
|||
margin-bottom: 20px
|
||||
font-size: 14pt
|
||||
|
||||
.btn-enroll
|
||||
margin-top: 20px
|
||||
|
||||
.center
|
||||
text-align: center
|
||||
|
||||
|
|
|
@ -15,24 +15,54 @@ block content
|
|||
if state === 'unknown_error'
|
||||
.alert.alert-danger.alert-dismissible= stateMessage
|
||||
|
||||
if studentMode
|
||||
+student-main
|
||||
if hocLandingPage
|
||||
+hoc-landing
|
||||
else
|
||||
+teacher-main
|
||||
.container-fluid
|
||||
- var i = 0
|
||||
while i < courses.length
|
||||
.row
|
||||
+course-block(courses[i], instances)
|
||||
- i++
|
||||
if i < courses.length
|
||||
if studentMode
|
||||
+student-main
|
||||
else
|
||||
if hocMode
|
||||
+teacher-hoc
|
||||
else
|
||||
+teacher-main
|
||||
.container-fluid
|
||||
- var i = 0
|
||||
while i < courses.length
|
||||
.row
|
||||
+course-block(courses[i], instances)
|
||||
- i++
|
||||
if i < courses.length
|
||||
+course-block(courses[i], instances)
|
||||
- i++
|
||||
|
||||
mixin hoc-landing
|
||||
h1.center Welcome Hour of Code!
|
||||
br
|
||||
.container-fluid
|
||||
.row
|
||||
.col-md-6.center
|
||||
button.btn.btn-lg.btn-success.btn-student(data-i18n="courses.students_click")
|
||||
.col-md-6.center
|
||||
button.btn.btn-lg.btn-default.btn-teacher(data-i18n="courses.teachers_click")
|
||||
|
||||
mixin student-main
|
||||
button.btn.btn-warning.btn-teacher(data-i18n="courses.teachers_click")
|
||||
h1.center(data-i18n="courses.courses_on_coco")
|
||||
|
||||
mixin teacher-hoc
|
||||
button.btn.btn-warning.btn-student(data-i18n="courses.students_click")
|
||||
h1.center Welcome Hour of Code!
|
||||
p
|
||||
strong How to use CodeCombat with your students:
|
||||
ol
|
||||
li Click the green 'Get FREE course' button below
|
||||
li Follow the enrollment instructions
|
||||
li Add students via the 'Add Students' tab
|
||||
p
|
||||
span.spr If you have any problems, please email
|
||||
a(href='mailto:team@codecombat.com') team@codecombat.com
|
||||
br
|
||||
|
||||
mixin teacher-main
|
||||
button.btn.btn-warning.btn-student(data-i18n="courses.students_click")
|
||||
h1.center(data-i18n="courses.courses_on_coco")
|
||||
|
@ -87,6 +117,14 @@ mixin student-dialog(course)
|
|||
input.code-input(type='text', data-course-id="#{course.id}", data-i18n="[placeholder]courses.enter_code1", placeholder="Enter unlock code")
|
||||
.col-md-4
|
||||
button.btn.btn-success.btn-enroll(data-course-id="#{course.id}", data-i18n="courses.enroll")
|
||||
if hocMode && course.get('pricePerSeat') === 0
|
||||
.row.button-row.center.row-pick-class
|
||||
.col-md-12
|
||||
br
|
||||
div.or(data-i18n="courses.or")
|
||||
.row.button-row.center
|
||||
.col-md-12
|
||||
button.btn.btn-success.btn-lg.btn-hoc-student-continue(data-course-id="#{course.id}") Continue by yourself
|
||||
|
||||
mixin teacher-dialog(course)
|
||||
.modal.continue-dialog(id="continueModal#{course.id}")
|
||||
|
|
|
@ -2,37 +2,24 @@ extends /templates/base
|
|||
|
||||
block content
|
||||
|
||||
h2(style='color:#CC0000;') Try CodeCombat Courses!
|
||||
p
|
||||
strong What are CodeCombat Courses?
|
||||
h2 Hour of Code(Combat)
|
||||
p
|
||||
a.spr(href='/courses') Courses
|
||||
span organize the same great levels into groups. They make it easier for you to manage a class of students and monitor their progress.
|
||||
strong Hi Teachers!
|
||||
p We're excited to participate in Hour of Code this year!
|
||||
p We've set up an Introduction to Computer Science course, just for you.
|
||||
p
|
||||
strong How to use them:
|
||||
strong How to use CodeCombat with your students:
|
||||
ol
|
||||
li
|
||||
span.spr Navigate to the
|
||||
a.spr(href='/courses') Courses
|
||||
a.spr(href='/courses/teachers?hoc=true') Courses
|
||||
span page
|
||||
li Click the green 'Get FREE course' button
|
||||
li Click the green 'Get FREE course' button under Introduction to Computer Science
|
||||
li Follow the enrollment instructions
|
||||
li Add students via the 'Add Students' tab
|
||||
p
|
||||
strong We Need Your Help!
|
||||
p Courses are still in early development, and we need your feedback to make them great for the classroom.
|
||||
p
|
||||
strong How you can help:
|
||||
ul
|
||||
li
|
||||
spa.spr Spend 5 minutes checking out
|
||||
a.spr(href='/courses') Courses
|
||||
li Enroll in a course and add a student
|
||||
li Monitor a group of students working through the first course
|
||||
p
|
||||
span.spr Send your feedback to
|
||||
span.spr If you have any problems, please email
|
||||
a(href='mailto:team@codecombat.com') team@codecombat.com
|
||||
p Thanks!
|
||||
br
|
||||
|
||||
h2 More Info for Teachers
|
||||
|
|
|
@ -37,10 +37,7 @@ module.exports = class PrepaidView extends RootView
|
|||
@updateTotal()
|
||||
|
||||
@codes = new CocoCollection([], { url: '/db/user/'+me.id+'/prepaid_codes', model: Prepaid })
|
||||
@codes.on 'add', (code) =>
|
||||
@render?()
|
||||
@codes.on 'sync', (code) =>
|
||||
@render?()
|
||||
@codes.on 'sync', (code) => @render?()
|
||||
@supermodel.loadCollection(@codes, 'prepaid', {cache: false})
|
||||
|
||||
@ppc = utils.getQueryVariable('_ppc') ? ''
|
||||
|
|
|
@ -30,7 +30,7 @@ module.exports = class TrialRequestsView extends RootView
|
|||
-1
|
||||
else
|
||||
1
|
||||
@trialRequests = new CocoCollection([], { url: '/db/trial.request', model: TrialRequest, comparator: sortRequests })
|
||||
@trialRequests = new CocoCollection([], { url: '/db/trial.request?conditions[sort]=-_id&conditions[limit]=500', model: TrialRequest, comparator: sortRequests })
|
||||
@supermodel.loadCollection(@trialRequests, 'trial-requests', {cache: false})
|
||||
|
||||
getRenderData: ->
|
||||
|
|
|
@ -7,6 +7,8 @@ RootView = require 'views/core/RootView'
|
|||
template = require 'templates/courses/courses'
|
||||
utils = require 'core/utils'
|
||||
|
||||
# TODO: Hour of Code (HoC) integration is a mess
|
||||
|
||||
module.exports = class CoursesView extends RootView
|
||||
id: 'courses-view'
|
||||
template: template
|
||||
|
@ -15,12 +17,15 @@ module.exports = class CoursesView extends RootView
|
|||
'click .btn-buy': 'onClickBuy'
|
||||
'click .btn-enroll': 'onClickEnroll'
|
||||
'click .btn-enter': 'onClickEnter'
|
||||
'click .btn-hoc-student-continue': 'onClickHocStudentContinue'
|
||||
'click .btn-student': 'onClickStudent'
|
||||
'click .btn-teacher': 'onClickTeacher'
|
||||
|
||||
constructor: (options) ->
|
||||
super(options)
|
||||
@praise = utils.getCoursePraise()
|
||||
@hocLandingPage = Backbone.history.getFragment()?.indexOf('hoc') >= 0
|
||||
@hocMode = utils.getQueryVariable('hoc', false)
|
||||
@studentMode = Backbone.history.getFragment()?.indexOf('courses/students') >= 0
|
||||
@courses = new CocoCollection([], { url: "/db/course", model: Course})
|
||||
@supermodel.loadCollection(@courses, 'courses')
|
||||
|
@ -38,6 +43,8 @@ module.exports = class CoursesView extends RootView
|
|||
context = super()
|
||||
context.courses = @courses.models ? []
|
||||
context.enrolledCourses = @enrolledCourses ? {}
|
||||
context.hocLandingPage = @hocLandingPage
|
||||
context.hocMode = @hocMode
|
||||
context.instances = @courseInstances.models ? []
|
||||
context.praise = @praise
|
||||
context.state = @state
|
||||
|
@ -95,14 +102,58 @@ module.exports = class CoursesView extends RootView
|
|||
navigationEvent = route: route, viewClass: viewClass, viewArgs: viewArgs
|
||||
Backbone.Mediator.publish 'router:navigate', navigationEvent
|
||||
|
||||
onClickHocStudentContinue: (e) ->
|
||||
$('.continue-dialog').modal('hide')
|
||||
return @openModalView new AuthModal() if me.isAnonymous()
|
||||
courseID = $(e.target).data('course-id')
|
||||
|
||||
@state = 'enrolling'
|
||||
@stateMessage = undefined
|
||||
@render?()
|
||||
|
||||
# TODO: Copied from CourseEnrollView
|
||||
|
||||
data =
|
||||
name: 'Single Player'
|
||||
seats: 9999
|
||||
courseID: courseID
|
||||
jqxhr = $.post('/db/course_instance/-/create', data)
|
||||
jqxhr.done (data, textStatus, jqXHR) =>
|
||||
application.tracker?.trackEvent 'Finished HoC student course creation', {courseID: courseID}
|
||||
# TODO: handle fetch errors
|
||||
me.fetch(cache: false).always =>
|
||||
courseID = courseID
|
||||
route = "/courses/#{courseID}"
|
||||
viewArgs = [{}, courseID]
|
||||
if data?.length > 0
|
||||
courseInstanceID = data[0]._id
|
||||
route += "/#{courseInstanceID}"
|
||||
viewArgs[0].courseInstanceID = courseInstanceID
|
||||
Backbone.Mediator.publish 'router:navigate',
|
||||
route: route
|
||||
viewClass: 'views/courses/CourseDetailsView'
|
||||
viewArgs: viewArgs
|
||||
jqxhr.fail (xhr, textStatus, errorThrown) =>
|
||||
console.error 'Got an error purchasing a course:', textStatus, errorThrown
|
||||
application.tracker?.trackEvent 'Failed HoC student course creation', status: textStatus
|
||||
if xhr.status is 402
|
||||
@state = 'declined'
|
||||
@stateMessage = arguments[2]
|
||||
else
|
||||
@state = 'unknown_error'
|
||||
@stateMessage = "#{xhr.status}: #{xhr.responseText}"
|
||||
@render?()
|
||||
|
||||
onClickStudent: (e) ->
|
||||
route = "/courses/students"
|
||||
route += "?hoc=true" if @hocLandingPage or @hocMode
|
||||
viewClass = require 'views/courses/CoursesView'
|
||||
navigationEvent = route: route, viewClass: viewClass, viewArgs: []
|
||||
Backbone.Mediator.publish 'router:navigate', navigationEvent
|
||||
|
||||
onClickTeacher: (e) ->
|
||||
route = "/courses/teachers"
|
||||
route += "?hoc=true" if @hocLandingPage or @hocMode
|
||||
viewClass = require 'views/courses/CoursesView'
|
||||
navigationEvent = route: route, viewClass: viewClass, viewArgs: []
|
||||
Backbone.Mediator.publish 'router:navigate', navigationEvent
|
||||
|
|
|
@ -179,21 +179,18 @@ module.exports = class Handler
|
|||
# if it's not a text search but the user is an admin, let him try stuff anyway
|
||||
else if req.user?.isAdmin()
|
||||
# admins can send any sort of query down the wire
|
||||
# Example URL: http://localhost:3000/db/user?filter[anonymous]=true
|
||||
filter = {}
|
||||
filter[key] = (val for own key, val of req.query.filter when key not in specialParameters) if 'filter' of req.query
|
||||
|
||||
filter[key] = JSON.parse(val) for own key, val of req.query.filter when key not in specialParameters if 'filter' of req.query
|
||||
query = @modelClass.find(filter)
|
||||
|
||||
# Conditions are chained query functions, for example: query.find().limit(20).sort('-dateCreated')
|
||||
conditions = JSON.parse(req.query.conditions || '[]')
|
||||
# Example URL: http://localhost:3000/db/user?conditions[limit]=20&conditions[sort]=-dateCreated
|
||||
hasLimit = false
|
||||
try
|
||||
for condition in conditions
|
||||
name = condition[0]
|
||||
f = query[name]
|
||||
args = condition[1..]
|
||||
query = query[name](args...)
|
||||
hasLimit ||= f is 'limit'
|
||||
for own key, val of req.query.conditions
|
||||
query = query[key](val)
|
||||
hasLimit ||= key is 'limit'
|
||||
catch e
|
||||
return @sendError(res, 422, 'Badly formed conditions.')
|
||||
query.limit(2000) unless hasLimit
|
||||
|
|
|
@ -53,7 +53,6 @@ config.mail =
|
|||
username: process.env.COCO_MAIL_SERVICE_USERNAME or ''
|
||||
supportPrimary: process.env.COCO_MAIL_SUPPORT_PRIMARY or ''
|
||||
supportPremium: process.env.COCO_MAIL_SUPPORT_PREMIUM or ''
|
||||
username: process.env.COCO_MAIL_SERVICE_USERNAME or ''
|
||||
mailchimpAPIKey: process.env.COCO_MAILCHIMP_API_KEY or ''
|
||||
mailchimpWebhook: process.env.COCO_MAILCHIMP_WEBHOOK or '/mail/webhook'
|
||||
sendwithusAPIKey: process.env.COCO_SENDWITHUS_API_KEY or ''
|
||||
|
|
|
@ -86,7 +86,6 @@ setupCountryRedirectMiddleware = (app, country="china", countryCode="CN", langua
|
|||
ip = req.headers['x-forwarded-for'] or req.connection.remoteAddress
|
||||
ip = ip?.split(/,? /)[0] # If there are two IP addresses, say because of CloudFlare, we just take the first.
|
||||
geo = geoip.lookup(ip)
|
||||
geo = country: 'CN'
|
||||
#if speaksLanguage or geo?.country is countryCode
|
||||
# log.info("Should we redirect to #{serverID} server? speaksLanguage: #{speaksLanguage}, firstLanguage: #{firstLanguage}, ip: #{ip}, geo: #{geo} -- so redirecting? #{geo?.country is 'CN' and speaksLanguage}")
|
||||
return geo?.country is countryCode and speaksLanguage
|
||||
|
|
|
@ -269,20 +269,10 @@ describe 'GET /db/user', ->
|
|||
expect(body.type).toBeDefined()
|
||||
done()
|
||||
|
||||
it 'is able to do a sweet query', (done) ->
|
||||
conditions = [
|
||||
['limit', 20]
|
||||
['where', 'email']
|
||||
['equals', 'admin@afc.com']
|
||||
['sort', '-dateCreated']
|
||||
]
|
||||
it 'is able to do a semi-sweet query', (done) ->
|
||||
options = {
|
||||
url: getURL(urlUser)
|
||||
qs: {
|
||||
conditions: JSON.stringify(conditions)
|
||||
}
|
||||
url: getURL(urlUser) + "?conditions[limit]=20&conditions[sort]=-dateCreated"
|
||||
}
|
||||
|
||||
req = request.get(options, (error, response) ->
|
||||
expect(response.statusCode).toBe(200)
|
||||
res = JSON.parse(response.body)
|
||||
|
@ -291,14 +281,8 @@ describe 'GET /db/user', ->
|
|||
)
|
||||
|
||||
it 'rejects bad conditions', (done) ->
|
||||
conditions = [
|
||||
['lime', 20]
|
||||
]
|
||||
options = {
|
||||
url: getURL(urlUser)
|
||||
qs: {
|
||||
conditions: JSON.stringify(conditions)
|
||||
}
|
||||
url: getURL(urlUser) + "?conditions[lime]=20&conditions[sort]=-dateCreated"
|
||||
}
|
||||
|
||||
req = request.get(options, (error, response) ->
|
||||
|
|
Loading…
Reference in a new issue