Merge branch 'master' into production

This commit is contained in:
phoenixeliot 2016-06-02 12:53:23 -07:00
commit 6424a52837
6 changed files with 113 additions and 73 deletions

View file

@ -735,7 +735,7 @@ module.exports = nativeDescription: "Tiếng Việt", englishDescription: "Vietn
mission_description_1: "<strong>Lập trình thật kì diệu</strong>. Bạn có thể tạo ra một thứ gì đó chỉ từ trí tưởng tượng. Chúng tôi bắt đầu CodeCombat để đem tới cho học viên những trải nghiệm nhiệm màu khi <strong>viết code</strong> thực tế." mission_description_1: "<strong>Lập trình thật kì diệu</strong>. Bạn có thể tạo ra một thứ gì đó chỉ từ trí tưởng tượng. Chúng tôi bắt đầu CodeCombat để đem tới cho học viên những trải nghiệm nhiệm màu khi <strong>viết code</strong> thực tế."
mission_description_2: "Trên thực tế, việc này giúp cho bạn học nhanh hơn. Nhanh hơn RẤT NHIỀU. Bạn được thực hành thay vì chỉ đọc lý thuyết. Chúng tôi muốn đưa môi trường thực hành này đến với trường học và đến tay <strong>mọi học sinh</strong>, bởi vì mọi người đều cần có cơ hội biết đến sự nhiệm màu của lập trình." mission_description_2: "Trên thực tế, việc này giúp cho bạn học nhanh hơn. Nhanh hơn RẤT NHIỀU. Bạn được thực hành thay vì chỉ đọc lý thuyết. Chúng tôi muốn đưa môi trường thực hành này đến với trường học và đến tay <strong>mọi học sinh</strong>, bởi vì mọi người đều cần có cơ hội biết đến sự nhiệm màu của lập trình."
team_title: "Đội ngũ của CodeCombat" team_title: "Đội ngũ của CodeCombat"
# 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." team_values: "Chúng tôi chân trọng những cuộc đối thoại mở và có sự tôn trọng lẫn nhau, nơi mà những ý tưởng tốt nhất giành chiến thắng. Những quyết định của chúng tôi được đưa ra hoàn toàn dựa trên những báo cáo nghiên cứu ý kiến khách hàng và quy trình của chúng tôi chú trọng vào mục tiêu đưa đến những giá trị hữu hình cho cho khách hàng. Mọi người đều có vai trò của mình, từ CEO của chúng tôi cho đến những người tham gia công đồng trên Github, bởi vì chúng tôi chân trọng sự phát triển và học hỏi của từng thành viên trong nhóm."
nick_title: "Đồng Sáng Lập, CEO" # {change} nick_title: "Đồng Sáng Lập, CEO" # {change}
nick_blurb: "Người truyền cảm hứng" nick_blurb: "Người truyền cảm hứng"
matt_title: "Đồng Sáng Lập, CTO" # {change} matt_title: "Đồng Sáng Lập, CTO" # {change}
@ -853,10 +853,10 @@ module.exports = nativeDescription: "Tiếng Việt", englishDescription: "Vietn
college_plus: "Cao đẳng/Đại học hoặc cao hơn" college_plus: "Cao đẳng/Đại học hoặc cao hơn"
anything_else: "Còn điều gì chúng tôi nên biết thêm nữa không?" anything_else: "Còn điều gì chúng tôi nên biết thêm nữa không?"
thanks_header: "Đã nhận yêu cầu!" thanks_header: "Đã nhận yêu cầu!"
# thanks_sub_header: "Thanks for expressing interest in CodeCombat for your school." thanks_sub_header: "Cảm ơn vì đã bày tỏ sự quan tâm của trường bạn với CodeCombat."
thanks_p: "Chúng tôi sẽ sớm trả lời lại! Nếu bạn cần liên hệ, hãy liên lạc với chúng tôi tại:" thanks_p: "Chúng tôi sẽ sớm trả lời lại! Nếu bạn cần liên hệ, hãy liên lạc với chúng tôi tại:"
# back_to_classes: "Back to Classes" back_to_classes: "Quay lại Lớp học"
# finish_signup: "Finish creating your teacher account:" finish_signup: "Hoàn thiện tài khoản giáo viên:"
# finish_signup_p: "Create an account to set up a class, add your students, and monitor their progress as they learn computer science." # finish_signup_p: "Create an account to set up a class, add your students, and monitor their progress as they learn computer science."
signup_with: "Đăng ký bằng:" signup_with: "Đăng ký bằng:"
connect_with: "Kết nối với:" connect_with: "Kết nối với:"
@ -866,7 +866,7 @@ module.exports = nativeDescription: "Tiếng Việt", englishDescription: "Vietn
# create_account_subtitle: "Get access to teacher-only tools for using CodeCombat in the classroom. <strong>Set up a class</strong>, add your students, and <strong>monitor their progress</strong>!" # create_account_subtitle: "Get access to teacher-only tools for using CodeCombat in the classroom. <strong>Set up a class</strong>, add your students, and <strong>monitor their progress</strong>!"
convert_account_title: "Năng cấp lên tài khoản Giáo Viên" convert_account_title: "Năng cấp lên tài khoản Giáo Viên"
not: "Không phải" not: "Không phải"
# setup_a_class: "Set Up a Class" setup_a_class: "Thiết lập một Lớp học"
versions: versions:
save_version_title: "Lưu phiên bản mới" save_version_title: "Lưu phiên bản mới"
@ -922,10 +922,10 @@ module.exports = nativeDescription: "Tiếng Việt", englishDescription: "Vietn
email_announcements: "Thông báo" email_announcements: "Thông báo"
email_announcements_description: "Nhận email về tin tức mới nhất và sự phát triển của Codecombat." email_announcements_description: "Nhận email về tin tức mới nhất và sự phát triển của Codecombat."
email_notifications: "Thông báo" email_notifications: "Thông báo"
# email_notifications_summary: "Controls for personalized, automatic email notifications related to your CodeCombat activity." email_notifications_summary: "Kiểm soát các thông báo cá nhân tự động liên quan đến các hoạt động của CodeCombat."
# email_any_notes: "Any Notifications" email_any_notes: "Bất kỳ thông báo nào"
# email_any_notes_description: "Disable to stop all activity notification emails." email_any_notes_description: "Vô hiệu hóa để ngừng mọi thông báo qua email."
# email_news: "News" email_news: "Tin tức"
email_recruit_notes: "Cơ hội việc làm" email_recruit_notes: "Cơ hội việc làm"
email_recruit_notes_description: "Nếu bạn chơi trò này rất giỏi, chúng tôi có thể sẽ liên lạc với bạn về cơ hội nghề nghiệp." email_recruit_notes_description: "Nếu bạn chơi trò này rất giỏi, chúng tôi có thể sẽ liên lạc với bạn về cơ hội nghề nghiệp."
contributor_emails: "Email tham gia đóng góp" contributor_emails: "Email tham gia đóng góp"
@ -957,7 +957,7 @@ module.exports = nativeDescription: "Tiếng Việt", englishDescription: "Vietn
# toggle_grid: "Toggle grid overlay." # toggle_grid: "Toggle grid overlay."
# toggle_pathfinding: "Toggle pathfinding overlay." # toggle_pathfinding: "Toggle pathfinding overlay."
# beautify: "Beautify your code by standardizing its formatting." # beautify: "Beautify your code by standardizing its formatting."
# maximize_editor: "Maximize/minimize code editor." maximize_editor: "Phong to/thu nhỏ trình soạn thảo code."
community: community:
main_title: "Cộng đồng CodeCombat" main_title: "Cộng đồng CodeCombat"
@ -1000,8 +1000,8 @@ module.exports = nativeDescription: "Tiếng Việt", englishDescription: "Vietn
edit_description: "sửa mô tả" edit_description: "sửa mô tả"
private: "(kín)" private: "(kín)"
summary: "Tóm tắt" summary: "Tóm tắt"
average_level: "Cấp độ trng bình" average_level: "Cấp độ trung bình"
# average_achievements: "Average Achievements" average_achievements: "Thành tựu trung bình"
delete_clan: "Xóa Clan" delete_clan: "Xóa Clan"
leave_clan: "Rời Clan" leave_clan: "Rời Clan"
join_clan: "Tham gia Clan" join_clan: "Tham gia Clan"
@ -1013,29 +1013,29 @@ module.exports = nativeDescription: "Tiếng Việt", englishDescription: "Vietn
started_1: "đã bắt đầu" started_1: "đã bắt đầu"
complete_1: "hoàn thành" complete_1: "hoàn thành"
# exp_levels: "Expand levels" # exp_levels: "Expand levels"
# rem_hero: "Remove Hero" rem_hero: "Xóa Tướng"
# status: "Status" status: "Trạng thái"
complete_2: "Hoàn thành" complete_2: "Hoàn thành"
started_2: "Đã bắt đầu" started_2: "Đã bắt đầu"
not_started_2: "Chưa bắt đầu" not_started_2: "Chưa bắt đầu"
view_solution: "Click để xem lời giải." view_solution: "Click để xem lời giải."
# view_attempt: "Click to view attempt." view_attempt: "Click để xem thử."
# latest_achievement: "Latest Achievement" latest_achievement: "Thành tựu mới nhất"
playtime: "Thời gian chơi" playtime: "Thời gian chơi"
last_played: "Lần chơi cuối" last_played: "Lần chơi cuối"
# leagues_explanation: "Play in a league against other clan members in these multiplayer arena instances." # leagues_explanation: "Play in a league against other clan members in these multiplayer arena instances."
# track_concepts1: "Track concepts" # track_concepts1: "Track concepts"
# track_concepts2a: "learned by each student" # track_concepts2a: "learned by each student"
# track_concepts2b: "learned by each member" # track_concepts2b: "learned by each member"
# track_concepts3a: "Track levels completed for each student" track_concepts3a: "Theo dõi các màn chơi được hoàn thành bởi mỗi học viên"
# track_concepts3b: "Track levels completed for each member" track_concepts3b: "Theo dõi các màn chơi được hoàn thành bởi mỗi thành viên"
track_concepts4a: "Xem các học viên của bạn'" track_concepts4a: "Xem các học viên của bạn'"
track_concepts4b: "Xem các thành viên của bạn'" track_concepts4b: "Xem các thành viên của bạn'"
track_concepts5: "lời giải" track_concepts5: "lời giải"
track_concepts6a: "Sắp xếp học viên theo tên hoặc tiến trình" track_concepts6a: "Sắp xếp học viên theo tên hoặc tiến trình"
track_concepts6b: "Sắp xếp thành viên theo tên hoặc tiến trình" track_concepts6b: "Sắp xếp thành viên theo tên hoặc tiến trình"
# track_concepts7: "Requires invitation" track_concepts7: "Yêu cầu lời mời"
# track_concepts8: "to join" track_concepts8: "để tham gia"
private_require_sub: "Các Clan kín cần mua subscription để tạo hoặc tham gia." private_require_sub: "Các Clan kín cần mua subscription để tạo hoặc tham gia."
courses: courses:
@ -1047,7 +1047,7 @@ module.exports = nativeDescription: "Tiếng Việt", englishDescription: "Vietn
visit_suf: "để tham gia." visit_suf: "để tham gia."
select_class: "Chọn một trong các lớp học của bạn" select_class: "Chọn một trong các lớp học của bạn"
unnamed: "*unnamed*" unnamed: "*unnamed*"
# select: "Select" select: "Lựa chọn"
unnamed_class: "Lớp học chưa đặt tên" unnamed_class: "Lớp học chưa đặt tên"
edit_settings: "thay đổi tùy chỉnh lớp học" edit_settings: "thay đổi tùy chỉnh lớp học"
edit_settings1: "Thay đổi tùy chỉnh lớp học" edit_settings1: "Thay đổi tùy chỉnh lớp học"
@ -1055,24 +1055,24 @@ module.exports = nativeDescription: "Tiếng Việt", englishDescription: "Vietn
add_students: "Thêm học sinh" add_students: "Thêm học sinh"
stats: "Thống kê" stats: "Thống kê"
total_students: "Tổng số học sinh:" total_students: "Tổng số học sinh:"
# average_time: "Average level play time:" average_time: "Thời gian chơi trung bình:"
total_time: "Tổng thời gian chơi:" total_time: "Tổng thời gian chơi:"
average_levels: "Lượng cấp độ trung bình đã hoàn thành:" average_levels: "Lượng cấp độ trung bình đã hoàn thành:"
total_levels: "Tổng số cấp độ đã hoàn thành" total_levels: "Tổng số cấp độ đã hoàn thành"
# furthest_level: "Furthest level completed:" furthest_level: "Màn chơi xa nhất đã hoàn thành:"
# students: "Students" students: "Học viên"
# students1: "students" students1: "học viên"
# concepts: "Concepts" concepts: "Các khái niệm"
# levels: "levels" levels: "màn chơi"
# played: "Played" played: "Đã chơi"
# play_time: "Play time:" play_time: "Thời gian chơi:"
# completed: "Completed:" completed: "Đã hoàn thành:"
# invite_students: "Invite students to join this class." invite_students: "Mời các học viên tham gia lớp học này."
# invite_link_header: "Link to join course" invite_link_header: "Đường link để tham gia khóa học"
# invite_link_p_1: "Give this link to students you would like to have join the 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:" # invite_link_p_2: "Or have us email them directly:"
# capacity_used: "Course slots used:" capacity_used: "Số chỗ đã đăng ký:"
# enter_emails: "Enter student emails to invite, one per line" enter_emails: "Nhập email học viên để gửi lời mời, mỗi email một dòng"
send_invites: "Gửi lời mời" send_invites: "Gửi lời mời"
creating_class: "Đang tạo lớp..." creating_class: "Đang tạo lớp..."
purchasing_course: "Đang mua khóa học..." purchasing_course: "Đang mua khóa học..."
@ -1086,15 +1086,15 @@ module.exports = nativeDescription: "Tiếng Việt", englishDescription: "Vietn
name_class: "Đặt tên lớp của bạn" name_class: "Đặt tên lớp của bạn"
# displayed_course_page: "This will be displayed on the course page for you and your students. It can be changed later." # displayed_course_page: "This will be displayed on the course page for you and your students. It can be changed later."
buy: "Mua" buy: "Mua"
# purchasing_for: "You are purchasing a license for" purchasing_for: "Bạn đang muc giấy phép cho"
# creating_for: "You are creating a class for" creating_for: "Bạn đang tạo một lớp cho"
# for: "for" # Like in 'for 30 students' for: "dành cho" # 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." # 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!" # free_trial: "Free trial for teachers!"
# get_access: "to get individual access to all courses for evalutaion purposes." # get_access: "to get individual access to all courses for evalutaion purposes."
# questions: "Questions?" questions: "Có câu hỏi?"
# teachers_click: "Teachers Click Here" teachers_click: "Giáo viên click vào đây"
# students_click: "Students Click Here" students_click: "Học viên click vào đây"
courses_on_coco: "Những khóa học trên CodeCombat" courses_on_coco: "Những khóa học trên 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." # 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" # more_in_less: "Learn more in less time"
@ -1406,7 +1406,7 @@ module.exports = nativeDescription: "Tiếng Việt", englishDescription: "Vietn
# level_title: "Level Editor" # level_title: "Level Editor"
# achievement_title: "Achievement Editor" # achievement_title: "Achievement Editor"
# poll_title: "Poll Editor" # poll_title: "Poll Editor"
# back: "Back" back: "Quay lại"
# revert: "Revert" # revert: "Revert"
# revert_models: "Revert Models" # revert_models: "Revert Models"
pick_a_terrain: "Chọn Địa Hình" pick_a_terrain: "Chọn Địa Hình"
@ -1418,8 +1418,8 @@ module.exports = nativeDescription: "Tiếng Việt", englishDescription: "Vietn
glacier: "Núi băng" glacier: "Núi băng"
small: "" small: ""
large: "Lớn" large: "Lớn"
# fork_title: "Fork New Version" fork_title: "Fork phiên bản mới"
# fork_creating: "Creating Fork..." fork_creating: "Đang tạo Fork..."
# generate_terrain: "Generate Terrain" # generate_terrain: "Generate Terrain"
more: "Thêm" more: "Thêm"
wiki: "Wiki" wiki: "Wiki"

View file

@ -7,6 +7,7 @@ application = require 'core/application'
Classroom = require 'models/Classroom' Classroom = require 'models/Classroom'
errors = require 'core/errors' errors = require 'core/errors'
COPPADenyModal = require 'views/core/COPPADenyModal' COPPADenyModal = require 'views/core/COPPADenyModal'
utils = require 'core/utils'
module.exports = class CreateAccountModal extends ModalView module.exports = class CreateAccountModal extends ModalView
@ -28,6 +29,8 @@ module.exports = class CreateAccountModal extends ModalView
initialize: (options={}) -> initialize: (options={}) ->
@onNameChange = _.debounce(_.bind(@checkNameExists, @), 500) @onNameChange = _.debounce(_.bind(@checkNameExists, @), 500)
options.initialValues ?= {}
options.initialValues?.classCode ?= utils.getQueryVariable('_cc', "")
@previousFormInputs = options.initialValues or {} @previousFormInputs = options.initialValues or {}
# TODO: Switch to promises and state, rather than using defer to hackily enable buttons after render # TODO: Switch to promises and state, rather than using defer to hackily enable buttons after render

View file

@ -55,7 +55,7 @@ module.exports = class TeachersContactModal extends ModalView
return unless _.isEmpty(formErrors) return unless _.isEmpty(formErrors)
@state.set('sendingState', 'sending') @state.set('sendingState', 'sending')
data = _.extend({ country: me.get('country'), recipientID: 'schools@codecombat.com' }, formValues) data = _.extend({ country: me.get('country'), recipientID: 'schools@codecombat.com', enrollmentsNeeded: @enrollmentsNeeded }, formValues)
contact.send({ contact.send({
data data
context: @ context: @

View file

@ -57,7 +57,7 @@ module.exports =
return done(error) if error return done(error) if error
leads = JSON.parse(body) leads = JSON.parse(body)
return done("Unexpected leads format: " + body) unless leads.data? return done("Unexpected leads format: " + body) unless leads.data?
return done(null, config.mail.supportSchools) unless leads.data?.length > 0 return done("No existing Close.IO lead found for #{email}") unless leads.data?.length > 0
lead = leads.data[0] lead = leads.data[0]
uri = "https://#{apiKey}:X@app.close.io/api/v1/activity/?lead_id=#{lead.id}" uri = "https://#{apiKey}:X@app.close.io/api/v1/activity/?lead_id=#{lead.id}"
request.get uri, (error, response, body) => request.get uri, (error, response, body) =>
@ -65,8 +65,33 @@ module.exports =
activities = JSON.parse(body) activities = JSON.parse(body)
return done("Unexpected activities format: " + body) unless activities.data? return done("Unexpected activities format: " + body) unless activities.data?
for activity in activities.data when activity._type is 'Email' for activity in activities.data when activity._type is 'Email'
return done(null, activity.sender) if /@codecombat\.com/ig.test(activity.sender) if /@codecombat\.com/ig.test(activity.sender) and not activity.sender?.indexOf(config.mail.username) >= 0
return done(null, config.mail.supportSchools) return done(null, activity.sender, lead.id)
return done(null, config.mail.supportSchools, lead.id)
catch error catch error
log.error("closeIO.getSalesContactEmail Error for #{email}: #{JSON.stringify(error)}") log.error("closeIO.getSalesContactEmail Error for #{email}: #{JSON.stringify(error)}")
return done(error, config.mail.supportSchools) return done(error)
sendMail: (fromAddress, subject, content, done) ->
# log.info("DEBUG: closeIO.sendMail #{fromAddress} #{subject} #{content}")
@getSalesContactEmail fromAddress, (err, salesContactEmail, leadID) ->
return done("Error getting sales contact for #{fromAddress}: #{err}") if err
matches = salesContactEmail.match(/^[a-zA-Z_]+ <(\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,3})>$|(\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,3})/i)
salesContactEmail = matches?[1] ? matches?[2] ? config.mail.supportSchools
postData =
to: [salesContactEmail]
sender: config.mail.username
subject: subject
body_text: content
lead_id: leadID
status: 'outbox'
options =
uri: "https://#{apiKey}:X@app.close.io/api/v1/activity/email/"
body: JSON.stringify(postData)
request.post options, (error, response, body) =>
return done(error) if error
result = JSON.parse(body);
if result.errors or result['field-errors']
errorMessage = "Close.io Send email POST error for #{fromAddress} #{JSON.stringify(result.errors)} #{JSON.stringify(result['field-errors'])}";
return done(errorMessage)
return done()

View file

@ -11,21 +11,27 @@ module.exports.setup = (app) ->
app.post '/contact', (req, res) -> app.post '/contact', (req, res) ->
return res.end() unless req.user return res.end() unless req.user
# log.info "Sending mail from #{req.body.email} saying #{req.body.message}" # log.info "Sending mail from #{req.body.email} saying #{req.body.message}"
createMailContext req, (context) -> fromAddress = req.body.sender or req.body.email or req.user.get('email')
sendwithus.api.send context, (err, result) -> createMailContent req, fromAddress, (subject, content) ->
if err if req.body.recipientID is 'schools@codecombat.com' or req.user.isTeacher()
log.error "Error sending contact form email: #{err.message or err}" req.user.update({$set: { enrollmentRequestSent: true }}).exec(_.noop) if req.body.recipientID is 'schools@codecombat.com'
closeIO.sendMail fromAddress, subject, content, (err) ->
log.error "Error sending contact form email via Close.io: #{err.message or err}" if err
else
createSendWithUsContext req, fromAddress, subject, content, (context) ->
sendwithus.api.send context, (err, result) ->
log.error "Error sending contact form email via sendwithus: #{err.message or err}" if err
return res.end() return res.end()
createMailContext = (req, done) -> createMailContent = (req, fromAddress, done) ->
sender = req.body.sender or req.body.email country = req.body.country
enrollmentsNeeded = req.body.enrollmentsNeeded
message = req.body.message message = req.body.message
user = req.user user = req.user
recipientID = req.body.recipientID subject = switch
subject = req.body.subject when enrollmentsNeeded then "#{enrollmentsNeeded} Licenses needed for #{fromAddress}"
country = req.body.country when req.body.subject then req.body.subject
sentFromLevel = levelID: req.body.levelID, courseID: req.body.courseID, courseInstanceID: req.body.courseInstanceID else "Contact Us Form: #{fromAddress}"
level = if user?.get('points') > 0 then Math.floor(5 * Math.log((1 / 100) * (user.get('points') + 100))) + 1 else 0 level = if user?.get('points') > 0 then Math.floor(5 * Math.log((1 / 100) * (user.get('points') + 100))) + 1 else 0
premium = user?.isPremium() premium = user?.isPremium()
teacher = user?.isTeacher() teacher = user?.isTeacher()
@ -34,15 +40,25 @@ createMailContext = (req, done) ->
-- --
http://codecombat.com/user/#{user.get('slug') or user.get('_id')} http://codecombat.com/user/#{user.get('slug') or user.get('_id')}
#{user.get('name') or 'Anonymous'} - Level #{level}#{if teacher then ' - Teacher' else ''}#{if premium then ' - Subscriber' else ''}#{if country then ' - ' + country else ''} #{fromAddress} - #{user.get('name') or 'Anonymous'} - Level #{level}#{if teacher then ' - Teacher' else ''}#{if premium then ' - Subscriber' else ''}#{if country then ' - ' + country else ''}
""" """
if req.body.browser if req.body.browser
content += "\n#{req.body.browser} - #{req.body.screenSize}" content += "\n#{req.body.browser} - #{req.body.screenSize}"
done(subject, content)
createSendWithUsContext = (req, fromAddress, subject, content, done) ->
user = req.user
recipientID = req.body.recipientID
sentFromLevel = levelID: req.body.levelID, courseID: req.body.courseID, courseInstanceID: req.body.courseInstanceID
premium = user?.isPremium()
teacher = user?.isTeacher()
if recipientID is 'schools@codecombat.com' or teacher
return done("Tried to send a teacher contact us email via sendwithus #{fromAddress} #{subject}")
toAddress = switch toAddress = switch
when premium then config.mail.supportPremium when premium then config.mail.supportPremium
else config.mail.supportPrimary else config.mail.supportPrimary
fromAddress = sender or user.get('email')
context = context =
email_id: sendwithus.templates.plain_text_email email_id: sendwithus.templates.plain_text_email
@ -53,30 +69,24 @@ createMailContext = (req, done) ->
reply_to: fromAddress reply_to: fromAddress
name: user.get('name') name: user.get('name')
email_data: email_data:
subject: "[CodeCombat] #{subject ? ('Feedback - ' + fromAddress)}" subject: subject
content: content content: content
contentHTML: content.replace /\n/g, '\n<br>' contentHTML: content.replace /\n/g, '\n<br>'
if recipientID is 'schools@codecombat.com' or teacher if recipientID and (user.isAdmin() or ('employer' in (user.get('permissions') ? [])))
req.user.update({$set: { enrollmentRequestSent: true }}).exec(_.noop) if recipientID is 'schools@codecombat.com'
closeIO.getSalesContactEmail fromAddress, (err, salesContactEmail) ->
console.error "Error getting sales contact for #{sender}: #{err}" if err
context.recipient.address = salesContactEmail ? config.mail.supportSchools
done context
else if recipientID and (user.isAdmin() or ('employer' in (user.get('permissions') ? [])))
User.findById(recipientID, 'email').exec (err, document) -> User.findById(recipientID, 'email').exec (err, document) ->
if err if err
log.error "Error looking up recipient to email from #{recipientID}: #{err}" if err log.error "Error looking up recipient to email from #{recipientID}: #{err}" if err
else else
context.recipient.bcc = [context.recipient.address, sender] context.recipient.bcc = [context.recipient.address, fromAddress]
context.recipient.address = document.get('email') context.recipient.address = document.get('email')
context.email_data.content = message context.email_data.content = content
done context done context
else else
async.waterfall [ async.waterfall [
fetchRecentSessions.bind undefined, user, context, sentFromLevel fetchRecentSessions.bind undefined, user, context, sentFromLevel
# Can add other data-grabbing stuff here if we want. # Can add other data-grabbing stuff here if we want.
], (err, results) -> ], (err, results) ->
console.error "Error getting contact message context for #{sender}: #{err}" if err console.error "Error getting contact message context for #{fromAddress}: #{err}" if err
if req.body.screenshotURL if req.body.screenshotURL
context.email_data.contentHTML += "\n<br><img src='#{req.body.screenshotURL}' />" context.email_data.contentHTML += "\n<br><img src='#{req.body.screenshotURL}' />"
done context done context

View file

@ -6,6 +6,8 @@ describe 'AuthModal', ->
modal = null modal = null
beforeEach -> beforeEach ->
application.facebookHandler.fakeAPI()
application.gplusHandler.fakeAPI()
modal = new AuthModal() modal = new AuthModal()
modal.render() modal.render()
@ -20,4 +22,4 @@ describe 'AuthModal', ->
expect(args[0] instanceof RecoverModal).toBeTruthy() expect(args[0] instanceof RecoverModal).toBeTruthy()
it '(demo)', -> it '(demo)', ->
jasmine.demoModal(modal) jasmine.demoModal(modal)