mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-12-14 01:31:15 -05:00
Merge branch 'master' into production
This commit is contained in:
commit
d8e217a232
46 changed files with 1425 additions and 452 deletions
BIN
app/assets/images/common/button-get-started.png
Normal file
BIN
app/assets/images/common/button-get-started.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.6 KiB |
11
app/collections/TrialRequests.coffee
Normal file
11
app/collections/TrialRequests.coffee
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
CocoCollection = require 'collections/CocoCollection'
|
||||||
|
TrialRequest = require 'models/TrialRequest'
|
||||||
|
|
||||||
|
module.exports = class TrialRequestCollection extends CocoCollection
|
||||||
|
url: '/db/trial.request'
|
||||||
|
model: TrialRequest
|
||||||
|
|
||||||
|
fetchOwn: (options) ->
|
||||||
|
options = _.extend({data: {}}, options)
|
||||||
|
options.url = _.result(@, 'url') + '/-/own'
|
||||||
|
@fetch(options)
|
|
@ -121,7 +121,8 @@ module.exports = class CocoRouter extends Backbone.Router
|
||||||
'schools': go('SalesView')
|
'schools': go('SalesView')
|
||||||
|
|
||||||
'teachers': go('TeachersView')
|
'teachers': go('TeachersView')
|
||||||
'teachers/freetrial': go('TeachersFreeTrialView')
|
'teachers/freetrial': go('RequestQuoteView')
|
||||||
|
'teachers/quote': go('RequestQuoteView')
|
||||||
|
|
||||||
'test(/*subpath)': go('TestView')
|
'test(/*subpath)': go('TestView')
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ module.exports = class Tracker
|
||||||
ga? 'send', 'pageview', url
|
ga? 'send', 'pageview', url
|
||||||
|
|
||||||
# Mixpanel
|
# Mixpanel
|
||||||
mixpanelIncludes = ['courses', 'courses/purchase', 'courses/teachers', 'courses/students', 'schools', 'teachers', 'teachers/freetrial']
|
mixpanelIncludes = ['', 'courses', 'courses/purchase', 'courses/teachers', 'courses/students', 'schools', 'teachers', 'teachers/freetrial', 'teachers/quote']
|
||||||
mixpanel.track('page viewed', 'page name' : name, url : url) if name in mixpanelIncludes
|
mixpanel.track('page viewed', 'page name' : name, url : url) if name in mixpanelIncludes
|
||||||
|
|
||||||
trackEvent: (action, properties={}, includeIntegrations=[]) =>
|
trackEvent: (action, properties={}, includeIntegrations=[]) =>
|
||||||
|
@ -142,7 +142,7 @@ module.exports = class Tracker
|
||||||
$.post("#{window.location.protocol or 'http:'}//analytics.codecombat.com/analytics", dataToSend).fail ->
|
$.post("#{window.location.protocol or 'http:'}//analytics.codecombat.com/analytics", dataToSend).fail ->
|
||||||
console.error "Analytics post failed!"
|
console.error "Analytics post failed!"
|
||||||
else
|
else
|
||||||
request = @supermodel.addRequestResource 'log_event', {
|
request = @supermodel.addRequestResource {
|
||||||
url: '/db/analytics.log.event/-/log_event'
|
url: '/db/analytics.log.event/-/log_event'
|
||||||
data: {event: event, properties: properties}
|
data: {event: event, properties: properties}
|
||||||
method: 'POST'
|
method: 'POST'
|
||||||
|
|
|
@ -1,22 +1,35 @@
|
||||||
module.exports.formToObject = (el) ->
|
module.exports.formToObject = ($el, options) ->
|
||||||
|
options = _.extend({ trim: true, ignoreEmptyString: true }, options)
|
||||||
obj = {}
|
obj = {}
|
||||||
|
|
||||||
inputs = $('input', el).add('textarea', el)
|
inputs = $('input, textarea, select', $el)
|
||||||
for input in inputs
|
for input in inputs
|
||||||
input = $(input)
|
input = $(input)
|
||||||
continue unless name = input.attr('name')
|
continue unless name = input.attr('name')
|
||||||
obj[name] = input.val()
|
if input.attr('type') is 'checkbox'
|
||||||
obj[name] = obj[name].trim() if obj[name]?.trim
|
obj[name] ?= []
|
||||||
|
if input.is(':checked')
|
||||||
|
obj[name].push(input.val())
|
||||||
|
else if input.attr('type') is 'radio'
|
||||||
|
continue unless input.is('checked')
|
||||||
|
obj[name] = input.val()
|
||||||
|
else
|
||||||
|
value = input.val() or ''
|
||||||
|
value = _.string.trim(value) if options.trim
|
||||||
|
if value or (not options.ignoreEmptyString)
|
||||||
|
obj[name] = value
|
||||||
obj
|
obj
|
||||||
|
|
||||||
module.exports.applyErrorsToForm = (el, errors, warning=false) ->
|
module.exports.applyErrorsToForm = (el, errors, warning=false) ->
|
||||||
errors = [errors] if not $.isArray(errors)
|
errors = [errors] if not $.isArray(errors)
|
||||||
missingErrors = []
|
missingErrors = []
|
||||||
for error in errors
|
for error in errors
|
||||||
if error.dataPath
|
if error.code is tv4.errorCodes.OBJECT_REQUIRED
|
||||||
|
prop = _.last(_.string.words(error.message)) # hack
|
||||||
|
message = 'Required field'
|
||||||
|
|
||||||
|
else if error.dataPath
|
||||||
prop = error.dataPath[1..]
|
prop = error.dataPath[1..]
|
||||||
console.log prop
|
|
||||||
message = error.message
|
message = error.message
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -35,8 +48,13 @@ module.exports.setErrorToField = setErrorToField = (el, message, warning=false)
|
||||||
return console.error el, " did not contain a form group, so couldn't show message:", message
|
return console.error el, " did not contain a form group, so couldn't show message:", message
|
||||||
|
|
||||||
kind = if warning then 'warning' else 'error'
|
kind = if warning then 'warning' else 'error'
|
||||||
|
afterEl = $(formGroup.find('.help-block, .form-control, input, select, textarea')[0])
|
||||||
formGroup.addClass "has-#{kind}"
|
formGroup.addClass "has-#{kind}"
|
||||||
formGroup.append $("<span class='help-block #{kind}-help-block'>#{message}</span>")
|
helpBlock = $("<span class='help-block #{kind}-help-block'>#{message}</span>")
|
||||||
|
if afterEl.length
|
||||||
|
afterEl.before helpBlock
|
||||||
|
else
|
||||||
|
formGroup.append helpBlock
|
||||||
|
|
||||||
module.exports.setErrorToProperty = setErrorToProperty = (el, property, message, warning=false) ->
|
module.exports.setErrorToProperty = setErrorToProperty = (el, property, message, warning=false) ->
|
||||||
input = $("[name='#{property}']", el)
|
input = $("[name='#{property}']", el)
|
||||||
|
|
|
@ -98,6 +98,7 @@ module.exports.thangNames = thangNames =
|
||||||
# Female
|
# Female
|
||||||
'Vyrryx'
|
'Vyrryx'
|
||||||
'Yzzrith'
|
'Yzzrith'
|
||||||
|
'Xith'
|
||||||
]
|
]
|
||||||
'Ogre Chieftain': [
|
'Ogre Chieftain': [
|
||||||
# Female
|
# Female
|
||||||
|
@ -146,6 +147,8 @@ module.exports.thangNames = thangNames =
|
||||||
# Animal
|
# Animal
|
||||||
'Nevermore'
|
'Nevermore'
|
||||||
'Baltimore'
|
'Baltimore'
|
||||||
|
'Columbia'
|
||||||
|
'Dawnstar'
|
||||||
]
|
]
|
||||||
'Cougar': [
|
'Cougar': [
|
||||||
# Animal
|
# Animal
|
||||||
|
@ -368,6 +371,7 @@ module.exports.thangNames = thangNames =
|
||||||
'Goliath': [
|
'Goliath': [
|
||||||
# Male
|
# Male
|
||||||
'Okar'
|
'Okar'
|
||||||
|
'Ivan'
|
||||||
]
|
]
|
||||||
'Guardian': [
|
'Guardian': [
|
||||||
# Female
|
# Female
|
||||||
|
|
|
@ -34,6 +34,11 @@
|
||||||
twitter_follow: "Follow"
|
twitter_follow: "Follow"
|
||||||
teachers: "Teachers"
|
teachers: "Teachers"
|
||||||
careers: "Careers"
|
careers: "Careers"
|
||||||
|
facebook: "Facebook"
|
||||||
|
twitter: "Twitter"
|
||||||
|
create_a_class: "Create a Class"
|
||||||
|
other: "Other"
|
||||||
|
learn_to_code: "Learn to Code!"
|
||||||
|
|
||||||
modal:
|
modal:
|
||||||
close: "Close"
|
close: "Close"
|
||||||
|
@ -618,6 +623,37 @@
|
||||||
fill_fields: "Please fill out all fields."
|
fill_fields: "Please fill out all fields."
|
||||||
thanks: "Thanks! We'll send you setup instructions shortly."
|
thanks: "Thanks! We'll send you setup instructions shortly."
|
||||||
|
|
||||||
|
teachers_quote:
|
||||||
|
name: "Quote Form"
|
||||||
|
title: "Request a Quote"
|
||||||
|
subtitle: "Get CodeCombat in your classroom, club, school or district!"
|
||||||
|
phone_number: "Phone number"
|
||||||
|
phone_number_help: "Where can we reach you during the workday?"
|
||||||
|
role_label: "Your role"
|
||||||
|
role_help: "Select your primary role."
|
||||||
|
tech_coordinator: "Technology coordinator"
|
||||||
|
advisor: "Advisor"
|
||||||
|
principal: "Principal"
|
||||||
|
superintendent: "Superintendent"
|
||||||
|
parent: "Parent"
|
||||||
|
organization_label: "Name of School/District"
|
||||||
|
city: "City"
|
||||||
|
state: "State"
|
||||||
|
country: "Country"
|
||||||
|
num_students_help: "How many do you anticipate enrolling in CodeCombat?"
|
||||||
|
education_level_label: "Education Level of Students"
|
||||||
|
education_level_help: "Choose as many as apply."
|
||||||
|
elementary_school: "Elementary School"
|
||||||
|
high_school: "High School"
|
||||||
|
please_explain: "(please explain)"
|
||||||
|
middle_school: "Middle School"
|
||||||
|
college_plus: "College or higher"
|
||||||
|
anything_else: "Anything else we should know?"
|
||||||
|
thanks_header: "Thanks for requesting a quote!"
|
||||||
|
thanks_p: "We'll be in touch soon. Questions? Email us:"
|
||||||
|
thanks_anon: "Login or sign up with your account below to access your two free enrollments (we’ll notify you by email when they have been approved, which usually takes less than 48 hours). As always, the first hour of content is free for an unlimited number of students."
|
||||||
|
thanks_logged_in: "Your two free enrollments are pending approval. We’ll notify you by email when they have been approved (usually within 48 hours). As always, the first hour of content is free for an unlimited number of students."
|
||||||
|
|
||||||
versions:
|
versions:
|
||||||
save_version_title: "Save New Version"
|
save_version_title: "Save New Version"
|
||||||
new_major_version: "New Major Version"
|
new_major_version: "New Major Version"
|
||||||
|
@ -1352,78 +1388,34 @@
|
||||||
|
|
||||||
loading_error:
|
loading_error:
|
||||||
could_not_load: "Error loading from server"
|
could_not_load: "Error loading from server"
|
||||||
connection_failure: "Connection failed."
|
connection_failure: "Connection Failed" # {change}
|
||||||
|
connection_failure_desc: "It doesn’t look like you’re connected to the internet! Check your network connection and then reload this page."
|
||||||
|
login_required: "Login Required"
|
||||||
|
login_required_desc: "You need to be logged in to access this page."
|
||||||
unauthorized: "You need to be signed in. Do you have cookies disabled?"
|
unauthorized: "You need to be signed in. Do you have cookies disabled?"
|
||||||
forbidden: "You do not have the permissions."
|
forbidden: "Forbidden" # {change}
|
||||||
not_found: "Not found."
|
forbidden_desc: "Oh no, there’s nothing we can show you here! Make sure you’re logged into the correct account, or visit one of the links below to get back to programming!"
|
||||||
|
not_found: "Not Found" # {change}
|
||||||
|
not_found_desc: "Hm, there’s nothing here. Visit one of the following links to get back to programming!"
|
||||||
not_allowed: "Method not allowed."
|
not_allowed: "Method not allowed."
|
||||||
timeout: "Server timeout."
|
timeout: "Server Timeout" # {change}
|
||||||
conflict: "Resource conflict."
|
conflict: "Resource conflict."
|
||||||
bad_input: "Bad input."
|
bad_input: "Bad input."
|
||||||
server_error: "Server error."
|
server_error: "Server error."
|
||||||
unknown: "Unknown error."
|
unknown: "Unknown Error" # {change}
|
||||||
error: "ERROR"
|
error: "ERROR"
|
||||||
|
general_desc: "Something went wrong, and it’s probably our fault. Try waiting a bit and then refreshing the page, or visit one of the following links to get back to programming!"
|
||||||
|
|
||||||
resources:
|
resources:
|
||||||
sessions: "Sessions"
|
|
||||||
your_sessions: "Your Sessions"
|
|
||||||
level: "Level"
|
level: "Level"
|
||||||
social_network_apis: "Social Network APIs"
|
|
||||||
facebook_status: "Facebook Status"
|
|
||||||
facebook_friends: "Facebook Friends"
|
|
||||||
facebook_friend_sessions: "Facebook Friend Sessions"
|
|
||||||
gplus_friends: "G+ Friends"
|
|
||||||
gplus_friend_sessions: "G+ Friend Sessions"
|
|
||||||
leaderboard: "Leaderboard"
|
|
||||||
user_schema: "User Schema"
|
|
||||||
user_profile: "User Profile"
|
|
||||||
patch: "Patch"
|
patch: "Patch"
|
||||||
patches: "Patches"
|
patches: "Patches"
|
||||||
patched_model: "Source Document"
|
|
||||||
model: "Model"
|
|
||||||
system: "System"
|
system: "System"
|
||||||
systems: "Systems"
|
systems: "Systems"
|
||||||
component: "Component"
|
component: "Component"
|
||||||
components: "Components"
|
components: "Components"
|
||||||
thang: "Thang"
|
|
||||||
thangs: "Thangs"
|
|
||||||
level_session: "Your Session"
|
|
||||||
opponent_session: "Opponent Session"
|
|
||||||
article: "Article"
|
|
||||||
user_names: "User Names"
|
|
||||||
thang_names: "Thang Names"
|
|
||||||
files: "Files"
|
|
||||||
top_simulators: "Top Simulators"
|
|
||||||
source_document: "Source Document"
|
|
||||||
document: "Document"
|
|
||||||
sprite_sheet: "Sprite Sheet"
|
|
||||||
employers: "Employers"
|
|
||||||
candidates: "Candidates"
|
|
||||||
candidate_sessions: "Candidate Sessions"
|
|
||||||
user_remark: "User Remark"
|
|
||||||
user_remarks: "User Remarks"
|
|
||||||
versions: "Versions"
|
|
||||||
items: "Items"
|
|
||||||
hero: "Hero"
|
hero: "Hero"
|
||||||
heroes: "Heroes"
|
|
||||||
achievement: "Achievement"
|
|
||||||
clas: "CLAs"
|
|
||||||
play_counts: "Play Counts"
|
|
||||||
feedback: "Feedback"
|
|
||||||
payment_info: "Payment Info"
|
|
||||||
campaigns: "Campaigns"
|
campaigns: "Campaigns"
|
||||||
poll: "Poll"
|
|
||||||
user_polls_record: "Poll Voting History"
|
|
||||||
course: "Course"
|
|
||||||
courses: "Courses"
|
|
||||||
course_instance: "Course Instance"
|
|
||||||
course_instances: "Course Instances"
|
|
||||||
classroom: "Classroom"
|
|
||||||
classrooms: "Classrooms"
|
|
||||||
clan: "Clan"
|
|
||||||
clans: "Clans"
|
|
||||||
members: "Members"
|
|
||||||
users: "Users"
|
|
||||||
|
|
||||||
concepts:
|
concepts:
|
||||||
advanced_strings: "Advanced Strings"
|
advanced_strings: "Advanced Strings"
|
||||||
|
|
|
@ -116,7 +116,7 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip
|
||||||
login_switch: "¿Ya tienes una cuenta?"
|
login_switch: "¿Ya tienes una cuenta?"
|
||||||
school_name: "Nombre de Escuela y Ciudad"
|
school_name: "Nombre de Escuela y Ciudad"
|
||||||
optional: "opcional"
|
optional: "opcional"
|
||||||
# school_name_placeholder: "Example High School, Springfield, IL"
|
school_name_placeholder: "Ejemplo: High School, Springfield, IL"
|
||||||
|
|
||||||
recover:
|
recover:
|
||||||
recover_account_title: "recuperar cuenta"
|
recover_account_title: "recuperar cuenta"
|
||||||
|
@ -251,7 +251,7 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip
|
||||||
victory_title_suffix: " Completo!"
|
victory_title_suffix: " Completo!"
|
||||||
victory_sign_up: "Regístrate para recibir actualizaciones"
|
victory_sign_up: "Regístrate para recibir actualizaciones"
|
||||||
victory_sign_up_poke: "¿Quieres recibir las ultimas noticias por correo? ¡Crea una cuenta gratuita y te mantendremos informado!"
|
victory_sign_up_poke: "¿Quieres recibir las ultimas noticias por correo? ¡Crea una cuenta gratuita y te mantendremos informado!"
|
||||||
victory_rate_the_level: "Valora el nivel: " # {change}
|
victory_rate_the_level: "¿Cómo de divertido estuvo este nivel?"
|
||||||
victory_return_to_ladder: "Volver a la escalera"
|
victory_return_to_ladder: "Volver a la escalera"
|
||||||
victory_saving_progress: "Guardando Progreso"
|
victory_saving_progress: "Guardando Progreso"
|
||||||
victory_go_home: "Ir al Inicio"
|
victory_go_home: "Ir al Inicio"
|
||||||
|
@ -403,7 +403,7 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip
|
||||||
comparison_blurb: "Agudiza tus habilidades con la suscripción a CodeCombat!"
|
comparison_blurb: "Agudiza tus habilidades con la suscripción a CodeCombat!"
|
||||||
feature1: "Más de 110 niveles basicos a lo largo de 4 mundos"
|
feature1: "Más de 110 niveles basicos a lo largo de 4 mundos"
|
||||||
feature2: "10 poderosos <strong>nuevos heroés</strong> con habilidades unicas!"
|
feature2: "10 poderosos <strong>nuevos heroés</strong> con habilidades unicas!"
|
||||||
feature3: "Más de 70 niveles extras" # {change}
|
feature3: "+80 niveles extras"
|
||||||
feature4: "<strong>{{gems}} gemas de bono</strong> cada mes!"
|
feature4: "<strong>{{gems}} gemas de bono</strong> cada mes!"
|
||||||
feature5: "Video tutoriales"
|
feature5: "Video tutoriales"
|
||||||
feature6: "Soporte Premium vía email"
|
feature6: "Soporte Premium vía email"
|
||||||
|
@ -436,12 +436,12 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip
|
||||||
parents_blurb3: "Sin Riesgo: Garantía de 100% de devolución, fácil 1-click y des- suscribirse."
|
parents_blurb3: "Sin Riesgo: Garantía de 100% de devolución, fácil 1-click y des- suscribirse."
|
||||||
payment_methods: "Metodos de pago"
|
payment_methods: "Metodos de pago"
|
||||||
payment_methods_title: "Metodos de pago aceptados."
|
payment_methods_title: "Metodos de pago aceptados."
|
||||||
payment_methods_blurb1: "Actualmente aceptamos tarjetas de credito y Alipay." # {change}
|
payment_methods_blurb1: "Actualmente aceptamos tarjetas de credito y Alipay. Tambíen puedes usar PayPal, enviando a nick@codecombat tu correo electrónico, y pudiendo adquirir por {{three_month_price}} USD una suscripción de tres meses y gemas, o por ${{year_price}} una de un año."
|
||||||
payment_methods_blurb2: "Si necesitas una forma alternativa de pago, por favor contactarse"
|
payment_methods_blurb2: "Si necesitas una forma alternativa de pago, por favor contactarse"
|
||||||
sale_button: "Venta!"
|
sale_button: "Venta!"
|
||||||
sale_button_title: "Ahorra ${{discount}} al adquirir una suscripción por 1 año" # {change}
|
sale_button_title: "Ahorre $21 al adquirir una suscripción por 1 año"
|
||||||
stripe_description: "Suscripción Mensual"
|
stripe_description: "Suscripción Mensual"
|
||||||
stripe_description_year_sale: "Suscripción por 1 año (${{discount}} descuento)" # {change}
|
stripe_description_year_sale: "Suscripción por 1 año (${{discount}} de descuento)"
|
||||||
subscription_required_to_play: "Necesitas una suscripción para jugar este nivel."
|
subscription_required_to_play: "Necesitas una suscripción para jugar este nivel."
|
||||||
unlock_help_videos: "Suscríbete para desbloquear todos los video tutoriales."
|
unlock_help_videos: "Suscríbete para desbloquear todos los video tutoriales."
|
||||||
personal_sub: "Suscripción Personal" # Accounts Subscription View below
|
personal_sub: "Suscripción Personal" # Accounts Subscription View below
|
||||||
|
@ -454,7 +454,7 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip
|
||||||
managed_subs: "Suscripciones administradas"
|
managed_subs: "Suscripciones administradas"
|
||||||
subscribing: "Suscribiendo..."
|
subscribing: "Suscribiendo..."
|
||||||
current_recipients: "Recipientes actuales"
|
current_recipients: "Recipientes actuales"
|
||||||
unsubscribing: "Desuscribiendo..." # {change}
|
unsubscribing: "Dando de baja..."
|
||||||
subscribe_prepaid: "Click en suscribirse para utlizar un código prepago"
|
subscribe_prepaid: "Click en suscribirse para utlizar un código prepago"
|
||||||
using_prepaid: "Usar código prepago para una suscribción mensual"
|
using_prepaid: "Usar código prepago para una suscribción mensual"
|
||||||
|
|
||||||
|
@ -552,22 +552,22 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip
|
||||||
press_paragraph_1_link: "paquete de prensa"
|
press_paragraph_1_link: "paquete de prensa"
|
||||||
press_paragraph_1_suffix: ". Todos los logos e imágenes pueden ser usados sin contactarnos directamente."
|
press_paragraph_1_suffix: ". Todos los logos e imágenes pueden ser usados sin contactarnos directamente."
|
||||||
team: "Equipo"
|
team: "Equipo"
|
||||||
nick_title: "Cofundador" # {change}
|
nick_title: "Cofundador, CEO"
|
||||||
nick_blurb: "Gurú motivacional"
|
nick_blurb: "Gurú motivacional"
|
||||||
matt_title: "Cofundador" # {change}
|
matt_title: "Cofundador, CTO"
|
||||||
matt_blurb: "Bicicletero"
|
matt_blurb: "Bicicletero"
|
||||||
cat_title: "Jefe Artesano" # {change}
|
cat_title: "Diseñadora de Juegos"
|
||||||
cat_blurb: "Maestro del Aire"
|
cat_blurb: "Maestro del Aire"
|
||||||
scott_title: "Cofundador" # {change}
|
scott_title: "Cofundador, Ingeniero de Software"
|
||||||
scott_blurb: "Razonable"
|
scott_blurb: "Razonable"
|
||||||
# maka_title: "Customer Advocate"
|
maka_title: "Defensor del Consumidor"
|
||||||
# maka_blurb: "Storyteller"
|
maka_blurb: "Cuentista"
|
||||||
rob_title: "Ingeniero de Compilación" # {change}
|
rob_title: "Ingeniero de Software"
|
||||||
rob_blurb: "Hace código y demás"
|
rob_blurb: "Hace código y demás"
|
||||||
josh_c_title: "Diseñador de Juegos"
|
josh_c_title: "Diseñador de Juegos"
|
||||||
josh_c_blurb: "Diseña juegos"
|
josh_c_blurb: "Diseña juegos"
|
||||||
# robin_title: "UX Design & Research"
|
robin_title: "Diseñadora de UX & Investigadora"
|
||||||
# robin_blurb: "Scaffolding"
|
robin_blurb: "Scaffolding"
|
||||||
josh_title: "Diseñador de Juegos"
|
josh_title: "Diseñador de Juegos"
|
||||||
josh_blurb: "El piso es Lava"
|
josh_blurb: "El piso es Lava"
|
||||||
retrostyle_title: "Ilustración"
|
retrostyle_title: "Ilustración"
|
||||||
|
@ -579,8 +579,8 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip
|
||||||
|
|
||||||
teachers:
|
teachers:
|
||||||
who_for_title: "¿Para quienes es CodeCombat?"
|
who_for_title: "¿Para quienes es CodeCombat?"
|
||||||
who_for_1: "Recomendamos CodeCombat para estudiantes de edades 9 y arriba. No se require experiencia en programación." # {change}
|
who_for_1: "Recomendamos CodeCombat para estudiantes con +9 años de edad. No se require experiencia en programación. Diseñamos CodeCombat para que sea atractivo tanto para los chicos como para las chicas."
|
||||||
who_for_2: "Hemos diseñado a CodeCombat para atraer a niños y niñas." # {change}
|
who_for_2: "Nuestro sistema de Cursos permite a los maestros configurar las clases, monitorizar el progreso y asignar contenido adicional a los estudiantes a través de una interfaz dedicada."
|
||||||
more_info_title: "¿Dónde puedo encontrar más información?"
|
more_info_title: "¿Dónde puedo encontrar más información?"
|
||||||
more_info_1: "Nuestro"
|
more_info_1: "Nuestro"
|
||||||
more_info_2: "el foro de profesores"
|
more_info_2: "el foro de profesores"
|
||||||
|
@ -590,14 +590,14 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip
|
||||||
title: "Encuesta de Maestros"
|
title: "Encuesta de Maestros"
|
||||||
must_be_logged: "Debes ingresar primero. Por favor, crea una cuenta o ingresa desde el menú de arriba."
|
must_be_logged: "Debes ingresar primero. Por favor, crea una cuenta o ingresa desde el menú de arriba."
|
||||||
retrieving: "Obteniendo información..."
|
retrieving: "Obteniendo información..."
|
||||||
being_reviewed_1: "Su aplicación a una suscripción gratuita está siendo" # {change}
|
being_reviewed_1: "Su aplicación a una suscripción gratuita está siendo"
|
||||||
being_reviewed_2: "revisada."
|
being_reviewed_2: "revisada."
|
||||||
approved_1: "Su aplicación a una suscripción gratuita fue" # {change}
|
approved_1: "Su aplicación para una prueba gratuita está siendo"
|
||||||
approved_2: "aprobada." # {change}
|
approved_2: "revisada."
|
||||||
# approved_4: "You can now enroll your students on the"
|
approved_4: "Ahora puedes inscribir a tus estudiantes en los"
|
||||||
approved_5: "cursos"
|
approved_5: "cursos"
|
||||||
# approved_6: "page."
|
approved_6: "página."
|
||||||
denied_1: "Su aplicación a una suscripción gratuita ha sido" # {change}
|
denied_1: "Su aplicación para una prueba gratuita ha sido"
|
||||||
denied_2: "denegada."
|
denied_2: "denegada."
|
||||||
contact_1: "Por favor contactarse"
|
contact_1: "Por favor contactarse"
|
||||||
contact_2: "si tiene más preguntas."
|
contact_2: "si tiene más preguntas."
|
||||||
|
@ -736,7 +736,7 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip
|
||||||
subs_only: "solo suscriptores"
|
subs_only: "solo suscriptores"
|
||||||
create_clan: "Crear nuevo clan"
|
create_clan: "Crear nuevo clan"
|
||||||
private_preview: "Vista previa"
|
private_preview: "Vista previa"
|
||||||
# private_clans: "Private Clans"
|
private_clans: "Clanes Privados"
|
||||||
public_clans: "Clanes publicos"
|
public_clans: "Clanes publicos"
|
||||||
my_clans: "Mis Clanes"
|
my_clans: "Mis Clanes"
|
||||||
clan_name: "Nombre del clan"
|
clan_name: "Nombre del clan"
|
||||||
|
@ -856,7 +856,7 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip
|
||||||
see_the: "Vea la"
|
see_the: "Vea la"
|
||||||
more_info: "para más información."
|
more_info: "para más información."
|
||||||
choose_course: "Elige tu Curso:"
|
choose_course: "Elige tu Curso:"
|
||||||
enter_code: "Introducir un código de desbloqueo" # {change}
|
enter_code: "Introducir un código de desbloqueo para ingresar a una clase"
|
||||||
enter_code1: "Introducir código de desbloqueo"
|
enter_code1: "Introducir código de desbloqueo"
|
||||||
enroll: "Inscribirse"
|
enroll: "Inscribirse"
|
||||||
pick_from_classes: "Elije de tus clases actuales"
|
pick_from_classes: "Elije de tus clases actuales"
|
||||||
|
@ -867,14 +867,14 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip
|
||||||
get_free: "Obtenga curso GRATIS"
|
get_free: "Obtenga curso GRATIS"
|
||||||
enroll_paid: "Anotar estudiantes en cursos pagos."
|
enroll_paid: "Anotar estudiantes en cursos pagos."
|
||||||
you_have1: "Tiene"
|
you_have1: "Tiene"
|
||||||
# you_have2: "unused paid enrollments"
|
you_have2: "matrículas pagadas no utilizadas"
|
||||||
# use_one: "Use 1 paid enrollment for"
|
use_one: "Utilizar 1 matrícula pagada para"
|
||||||
# use_multiple: "Use paid enrollments for the following students:"
|
use_multiple: "Utilizar matrículas pagadas para los siguientes estudiantes:"
|
||||||
# already_enrolled: "already enrolled"
|
already_enrolled: "ya matriculados"
|
||||||
licenses_remaining: "licencias restantes:"
|
licenses_remaining: "licencias restantes:"
|
||||||
# insufficient_enrollments: "insufficient paid enrollments"
|
insufficient_enrollments: "matrículas pagas insuficientes"
|
||||||
# enroll_students: "Enroll Students"
|
enroll_students: "Matricular Estudiantes"
|
||||||
# get_enrollments: "Get More Enrollments"
|
get_enrollments: "Obtener Más Matrículas"
|
||||||
change_language: "Cambiar idioma del curso"
|
change_language: "Cambiar idioma del curso"
|
||||||
keep_using: "Seguir Usando"
|
keep_using: "Seguir Usando"
|
||||||
switch_to: "Cambiar a"
|
switch_to: "Cambiar a"
|
||||||
|
@ -885,24 +885,24 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip
|
||||||
back_classrooms: "Volver a mis aulas"
|
back_classrooms: "Volver a mis aulas"
|
||||||
back_courses: "Volver a mis cursos"
|
back_courses: "Volver a mis cursos"
|
||||||
edit_details: "Editar detallesde clase"
|
edit_details: "Editar detallesde clase"
|
||||||
# enrolled_courses: "enrolled in paid courses:"
|
enrolled_courses: "matriculados en cursos pagos:"
|
||||||
# purchase_enrollments: "Purchase Enrollments"
|
purchase_enrollments: "Comprar Matrículas"
|
||||||
remove_student: "Quitar alumno"
|
remove_student: "Quitar alumno"
|
||||||
assign: "Asignar"
|
assign: "Asignar"
|
||||||
# to_assign: "to assign paid courses."
|
to_assign: "para asignar cursos pagos."
|
||||||
teacher: "Maestro"
|
teacher: "Maestro"
|
||||||
complete: "Completado"
|
complete: "Completado"
|
||||||
# none: "None"
|
none: "Ninguno"
|
||||||
save: "Guardar"
|
save: "Guardar"
|
||||||
play_campaign_title: "Jugar Campaña"
|
play_campaign_title: "Jugar Campaña"
|
||||||
play_campaign_description: "Estas listo para dar el siguiente paso! Explora cientos de desafiantes niveles, aprende habilidades avanzadas de programación, y compite en arenas multijugador!"
|
play_campaign_description: "Estas listo para dar el siguiente paso! Explora cientos de desafiantes niveles, aprende habilidades avanzadas de programación, y compite en arenas multijugador!"
|
||||||
create_account_title: "Crea una Cuenta"
|
create_account_title: "Crea una Cuenta"
|
||||||
create_account_description: "Registrate gratis con una cuenta CodeCombat y obten acceso a mas niveles, mas habilidades de programacion, y mas diversion!"
|
create_account_description: "Registrate gratis con una cuenta CodeCombat y obten acceso a mas niveles, mas habilidades de programacion, y mas diversion!"
|
||||||
preview_campaign_title: "Previsualizar campaña"
|
preview_campaign_title: "Previsualizar campaña"
|
||||||
# preview_campaign_description: "Take a sneak peek at all that CodeCombat has to offer before signing up for your FREE account."
|
preview_campaign_description: "Echa un vistazo a todo lo que CodeCombat tiene para ofrecer antes de registrarse con una cuenta GRATUITA."
|
||||||
arena: "Arena"
|
arena: "Arena"
|
||||||
arena_soon_title: "Arena pronto disponible"
|
arena_soon_title: "Arena pronto disponible"
|
||||||
# arena_soon_description: "We are working on a multiplayer arena for classrooms at the end of"
|
arena_soon_description: "Estamos trabajando en una arena multijugador para las aulas para finales de"
|
||||||
not_enrolled1: "No inscrito"
|
not_enrolled1: "No inscrito"
|
||||||
not_enrolled2: "Preguntale a tu maestro para anotarte en el proximo curso."
|
not_enrolled2: "Preguntale a tu maestro para anotarte en el proximo curso."
|
||||||
next_course: "Próximo curso"
|
next_course: "Próximo curso"
|
||||||
|
@ -914,7 +914,7 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip
|
||||||
start_new_game: "Iniciar un Nuevo Juego"
|
start_new_game: "Iniciar un Nuevo Juego"
|
||||||
play_now_learn_header: "Juega y Aprende"
|
play_now_learn_header: "Juega y Aprende"
|
||||||
play_now_learn_1: "Sintaxis básica para controlar a tu personaje"
|
play_now_learn_1: "Sintaxis básica para controlar a tu personaje"
|
||||||
# play_now_learn_2: "while loops to solve pesky puzzles"
|
play_now_learn_2: "bucles while para resolver rompecabezas molestos"
|
||||||
play_now_learn_3: "cadenas & variables para personalizar acciones"
|
play_now_learn_3: "cadenas & variables para personalizar acciones"
|
||||||
play_now_learn_4: "como vencer a un ogro (habilidades importantes en la vida!)"
|
play_now_learn_4: "como vencer a un ogro (habilidades importantes en la vida!)"
|
||||||
welcome_to_page: "¡Bienvenido a tu página de cursose!"
|
welcome_to_page: "¡Bienvenido a tu página de cursose!"
|
||||||
|
@ -931,7 +931,7 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip
|
||||||
view_levels: "ver niveles"
|
view_levels: "ver niveles"
|
||||||
join_class: "Unirse a clase"
|
join_class: "Unirse a clase"
|
||||||
ask_teacher_for_code: "Preguntalé a tu profesor si tu tienes un código de CodeCombat! Si lo tiene, ingresalo debajo:"
|
ask_teacher_for_code: "Preguntalé a tu profesor si tu tienes un código de CodeCombat! Si lo tiene, ingresalo debajo:"
|
||||||
# enter_c_code: "<Enter Class Code>"
|
enter_c_code: "<Ingresar Código de la Clase>"
|
||||||
join: "Unirse"
|
join: "Unirse"
|
||||||
joining: "Uniendose a claseJoining class"
|
joining: "Uniendose a claseJoining class"
|
||||||
course_complete: "Curso completo"
|
course_complete: "Curso completo"
|
||||||
|
@ -945,72 +945,72 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip
|
||||||
continue_playing: "Seguir jugando"
|
continue_playing: "Seguir jugando"
|
||||||
more_options: "Másopciones:"
|
more_options: "Másopciones:"
|
||||||
option1_header: "Opción 1: Invitar estudiantes vía email"
|
option1_header: "Opción 1: Invitar estudiantes vía email"
|
||||||
# option1_body: "Students will automatically be sent an invitation to join this class, and will need to create an account with a username and password."
|
option1_body: "Se enviará automaticamente una invitación a los estudiantes para unirse a esta clase, y tendrán que crear una cuenta con un nombre de usuario y una contraseña."
|
||||||
option2_header: "Opción 2: Enviarles la URL a tus estudiantes"
|
option2_header: "Opción 2: Enviarles la URL a tus estudiantes"
|
||||||
# option2_body: "Students will be asked to enter an email address, username and password to create an account."
|
option2_body: "Se pedirá a los estudiantes que ingresen un correo electrónico, un nombre de usuario y una contraseña para crear una cuenta."
|
||||||
option3_header: "Opción 3: Dirigir estudiantes a to codecombat.com/courses"
|
option3_header: "Opción 3: Dirigir estudiantes a to codecombat.com/courses"
|
||||||
# option3_body: "Give students the following passcode to enter along with an email address, username and password when they create an account."
|
option3_body: "Dar a los estudiantes el siguiente código de acceso para ingresar junto con el correo electrónico, el nombre de usuario y la contraseña cuando creen una cuenta."
|
||||||
thank_you_pref: "Gracias por tu compra! Ahora puedes asignar"
|
thank_you_pref: "Gracias por tu compra! Ahora puedes asignar"
|
||||||
thank_you_suff: "más estudiantes a cursos pagos."
|
thank_you_suff: "más estudiantes a cursos pagos."
|
||||||
# return_to_class: "Return to classroom"
|
return_to_class: "Regresar al aula"
|
||||||
# return_to_course_man: "Return to course management."
|
return_to_course_man: "Regresar a la administración del curso."
|
||||||
# students_not_enrolled: "students not enrolled"
|
students_not_enrolled: "estudiantes no matriculados"
|
||||||
# total_all_classes: "Total Across All Classes"
|
total_all_classes: "Total Por Todas las Clases"
|
||||||
# how_many_enrollments: "How many additional paid enrollments do you need?"
|
how_many_enrollments: "¿Cuántas matriculas pagas adicionales necesitas?"
|
||||||
# each_student_access: "Each student in a class will get access to Courses 2-4 once they are enrolled in paid courses. You may assign each course to each student individually."
|
each_student_access: "Cada estudiante en una clase obtendrá acceso a los Cursos 2-4 una vez que esten matriculados en los cursos pagos. Puedes asignar cada curso a cada estudiante de forma individual."
|
||||||
purchase_now: "Comprar Ahora"
|
purchase_now: "Comprar Ahora"
|
||||||
# enrollments: "enrollments"
|
enrollments: "matrículas"
|
||||||
remove_student1: "Quitar alumno"
|
remove_student1: "Quitar alumno"
|
||||||
are_you_sure: "¿Estás seguro que quieres quitar este alumno de tu clase?"
|
are_you_sure: "¿Estás seguro que quieres quitar este alumno de tu clase?"
|
||||||
# remove_description1: "Student will lose access to this classroom and assigned classes. Progress and gameplay is NOT lost, and the student can be added back to the classroom at any time."
|
remove_description1: "El estudiante perderá acceso a esta aula y a sus clases asignadas. El progreso y la experiencia del juego NO se pierde, y el estudiante puede ser agregado de vuelta al aula en cualquier momento."
|
||||||
# remove_description2: "The activated paid license will not be returned."
|
remove_description2: "La matrícula paga activada no será devuelta."
|
||||||
keep_student: "Mantener alumno"
|
keep_student: "Mantener alumno"
|
||||||
removing_user: "Removiendo usuario"
|
removing_user: "Removiendo usuario"
|
||||||
to_join_ask: "Para ingresar a una clase, preguntale a tu maestro por un código de acceso."
|
to_join_ask: "Para ingresar a una clase, preguntale a tu maestro por un código de acceso."
|
||||||
join_this_class: "Ingresar clase"
|
join_this_class: "Ingresar clase"
|
||||||
enter_here: "<Ingresar el código aquí>"
|
enter_here: "<Ingresar el código aquí>"
|
||||||
# successfully_joined: "Successfully joined"
|
successfully_joined: "Ingresado exitosamente"
|
||||||
# click_to_start: "Click here to start taking"
|
click_to_start: "Click aquí para comenzar a hablar"
|
||||||
my_courses: "Mis Cursos"
|
my_courses: "Mis Cursos"
|
||||||
classroom: "Aulas"
|
classroom: "Aulas"
|
||||||
# use_school_email: "use your school email if you have one"
|
use_school_email: "utilize su correo electrónico de la escuela si tiene uno"
|
||||||
# unique_name: "a unique name no one has chosen"
|
unique_name: "un nombre único, no uno que ya esté escogido"
|
||||||
pick_something: "Escoge algo que recuerdes"
|
pick_something: "Escoge algo que recuerdes"
|
||||||
# class_code: "Class Code"
|
class_code: "Código de acceso"
|
||||||
# optional_ask: "optional - ask your teacher to give you one!"
|
optional_ask: "opcional - pregunta a tu maestro para que te de uno!"
|
||||||
optional_school: "opcional - a qué escuela vas?"
|
optional_school: "opcional - a qué escuela vas?"
|
||||||
start_playing: "Comienza a Jugar"
|
start_playing: "Comienza a Jugar"
|
||||||
skip_this: "Saltar esto, Crearé una cuenta mas tarde!"
|
skip_this: "Saltar esto, Crearé una cuenta mas tarde!"
|
||||||
welcome: "Bienvenido"
|
welcome: "Bienvenido"
|
||||||
# getting_started: "Getting Started with Courses"
|
getting_started: "Cómo empezar con los Cursos"
|
||||||
# download_getting_started: "Download Getting Started Guide [PDF]"
|
download_getting_started: "Descargar Guía de Introducción [PDF]"
|
||||||
# getting_started_1: "Create a new class by clicking the green 'Create New Class' button below."
|
getting_started_1: "Crea una nueva clase haciendo click en el botón verde 'Crear Nueva Clase' de más abajo."
|
||||||
# getting_started_2: "Once you've created a class, click the blue 'Add Students' button."
|
getting_started_2: "Una vez que creaste una clase, haz click en el botón azul 'Añadir Estudiantes'"
|
||||||
# getting_started_3: "You'll see student's progress below as they sign up and join your class."
|
getting_started_3: "Verás los progresos de los estudiantes más abajo cuando se registren e ingresen a tu clase."
|
||||||
# additional_resources: "Additional Resources"
|
additional_resources: "Recursos Adicionales"
|
||||||
# additional_resources_1_pref: "Download/print our"
|
additional_resources_1_pref: "Descargar/imprimir nuestra"
|
||||||
# additional_resources_1_mid: "Course 1 Teacher's Guide"
|
additional_resources_1_mid: "Guía para maestros: Curso 1"
|
||||||
# additional_resources_1_suff: "explanations and solutions to each level."
|
additional_resources_1_suff: "explicaciones y soluciones para cada nivel."
|
||||||
# additional_resources_2_pref: "Complete our"
|
additional_resources_2_pref: "Complete nuestro"
|
||||||
# additional_resources_2_suff: "to get two free enrollments for the rest of our paid courses."
|
additional_resources_2_suff: "para obtener dos matrículas gratuitas para el resto de nuestros cursos pagos."
|
||||||
# additional_resources_3_pref: "Visit our"
|
additional_resources_3_pref: "Visite nuestro"
|
||||||
# additional_resources_3_mid: "Teacher Forums"
|
additional_resources_3_mid: "Foro de Maestros"
|
||||||
# additional_resources_3_suff: "to connect to fellow educators who are using CodeCombat."
|
additional_resources_3_suff: "para relacionarse con sus colegas educadores que están usando CodeCombat."
|
||||||
# additional_resources_4_pref: "Check out our"
|
additional_resources_4_pref: "Consulte nuestra"
|
||||||
# additional_resources_4_mid: "Schools Page"
|
additional_resources_4_mid: "Página de Escuelas"
|
||||||
# additional_resources_4_suff: "to learn more about CodeCombat's classroom offerings."
|
additional_resources_4_suff: "para aprender más sobre la oferta para el aula de CodeCombat."
|
||||||
# your_classes: "Your Classes"
|
your_classes: "Tus Clases"
|
||||||
# no_classes: "No classes yet!"
|
no_classes: "Aún no hay clases!"
|
||||||
# create_new_class1: "create new class"
|
create_new_class1: "crear nueva clase"
|
||||||
available_courses: "Cursos Disponibles"
|
available_courses: "Cursos Disponibles"
|
||||||
# unused_enrollments: "Unused enrollments available:"
|
unused_enrollments: "Matrículas no utilizadas disponibles:"
|
||||||
# students_access: "All students get access to Introduction to Computer Science for free. One enrollment per student is required to assign them to paid CodeCombat courses. A single student does not need multiple enrollments to access all paid courses."
|
students_access: "Todos los estudiantes obtienen acceso gratuito a Introducción a la Informática. Una matrícula por estudiante es necesaria para asignarles los cursos pagos de CodeCombat. Un solo estudiante no necesita múltiples matrículas para acceder a todos los cursos pagos."
|
||||||
# active_courses: "active courses"
|
active_courses: "cursos activos"
|
||||||
no_students: "Aún no hay alumnos!"
|
no_students: "Aún no hay alumnos!"
|
||||||
add_students1: "añadir alumnos"
|
add_students1: "añadir alumnos"
|
||||||
view_edit: "ver/editar"
|
view_edit: "ver/editar"
|
||||||
# students_enrolled: "students enrolled"
|
students_enrolled: "estudiantes matriculados"
|
||||||
# length: "Length:"
|
length: "Duración:"
|
||||||
|
|
||||||
classes:
|
classes:
|
||||||
archmage_title: "Archimago"
|
archmage_title: "Archimago"
|
||||||
|
@ -1232,7 +1232,7 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip
|
||||||
tutorial_skip: "Saltar Tutorial"
|
tutorial_skip: "Saltar Tutorial"
|
||||||
tutorial_not_sure: "¿No estás seguro de que sucede?"
|
tutorial_not_sure: "¿No estás seguro de que sucede?"
|
||||||
tutorial_play_first: "Juega el Tutorial primero."
|
tutorial_play_first: "Juega el Tutorial primero."
|
||||||
simple_ai: "IA Simple" # {change}
|
simple_ai: "IA Simple"
|
||||||
warmup: "Calentamiento"
|
warmup: "Calentamiento"
|
||||||
friends_playing: "Amigos Jugando"
|
friends_playing: "Amigos Jugando"
|
||||||
log_in_for_friends: "Ingresa para jugar con tus amigos!"
|
log_in_for_friends: "Ingresa para jugar con tus amigos!"
|
||||||
|
@ -1255,7 +1255,7 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip
|
||||||
winners: "Ganadores"
|
winners: "Ganadores"
|
||||||
league: "Liga"
|
league: "Liga"
|
||||||
red_ai: "IA Roja" # "Red AI Wins", at end of multiplayer match playback
|
red_ai: "IA Roja" # "Red AI Wins", at end of multiplayer match playback
|
||||||
blue_ai: "IA Azul" # {change}
|
blue_ai: "IA Azul"
|
||||||
wins: "Gana" # At end of multiplayer match playback
|
wins: "Gana" # At end of multiplayer match playback
|
||||||
humans: "Rojo" # Ladder page display team name
|
humans: "Rojo" # Ladder page display team name
|
||||||
ogres: "Azul"
|
ogres: "Azul"
|
||||||
|
@ -1329,7 +1329,7 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip
|
||||||
months: "Meses"
|
months: "Meses"
|
||||||
purchase_total: "Total"
|
purchase_total: "Total"
|
||||||
purchase_button: "Enviar Adquisición"
|
purchase_button: "Enviar Adquisición"
|
||||||
your_codes: "Tus Códigos:" # {change}
|
your_codes: "Tus Códigos:"
|
||||||
redeem_codes: "Reclamar un Código de Suscripción"
|
redeem_codes: "Reclamar un Código de Suscripción"
|
||||||
prepaid_code: "Código Prepagado"
|
prepaid_code: "Código Prepagado"
|
||||||
lookup_code: "Buscar código prepagado"
|
lookup_code: "Buscar código prepagado"
|
||||||
|
@ -1408,8 +1408,8 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip
|
||||||
user_polls_record: "Historia de Visitas de Encuestas"
|
user_polls_record: "Historia de Visitas de Encuestas"
|
||||||
course: "Curso"
|
course: "Curso"
|
||||||
courses: "Cursos"
|
courses: "Cursos"
|
||||||
# course_instance: "Course Instance"
|
course_instance: "Muestra del Curso"
|
||||||
# course_instances: "Course Instances"
|
course_instances: "Muestras del Curso"
|
||||||
classroom: "Salón"
|
classroom: "Salón"
|
||||||
classrooms: "Salones"
|
classrooms: "Salones"
|
||||||
clan: "Clan"
|
clan: "Clan"
|
||||||
|
@ -1516,8 +1516,8 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip
|
||||||
nutshell_title: "En una palabra"
|
nutshell_title: "En una palabra"
|
||||||
nutshell_description: "Cualquier recurso que te proveamos en el Editor de Niveles es gratis de usar como te plazca para la creación de Niveles. Sin embargo, nos reservamos el derecho de restringir la distribución de los niveles por sí mismos (aquellos creados en codecombat.com) para así poder cobrar por ellos en el futuro, si es que eso es lo que termina pasando."
|
nutshell_description: "Cualquier recurso que te proveamos en el Editor de Niveles es gratis de usar como te plazca para la creación de Niveles. Sin embargo, nos reservamos el derecho de restringir la distribución de los niveles por sí mismos (aquellos creados en codecombat.com) para así poder cobrar por ellos en el futuro, si es que eso es lo que termina pasando."
|
||||||
canonical: "La versión en inglés de este documento es la versión canónica y definitiva. Si hay alguna discrepancia entre las traducciones, la versión en inglés toma precedencia."
|
canonical: "La versión en inglés de este documento es la versión canónica y definitiva. Si hay alguna discrepancia entre las traducciones, la versión en inglés toma precedencia."
|
||||||
# third_party_title: "Third Party Services"
|
third_party_title: "Servicios de Terceros"
|
||||||
# third_party_description: "CodeCombat uses the following third party services (among others):"
|
third_party_description: "CodeCombat utiliza los siguientes servicios de terceros (entre otros):"
|
||||||
|
|
||||||
ladder_prizes:
|
ladder_prizes:
|
||||||
title: "Premios de Torneos" # This section was for an old tournament and doesn't need new translations now.
|
title: "Premios de Torneos" # This section was for an old tournament and doesn't need new translations now.
|
||||||
|
|
|
@ -908,7 +908,7 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
|
||||||
next_course: "Следующий курс"
|
next_course: "Следующий курс"
|
||||||
coming_soon1: "Скоро появится"
|
coming_soon1: "Скоро появится"
|
||||||
# coming_soon2: "We are hard at work making more courses for you!"
|
# coming_soon2: "We are hard at work making more courses for you!"
|
||||||
# available_levels: "Available Levels"
|
available_levels: "Доступные уровни"
|
||||||
welcome_to_courses: "Искатели приключений, добро пожаловать на курсы!"
|
welcome_to_courses: "Искатели приключений, добро пожаловать на курсы!"
|
||||||
ready_to_play: "Готовы приступить к игре?"
|
ready_to_play: "Готовы приступить к игре?"
|
||||||
start_new_game: "Начать новую игру"
|
start_new_game: "Начать новую игру"
|
||||||
|
@ -930,19 +930,19 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
|
||||||
view_class: "смотреть класс"
|
view_class: "смотреть класс"
|
||||||
view_levels: "смотреть уровни"
|
view_levels: "смотреть уровни"
|
||||||
join_class: "Присоединиться к классу"
|
join_class: "Присоединиться к классу"
|
||||||
# ask_teacher_for_code: "Ask your teacher if you have a CodeCombat class code! If so, enter it below:"
|
ask_teacher_for_code: "Спросите у вашего учителя код класса для CodeCombat! Введите его ниже:"
|
||||||
# enter_c_code: "<Enter Class Code>"
|
enter_c_code: "<Введите Код Класса>"
|
||||||
# join: "Присоединиться"
|
join: "Присоединиться"
|
||||||
# joining: "Joining class"
|
# joining: "Joining class"
|
||||||
course_complete: "Курс завершён"
|
course_complete: "Курс завершён"
|
||||||
play_arena: "Играть Арену"
|
play_arena: "Играть Арену"
|
||||||
# start: "Старт"
|
start: "Старт"
|
||||||
# last_level: "Последний уровень"
|
last_level: "Последний уровень"
|
||||||
welcome_to_hoc: "Искатели приключений, добро пожаловать на Час кода!"
|
welcome_to_hoc: "Искатели приключений, добро пожаловать на Час кода!"
|
||||||
# logged_in_as: "Logged in as:"
|
logged_in_as: "Вошли как:"
|
||||||
# not_you: "Не вы?"
|
not_you: "Не вы?"
|
||||||
# welcome_back: "Привет, искатель приключений, добро пожаловать!"
|
welcome_back: "Привет, искатель приключений, добро пожаловать!"
|
||||||
# continue_playing: "Continue Playing"
|
continue_playing: "Играть Дальше"
|
||||||
more_options: "Другие варианты:"
|
more_options: "Другие варианты:"
|
||||||
option1_header: "Вариант 1: Пригласить учеников по email"
|
option1_header: "Вариант 1: Пригласить учеников по email"
|
||||||
# option1_body: "Students will automatically be sent an invitation to join this class, and will need to create an account with a username and password."
|
# option1_body: "Students will automatically be sent an invitation to join this class, and will need to create an account with a username and password."
|
||||||
|
@ -952,7 +952,7 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
|
||||||
# option3_body: "Give students the following passcode to enter along with an email address, username and password when they create an account."
|
# option3_body: "Give students the following passcode to enter along with an email address, username and password when they create an account."
|
||||||
# thank_you_pref: "Thank you for your purchase! You can now assign"
|
# thank_you_pref: "Thank you for your purchase! You can now assign"
|
||||||
# thank_you_suff: "more students to paid courses."
|
# thank_you_suff: "more students to paid courses."
|
||||||
# return_to_class: "Return to classroom"
|
return_to_class: "Вернуться в класс"
|
||||||
return_to_course_man: "Вернуться к управлению курсом."
|
return_to_course_man: "Вернуться к управлению курсом."
|
||||||
# students_not_enrolled: "students not enrolled"
|
# students_not_enrolled: "students not enrolled"
|
||||||
total_all_classes: "Общее по всем классам"
|
total_all_classes: "Общее по всем классам"
|
||||||
|
@ -968,7 +968,7 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
|
||||||
# removing_user: "Removing user"
|
# removing_user: "Removing user"
|
||||||
# to_join_ask: "To join a class, ask your teacher for an unlock code."
|
# to_join_ask: "To join a class, ask your teacher for an unlock code."
|
||||||
# join_this_class: "Join Class"
|
# join_this_class: "Join Class"
|
||||||
# enter_here: "<Ввести здесь код разблокировки>"
|
enter_here: "<Ввести здесь код разблокировки>"
|
||||||
# successfully_joined: "Successfully joined"
|
# successfully_joined: "Successfully joined"
|
||||||
# click_to_start: "Click here to start taking"
|
# click_to_start: "Click here to start taking"
|
||||||
my_courses: "Мои курсы"
|
my_courses: "Мои курсы"
|
||||||
|
@ -976,7 +976,7 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
|
||||||
# use_school_email: "use your school email if you have one"
|
# use_school_email: "use your school email if you have one"
|
||||||
# unique_name: "a unique name no one has chosen"
|
# unique_name: "a unique name no one has chosen"
|
||||||
# pick_something: "pick something you can remember"
|
# pick_something: "pick something you can remember"
|
||||||
# class_code: "Class Code"
|
class_code: "Код класса"
|
||||||
optional_ask: "Как вариант - попросите учителя дать вам какой-нибудь!"
|
optional_ask: "Как вариант - попросите учителя дать вам какой-нибудь!"
|
||||||
optional_school: "Не обязательное - в какую школу вы ходите?"
|
optional_school: "Не обязательное - в какую школу вы ходите?"
|
||||||
start_playing: "Начать играть"
|
start_playing: "Начать играть"
|
||||||
|
@ -1000,17 +1000,17 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
|
||||||
# additional_resources_4_mid: "Schools Page"
|
# additional_resources_4_mid: "Schools Page"
|
||||||
# additional_resources_4_suff: "to learn more about CodeCombat's classroom offerings."
|
# additional_resources_4_suff: "to learn more about CodeCombat's classroom offerings."
|
||||||
your_classes: "Ваши классы"
|
your_classes: "Ваши классы"
|
||||||
# no_classes: "No classes yet!"
|
no_classes: "Ещё нет классов!"
|
||||||
create_new_class1: "создать новый класс"
|
create_new_class1: "создать новый класс"
|
||||||
# available_courses: "Available Courses"
|
available_courses: "Доступные курсы"
|
||||||
# unused_enrollments: "Unused enrollments available:"
|
# unused_enrollments: "Unused enrollments available:"
|
||||||
# students_access: "All students get access to Introduction to Computer Science for free. One enrollment per student is required to assign them to paid CodeCombat courses. A single student does not need multiple enrollments to access all paid courses."
|
# students_access: "All students get access to Introduction to Computer Science for free. One enrollment per student is required to assign them to paid CodeCombat courses. A single student does not need multiple enrollments to access all paid courses."
|
||||||
# active_courses: "active courses"
|
active_courses: "активные курсы"
|
||||||
no_students: "Ещё нет учеников!"
|
no_students: "Ещё нет учеников!"
|
||||||
add_students1: "добавить учеников"
|
add_students1: "добавить учеников"
|
||||||
view_edit: "смотреть/редактировать"
|
view_edit: "смотреть/редактировать"
|
||||||
students_enrolled: "учеников зачислено"
|
students_enrolled: "учеников зачислено"
|
||||||
# length: "Length:"
|
length: "Длительность:"
|
||||||
|
|
||||||
classes:
|
classes:
|
||||||
archmage_title: "Архимаг"
|
archmage_title: "Архимаг"
|
||||||
|
@ -1256,9 +1256,9 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
|
||||||
league: "Лига"
|
league: "Лига"
|
||||||
red_ai: "CPU красного" # "Red AI Wins", at end of multiplayer match playback
|
red_ai: "CPU красного" # "Red AI Wins", at end of multiplayer match playback
|
||||||
blue_ai: "CPU синего"
|
blue_ai: "CPU синего"
|
||||||
wins: "Победы" # At end of multiplayer match playback
|
wins: "Побеждает" # At end of multiplayer match playback
|
||||||
humans: "Красный" # Ladder page display team name
|
humans: "Красных" # Ladder page display team name
|
||||||
ogres: "Синий"
|
ogres: "Синих"
|
||||||
|
|
||||||
user:
|
user:
|
||||||
stats: "Характеристики"
|
stats: "Характеристики"
|
||||||
|
|
|
@ -8,23 +8,23 @@ module.exports = nativeDescription: "српски", englishDescription: "Serbian
|
||||||
# old_browser: "Uh oh, your browser is too old to run CodeCombat. Sorry!" # Warning that shows up on really old Firefox/Chrome/Safari
|
# old_browser: "Uh oh, your browser is too old to run CodeCombat. Sorry!" # Warning that shows up on really old Firefox/Chrome/Safari
|
||||||
# old_browser_suffix: "You can try anyway, but it probably won't work."
|
# old_browser_suffix: "You can try anyway, but it probably won't work."
|
||||||
# ipad_browser: "Bad news: CodeCombat doesn't run on iPad in the browser. Good news: our native iPad app is awaiting Apple approval."
|
# ipad_browser: "Bad news: CodeCombat doesn't run on iPad in the browser. Good news: our native iPad app is awaiting Apple approval."
|
||||||
# campaign: "Campaign"
|
campaign: "Кампања"
|
||||||
# for_beginners: "For Beginners"
|
for_beginners: "За почетнике"
|
||||||
# multiplayer: "Multiplayer" # Not currently shown on home page
|
multiplayer: "Мултиплејер" # Not currently shown on home page
|
||||||
# for_developers: "For Developers" # Not currently shown on home page.
|
for_developers: "За Девелопере" # Not currently shown on home page.
|
||||||
# or_ipad: "Or download for iPad"
|
or_ipad: "Или скини за iPad"
|
||||||
|
|
||||||
nav:
|
nav:
|
||||||
play: "Нивои" # The top nav bar entry where players choose which levels to play
|
play: "Нивои" # The top nav bar entry where players choose which levels to play
|
||||||
# community: "Community"
|
community: "Заједница"
|
||||||
# courses: "Courses"
|
courses: "Курсеви"
|
||||||
editor: "Уређивач"
|
editor: "Уређивач"
|
||||||
blog: "Блог"
|
blog: "Блог"
|
||||||
forum: "Форум"
|
forum: "Форум"
|
||||||
# account: "Account"
|
account: "Налог"
|
||||||
# profile: "Profile"
|
profile: "Профил"
|
||||||
# stats: "Stats"
|
stats: "Статистика"
|
||||||
# code: "Code"
|
code: "Код"
|
||||||
admin: "Админ" # Only shows up when you are an admin
|
admin: "Админ" # Only shows up when you are an admin
|
||||||
home: "Почетна"
|
home: "Почетна"
|
||||||
contribute: "Допринеси"
|
contribute: "Допринеси"
|
||||||
|
@ -32,8 +32,8 @@ module.exports = nativeDescription: "српски", englishDescription: "Serbian
|
||||||
about: "О нама"
|
about: "О нама"
|
||||||
contact: "Контакт"
|
contact: "Контакт"
|
||||||
twitter_follow: "Прати"
|
twitter_follow: "Прати"
|
||||||
# teachers: "Teachers"
|
teachers: "Учитељи"
|
||||||
# careers: "Careers"
|
careers: "Каријере"
|
||||||
|
|
||||||
modal:
|
modal:
|
||||||
close: "Затвори"
|
close: "Затвори"
|
||||||
|
@ -51,29 +51,29 @@ module.exports = nativeDescription: "српски", englishDescription: "Serbian
|
||||||
subscribe_as_diplomat: "Претплати се као Дипломата"
|
subscribe_as_diplomat: "Претплати се као Дипломата"
|
||||||
|
|
||||||
play:
|
play:
|
||||||
# play_as: "Play As" # Ladder page
|
play_as: "Играј као" # Ladder page
|
||||||
# compete: "Compete!" # Course details page
|
compete: "Такмичи се!" # Course details page
|
||||||
# spectate: "Spectate" # Ladder page
|
spectate: "Посматрај" # Ladder page
|
||||||
# players: "players" # Hover over a level on /play
|
players: "играчи" # Hover over a level on /play
|
||||||
# hours_played: "hours played" # Hover over a level on /play
|
hours_played: "потребно сати играња" # Hover over a level on /play
|
||||||
# items: "Items" # Tooltip on item shop button from /play
|
items: "Ствари" # Tooltip on item shop button from /play
|
||||||
# unlock: "Unlock" # For purchasing items and heroes
|
unlock: "Откључај" # For purchasing items and heroes
|
||||||
# confirm: "Confirm"
|
confirm: "Потврди"
|
||||||
# owned: "Owned" # For items you own
|
owned: "У поседу" # For items you own
|
||||||
# locked: "Locked"
|
locked: "Закључани"
|
||||||
# purchasable: "Purchasable" # For a hero you unlocked but haven't purchased
|
purchasable: "Могуће купити" # For a hero you unlocked but haven't purchased
|
||||||
# available: "Available"
|
available: "Доступни"
|
||||||
# skills_granted: "Skills Granted" # Property documentation details
|
skills_granted: "Обезбеђени скилови" # Property documentation details
|
||||||
# heroes: "Heroes" # Tooltip on hero shop button from /play
|
heroes: "Хероји" # Tooltip on hero shop button from /play
|
||||||
# achievements: "Achievements" # Tooltip on achievement list button from /play
|
achievements: "Достигнућа" # Tooltip on achievement list button from /play
|
||||||
# account: "Account" # Tooltip on account button from /play
|
account: "Налог" # Tooltip on account button from /play
|
||||||
# settings: "Settings" # Tooltip on settings button from /play
|
settings: "Подешавања" # Tooltip on settings button from /play
|
||||||
# poll: "Poll" # Tooltip on poll button from /play
|
poll: "Покрени" # Tooltip on poll button from /play
|
||||||
# next: "Next" # Go from choose hero to choose inventory before playing a level
|
next: "Следећи" # Go from choose hero to choose inventory before playing a level
|
||||||
# change_hero: "Change Hero" # Go back from choose inventory to choose hero
|
change_hero: "Промени Хероја" # Go back from choose inventory to choose hero
|
||||||
# buy_gems: "Buy Gems"
|
buy_gems: "Купи драгуље"
|
||||||
# subscription_required: "Subscription Required"
|
subscription_required: "Потребна пријава"
|
||||||
# anonymous: "Anonymous Player"
|
anonymous: "Анонимни играч"
|
||||||
level_difficulty: "Тежина: "
|
level_difficulty: "Тежина: "
|
||||||
# play_classroom_version: "Play Classroom Version" # Choose a level in campaign version that you also can play in one of your courses
|
# play_classroom_version: "Play Classroom Version" # Choose a level in campaign version that you also can play in one of your courses
|
||||||
campaign_beginner: "Почетничка кампања"
|
campaign_beginner: "Почетничка кампања"
|
||||||
|
@ -97,72 +97,72 @@ module.exports = nativeDescription: "српски", englishDescription: "Serbian
|
||||||
login:
|
login:
|
||||||
sign_up: "Направи Налог"
|
sign_up: "Направи Налог"
|
||||||
log_in: "Улогуј Се"
|
log_in: "Улогуј Се"
|
||||||
# logging_in: "Logging In"
|
logging_in: "Логовање"
|
||||||
log_out: "Излогуј Се"
|
log_out: "Излогуј Се"
|
||||||
# forgot_password: "Forgot your password?"
|
forgot_password: "Да ли си заборавио шифру?"
|
||||||
# authenticate_gplus: "Authenticate G+"
|
# authenticate_gplus: "Authenticate G+"
|
||||||
# load_profile: "Load G+ Profile"
|
# load_profile: "Load G+ Profile"
|
||||||
# finishing: "Finishing"
|
finishing: "Завршавање"
|
||||||
# sign_in_with_facebook: "Sign in with Facebook"
|
sign_in_with_facebook: "Учлани се преко Фејсбука"
|
||||||
# sign_in_with_gplus: "Sign in with G+"
|
sign_in_with_gplus: "Учлани се преко Гугл +"
|
||||||
# signup_switch: "Want to create an account?"
|
signup_switch: "Да ли желиш да направиш налог?"
|
||||||
|
|
||||||
signup:
|
signup:
|
||||||
email_announcements: "Примај обавештења на мејл"
|
email_announcements: "Примај обавештења на мејл"
|
||||||
creating: "Прављење налога..."
|
creating: "Прављење налога..."
|
||||||
sign_up: "Упиши се"
|
sign_up: "Упиши се"
|
||||||
log_in: "улогуј се са шифром"
|
log_in: "улогуј се са шифром"
|
||||||
# required: "You need to log in before you can go that way."
|
required: "Мораш да се улогујеш пре него што наставиш"
|
||||||
# login_switch: "Already have an account?"
|
login_switch: "Већ имаш налог?"
|
||||||
# school_name: "School Name and City"
|
school_name: "Име школе и града"
|
||||||
# optional: "optional"
|
optional: "опционо"
|
||||||
# school_name_placeholder: "Example High School, Springfield, IL"
|
# school_name_placeholder: "Example High School, Springfield, IL"
|
||||||
|
|
||||||
recover:
|
recover:
|
||||||
recover_account_title: "Поврати налог"
|
recover_account_title: "Поврати налог"
|
||||||
# send_password: "Send Recovery Password"
|
send_password: "Пошаљи помоћну шифру"
|
||||||
# recovery_sent: "Recovery email sent."
|
recovery_sent: "Послат мејл за потврду опоравка."
|
||||||
|
|
||||||
# items:
|
items:
|
||||||
# primary: "Primary"
|
primary: "Примарни"
|
||||||
# secondary: "Secondary"
|
secondary: "Секундарни"
|
||||||
# armor: "Armor"
|
armor: "Оклоп"
|
||||||
# accessories: "Accessories"
|
accessories: "Опрема"
|
||||||
# misc: "Misc"
|
misc: "Остало"
|
||||||
# books: "Books"
|
books: "Књиге"
|
||||||
|
|
||||||
common:
|
common:
|
||||||
# back: "Back" # When used as an action verb, like "Navigate backward"
|
back: "Уназад" # When used as an action verb, like "Navigate backward"
|
||||||
# continue: "Continue" # When used as an action verb, like "Continue forward"
|
# continue: "Continue" # When used as an action verb, like "Continue forward"
|
||||||
loading: "Учитавање"
|
loading: "Учитавање"
|
||||||
saving: "Чување..."
|
saving: "Чување..."
|
||||||
sending: "Шаље се..."
|
sending: "Шаље се..."
|
||||||
# send: "Send"
|
send: "Пошаљи"
|
||||||
cancel: "Откажи"
|
cancel: "Откажи"
|
||||||
# save: "Save"
|
save: "Сачувај"
|
||||||
# publish: "Publish"
|
publish: "Објави"
|
||||||
# create: "Create"
|
create: "Створи"
|
||||||
# fork: "Fork"
|
# fork: "Fork"
|
||||||
play: "Нивои" # When used as an action verb, like "Play next level"
|
play: "Нивои" # When used as an action verb, like "Play next level"
|
||||||
# retry: "Retry"
|
# retry: "Retry"
|
||||||
# actions: "Actions"
|
# actions: "Actions"
|
||||||
# info: "Info"
|
info: "Инфо"
|
||||||
# help: "Help"
|
help: "Помоћ"
|
||||||
# watch: "Watch"
|
watch: "Одгледај"
|
||||||
# unwatch: "Unwatch"
|
unwatch: "Не гледај"
|
||||||
# submit_patch: "Submit Patch"
|
submit_patch: "Потврди закрпу"
|
||||||
# submit_changes: "Submit Changes"
|
submit_changes: "Потврди измене"
|
||||||
# save_changes: "Save Changes"
|
save_changes: "Сачувај измене"
|
||||||
|
|
||||||
general:
|
general:
|
||||||
# and: "and"
|
# and: "and"
|
||||||
name: "Име"
|
name: "Име"
|
||||||
# date: "Date"
|
date: "Датум"
|
||||||
# body: "Body"
|
body: "Тело"
|
||||||
# version: "Version"
|
version: "Верзија"
|
||||||
# pending: "Pending"
|
pending: "Учитавање"
|
||||||
# accepted: "Accepted"
|
accepted: "Прихваћен"
|
||||||
# rejected: "Rejected"
|
rejected: "Одбијен"
|
||||||
# withdrawn: "Withdrawn"
|
# withdrawn: "Withdrawn"
|
||||||
# accept: "Accept"
|
# accept: "Accept"
|
||||||
# reject: "Reject"
|
# reject: "Reject"
|
||||||
|
@ -178,103 +178,103 @@ module.exports = nativeDescription: "српски", englishDescription: "Serbian
|
||||||
# redo_prefix: "Redo"
|
# redo_prefix: "Redo"
|
||||||
# redo_shortcut: "(Ctrl+Shift+Z)"
|
# redo_shortcut: "(Ctrl+Shift+Z)"
|
||||||
# play_preview: "Play preview of current level"
|
# play_preview: "Play preview of current level"
|
||||||
# result: "Result"
|
result: "Резултат"
|
||||||
# results: "Results"
|
results: "Резултати"
|
||||||
# description: "Description"
|
description: "Опис"
|
||||||
or: "или"
|
or: "или"
|
||||||
# subject: "Subject"
|
subject: "Субјекат"
|
||||||
email: "Мејл"
|
email: "Мејл"
|
||||||
# password: "Password"
|
password: "Шифра"
|
||||||
message: "Порука"
|
message: "Порука"
|
||||||
# code: "Code"
|
code: "Код"
|
||||||
# ladder: "Ladder"
|
# ladder: "Ladder"
|
||||||
# when: "When"
|
# when: "When"
|
||||||
# opponent: "Opponent"
|
opponent: "Противник"
|
||||||
# rank: "Rank"
|
rank: "Чин"
|
||||||
# score: "Score"
|
score: "Поен"
|
||||||
# win: "Win"
|
win: "Победа"
|
||||||
# loss: "Loss"
|
loss: "Пораз"
|
||||||
# tie: "Tie"
|
tie: "Нерешено"
|
||||||
# easy: "Easy"
|
easy: "Лако"
|
||||||
# medium: "Medium"
|
medium: "Средње"
|
||||||
# hard: "Hard"
|
hard: "Тешко"
|
||||||
# player: "Player"
|
player: "Играч"
|
||||||
# player_level: "Level" # Like player level 5, not like level: Dungeons of Kithgard
|
player_level: "Ранг играча" # Like player level 5, not like level: Dungeons of Kithgard
|
||||||
# warrior: "Warrior"
|
warrior: "Ратник"
|
||||||
# ranger: "Ranger"
|
ranger: "Извиђач"
|
||||||
# wizard: "Wizard"
|
wizard: "Маг"
|
||||||
|
|
||||||
# units:
|
units:
|
||||||
# second: "second"
|
second: "секунда"
|
||||||
# seconds: "seconds"
|
seconds: "секунде"
|
||||||
# minute: "minute"
|
minute: "минут"
|
||||||
# minutes: "minutes"
|
minutes: "минути"
|
||||||
# hour: "hour"
|
hour: "сат"
|
||||||
# hours: "hours"
|
hours: "сати"
|
||||||
# day: "day"
|
day: "дан"
|
||||||
# days: "days"
|
days: "дани"
|
||||||
# week: "week"
|
week: "недеља"
|
||||||
# weeks: "weeks"
|
weeks: "недеље"
|
||||||
# month: "month"
|
month: "месец"
|
||||||
# months: "months"
|
months: "месеци"
|
||||||
# year: "year"
|
year: "година"
|
||||||
# years: "years"
|
years: "године"
|
||||||
|
|
||||||
play_level:
|
play_level:
|
||||||
# completed_level: "Completed Level:"
|
completed_level: "Завршен ниво:"
|
||||||
# course: "Course:"
|
course: "Курс:"
|
||||||
done: "Урађено"
|
done: "Урађено"
|
||||||
# next_level: "Next Level:"
|
next_level: "Следећи ниво:"
|
||||||
# next_game: "Next game"
|
next_game: "Следећа игра"
|
||||||
# show_menu: "Show game menu"
|
show_menu: "Види мени игре"
|
||||||
home: "Почетна" # Not used any more, will be removed soon.
|
home: "Почетна" # Not used any more, will be removed soon.
|
||||||
# level: "Level" # Like "Level: Dungeons of Kithgard"
|
level: "Ниво" # Like "Level: Dungeons of Kithgard"
|
||||||
# skip: "Skip"
|
skip: "Прескочи"
|
||||||
# game_menu: "Game Menu"
|
game_menu: "Мени игре"
|
||||||
guide: "Водич"
|
guide: "Водич"
|
||||||
restart: "Поновно учитавање"
|
restart: "Поновно учитавање"
|
||||||
goals: "Циљеви"
|
goals: "Циљеви"
|
||||||
# goal: "Goal"
|
goal: "Циљ"
|
||||||
# running: "Running..."
|
running: "Покретање..."
|
||||||
# success: "Success!"
|
success: "Успех!"
|
||||||
# incomplete: "Incomplete"
|
incomplete: "Недовољно"
|
||||||
# timed_out: "Ran out of time"
|
timed_out: "Истекло времe"
|
||||||
# failing: "Failing"
|
failing: "Губљење"
|
||||||
# control_bar_multiplayer: "Multiplayer"
|
control_bar_multiplayer: "Мултиплејер"
|
||||||
# control_bar_join_game: "Join Game"
|
control_bar_join_game: "Прикључи се игри"
|
||||||
# reload: "Reload"
|
reload: "Поновно учитавање"
|
||||||
reload_title: "Поновно учитавање целог кода?"
|
reload_title: "Поновно учитавање целог кода?"
|
||||||
reload_really: "Да ли сте сигурни да желите да кренете ниво испочетка?"
|
reload_really: "Да ли сте сигурни да желите да кренете ниво испочетка?"
|
||||||
reload_confirm: "Поновно учитавање свега"
|
reload_confirm: "Поновно учитавање свега"
|
||||||
# victory: "Victory"
|
victory: "Победа"
|
||||||
# victory_title_prefix: ""
|
victory_title_prefix: "Урааа победааа!"
|
||||||
victory_title_suffix: " Завршено"
|
victory_title_suffix: " Завршено"
|
||||||
victory_sign_up: "Пријави се за новости"
|
victory_sign_up: "Пријави се за новости"
|
||||||
victory_sign_up_poke: "Желиш ли да примаш најновије вести на мејл? Направи бесплатан налог и ми ћемо те обавештавати!"
|
victory_sign_up_poke: "Желиш ли да примаш најновије вести на мејл? Направи бесплатан налог и ми ћемо те обавештавати!"
|
||||||
victory_rate_the_level: "Оцени ниво: " # {change}
|
victory_rate_the_level: "Оцени ниво: " # {change}
|
||||||
# victory_return_to_ladder: "Return to Ladder"
|
victory_return_to_ladder: "Врати се на лествицу"
|
||||||
# victory_saving_progress: "Saving Progress"
|
victory_saving_progress: "Чување напретка"
|
||||||
victory_go_home: "Иди на почетну"
|
victory_go_home: "Иди на почетну"
|
||||||
victory_review: "Реци нам више!"
|
victory_review: "Реци нам више!"
|
||||||
# victory_review_placeholder: "How was the level?"
|
victory_review_placeholder: "Колико је био тежак ниво?"
|
||||||
victory_hour_of_code_done: "Јеси ли завршио?"
|
victory_hour_of_code_done: "Јеси ли завршио?"
|
||||||
victory_hour_of_code_done_yes: "Да, завршио сам свој Сат Кода!"
|
victory_hour_of_code_done_yes: "Да, завршио сам свој Сат Кода!"
|
||||||
# victory_experience_gained: "XP Gained"
|
victory_experience_gained: "Добијено искуство"
|
||||||
# victory_gems_gained: "Gems Gained"
|
victory_gems_gained: "Добијени драгуљи"
|
||||||
# victory_new_item: "New Item"
|
victory_new_item: "Нови Итем"
|
||||||
# victory_viking_code_school: "Holy smokes, that was a hard level you just beat! If you aren't already a software developer, you should be. You just got fast-tracked for acceptance with Viking Code School, where you can take your skills to the next level and become a professional web developer in 14 weeks."
|
# victory_viking_code_school: "Holy smokes, that was a hard level you just beat! If you aren't already a software developer, you should be. You just got fast-tracked for acceptance with Viking Code School, where you can take your skills to the next level and become a professional web developer in 14 weeks."
|
||||||
# victory_become_a_viking: "Become a Viking"
|
victory_become_a_viking: "Постани Викинг"
|
||||||
guide_title: "Водич"
|
guide_title: "Водич"
|
||||||
# tome_cast_button_run: "Run"
|
# tome_cast_button_run: "Run"
|
||||||
# tome_cast_button_running: "Running"
|
# tome_cast_button_running: "Running"
|
||||||
# tome_cast_button_ran: "Ran"
|
# tome_cast_button_ran: "Ran"
|
||||||
# tome_submit_button: "Submit"
|
tome_submit_button: "Потврди"
|
||||||
# tome_reload_method: "Reload original code for this method" # Title text for individual method reload button.
|
# tome_reload_method: "Reload original code for this method" # Title text for individual method reload button.
|
||||||
# tome_select_method: "Select a Method"
|
# tome_select_method: "Select a Method"
|
||||||
# tome_see_all_methods: "See all methods you can edit" # Title text for method list selector (shown when there are multiple programmable methods).
|
# tome_see_all_methods: "See all methods you can edit" # Title text for method list selector (shown when there are multiple programmable methods).
|
||||||
tome_select_a_thang: "Изабери неког за "
|
tome_select_a_thang: "Изабери неког за "
|
||||||
tome_available_spells: "Доступне чини"
|
tome_available_spells: "Доступне чини"
|
||||||
# tome_your_skills: "Your Skills"
|
tome_your_skills: "Твоје вештине"
|
||||||
# tome_current_method: "Current Method"
|
# tome_current_method: "Current Method"
|
||||||
# code_saved: "Code Saved"
|
# code_saved: "Code Saved"
|
||||||
# skip_tutorial: "Skip (esc)"
|
# skip_tutorial: "Skip (esc)"
|
||||||
|
@ -361,30 +361,30 @@ module.exports = nativeDescription: "српски", englishDescription: "Serbian
|
||||||
# multiplayer_caption: "Play with friends!"
|
# multiplayer_caption: "Play with friends!"
|
||||||
# auth_caption: "Save your progress."
|
# auth_caption: "Save your progress."
|
||||||
|
|
||||||
# leaderboard:
|
leaderboard:
|
||||||
# view_other_solutions: "View Leaderboards"
|
view_other_solutions: "Види табелу напредовања"
|
||||||
# scores: "Scores"
|
scores: "Резултати"
|
||||||
# top_players: "Top Players by"
|
top_players: "Рангирање играча по"
|
||||||
# day: "Today"
|
day: "Данас"
|
||||||
# week: "This Week"
|
week: "Ове недеље"
|
||||||
# all: "All-Time"
|
all: "Све-време"
|
||||||
# time: "Time"
|
time: "Време"
|
||||||
# damage_taken: "Damage Taken"
|
damage_taken: "Претпљена штета"
|
||||||
# damage_dealt: "Damage Dealt"
|
damage_dealt: "Нанета штета"
|
||||||
# difficulty: "Difficulty"
|
difficulty: "Тежина"
|
||||||
# gold_collected: "Gold Collected"
|
gold_collected: "Сакупљено злата"
|
||||||
|
|
||||||
# inventory:
|
inventory:
|
||||||
# equipped_item: "Equipped"
|
equipped_item: "Опремљен"
|
||||||
# required_purchase_title: "Required"
|
required_purchase_title: "Потребно"
|
||||||
# available_item: "Available"
|
available_item: "Доступно"
|
||||||
# restricted_title: "Restricted"
|
restricted_title: "Забрањено"
|
||||||
# should_equip: "(double-click to equip)"
|
should_equip: "(Дупли-клик за опремање)"
|
||||||
# equipped: "(equipped)"
|
equipped: "(опремљен/а)"
|
||||||
# locked: "(locked)"
|
# locked: "(locked)"
|
||||||
# restricted: "(restricted in this level)"
|
# restricted: "(restricted in this level)"
|
||||||
# equip: "Equip"
|
equip: "Опреми"
|
||||||
# unequip: "Unequip"
|
unequip: "Скини"
|
||||||
|
|
||||||
# buy_gems:
|
# buy_gems:
|
||||||
# few_gems: "A few gems"
|
# few_gems: "A few gems"
|
||||||
|
@ -458,12 +458,12 @@ module.exports = nativeDescription: "српски", englishDescription: "Serbian
|
||||||
# subscribe_prepaid: "Click Subscribe to use prepaid code"
|
# subscribe_prepaid: "Click Subscribe to use prepaid code"
|
||||||
# using_prepaid: "Using prepaid code for monthly subscription"
|
# using_prepaid: "Using prepaid code for monthly subscription"
|
||||||
|
|
||||||
# choose_hero:
|
choose_hero:
|
||||||
# choose_hero: "Choose Your Hero"
|
choose_hero: "Изабери свог хероја"
|
||||||
# programming_language: "Programming Language"
|
programming_language: "Програмски језик"
|
||||||
# programming_language_description: "Which programming language do you want to use?"
|
programming_language_description: "Који програмски језик желиш да користиш у игри?"
|
||||||
# default: "Default"
|
# default: "Default"
|
||||||
# experimental: "Experimental"
|
experimental: "Експеро+иментални"
|
||||||
# python_blurb: "Simple yet powerful, great for beginners and experts."
|
# python_blurb: "Simple yet powerful, great for beginners and experts."
|
||||||
# javascript_blurb: "The language of the web. (Not the same as Java.)"
|
# javascript_blurb: "The language of the web. (Not the same as Java.)"
|
||||||
# coffeescript_blurb: "Nicer JavaScript syntax."
|
# coffeescript_blurb: "Nicer JavaScript syntax."
|
||||||
|
|
|
@ -28,6 +28,10 @@ module.exports = class SuperModel extends Backbone.Model
|
||||||
unfinished
|
unfinished
|
||||||
|
|
||||||
loadModel: (model, name, fetchOptions, value=1) ->
|
loadModel: (model, name, fetchOptions, value=1) ->
|
||||||
|
# Deprecating name. Handle if name is not included
|
||||||
|
value = fetchOptions if _.isNumber(fetchOptions)
|
||||||
|
fetchOptions = name if _.isObject(name)
|
||||||
|
|
||||||
# hero-ladder levels need remote opponent_session for latest session data (e.g. code)
|
# hero-ladder levels need remote opponent_session for latest session data (e.g. code)
|
||||||
# Can't apply to everything since other features rely on cached models being more recent (E.g. level_session)
|
# Can't apply to everything since other features rely on cached models being more recent (E.g. level_session)
|
||||||
# E.g.#2 heroConfig isn't necessarily saved to db in world map inventory modal, so we need to load the cached session on level start
|
# E.g.#2 heroConfig isn't necessarily saved to db in world map inventory modal, so we need to load the cached session on level start
|
||||||
|
@ -48,6 +52,10 @@ module.exports = class SuperModel extends Backbone.Model
|
||||||
return res
|
return res
|
||||||
|
|
||||||
loadCollection: (collection, name, fetchOptions, value=1) ->
|
loadCollection: (collection, name, fetchOptions, value=1) ->
|
||||||
|
# Deprecating name. Handle if name is not included
|
||||||
|
value = fetchOptions if _.isNumber(fetchOptions)
|
||||||
|
fetchOptions = name if _.isObject(name)
|
||||||
|
|
||||||
url = collection.getURL()
|
url = collection.getURL()
|
||||||
if cachedCollection = @collections[url]
|
if cachedCollection = @collections[url]
|
||||||
console.debug 'Collection cache hit', url, 'already loaded', cachedCollection.loaded
|
console.debug 'Collection cache hit', url, 'already loaded', cachedCollection.loaded
|
||||||
|
@ -132,9 +140,13 @@ module.exports = class SuperModel extends Backbone.Model
|
||||||
# Tracking resources being loaded for this supermodel
|
# Tracking resources being loaded for this supermodel
|
||||||
|
|
||||||
finished: ->
|
finished: ->
|
||||||
return @progress is 1.0 or not @denom
|
return (@progress is 1.0) or (not @denom) or @failed
|
||||||
|
|
||||||
addModelResource: (modelOrCollection, name, fetchOptions, value=1) ->
|
addModelResource: (modelOrCollection, name, fetchOptions, value=1) ->
|
||||||
|
# Deprecating name. Handle if name is not included
|
||||||
|
value = fetchOptions if _.isNumber(fetchOptions)
|
||||||
|
fetchOptions = name if _.isObject(name)
|
||||||
|
|
||||||
modelOrCollection.saveBackups = modelOrCollection.saveBackups or @shouldSaveBackups(modelOrCollection)
|
modelOrCollection.saveBackups = modelOrCollection.saveBackups or @shouldSaveBackups(modelOrCollection)
|
||||||
@checkName(name)
|
@checkName(name)
|
||||||
res = new ModelResource(modelOrCollection, name, fetchOptions, value)
|
res = new ModelResource(modelOrCollection, name, fetchOptions, value)
|
||||||
|
@ -145,20 +157,25 @@ module.exports = class SuperModel extends Backbone.Model
|
||||||
@removeResource _.find(@resources, (resource) -> resource?.model is modelOrCollection)
|
@removeResource _.find(@resources, (resource) -> resource?.model is modelOrCollection)
|
||||||
|
|
||||||
addRequestResource: (name, jqxhrOptions, value=1) ->
|
addRequestResource: (name, jqxhrOptions, value=1) ->
|
||||||
|
# Deprecating name. Handle if name is not included
|
||||||
|
value = jqxhrOptions if _.isNumber(jqxhrOptions)
|
||||||
|
jqxhrOptions = name if _.isObject(name)
|
||||||
|
|
||||||
@checkName(name)
|
@checkName(name)
|
||||||
res = new RequestResource(name, jqxhrOptions, value)
|
res = new RequestResource(name, jqxhrOptions, value)
|
||||||
@storeResource(res, value)
|
@storeResource(res, value)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
addSomethingResource: (name, value=1) ->
|
addSomethingResource: (name, value=1) ->
|
||||||
|
value = name if _.isNumber(name)
|
||||||
@checkName(name)
|
@checkName(name)
|
||||||
res = new SomethingResource(name, value)
|
res = new SomethingResource(name, value)
|
||||||
@storeResource(res, value)
|
@storeResource(res, value)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
checkName: (name) ->
|
checkName: (name) ->
|
||||||
if not name
|
if _.isString(name)
|
||||||
throw new Error('Resource name should not be empty.')
|
console.warn("SuperModel name property deprecated. Remove '#{name}' from code.")
|
||||||
|
|
||||||
storeResource: (resource, value) ->
|
storeResource: (resource, value) ->
|
||||||
@rid++
|
@rid++
|
||||||
|
@ -186,6 +203,7 @@ module.exports = class SuperModel extends Backbone.Model
|
||||||
|
|
||||||
onResourceFailed: (r) ->
|
onResourceFailed: (r) ->
|
||||||
return unless @resources[r.rid]
|
return unless @resources[r.rid]
|
||||||
|
@failed = true
|
||||||
@trigger('failed', resource: r)
|
@trigger('failed', resource: r)
|
||||||
r.clean()
|
r.clean()
|
||||||
|
|
||||||
|
|
|
@ -5,3 +5,17 @@ module.exports = class TrialRequest extends CocoModel
|
||||||
@className: 'TrialRequest'
|
@className: 'TrialRequest'
|
||||||
@schema: schema
|
@schema: schema
|
||||||
urlRoot: '/db/trial.request'
|
urlRoot: '/db/trial.request'
|
||||||
|
|
||||||
|
nameString: ->
|
||||||
|
props = @get('properties')
|
||||||
|
values = _.filter(_.at(props, 'name', 'email'))
|
||||||
|
return values.join(' / ')
|
||||||
|
|
||||||
|
locationString: ->
|
||||||
|
props = @get('properties')
|
||||||
|
values = _.filter(_.at(props, 'city', 'state', 'country'))
|
||||||
|
return values.join(' ')
|
||||||
|
|
||||||
|
educationLevelString: ->
|
||||||
|
levels = @get('properties').educationLevel or []
|
||||||
|
return levels.join(', ')
|
||||||
|
|
|
@ -118,6 +118,9 @@ _.extend CampaignSchema.properties, {
|
||||||
campaign: c.shortString title: 'Campaign', description: 'Which campaign this level is part of (like "desert").', format: 'hidden' # Automatically set by campaign editor.
|
campaign: c.shortString title: 'Campaign', description: 'Which campaign this level is part of (like "desert").', format: 'hidden' # Automatically set by campaign editor.
|
||||||
campaignIndex: c.int title: 'Campaign Index', description: 'The 0-based index of this level in its campaign.', format: 'hidden' # Automatically set by campaign editor.
|
campaignIndex: c.int title: 'Campaign Index', description: 'The 0-based index of this level in its campaign.', format: 'hidden' # Automatically set by campaign editor.
|
||||||
|
|
||||||
|
scoreTypes: c.array {title: 'Score Types', description: 'What metric to show leaderboards for.', uniqueItems: true},
|
||||||
|
c.shortString(title: 'Score Type', 'enum': ['time', 'damage-taken', 'damage-dealt', 'gold-collected', 'difficulty']) # TODO: good version of LoC; total gear value.
|
||||||
|
|
||||||
tasks: c.array {title: 'Tasks', description: 'Tasks to be completed for this level.'}, c.task
|
tasks: c.array {title: 'Tasks', description: 'Tasks to be completed for this level.'}, c.task
|
||||||
concepts: c.array {title: 'Programming Concepts', description: 'Which programming concepts this level covers.'}, c.concept
|
concepts: c.array {title: 'Programming Concepts', description: 'Which programming concepts this level covers.'}, c.concept
|
||||||
|
|
||||||
|
|
|
@ -254,6 +254,7 @@ LevelSchema = c.object {
|
||||||
'default':
|
'default':
|
||||||
name: 'Ineffable Wizardry'
|
name: 'Ineffable Wizardry'
|
||||||
description: 'This level is indescribably flarmy.'
|
description: 'This level is indescribably flarmy.'
|
||||||
|
tasks: (name: t, complete: false for t in defaultTasks)
|
||||||
documentation: {}
|
documentation: {}
|
||||||
scripts: []
|
scripts: []
|
||||||
thangs: []
|
thangs: []
|
||||||
|
|
15
app/styles/core/loading-error.sass
Normal file
15
app/styles/core/loading-error.sass
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#loading-error
|
||||||
|
padding: 20px
|
||||||
|
|
||||||
|
.btn
|
||||||
|
margin-top: 20px
|
||||||
|
|
||||||
|
.login-btn
|
||||||
|
margin-right: 10px
|
||||||
|
|
||||||
|
#not-found-img
|
||||||
|
max-width: 20%
|
||||||
|
margin: 20px 0
|
||||||
|
|
||||||
|
#links-row
|
||||||
|
margin-top: 50px
|
3
app/styles/editor/level/modal/artisan-guide-modal.sass
Normal file
3
app/styles/editor/level/modal/artisan-guide-modal.sass
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#artisan-guide-modal
|
||||||
|
.centered-stack
|
||||||
|
text-align: center
|
19
app/styles/editor/level/tasks-tab.sass
Normal file
19
app/styles/editor/level/tasks-tab.sass
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#editor-level-tasks-tab-view
|
||||||
|
td
|
||||||
|
cursor: pointer
|
||||||
|
.task-check
|
||||||
|
width: 5em
|
||||||
|
.task-check, .task-check *
|
||||||
|
margin: auto
|
||||||
|
text-align: center
|
||||||
|
.edit-cell
|
||||||
|
width: 5em
|
||||||
|
.edit-cell, .edit-cell *
|
||||||
|
margin: auto
|
||||||
|
text-align: center
|
||||||
|
.task-name
|
||||||
|
margin: auto
|
||||||
|
.start-edit
|
||||||
|
cursor: pointer
|
||||||
|
.no-article
|
||||||
|
color: rgba(160, 0, 0, 1)
|
|
@ -280,7 +280,7 @@ $gameControlMargin: 30px
|
||||||
opacity: 1
|
opacity: 1
|
||||||
padding: 3px 9px
|
padding: 3px 9px
|
||||||
|
|
||||||
&.complete
|
&.shows-leaderboard
|
||||||
.start-level, .view-solutions
|
.start-level, .view-solutions
|
||||||
min-width: calc(50% - 5px)
|
min-width: calc(50% - 5px)
|
||||||
display: inline-block
|
display: inline-block
|
||||||
|
|
33
app/styles/request-quote-view.sass
Normal file
33
app/styles/request-quote-view.sass
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#request-quote-view
|
||||||
|
|
||||||
|
label
|
||||||
|
margin-bottom: 2px
|
||||||
|
|
||||||
|
.row
|
||||||
|
margin: 10px 0
|
||||||
|
|
||||||
|
.help-block
|
||||||
|
margin: 0
|
||||||
|
|
||||||
|
p
|
||||||
|
margin: 0 0 20px
|
||||||
|
|
||||||
|
hr
|
||||||
|
margin: 30px 0
|
||||||
|
|
||||||
|
.checkbox, .checkbox-inline
|
||||||
|
margin: 0
|
||||||
|
|
||||||
|
#anything-else-row
|
||||||
|
margin: 50px 0 20px
|
||||||
|
|
||||||
|
#other-education-level-input
|
||||||
|
display: inline-block
|
||||||
|
width: 200px
|
||||||
|
margin-left: 5px
|
||||||
|
|
||||||
|
#submit-request-btn
|
||||||
|
margin-left: 10px
|
||||||
|
|
||||||
|
#login-btn
|
||||||
|
margin-right: 10px
|
|
@ -18,9 +18,9 @@ block content
|
||||||
th Applicant
|
th Applicant
|
||||||
th School
|
th School
|
||||||
th Location
|
th Location
|
||||||
th Age
|
th Age / Level
|
||||||
th Students
|
th Students
|
||||||
th How Found
|
th How Found / Notes
|
||||||
th Status
|
th Status
|
||||||
tbody
|
tbody
|
||||||
- var numReviewed = 0
|
- var numReviewed = 0
|
||||||
|
@ -35,13 +35,14 @@ block content
|
||||||
td.reviewed
|
td.reviewed
|
||||||
if trialRequest.get('reviewDate')
|
if trialRequest.get('reviewDate')
|
||||||
span= trialRequest.get('reviewDate').substring(0, 10)
|
span= trialRequest.get('reviewDate').substring(0, 10)
|
||||||
|
- var props = trialRequest.get('properties')
|
||||||
td
|
td
|
||||||
a(href="/user/#{trialRequest.get('applicant')}")= trialRequest.get('properties').email
|
a(href="/user/#{trialRequest.get('applicant')}")= trialRequest.nameString()
|
||||||
td= trialRequest.get('properties').school
|
td= props.school || props.organization
|
||||||
td= trialRequest.get('properties').location
|
td= props.location || trialRequest.locationString()
|
||||||
td= trialRequest.get('properties').age
|
td= props.age || trialRequest.educationLevelString()
|
||||||
td= trialRequest.get('properties').numStudents
|
td= props.numStudents
|
||||||
td= trialRequest.get('properties').heardAbout
|
td= props.heardAbout || props.notes
|
||||||
td.status-cell
|
td.status-cell
|
||||||
if trialRequest.get('status') === 'submitted'
|
if trialRequest.get('status') === 'submitted'
|
||||||
button.btn.btn-xs.btn-success.btn-approve(data-trial-request-id=trialRequest.id) Approve
|
button.btn.btn-xs.btn-success.btn-approve(data-trial-request-id=trialRequest.id) Approve
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
| :
|
| :
|
||||||
.input-border
|
.input-border
|
||||||
if me.get('name')
|
if me.get('name')
|
||||||
input#name.input-large.form-control(name="name", type="text", value="#{me.get('name')}")
|
input#name.input-large.form-control(name="name", type="text", value=me.get('name'))
|
||||||
else
|
else
|
||||||
input#name.input-large.form-control(name="name", type="text", value="", placeholder="e.g. Alex W the Skater")
|
input#name.input-large.form-control(name="name", type="text", value="", placeholder="e.g. Alex W the Skater")
|
||||||
.col-md-6
|
.col-md-6
|
||||||
|
@ -62,7 +62,7 @@
|
||||||
span(data-i18n="signup.optional") optional
|
span(data-i18n="signup.optional") optional
|
||||||
| ):
|
| ):
|
||||||
.input-border
|
.input-border
|
||||||
input#school-input.input-large.form-control(name="schoolName", data-i18n="[placeholder]signup.school_name_placeholder")
|
input#school-input.input-large.form-control(name="schoolName", data-i18n="[placeholder]signup.school_name_placeholder", value=formValues.schoolName || '')
|
||||||
.form-group.checkbox
|
.form-group.checkbox
|
||||||
label.control-label(for="subscribe")
|
label.control-label(for="subscribe")
|
||||||
.input-border
|
.input-border
|
||||||
|
|
|
@ -1,28 +1,97 @@
|
||||||
.alert.alert-danger.loading-error-alert
|
#loading-error.text-center
|
||||||
span(data-i18n="loading_error.could_not_load") Error loading from server
|
if jqxhr.status === 401
|
||||||
span (
|
h1
|
||||||
span(data-i18n="resources.#{name}")
|
span.spr 401:
|
||||||
span )
|
span(data-i18n="loading_error.login_required")
|
||||||
if !responseText
|
p(data-i18n="loading_error.login_required_desc")
|
||||||
strong(data-i18n="loading_error.connection_failure") Connection failed.
|
button.login-btn.btn.btn-primary(data-i18n="login.log_in")
|
||||||
else if status === 401
|
button#create-account-btn.btn.btn-primary(data-i18n="login.sign_up")
|
||||||
strong(data-i18n="loading_error.unauthorized") You need to be signed in. Do you have cookies disabled?
|
|
||||||
else if status === 403
|
|
||||||
strong(data-i18n="loading_error.forbidden") You do not have the permissions.
|
|
||||||
else if status === 404
|
|
||||||
strong(data-i18n="loading_error.not_found") Not found.
|
|
||||||
else if status === 405
|
|
||||||
strong(data-i18n="loading_error.not_allowed") Method not allowed.
|
|
||||||
else if status === 408
|
|
||||||
strong(data-i18n="loading_error.timeout") Server timeout.
|
|
||||||
else if status === 409
|
|
||||||
strong(data-i18n="loading_error.conflict") Resource conflict.
|
|
||||||
else if status === 422
|
|
||||||
strong(data-i18n="loading_error.bad_input") Bad input.
|
|
||||||
else if status >= 500
|
|
||||||
strong(data-i18n="loading_error.server_error") Server error.
|
|
||||||
else
|
|
||||||
strong(data-i18n="loading_error.unknown") Unknown error.
|
|
||||||
|
|
||||||
button.btn.btn-xs.retry-loading-resource(data-i18n="common.retry", data-resource-index=resourceIndex) Retry
|
// 402 currently not in use. TODO: Set it up
|
||||||
button.btn.btn-xs.skip-loading-resource(data-i18n="play_level.skip", data-resource-index=resourceIndex) Skip
|
else if jqxhr.status === 402
|
||||||
|
h2 402: Payment Required
|
||||||
|
|
||||||
|
else if jqxhr.status === 403
|
||||||
|
h1
|
||||||
|
span.spr 403:
|
||||||
|
span(data-i18n="loading_error.forbidden") Forbidden
|
||||||
|
p(data-i18n="loading_error.forbidden_desc")
|
||||||
|
|
||||||
|
// this should make no diff... but sometimes the server returns 403 when it should return 401
|
||||||
|
if !me.isAnonymous()
|
||||||
|
button#logout-btn.btn.btn-primary(data-i18n="login.log_out")
|
||||||
|
|
||||||
|
else if jqxhr.status === 404
|
||||||
|
h1
|
||||||
|
span.spr 404:
|
||||||
|
span(data-i18n="loading_error.not_found")
|
||||||
|
- var num = Math.floor(Math.random() * 3) + 1;
|
||||||
|
img#not-found-img(src="/images/pages/not_found/404_#{num}.png")
|
||||||
|
p(data-i18n="loading_error.not_found_desc")
|
||||||
|
|
||||||
|
else if !jqxhr.status
|
||||||
|
h1(data-i18n="loading_error.connection_failure")
|
||||||
|
p(data-i18n="loading_error.connection_failure_desc")
|
||||||
|
|
||||||
|
else
|
||||||
|
if jqxhr.status === 408
|
||||||
|
h1
|
||||||
|
span.spr 408:
|
||||||
|
span(data-i18n="loading_error.timeout")
|
||||||
|
else if jqxhr.status >= 500 && jqxhr.status <= 599
|
||||||
|
h1
|
||||||
|
span.spr #{jqxhr.status}:
|
||||||
|
span(data-i18n="loading_error.server_error")
|
||||||
|
else
|
||||||
|
h1(data-i18n="loading_error.unknown")
|
||||||
|
|
||||||
|
p(data-i18n="loading_error.general_desc")
|
||||||
|
|
||||||
|
#links-row.row
|
||||||
|
.col-sm-3
|
||||||
|
ul.list-unstyled
|
||||||
|
li
|
||||||
|
strong(data-i18n="common.help")
|
||||||
|
li
|
||||||
|
a(href="/", data-i18n="nav.home")
|
||||||
|
li
|
||||||
|
a(href=view.forumLink(), data-i18n="nav.forum")
|
||||||
|
li
|
||||||
|
a(tabindex=-1, data-toggle="coco-modal", data-target="core/ContactModal", data-i18n="nav.contact")
|
||||||
|
li
|
||||||
|
a(href='/community', data-i18n="nav.community")
|
||||||
|
|
||||||
|
.col-sm-3
|
||||||
|
ul.list-unstyled
|
||||||
|
li
|
||||||
|
strong(data-i18n="courses.students")
|
||||||
|
li
|
||||||
|
a(href="/courses/students", data-i18n="nav.learn_to_code")
|
||||||
|
if me.isAnonymous()
|
||||||
|
li
|
||||||
|
a.login-btn(data-i18n="login.log_in")
|
||||||
|
li
|
||||||
|
a(href="/courses", data-i18n="courses.join_class")
|
||||||
|
|
||||||
|
.col-sm-3
|
||||||
|
ul.list-unstyled
|
||||||
|
li
|
||||||
|
strong(data-i18n="nav.teachers")
|
||||||
|
li
|
||||||
|
a(href="/schools", data-i18n="about.why_codecombat")
|
||||||
|
if me.isAnonymous()
|
||||||
|
li
|
||||||
|
a.login-btn(data-i18n="login.log_in")
|
||||||
|
li
|
||||||
|
a(href="/courses/teachers", data-i18n="nav.create_a_class")
|
||||||
|
|
||||||
|
.col-sm-3
|
||||||
|
ul.list-unstyled
|
||||||
|
li
|
||||||
|
strong(data-i18n="nav.other")
|
||||||
|
li
|
||||||
|
a(href="http://blog.codecombat.com/", data-i18n="nav.blog")
|
||||||
|
li
|
||||||
|
a(href="https://www.facebook.com/codecombat", data-i18n="nav.facebook")
|
||||||
|
li
|
||||||
|
a(href="https://twitter.com/codecombat", data-i18n="nav.twitter")
|
|
@ -43,7 +43,7 @@ block content
|
||||||
span.spl(data-i18n="courses.educator_wiki_suff")
|
span.spl(data-i18n="courses.educator_wiki_suff")
|
||||||
li
|
li
|
||||||
span.spr(data-i18n="courses.additional_resources_2_pref")
|
span.spr(data-i18n="courses.additional_resources_2_pref")
|
||||||
a(href='/teachers/freetrial', data-i18n="teachers_survey.title")
|
a(href='/teachers/quote', data-i18n="teachers_quote.name")
|
||||||
span.spl(data-i18n="courses.additional_resources_2_suff")
|
span.spl(data-i18n="courses.additional_resources_2_suff")
|
||||||
li
|
li
|
||||||
span.spr(data-i18n="courses.additional_resources_3_pref")
|
span.spr(data-i18n="courses.additional_resources_3_pref")
|
||||||
|
|
|
@ -27,6 +27,8 @@ block header
|
||||||
a(href="#editor-level-components-tab-view", data-toggle="tab", data-i18n="editor.level_tab_components")#components-tab Components
|
a(href="#editor-level-components-tab-view", data-toggle="tab", data-i18n="editor.level_tab_components")#components-tab Components
|
||||||
li
|
li
|
||||||
a(href="#systems-tab-view", data-toggle="tab", data-i18n="editor.level_tab_systems") Systems
|
a(href="#systems-tab-view", data-toggle="tab", data-i18n="editor.level_tab_systems") Systems
|
||||||
|
li
|
||||||
|
a(href="#editor-level-tasks-tab-view", data-toggle="tab", data-i18n="editor.level_tab_tasks")#tasks-tab= "Tasks" + " " + view.getTaskCompletionRatio()
|
||||||
li
|
li
|
||||||
a(href="#editor-level-patches", data-toggle="tab")#patches-tab
|
a(href="#editor-level-patches", data-toggle="tab")#patches-tab
|
||||||
span(data-i18n="resources.patches").spr Patches
|
span(data-i18n="resources.patches").spr Patches
|
||||||
|
@ -50,6 +52,9 @@ block header
|
||||||
li#redo-button
|
li#redo-button
|
||||||
a
|
a
|
||||||
span.glyphicon-arrow-right.glyphicon
|
span.glyphicon-arrow-right.glyphicon
|
||||||
|
li#artisan-guide-button
|
||||||
|
a
|
||||||
|
span.glyphicon-book.glyphicon
|
||||||
if authorized
|
if authorized
|
||||||
li#commit-level-start-button
|
li#commit-level-start-button
|
||||||
a
|
a
|
||||||
|
@ -125,6 +130,8 @@ block outer_content
|
||||||
|
|
||||||
div.tab-pane#systems-tab-view
|
div.tab-pane#systems-tab-view
|
||||||
|
|
||||||
|
div.tab-pane#editor-level-tasks-tab-view
|
||||||
|
|
||||||
div.tab-pane#editor-level-patches
|
div.tab-pane#editor-level-patches
|
||||||
.patches-view
|
.patches-view
|
||||||
|
|
||||||
|
|
42
app/templates/editor/level/modal/artisan-guide-modal.jade
Normal file
42
app/templates/editor/level/modal/artisan-guide-modal.jade
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
extends /templates/core/modal-base
|
||||||
|
|
||||||
|
block modal-header-content
|
||||||
|
h3 Artisan Compendium
|
||||||
|
|
||||||
|
block modal-body-content
|
||||||
|
p
|
||||||
|
| Welcome to the Artisan Compendium. Below you will find a series of helpful guides and tutorials for getting your levels to Master Artisan quality
|
||||||
|
if view.creator === view.meID
|
||||||
|
|, as well as a way to submit your level for official Artisan review
|
||||||
|
|! If you have any feedback on the Level Editor, please contact us at:
|
||||||
|
a(href='mailto:artisans@codecombat.com') artisans@codecombat.com
|
||||||
|
div.centered-stack
|
||||||
|
div
|
||||||
|
a(href='https://github.com/codecombat/codecombat/wiki/Artisan-Home', target='_blank') Wiki Homepage
|
||||||
|
div
|
||||||
|
a(href='https://github.com/codecombat/codecombat/wiki/Artisan-How-To-Index', target='_blank') Basic How-tos
|
||||||
|
div
|
||||||
|
a(href='http://direct.codecombat.com/community', target='_blank') Artisan Rankings
|
||||||
|
if view.creator === view.meID
|
||||||
|
h4 Level Submission
|
||||||
|
p
|
||||||
|
| Do you want your level to be added to the campaign? Please take a moment to fill out the questions below! Don’t worry, this isn’t a timed quiz. It is just a way for the artisans at CodeCombat HQ to get a feel for the purpose of this level. If it doesn’t quite yet meet our standards for release we will give you feedback to help polish it further!
|
||||||
|
.form
|
||||||
|
.form-group
|
||||||
|
label.control-label(for='credit-name') How would you like to be credited?
|
||||||
|
input#credit-name.form-control(name='creditName')
|
||||||
|
.form-group
|
||||||
|
label.control-label(for='level-purpose') What is the purpose of this level?
|
||||||
|
textarea#level-purpose.form-control(name='levelPurpose', rows=4)
|
||||||
|
.form-group
|
||||||
|
label.control-label(for='level-inspiration') What was the inspiration for the level?
|
||||||
|
textarea#level-inspiration.form-control(name='levelInspiration', rows=4)
|
||||||
|
.form-group
|
||||||
|
label.control-label(for='level-location') Where in the campaign do you think this level belongs?
|
||||||
|
textarea#level-location.form-control(name='levelLocation', rows=4)
|
||||||
|
|
||||||
|
block modal-footer-content
|
||||||
|
div
|
||||||
|
a(href='#', data-dismiss="modal", aria-hidden="true").btn Close
|
||||||
|
if view.creator === view.meID
|
||||||
|
button.btn.btn-primary#level-submit Submit
|
44
app/templates/editor/level/tasks-tab.jade
Normal file
44
app/templates/editor/level/tasks-tab.jade
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
mixin task-row(cid)
|
||||||
|
- var task = view.getTaskByCID(cid)
|
||||||
|
- var taskName = task.get('name');
|
||||||
|
- var isComplete = task.get('complete')
|
||||||
|
- var taskLink = view.defaultTaskLinks[taskName]
|
||||||
|
tr.task-row(data-task-cid=cid)
|
||||||
|
td.task-check
|
||||||
|
div.checkbox
|
||||||
|
input(type='checkbox', checked=(isComplete || false)).task-input
|
||||||
|
if task.get('curEdit') == true
|
||||||
|
td.edit-cell
|
||||||
|
td.task-name
|
||||||
|
input(type="input", value=taskName)#cur-edit
|
||||||
|
else
|
||||||
|
td.edit-cell
|
||||||
|
span.glyphicon.glyphicon-edit.start-edit
|
||||||
|
td.task-name
|
||||||
|
if taskLink
|
||||||
|
if taskLink === './'
|
||||||
|
a.no-article(href='https://github.com/codecombat/codecombat/wiki/Artisan-Home', target='blank')= taskName
|
||||||
|
else
|
||||||
|
a(href=taskLink, target='_blank')= taskName
|
||||||
|
else
|
||||||
|
span= taskName
|
||||||
|
|
||||||
|
block
|
||||||
|
table.table.table-striped.table-hover
|
||||||
|
tr
|
||||||
|
th.task-check Complete
|
||||||
|
th.edit-cell Edit
|
||||||
|
th Incomplete Tasks
|
||||||
|
for task in (view.taskArray() || [])
|
||||||
|
if task.get('revert').complete !== true
|
||||||
|
+task-row(task.cid)
|
||||||
|
tr
|
||||||
|
th.task-check
|
||||||
|
th.edit-cell
|
||||||
|
th Completed Tasks
|
||||||
|
for task in (view.taskArray() || [])
|
||||||
|
if task.get('revert').complete === true
|
||||||
|
+task-row(task.cid)
|
||||||
|
button#create-task.btn.btn-primary Add Task
|
||||||
|
if view.missingDefaults().length !== 0
|
||||||
|
button#add-default-tasks.btn.btn-default Add Default Tasks
|
|
@ -30,7 +30,9 @@ if campaign
|
||||||
- var playCount = levelPlayCountMap[level.slug]
|
- var playCount = levelPlayCountMap[level.slug]
|
||||||
.progress.progress-striped.active.hide
|
.progress.progress-striped.active.hide
|
||||||
.progress-bar(style="width: 100%")
|
.progress-bar(style="width: 100%")
|
||||||
div(class="level-info " + (levelStatusMap[level.slug] || "") + (level.requiresSubscription ? " premium" : ""))
|
- var showsLeaderboard = levelStatusMap[level.slug] === 'complete' && ((level.scoreTypes && level.scoreTypes.length) || ['hero-ladder', 'course-ladder'].indexOf(level.type) !== -1);
|
||||||
|
|
||||||
|
div(class="level-info " + (levelStatusMap[level.slug] || "") + (level.requiresSubscription ? " premium" : "") + (showsLeaderboard ? " shows-leaderboard" : ""))
|
||||||
.level-status
|
.level-status
|
||||||
h3= i18n(level, 'name') + (level.disabled ? " (Coming soon!)" : (level.locked ? " (Locked)" : ""))
|
h3= i18n(level, 'name') + (level.disabled ? " (Coming soon!)" : (level.locked ? " (Locked)" : ""))
|
||||||
- var description = i18n(level, 'description') || level.description || ""
|
- var description = i18n(level, 'description') || level.description || ""
|
||||||
|
@ -53,7 +55,7 @@ if campaign
|
||||||
span(data-i18n="play.players") players
|
span(data-i18n="play.players") players
|
||||||
span.spr , #{Math.round(playCount.playtime / 3600)}
|
span.spr , #{Math.round(playCount.playtime / 3600)}
|
||||||
span(data-i18n="play.hours_played") hours played
|
span(data-i18n="play.hours_played") hours played
|
||||||
if levelStatusMap[level.slug] === 'complete'
|
if showsLeaderboard
|
||||||
button.btn.btn-warning.btn.btn-lg.btn-illustrated.view-solutions(data-level-slug=level.slug)
|
button.btn.btn-warning.btn.btn-lg.btn-illustrated.view-solutions(data-level-slug=level.slug)
|
||||||
span(data-i18n="leaderboard.scores")
|
span(data-i18n="leaderboard.scores")
|
||||||
button.btn.btn-success.btn.btn-lg.btn-illustrated.start-level(data-i18n="common.play") Play
|
button.btn.btn-success.btn.btn-lg.btn-illustrated.start-level(data-i18n="common.play") Play
|
||||||
|
|
150
app/templates/request-quote-view.jade
Normal file
150
app/templates/request-quote-view.jade
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
extends /templates/base
|
||||||
|
|
||||||
|
block content
|
||||||
|
form.form(class=view.trialRequest.isNew() ? '' : 'hide')
|
||||||
|
h1.text-center(data-i18n="teachers_quote.title")
|
||||||
|
p.text-center(data-i18n="teachers_quote.subtitle")
|
||||||
|
|
||||||
|
.row
|
||||||
|
.col-sm-offset-2.col-sm-4
|
||||||
|
.form-group
|
||||||
|
label.control-label(data-i18n="general.name")
|
||||||
|
input.form-control(name="name")
|
||||||
|
|
||||||
|
.col-sm-4
|
||||||
|
.form-group
|
||||||
|
label.control-label(data-i18n="general.email")
|
||||||
|
input.form-control(name="email")
|
||||||
|
|
||||||
|
.row
|
||||||
|
.col-sm-offset-2.col-sm-4
|
||||||
|
.form-group
|
||||||
|
label.control-label
|
||||||
|
span(data-i18n="teachers_quote.phone_number")
|
||||||
|
span.spl.text-muted(data-i18n="signup.optional")
|
||||||
|
.help-block
|
||||||
|
em.text-info(data-i18n="teachers_quote.phone_number_help")
|
||||||
|
input.form-control(name="phoneNumber")
|
||||||
|
|
||||||
|
.col-sm-4
|
||||||
|
.form-group
|
||||||
|
label.control-label(data-i18n="teachers_quote.role_label")
|
||||||
|
.help-block
|
||||||
|
em.text-info(data-i18n="teachers_quote.role_help")
|
||||||
|
select.form-control(name="role")
|
||||||
|
option
|
||||||
|
option(data-i18n="courses.teacher", value="Teacher")
|
||||||
|
option(data-i18n="teachers_quote.tech_coordinator", value="Technology coordinator")
|
||||||
|
option(data-i18n="teachers_quote.advisor", value="Advisor")
|
||||||
|
option(data-i18n="teachers_quote.principal", value="Principal")
|
||||||
|
option(data-i18n="teachers_quote.superintendent", value="Superintendent")
|
||||||
|
option(data-i18n="teachers_quote.parent", value="Parent")
|
||||||
|
|
||||||
|
.row
|
||||||
|
.col-sm-offset-2.col-sm-8
|
||||||
|
hr
|
||||||
|
|
||||||
|
.row
|
||||||
|
.col-sm-offset-2.col-sm-4
|
||||||
|
.form-group
|
||||||
|
label.control-label(data-i18n="teachers_quote.organization_label")
|
||||||
|
input.form-control(name="organization")
|
||||||
|
|
||||||
|
.col-sm-4
|
||||||
|
.form-group
|
||||||
|
label.control-label(data-i18n="teachers_quote.city")
|
||||||
|
input.form-control(name="city")
|
||||||
|
|
||||||
|
.row
|
||||||
|
.col-sm-offset-2.col-sm-4
|
||||||
|
.form-group
|
||||||
|
label.control-label(data-i18n="teachers_quote.state")
|
||||||
|
input.form-control(name="state")
|
||||||
|
|
||||||
|
.col-sm-4
|
||||||
|
.form-group
|
||||||
|
label.control-labellabel.control-label(data-i18n="teachers_quote.country")
|
||||||
|
input.form-control(name="country")
|
||||||
|
|
||||||
|
.row
|
||||||
|
.col-sm-offset-2.col-sm-8
|
||||||
|
hr
|
||||||
|
|
||||||
|
.row
|
||||||
|
.col-sm-offset-2.col-sm-5
|
||||||
|
.form-group
|
||||||
|
label.control-label(data-i18n="courses.number_students")
|
||||||
|
.help-block
|
||||||
|
em.text-info(data-i18n="teachers_quote.num_students_help")
|
||||||
|
select.form-control(name="numStudents")
|
||||||
|
option
|
||||||
|
option 1-10
|
||||||
|
option 11-50
|
||||||
|
option 51-100
|
||||||
|
option 101-200
|
||||||
|
option 201-500
|
||||||
|
option 501-1000
|
||||||
|
option 1000+
|
||||||
|
|
||||||
|
.form-group
|
||||||
|
|
||||||
|
.row
|
||||||
|
.col-sm-offset-2.col-sm-4
|
||||||
|
label.control-label(data-i18n="teachers_quote.education_level_label")
|
||||||
|
.help-block
|
||||||
|
em.text-info(data-i18n="teachers_quote.education_level_help")
|
||||||
|
|
||||||
|
.row
|
||||||
|
.col-sm-offset-2.col-sm-2
|
||||||
|
label.control-label.checkbox
|
||||||
|
input(type="checkbox" name="educationLevel" value="Elementary")
|
||||||
|
span(data-i18n="teachers_quote.elementary_school")
|
||||||
|
.col-sm-2
|
||||||
|
label.control-label.checkbox
|
||||||
|
input(type="checkbox" name="educationLevel" value="High")
|
||||||
|
span(data-i18n="teachers_quote.high_school")
|
||||||
|
.col-sm-6
|
||||||
|
.checkbox-inline
|
||||||
|
label.control-label
|
||||||
|
input#other-education-level-checkbox(type="checkbox")
|
||||||
|
span(data-i18n="nav.other")
|
||||||
|
br
|
||||||
|
span(data-i18n="teachers_quote.please_explain")
|
||||||
|
input#other-education-level-input.form-control
|
||||||
|
|
||||||
|
.row
|
||||||
|
.col-sm-offset-2.col-sm-2
|
||||||
|
label.control-label.checkbox
|
||||||
|
input(type="checkbox" name="educationLevel" value="Middle")
|
||||||
|
span(data-i18n="teachers_quote.middle_school")
|
||||||
|
.col-sm-2
|
||||||
|
label.control-label.checkbox
|
||||||
|
input(type="checkbox" name="educationLevel" value="College+")
|
||||||
|
span(data-i18n="teachers_quote.college_plus")
|
||||||
|
|
||||||
|
#anything-else-row.row
|
||||||
|
.col-sm-offset-2.col-sm-8
|
||||||
|
label.control-label
|
||||||
|
span(data-i18n="teachers_quote.anything_else")
|
||||||
|
span.spl.text-muted(data-i18n="signup.optional")
|
||||||
|
|
||||||
|
textarea.form-control(rows=8, name="notes")
|
||||||
|
|
||||||
|
#buttons-row.row.text-center
|
||||||
|
input#submit-request-btn.btn.btn-primary(type="submit" data-i18n="[value]common.send")
|
||||||
|
|
||||||
|
|
||||||
|
#form-submit-success.text-center(class=view.trialRequest.isNew() ? 'hide' : '')
|
||||||
|
h1.text-center(data-i18n="teachers_quote.thanks_header")
|
||||||
|
p.text-center
|
||||||
|
span.spr(data-i18n="teachers_quote.thanks_p")
|
||||||
|
a.spl(href="mailto:team@codecombat.com") team@codecombat.com
|
||||||
|
|
||||||
|
if me.isAnonymous()
|
||||||
|
p.text-center(data-i18n="teachers_quote.thanks_anon")
|
||||||
|
|
||||||
|
p.text-center
|
||||||
|
button#login-btn.btn.btn-info(data-i18n="login.log_in")
|
||||||
|
button#signup-btn.btn.btn-info(data-i18n="login.sign_up")
|
||||||
|
else
|
||||||
|
p.text-center(data-i18n="teachers_quote.thanks_logged_in")
|
|
@ -7,9 +7,9 @@ block content
|
||||||
br
|
br
|
||||||
br
|
br
|
||||||
.text-right
|
.text-right
|
||||||
button.btn-contact-us(href='/teachers/freetrial')
|
button.btn-contact-us(href='/teachers/quote')
|
||||||
img(src='/images/pages/sales/chat_icon.png')
|
img(src='/images/pages/sales/chat_icon.png')
|
||||||
div contact us for pricing and a free trial
|
div contact us for a quote
|
||||||
|
|
||||||
table
|
table
|
||||||
tr
|
tr
|
||||||
|
@ -216,5 +216,5 @@ block content
|
||||||
br
|
br
|
||||||
|
|
||||||
p.text-center
|
p.text-center
|
||||||
button.btn-contact-us contact us for a free trial
|
button.btn-contact-us contact us for a quote
|
||||||
br
|
br
|
||||||
|
|
|
@ -6,10 +6,17 @@ ol.breadcrumb
|
||||||
a(href=path.url)= path.name
|
a(href=path.url)= path.name
|
||||||
li.active= currentFolder
|
li.active= currentFolder
|
||||||
|
|
||||||
.well.pull-left#test-wrapper
|
#test-wrapper.well.pull-left
|
||||||
|
#demo-area
|
||||||
#testing-area
|
#testing-area
|
||||||
|
|
||||||
.nav.nav-pills.nav-stacked.pull-right.well#test-nav
|
.nav.nav-pills.nav-stacked.pull-right.well#test-nav
|
||||||
|
if view.demosOn
|
||||||
|
button#hide-demos-btn.btn.btn-danger.btn-block Hide Demos
|
||||||
|
else
|
||||||
|
button#show-demos-btn.btn.btn-info.btn-block Show Demos
|
||||||
|
|
||||||
|
hr
|
||||||
for child in children
|
for child in children
|
||||||
li(class=child.type)
|
li(class=child.type)
|
||||||
a(href=child.url).small
|
a(href=child.url).small
|
||||||
|
|
96
app/views/RequestQuoteView.coffee
Normal file
96
app/views/RequestQuoteView.coffee
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
RootView = require 'views/core/RootView'
|
||||||
|
forms = require 'core/forms'
|
||||||
|
TrialRequest = require 'models/TrialRequest'
|
||||||
|
TrialRequests = require 'collections/TrialRequests'
|
||||||
|
AuthModal = require 'views/core/AuthModal'
|
||||||
|
|
||||||
|
formSchema = {
|
||||||
|
type: 'object'
|
||||||
|
required: ['name', 'email', 'organization', 'role', 'numStudents']
|
||||||
|
properties:
|
||||||
|
name: { type: 'string', minLength: 1 }
|
||||||
|
email: { type: 'string', format: 'email' }
|
||||||
|
phoneNumber: { type: 'string' }
|
||||||
|
role: { type: 'string' }
|
||||||
|
organization: { type: 'string' }
|
||||||
|
city: { type: 'string' }
|
||||||
|
state: { type: 'string' }
|
||||||
|
country: { type: 'string' }
|
||||||
|
numStudents: { type: 'string' }
|
||||||
|
educationLevel: {
|
||||||
|
type: 'array'
|
||||||
|
items: { type: 'string' }
|
||||||
|
}
|
||||||
|
notes: { type: 'string' }
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = class RequestQuoteView extends RootView
|
||||||
|
id: 'request-quote-view'
|
||||||
|
template: require 'templates/request-quote-view'
|
||||||
|
|
||||||
|
events:
|
||||||
|
'submit form': 'onSubmitForm'
|
||||||
|
'click #login-btn': 'onClickLoginButton'
|
||||||
|
'click #signup-btn': 'onClickSignupButton'
|
||||||
|
|
||||||
|
initialize: ->
|
||||||
|
@trialRequest = new TrialRequest()
|
||||||
|
@trialRequests = new TrialRequests()
|
||||||
|
@trialRequests.fetchOwn()
|
||||||
|
@supermodel.loadCollection(@trialRequests)
|
||||||
|
|
||||||
|
onLoaded: ->
|
||||||
|
if @trialRequests.size()
|
||||||
|
@trialRequest = @trialRequests.first()
|
||||||
|
|
||||||
|
super()
|
||||||
|
|
||||||
|
onSubmitForm: (e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
form = @$('form')
|
||||||
|
attrs = forms.formToObject(form)
|
||||||
|
if @$('#other-education-level-checkbox').is(':checked')
|
||||||
|
attrs.educationLevel.push(@$('#other-education-level-input').val())
|
||||||
|
forms.clearFormAlerts(form)
|
||||||
|
result = tv4.validateMultiple(attrs, formSchema)
|
||||||
|
if not result.valid
|
||||||
|
return forms.applyErrorsToForm(form, result.errors)
|
||||||
|
if not /^.+@.+\..+$/.test(attrs.email)
|
||||||
|
return forms.setErrorToProperty(form, 'email', 'Invalid email.')
|
||||||
|
if not _.size(attrs.educationLevel)
|
||||||
|
return forms.setErrorToProperty(form, 'educationLevel', 'Check at least one.')
|
||||||
|
@trialRequest = new TrialRequest({
|
||||||
|
type: 'course'
|
||||||
|
properties: attrs
|
||||||
|
})
|
||||||
|
@$('#submit-request-btn').text('Sending').attr('disabled', true)
|
||||||
|
@trialRequest.save()
|
||||||
|
@trialRequest.on 'sync', @onTrialRequestSubmit, @
|
||||||
|
@trialRequest.on 'error', @onTrialRequestError, @
|
||||||
|
|
||||||
|
onTrialRequestError: ->
|
||||||
|
@$('#submit-request-btn').text('Submit').attr('disabled', false)
|
||||||
|
|
||||||
|
onTrialRequestSubmit: ->
|
||||||
|
@$('form, #form-submit-success').toggleClass('hide')
|
||||||
|
|
||||||
|
onClickLoginButton: ->
|
||||||
|
modal = new AuthModal({
|
||||||
|
mode: 'login'
|
||||||
|
initialValues: { email: @trialRequest.get('properties')?.email }
|
||||||
|
})
|
||||||
|
@openModalView(modal)
|
||||||
|
window.nextURL = '/courses/teachers' unless @trialRequest.isNew()
|
||||||
|
|
||||||
|
onClickSignupButton: ->
|
||||||
|
props = @trialRequest.get('properties') or {}
|
||||||
|
me.set('name', props.name)
|
||||||
|
modal = new AuthModal({
|
||||||
|
mode: 'signup'
|
||||||
|
initialValues: {
|
||||||
|
email: props.email
|
||||||
|
schoolName: props.organization
|
||||||
|
}
|
||||||
|
})
|
||||||
|
@openModalView(modal)
|
||||||
|
window.nextURL = '/courses/teachers' unless @trialRequest.isNew()
|
|
@ -17,7 +17,7 @@ module.exports = class SalesView extends RootView
|
||||||
'CodeCombat'
|
'CodeCombat'
|
||||||
|
|
||||||
onClickContactUs: (e) ->
|
onClickContactUs: (e) ->
|
||||||
app.router.navigate '/teachers/freetrial', trigger: true
|
app.router.navigate '/teachers/quote', trigger: true
|
||||||
|
|
||||||
onClickLogin: (e) ->
|
onClickLogin: (e) ->
|
||||||
@openModalView new AuthModal(mode: 'login') if me.get('anonymous')
|
@openModalView new AuthModal(mode: 'login') if me.get('anonymous')
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
RootView = require 'views/core/RootView'
|
RootView = require 'views/core/RootView'
|
||||||
template = require 'templates/test-view'
|
template = require 'templates/test-view'
|
||||||
requireUtils = require 'lib/requireUtils'
|
requireUtils = require 'lib/requireUtils'
|
||||||
|
storage = require 'core/storage'
|
||||||
|
|
||||||
require 'vendor/jasmine-bundle'
|
require 'vendor/jasmine-bundle'
|
||||||
require 'tests'
|
require 'tests'
|
||||||
|
@ -14,18 +15,32 @@ module.exports = TestView = class TestView extends RootView
|
||||||
reloadOnClose: true
|
reloadOnClose: true
|
||||||
loadedFileIDs: []
|
loadedFileIDs: []
|
||||||
|
|
||||||
|
events:
|
||||||
|
'click #show-demos-btn': 'onClickShowDemosButton'
|
||||||
|
'click #hide-demos-btn': 'onClickHideDemosButton'
|
||||||
|
|
||||||
# INITIALIZE
|
# INITIALIZE
|
||||||
|
|
||||||
constructor: (options, @subPath='') ->
|
initialize: (options, @subPath='') ->
|
||||||
super(options)
|
|
||||||
@subPath = @subPath[1..] if @subPath[0] is '/'
|
@subPath = @subPath[1..] if @subPath[0] is '/'
|
||||||
|
@demosOn = storage.load('demos-on')
|
||||||
|
|
||||||
afterInsert: ->
|
afterInsert: ->
|
||||||
@initSpecFiles()
|
@initSpecFiles()
|
||||||
@render()
|
@render()
|
||||||
TestView.runTests(@specFiles)
|
TestView.runTests(@specFiles, @demosOn)
|
||||||
window.runJasmine()
|
window.runJasmine()
|
||||||
|
|
||||||
|
# EVENTS
|
||||||
|
|
||||||
|
onClickShowDemosButton: ->
|
||||||
|
storage.save('demos-on', true)
|
||||||
|
document.location.reload()
|
||||||
|
|
||||||
|
onClickHideDemosButton: ->
|
||||||
|
storage.remove('demos-on')
|
||||||
|
document.location.reload()
|
||||||
|
|
||||||
# RENDER DATA
|
# RENDER DATA
|
||||||
|
|
||||||
getRenderData: ->
|
getRenderData: ->
|
||||||
|
@ -44,8 +59,22 @@ module.exports = TestView = class TestView extends RootView
|
||||||
prefix = TEST_REQUIRE_PREFIX + @subPath
|
prefix = TEST_REQUIRE_PREFIX + @subPath
|
||||||
@specFiles = (f for f in @specFiles when _.string.startsWith f, prefix)
|
@specFiles = (f for f in @specFiles when _.string.startsWith f, prefix)
|
||||||
|
|
||||||
@runTests: (specFiles) ->
|
@runTests: (specFiles, demosOn=false) ->
|
||||||
specFiles ?= @getAllSpecFiles()
|
specFiles ?= @getAllSpecFiles()
|
||||||
|
if demosOn
|
||||||
|
jasmine.demoEl = ($el) ->
|
||||||
|
$el.css({
|
||||||
|
'border': '2px solid black'
|
||||||
|
'background': 'white'
|
||||||
|
'padding': '20px'
|
||||||
|
})
|
||||||
|
$('#demo-area').append($el)
|
||||||
|
jasmine.demoModal = _.once (modal) ->
|
||||||
|
currentView.openModalView(modal)
|
||||||
|
else
|
||||||
|
jasmine.demoEl = _.noop
|
||||||
|
jasmine.demoModal = _.noop
|
||||||
|
|
||||||
describe 'CodeCombat Client', =>
|
describe 'CodeCombat Client', =>
|
||||||
jasmine.Ajax.install()
|
jasmine.Ajax.install()
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
|
|
|
@ -30,6 +30,7 @@ module.exports = class AuthModal extends ModalView
|
||||||
@onNameChange = _.debounce @checkNameExists, 500
|
@onNameChange = _.debounce @checkNameExists, 500
|
||||||
super options
|
super options
|
||||||
@mode = options.mode if options.mode
|
@mode = options.mode if options.mode
|
||||||
|
@previousFormInputs = options.initialValues or {}
|
||||||
|
|
||||||
getRenderData: ->
|
getRenderData: ->
|
||||||
c = super()
|
c = super()
|
||||||
|
|
|
@ -3,6 +3,7 @@ utils = require 'core/utils'
|
||||||
CocoClass = require 'core/CocoClass'
|
CocoClass = require 'core/CocoClass'
|
||||||
loadingScreenTemplate = require 'templates/core/loading'
|
loadingScreenTemplate = require 'templates/core/loading'
|
||||||
loadingErrorTemplate = require 'templates/core/loading-error'
|
loadingErrorTemplate = require 'templates/core/loading-error'
|
||||||
|
auth = require 'core/auth'
|
||||||
|
|
||||||
lastToggleModalCall = 0
|
lastToggleModalCall = 0
|
||||||
visibleModal = null
|
visibleModal = null
|
||||||
|
@ -16,8 +17,9 @@ module.exports = class CocoView extends Backbone.View
|
||||||
template: -> ''
|
template: -> ''
|
||||||
|
|
||||||
events:
|
events:
|
||||||
'click .retry-loading-resource': 'onRetryResource'
|
'click #loading-error .login-btn': 'onClickLoadingErrorLoginButton'
|
||||||
'click .skip-loading-resource': 'onSkipResource'
|
'click #loading-error #create-account-btn': 'onClickLoadingErrorCreateAccountButton'
|
||||||
|
'click #loading-error #logout-btn': 'onClickLoadingErrorLogoutButton'
|
||||||
|
|
||||||
subscriptions: {}
|
subscriptions: {}
|
||||||
shortcuts: {}
|
shortcuts: {}
|
||||||
|
@ -156,44 +158,27 @@ module.exports = class CocoView extends Backbone.View
|
||||||
# Error handling for loading
|
# Error handling for loading
|
||||||
onResourceLoadFailed: (e) ->
|
onResourceLoadFailed: (e) ->
|
||||||
r = e.resource
|
r = e.resource
|
||||||
|
@stopListening @supermodel
|
||||||
return if r.jqxhr?.status is 402 # payment-required failures are handled separately
|
return if r.jqxhr?.status is 402 # payment-required failures are handled separately
|
||||||
if r.jqxhr?.status is 0
|
@showError(r.jqxhr)
|
||||||
r.retries ?= 0
|
|
||||||
r.retries += 1
|
|
||||||
if r.retries > 20
|
|
||||||
msg = 'Your computer or our servers appear to be offline. Please try refreshing.'
|
|
||||||
noty text: msg, layout: 'center', type: 'error', killer: true
|
|
||||||
return
|
|
||||||
else
|
|
||||||
@warnConnectionError()
|
|
||||||
return _.delay (=> r.load()), 3000
|
|
||||||
|
|
||||||
@$el.find('.loading-container .errors').append(loadingErrorTemplate({
|
|
||||||
status: r.jqxhr?.status
|
|
||||||
name: r.name
|
|
||||||
resourceIndex: r.rid,
|
|
||||||
responseText: r.jqxhr?.responseText
|
|
||||||
})).i18n()
|
|
||||||
@$el.find('.progress').hide()
|
|
||||||
|
|
||||||
warnConnectionError: ->
|
warnConnectionError: ->
|
||||||
msg = $.i18n.t 'loading_error.connection_failure', defaultValue: 'Connection failed.'
|
msg = $.i18n.t 'loading_error.connection_failure', defaultValue: 'Connection failed.'
|
||||||
noty text: msg, layout: 'center', type: 'error', killer: true, timeout: 3000
|
noty text: msg, layout: 'center', type: 'error', killer: true, timeout: 3000
|
||||||
|
|
||||||
onRetryResource: (e) ->
|
onClickLoadingErrorLoginButton: (e) ->
|
||||||
res = @supermodel.getResource($(e.target).data('resource-index'))
|
e.stopPropagation() # Backbone subviews and superviews will handle this call repeatedly otherwise
|
||||||
# different views may respond to this call, and not all have the resource to reload
|
AuthModal = require 'views/core/AuthModal'
|
||||||
return unless res and res.isFailed
|
@openModalView(new AuthModal({mode: 'login'}))
|
||||||
res.load()
|
|
||||||
@$el.find('.progress').show()
|
|
||||||
$(e.target).closest('.loading-error-alert').remove()
|
|
||||||
|
|
||||||
onSkipResource: (e) ->
|
onClickLoadingErrorCreateAccountButton: (e) ->
|
||||||
res = @supermodel.getResource($(e.target).data('resource-index'))
|
e.stopPropagation()
|
||||||
return unless res and res.isFailed
|
AuthModal = require 'views/core/AuthModal'
|
||||||
res.markLoaded()
|
@openModalView(new AuthModal({mode: 'signup'}))
|
||||||
@$el.find('.progress').show()
|
|
||||||
$(e.target).closest('.loading-error-alert').remove()
|
onClickLoadingErrorLogoutButton: (e) ->
|
||||||
|
e.stopPropagation()
|
||||||
|
auth.logoutUser()
|
||||||
|
|
||||||
# Modals
|
# Modals
|
||||||
|
|
||||||
|
@ -255,6 +240,23 @@ module.exports = class CocoView extends Backbone.View
|
||||||
@_lastLoading.find('>').removeClass('hidden')
|
@_lastLoading.find('>').removeClass('hidden')
|
||||||
@_lastLoading = null
|
@_lastLoading = null
|
||||||
|
|
||||||
|
showError: (jqxhr) ->
|
||||||
|
return unless @_lastLoading?
|
||||||
|
context = {
|
||||||
|
jqxhr: jqxhr
|
||||||
|
view: @
|
||||||
|
me: me
|
||||||
|
}
|
||||||
|
@_lastLoading.find('.loading-screen').replaceWith((loadingErrorTemplate(context)))
|
||||||
|
@_lastLoading.i18n()
|
||||||
|
|
||||||
|
forumLink: ->
|
||||||
|
link = 'http://discourse.codecombat.com/'
|
||||||
|
lang = (me.get('preferredLanguage') or 'en-US').split('-')[0]
|
||||||
|
if lang in ['zh', 'ru', 'es', 'fr', 'pt', 'de', 'nl', 'lt']
|
||||||
|
link += "c/other-languages/#{lang}"
|
||||||
|
link
|
||||||
|
|
||||||
showReadOnly: ->
|
showReadOnly: ->
|
||||||
return if me.isAdmin() or me.isArtisan()
|
return if me.isAdmin() or me.isArtisan()
|
||||||
warning = $.i18n.t 'editor.read_only_warning2', defaultValue: 'Note: you can\'t save any edits here, because you\'re not logged in.'
|
warning = $.i18n.t 'editor.read_only_warning2', defaultValue: 'Note: you can\'t save any edits here, because you\'re not logged in.'
|
||||||
|
|
|
@ -100,13 +100,6 @@ module.exports = class RootView extends CocoView
|
||||||
c.usesSocialMedia = @usesSocialMedia
|
c.usesSocialMedia = @usesSocialMedia
|
||||||
c
|
c
|
||||||
|
|
||||||
forumLink: ->
|
|
||||||
link = 'http://discourse.codecombat.com/'
|
|
||||||
lang = (me.get('preferredLanguage') or 'en-US').split('-')[0]
|
|
||||||
if lang in ['zh', 'ru', 'es', 'fr', 'pt', 'de', 'nl', 'lt']
|
|
||||||
link += "c/other-languages/#{lang}"
|
|
||||||
link
|
|
||||||
|
|
||||||
afterRender: ->
|
afterRender: ->
|
||||||
if @$el.find('#site-nav').length # hack...
|
if @$el.find('#site-nav').length # hack...
|
||||||
@$el.addClass('site-chrome')
|
@$el.addClass('site-chrome')
|
||||||
|
|
|
@ -32,23 +32,23 @@ module.exports = class ClassroomView extends RootView
|
||||||
initialize: (options, classroomID) ->
|
initialize: (options, classroomID) ->
|
||||||
return if me.isAnonymous()
|
return if me.isAnonymous()
|
||||||
@classroom = new Classroom({_id: classroomID})
|
@classroom = new Classroom({_id: classroomID})
|
||||||
@supermodel.loadModel @classroom, 'classroom'
|
@supermodel.loadModel @classroom
|
||||||
@courses = new CocoCollection([], { url: "/db/course", model: Course})
|
@courses = new CocoCollection([], { url: "/db/course", model: Course})
|
||||||
@courses.comparator = '_id'
|
@courses.comparator = '_id'
|
||||||
@supermodel.loadCollection(@courses, 'courses')
|
@supermodel.loadCollection(@courses)
|
||||||
@campaigns = new CocoCollection([], { url: "/db/campaign", model: Campaign })
|
@campaigns = new CocoCollection([], { url: "/db/campaign", model: Campaign })
|
||||||
@courses.comparator = '_id'
|
@courses.comparator = '_id'
|
||||||
@supermodel.loadCollection(@campaigns, 'campaigns', { data: { type: 'course' }})
|
@supermodel.loadCollection(@campaigns, { data: { type: 'course' }})
|
||||||
@courseInstances = new CocoCollection([], { url: "/db/course_instance", model: CourseInstance})
|
@courseInstances = new CocoCollection([], { url: "/db/course_instance", model: CourseInstance})
|
||||||
@courseInstances.comparator = 'courseID'
|
@courseInstances.comparator = 'courseID'
|
||||||
@supermodel.loadCollection(@courseInstances, 'course_instances', { data: { classroomID: classroomID } })
|
@supermodel.loadCollection(@courseInstances, { data: { classroomID: classroomID } })
|
||||||
@prepaids = new Prepaids()
|
@prepaids = new Prepaids()
|
||||||
@prepaids.comparator = '_id'
|
@prepaids.comparator = '_id'
|
||||||
@prepaids.fetchByCreator(me.id)
|
@prepaids.fetchByCreator(me.id)
|
||||||
@supermodel.loadCollection(@prepaids, 'prepaids')
|
@supermodel.loadCollection(@prepaids)
|
||||||
@users = new CocoCollection([], { url: "/db/classroom/#{classroomID}/members", model: User })
|
@users = new CocoCollection([], { url: "/db/classroom/#{classroomID}/members", model: User })
|
||||||
@users.comparator = (user) => user.broadName().toLowerCase()
|
@users.comparator = (user) => user.broadName().toLowerCase()
|
||||||
@supermodel.loadCollection(@users, 'users')
|
@supermodel.loadCollection(@users)
|
||||||
@listenToOnce @courseInstances, 'sync', @onCourseInstancesSync
|
@listenToOnce @courseInstances, 'sync', @onCourseInstancesSync
|
||||||
@sessions = new CocoCollection([], { model: LevelSession })
|
@sessions = new CocoCollection([], { model: LevelSession })
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ module.exports = class ClassroomView extends RootView
|
||||||
@sessions = new CocoCollection([], { model: LevelSession })
|
@sessions = new CocoCollection([], { model: LevelSession })
|
||||||
for courseInstance in @courseInstances.models
|
for courseInstance in @courseInstances.models
|
||||||
sessions = new CocoCollection([], { url: "/db/course_instance/#{courseInstance.id}/level_sessions", model: LevelSession })
|
sessions = new CocoCollection([], { url: "/db/course_instance/#{courseInstance.id}/level_sessions", model: LevelSession })
|
||||||
@supermodel.loadCollection(sessions, 'sessions', { data: { project: ['level', 'playtime', 'creator', 'changed', 'state.complete'].join(' ') } })
|
@supermodel.loadCollection(sessions, { data: { project: ['level', 'playtime', 'creator', 'changed', 'state.complete'].join(' ') } })
|
||||||
courseInstance.sessions = sessions
|
courseInstance.sessions = sessions
|
||||||
sessions.courseInstance = courseInstance
|
sessions.courseInstance = courseInstance
|
||||||
courseInstance.sessionsByUser = {}
|
courseInstance.sessionsByUser = {}
|
||||||
|
|
|
@ -31,13 +31,13 @@ module.exports = class CoursesView extends RootView
|
||||||
@courseInstances = new CocoCollection([], { url: "/db/user/#{me.id}/course_instances", model: CourseInstance})
|
@courseInstances = new CocoCollection([], { url: "/db/user/#{me.id}/course_instances", model: CourseInstance})
|
||||||
@courseInstances.comparator = (ci) -> return ci.get('classroomID') + ci.get('courseID')
|
@courseInstances.comparator = (ci) -> return ci.get('classroomID') + ci.get('courseID')
|
||||||
@listenToOnce @courseInstances, 'sync', @onCourseInstancesLoaded
|
@listenToOnce @courseInstances, 'sync', @onCourseInstancesLoaded
|
||||||
@supermodel.loadCollection(@courseInstances, 'course_instances')
|
@supermodel.loadCollection(@courseInstances)
|
||||||
@classrooms = new CocoCollection([], { url: "/db/classroom", model: Classroom })
|
@classrooms = new CocoCollection([], { url: "/db/classroom", model: Classroom })
|
||||||
@supermodel.loadCollection(@classrooms, 'classrooms', { data: {memberID: me.id} })
|
@supermodel.loadCollection(@classrooms, { data: {memberID: me.id} })
|
||||||
@courses = new CocoCollection([], { url: "/db/course", model: Course})
|
@courses = new CocoCollection([], { url: "/db/course", model: Course})
|
||||||
@supermodel.loadCollection(@courses, 'courses')
|
@supermodel.loadCollection(@courses)
|
||||||
@campaigns = new CocoCollection([], { url: "/db/campaign", model: Campaign })
|
@campaigns = new CocoCollection([], { url: "/db/campaign", model: Campaign })
|
||||||
@supermodel.loadCollection(@campaigns, 'campaigns', { data: { type: 'course' }})
|
@supermodel.loadCollection(@campaigns, { data: { type: 'course' }})
|
||||||
|
|
||||||
onCourseInstancesLoaded: ->
|
onCourseInstancesLoaded: ->
|
||||||
map = {}
|
map = {}
|
||||||
|
@ -51,7 +51,7 @@ module.exports = class CoursesView extends RootView
|
||||||
model: LevelSession
|
model: LevelSession
|
||||||
})
|
})
|
||||||
courseInstance.sessions.comparator = 'changed'
|
courseInstance.sessions.comparator = 'changed'
|
||||||
@supermodel.loadCollection(courseInstance.sessions, 'sessions', { data: { project: 'state.complete level.original playtime changed' }})
|
@supermodel.loadCollection(courseInstance.sessions, { data: { project: 'state.complete level.original playtime changed' }})
|
||||||
|
|
||||||
@hocCourseInstance = @courseInstances.findWhere({hourOfCode: true})
|
@hocCourseInstance = @courseInstances.findWhere({hourOfCode: true})
|
||||||
if @hocCourseInstance
|
if @hocCourseInstance
|
||||||
|
|
|
@ -15,7 +15,9 @@ SettingsTabView = require './settings/SettingsTabView'
|
||||||
ScriptsTabView = require './scripts/ScriptsTabView'
|
ScriptsTabView = require './scripts/ScriptsTabView'
|
||||||
ComponentsTabView = require './components/ComponentsTabView'
|
ComponentsTabView = require './components/ComponentsTabView'
|
||||||
SystemsTabView = require './systems/SystemsTabView'
|
SystemsTabView = require './systems/SystemsTabView'
|
||||||
|
TasksTabView = require './tasks/TasksTabView'
|
||||||
SaveLevelModal = require './modals/SaveLevelModal'
|
SaveLevelModal = require './modals/SaveLevelModal'
|
||||||
|
ArtisanGuideModal = require './modals/ArtisanGuideModal'
|
||||||
ForkModal = require 'views/editor/ForkModal'
|
ForkModal = require 'views/editor/ForkModal'
|
||||||
SaveVersionModal = require 'views/editor/modal/SaveVersionModal'
|
SaveVersionModal = require 'views/editor/modal/SaveVersionModal'
|
||||||
PatchesView = require 'views/editor/PatchesView'
|
PatchesView = require 'views/editor/PatchesView'
|
||||||
|
@ -56,6 +58,7 @@ module.exports = class LevelEditView extends RootView
|
||||||
'mouseenter #redo-button': 'showRedoDescription'
|
'mouseenter #redo-button': 'showRedoDescription'
|
||||||
'click #patches-tab': -> @patchesView.load()
|
'click #patches-tab': -> @patchesView.load()
|
||||||
'click #components-tab': -> @subviews.editor_level_components_tab_view.refreshLevelThangsTreema @level.get('thangs')
|
'click #components-tab': -> @subviews.editor_level_components_tab_view.refreshLevelThangsTreema @level.get('thangs')
|
||||||
|
'click #artisan-guide-button': 'showArtisanGuide'
|
||||||
'click #level-patch-button': 'startPatchingLevel'
|
'click #level-patch-button': 'startPatchingLevel'
|
||||||
'click #level-watch-button': 'toggleWatchLevel'
|
'click #level-watch-button': 'toggleWatchLevel'
|
||||||
'click li:not(.disabled) > #pop-level-i18n-button': 'onPopulateI18N'
|
'click li:not(.disabled) > #pop-level-i18n-button': 'onPopulateI18N'
|
||||||
|
@ -105,11 +108,13 @@ module.exports = class LevelEditView extends RootView
|
||||||
@insertSubView new ScriptsTabView world: @world, supermodel: @supermodel, files: @files
|
@insertSubView new ScriptsTabView world: @world, supermodel: @supermodel, files: @files
|
||||||
@insertSubView new ComponentsTabView supermodel: @supermodel
|
@insertSubView new ComponentsTabView supermodel: @supermodel
|
||||||
@insertSubView new SystemsTabView supermodel: @supermodel, world: @world
|
@insertSubView new SystemsTabView supermodel: @supermodel, world: @world
|
||||||
|
@insertSubView new TasksTabView world: @world, supermodel: @supermodel, level: @level
|
||||||
@insertSubView new RelatedAchievementsView supermodel: @supermodel, level: @level
|
@insertSubView new RelatedAchievementsView supermodel: @supermodel, level: @level
|
||||||
@insertSubView new ComponentsDocumentationView lazy: true # Don't give it the supermodel, it'll pollute it!
|
@insertSubView new ComponentsDocumentationView lazy: true # Don't give it the supermodel, it'll pollute it!
|
||||||
@insertSubView new SystemsDocumentationView lazy: true # Don't give it the supermodel, it'll pollute it!
|
@insertSubView new SystemsDocumentationView lazy: true # Don't give it the supermodel, it'll pollute it!
|
||||||
@insertSubView new LevelFeedbackView level: @level
|
@insertSubView new LevelFeedbackView level: @level
|
||||||
|
|
||||||
|
|
||||||
Backbone.Mediator.publish 'editor:level-loaded', level: @level
|
Backbone.Mediator.publish 'editor:level-loaded', level: @level
|
||||||
@showReadOnly() if me.get('anonymous')
|
@showReadOnly() if me.get('anonymous')
|
||||||
@patchesView = @insertSubView(new PatchesView(@level), @$el.find('.patches-view'))
|
@patchesView = @insertSubView(new PatchesView(@level), @$el.find('.patches-view'))
|
||||||
|
@ -170,6 +175,10 @@ module.exports = class LevelEditView extends RootView
|
||||||
@openModalView new SaveLevelModal level: @level, supermodel: @supermodel, buildTime: @levelBuildTime
|
@openModalView new SaveLevelModal level: @level, supermodel: @supermodel, buildTime: @levelBuildTime
|
||||||
Backbone.Mediator.publish 'editor:view-switched', {}
|
Backbone.Mediator.publish 'editor:view-switched', {}
|
||||||
|
|
||||||
|
showArtisanGuide: (e) ->
|
||||||
|
@openModalView new ArtisanGuideModal level: @level
|
||||||
|
Backbone.Mediator.publish 'editor:view-switched', {}
|
||||||
|
|
||||||
startForking: (e) ->
|
startForking: (e) ->
|
||||||
@openModalView new ForkModal model: @level, editorPath: 'level'
|
@openModalView new ForkModal model: @level, editorPath: 'level'
|
||||||
Backbone.Mediator.publish 'editor:view-switched', {}
|
Backbone.Mediator.publish 'editor:view-switched', {}
|
||||||
|
@ -210,3 +219,9 @@ module.exports = class LevelEditView extends RootView
|
||||||
return if application.userIsIdle
|
return if application.userIsIdle
|
||||||
@levelBuildTime ?= @level.get('buildTime') ? 0
|
@levelBuildTime ?= @level.get('buildTime') ? 0
|
||||||
++@levelBuildTime
|
++@levelBuildTime
|
||||||
|
|
||||||
|
getTaskCompletionRatio: ->
|
||||||
|
if not @level.get('tasks')?
|
||||||
|
return '0/0'
|
||||||
|
else
|
||||||
|
return _.filter(@level.get('tasks'), (_elem) -> return _elem.complete).length + '/' + @level.get('tasks').length
|
||||||
|
|
48
app/views/editor/level/modals/ArtisanGuideModal.coffee
Normal file
48
app/views/editor/level/modals/ArtisanGuideModal.coffee
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
ModalView = require 'views/core/ModalView'
|
||||||
|
template = require 'templates/editor/level/modal/artisan-guide-modal'
|
||||||
|
|
||||||
|
forms = require 'core/forms'
|
||||||
|
{sendContactMessage} = require 'core/contact'
|
||||||
|
|
||||||
|
contactSchema =
|
||||||
|
additionalProperties: false
|
||||||
|
required: ['creditName', 'levelPurpose', 'levelInspiration', 'levelLocation']
|
||||||
|
properties:
|
||||||
|
creditName:
|
||||||
|
type: 'string'
|
||||||
|
levelPurpose:
|
||||||
|
type: 'string'
|
||||||
|
levelInspiration:
|
||||||
|
type: 'string'
|
||||||
|
levelLocation:
|
||||||
|
type: 'string'
|
||||||
|
|
||||||
|
module.exports = class ArtisanGuideModal extends ModalView
|
||||||
|
id: 'artisan-guide-modal'
|
||||||
|
template: template
|
||||||
|
events:
|
||||||
|
'click #level-submit': 'levelSubmit'
|
||||||
|
|
||||||
|
initialize: (options) ->
|
||||||
|
@level = options.level
|
||||||
|
@options = level: @level.get 'name'
|
||||||
|
@creator = @level.get 'creator'
|
||||||
|
@meID = me.id
|
||||||
|
|
||||||
|
levelSubmit: ->
|
||||||
|
@playSound 'menu-button-click'
|
||||||
|
forms.clearFormAlerts @$el
|
||||||
|
contactMessage = forms.formToObject @$el
|
||||||
|
res = tv4.validateMultiple contactMessage, contactSchema
|
||||||
|
return forms.applyErrorsToForm @$el, res.errors unless res.valid
|
||||||
|
@populateBrowserData contactMessage
|
||||||
|
contactMessage = _.merge contactMessage, @options
|
||||||
|
contactMessage.country = me.get('country')
|
||||||
|
sendContactMessage contactMessage, @$el
|
||||||
|
$.post "/db/user/#{me.id}/track/contact_codecombat"
|
||||||
|
|
||||||
|
populateBrowserData: (context) ->
|
||||||
|
if $.browser
|
||||||
|
context.browser = "#{$.browser.platform} #{$.browser.name} #{$.browser.versionNumber}"
|
||||||
|
context.screenSize = "#{screen?.width ? $(window).width()} x #{screen?.height ? $(window).height()}"
|
||||||
|
context.screenshotURL = @screenshotURL
|
|
@ -15,7 +15,7 @@ module.exports = class SettingsTabView extends CocoView
|
||||||
editableSettings: [
|
editableSettings: [
|
||||||
'name', 'description', 'documentation', 'nextLevel', 'background', 'victory', 'i18n', 'icon', 'goals',
|
'name', 'description', 'documentation', 'nextLevel', 'background', 'victory', 'i18n', 'icon', 'goals',
|
||||||
'type', 'terrain', 'showsGuide', 'banner', 'employerDescription', 'loadingTip', 'requiresSubscription',
|
'type', 'terrain', 'showsGuide', 'banner', 'employerDescription', 'loadingTip', 'requiresSubscription',
|
||||||
'tasks', 'helpVideos', 'replayable', 'scoreTypes', 'concepts'
|
'helpVideos', 'replayable', 'scoreTypes', 'concepts'
|
||||||
]
|
]
|
||||||
|
|
||||||
subscriptions:
|
subscriptions:
|
||||||
|
|
183
app/views/editor/level/tasks/TasksTabView.coffee
Normal file
183
app/views/editor/level/tasks/TasksTabView.coffee
Normal file
|
@ -0,0 +1,183 @@
|
||||||
|
CocoView = require 'views/core/CocoView'
|
||||||
|
template = require 'templates/editor/level/tasks-tab'
|
||||||
|
Level = require 'models/Level'
|
||||||
|
|
||||||
|
module.exports = class TasksTabView extends CocoView
|
||||||
|
id: 'editor-level-tasks-tab-view'
|
||||||
|
className: 'tab-pane'
|
||||||
|
template: template
|
||||||
|
events:
|
||||||
|
'click .task-row': 'onClickTaskRow'
|
||||||
|
'click .task-input': 'onClickTaskInput'
|
||||||
|
'click .start-edit': 'onClickStartEdit'
|
||||||
|
'click #create-task': 'onClickCreateTask'
|
||||||
|
'keydown #cur-edit': 'onKeyDownCurEdit'
|
||||||
|
'blur #cur-edit': 'onBlurCurEdit'
|
||||||
|
'click #add-default-tasks': 'onClickAddDefaultTasks'
|
||||||
|
|
||||||
|
subscriptions:
|
||||||
|
'editor:level-loaded': 'onLevelLoaded'
|
||||||
|
|
||||||
|
defaultTaskLinks:
|
||||||
|
# Order doesn't matter.
|
||||||
|
'Name the level.':'./'
|
||||||
|
'Create a Referee stub, if needed.':'./'
|
||||||
|
'Build the level.':'./'
|
||||||
|
'Set up goals.':'./'
|
||||||
|
'Choose the Existence System lifespan and frame rate.':'./'
|
||||||
|
'Choose the UI System paths and coordinate hover if needed.':'./'
|
||||||
|
'Choose the AI System pathfinding and Vision System line of sight.':'./'
|
||||||
|
'Write the sample code.':'./'
|
||||||
|
'Do basic set decoration.':'./'
|
||||||
|
'Adjust script camera bounds.':'./'
|
||||||
|
'Choose music file in Introduction script.':'./'
|
||||||
|
'Choose autoplay in Introduction script.':'./'
|
||||||
|
'Add to a campaign.':'./'
|
||||||
|
'Publish.':'./'
|
||||||
|
'Choose level options like required/restricted gear.':'./'
|
||||||
|
'Create achievements, including unlocking next level.':'./'
|
||||||
|
'Choose leaderboard score types.':'./'
|
||||||
|
'Playtest with a slow/tough hero.':'./'
|
||||||
|
'Playtest with a fast/weak hero.':'./'
|
||||||
|
'Playtest with a couple random seeds.':'./'
|
||||||
|
'Make sure the level ends promptly on success and failure.':'./'
|
||||||
|
'Remove/simplify unnecessary doodad collision.':'./'
|
||||||
|
'Release to adventurers via MailChimp.':'./'
|
||||||
|
'Write the description.':'./'
|
||||||
|
'Add i18n field for the sample code comments.':'./'
|
||||||
|
'Add Clojure/Lua/CoffeeScript.':'./'
|
||||||
|
'Write the guide.':'./'
|
||||||
|
'Write a loading tip, if needed.':'./'
|
||||||
|
'Click the Populate i18n button.':'./'
|
||||||
|
'Add programming concepts covered.':'./'
|
||||||
|
'Mark whether it requires a subscription.':'./'
|
||||||
|
'Release to everyone via MailChimp.':'./'
|
||||||
|
'Check completion/engagement/problem analytics.':'./'
|
||||||
|
'Do thorough set decoration.':'./'
|
||||||
|
'Add a walkthrough video.':'./'
|
||||||
|
|
||||||
|
missingDefaults: ->
|
||||||
|
missingTasks = []
|
||||||
|
if @level
|
||||||
|
for task in @level.schema().properties.tasks.default
|
||||||
|
unless _.findIndex(@level.get('tasks'), {name: task.name}) isnt -1
|
||||||
|
missingTasks.push task
|
||||||
|
return missingTasks
|
||||||
|
|
||||||
|
onClickAddDefaultTasks: ->
|
||||||
|
results = @missingDefaults()
|
||||||
|
for result in results
|
||||||
|
@tasks.add
|
||||||
|
name: result.name
|
||||||
|
complete: result.complete
|
||||||
|
curEdit: false
|
||||||
|
revert:
|
||||||
|
name: result.name
|
||||||
|
complete: false
|
||||||
|
@pushTasks()
|
||||||
|
@render()
|
||||||
|
|
||||||
|
applyTaskName: (_task, _input) ->
|
||||||
|
name = _input.value
|
||||||
|
potentialTask = @tasks.findWhere({'name':_input})
|
||||||
|
if potentialTask and potentialTask isnt _task
|
||||||
|
noty
|
||||||
|
timeout: 5000
|
||||||
|
text: 'Task with name already exists!'
|
||||||
|
type: 'error'
|
||||||
|
layout: 'topCenter'
|
||||||
|
_input.focus()
|
||||||
|
else if name is ''
|
||||||
|
@tasks.remove _task
|
||||||
|
@pushTasks()
|
||||||
|
@render()
|
||||||
|
else
|
||||||
|
_task.set 'name', name
|
||||||
|
_task.set 'curEdit', false
|
||||||
|
@pushTasks()
|
||||||
|
@render()
|
||||||
|
|
||||||
|
focusEditInput: ->
|
||||||
|
editInput = @$el.find('#cur-edit')[0]
|
||||||
|
if editInput
|
||||||
|
editInput.focus()
|
||||||
|
len = editInput.value.length * 2
|
||||||
|
editInput.setSelectionRange len, len
|
||||||
|
|
||||||
|
getTaskByCID: (_cid) ->
|
||||||
|
return @tasks.get _cid
|
||||||
|
|
||||||
|
taskMap: ->
|
||||||
|
return @tasks?.map((_obj) -> return (name: _obj.get('name'), complete: (_obj.get('complete') || false)))
|
||||||
|
|
||||||
|
taskArray: ->
|
||||||
|
return @tasks?.toArray()
|
||||||
|
|
||||||
|
onLevelLoaded: (e) ->
|
||||||
|
@level = e.level
|
||||||
|
Task = Backbone.Model.extend({
|
||||||
|
initialize: ->
|
||||||
|
# We want to keep track of the revertAttributes easily without digging back into the level every time.
|
||||||
|
# So per TaskModel we check to see if there is a revertAttribute associated with the task's name.
|
||||||
|
# If there is a reversion available, we use it, otherwise (e.g. new tasks without a reversion) we just use the Task's current name/completion status.
|
||||||
|
if e?.level?._revertAttributes?.tasks?
|
||||||
|
if _.find(e.level._revertAttributes.tasks, {name:arguments[0].name})
|
||||||
|
@set 'revert', _.find(e.level._revertAttributes.tasks, {name:arguments[0].name})
|
||||||
|
else
|
||||||
|
@set 'revert', arguments[0]
|
||||||
|
else
|
||||||
|
@set 'revert', arguments[0]
|
||||||
|
})
|
||||||
|
TaskList = Backbone.Collection.extend({
|
||||||
|
model: Task
|
||||||
|
})
|
||||||
|
@tasks = new TaskList(@level.get 'tasks')
|
||||||
|
@render()
|
||||||
|
|
||||||
|
pushTasks: ->
|
||||||
|
@level.set 'tasks', @taskMap()
|
||||||
|
|
||||||
|
onClickTaskRow: (e) ->
|
||||||
|
if not @$el.find(e.target).is('input') and not @$el.find(e.target).is('a') and not @$el.find(e.target).hasClass('start-edit') and @$el.find('#cur-edit').length is 0
|
||||||
|
task = @tasks.get @$el.find(e.target).closest('tr').data('task-cid')
|
||||||
|
checkbox = @$el.find(e.currentTarget).find('.task-input')[0]
|
||||||
|
if task.get 'complete'
|
||||||
|
task.set 'complete', false
|
||||||
|
else
|
||||||
|
task.set 'complete', true
|
||||||
|
checkbox.checked = task.get 'complete'
|
||||||
|
@pushTasks()
|
||||||
|
|
||||||
|
onClickTaskInput: (e) ->
|
||||||
|
task = @tasks.get @$el.find(e.target).closest('tr').data('task-cid')
|
||||||
|
task.set 'complete', e.currentTarget.checked
|
||||||
|
@pushTasks()
|
||||||
|
|
||||||
|
onClickStartEdit: (e) ->
|
||||||
|
if @$el.find('#cur-edit').length is 0
|
||||||
|
task = @tasks.get @$el.find(e.target).closest('tr').data('task-cid')
|
||||||
|
task.set 'curEdit', true
|
||||||
|
@render()
|
||||||
|
@focusEditInput()
|
||||||
|
|
||||||
|
onKeyDownCurEdit: (e) ->
|
||||||
|
if e.keyCode is 13
|
||||||
|
editInput = @$el.find('#cur-edit')[0]
|
||||||
|
editInput.blur()
|
||||||
|
|
||||||
|
onBlurCurEdit: (e) ->
|
||||||
|
editInput = @$el.find('#cur-edit')[0]
|
||||||
|
task = @tasks.get @$el.find(e.target).closest('tr').data('task-cid')
|
||||||
|
@applyTaskName(task, editInput)
|
||||||
|
|
||||||
|
onClickCreateTask: (e) ->
|
||||||
|
if @$el.find('#cur-edit').length is 0
|
||||||
|
@tasks.add
|
||||||
|
name: ''
|
||||||
|
complete: false
|
||||||
|
curEdit: true
|
||||||
|
revert:
|
||||||
|
name: 'null'
|
||||||
|
complete: false
|
||||||
|
@render()
|
||||||
|
@focusEditInput()
|
|
@ -22,6 +22,8 @@ module.exports = class NewModelModal extends ModalView
|
||||||
model = new @modelClass
|
model = new @modelClass
|
||||||
name = @$el.find('#name').val()
|
name = @$el.find('#name').val()
|
||||||
model.set('name', name)
|
model.set('name', name)
|
||||||
|
if @modelClass.name is 'Level'
|
||||||
|
model.set('tasks', @modelClass.schema.default.tasks)
|
||||||
if model.schema().properties.permissions
|
if model.schema().properties.permissions
|
||||||
model.set 'permissions', [{access: 'owner', target: me.id}]
|
model.set 'permissions', [{access: 'owner', target: me.id}]
|
||||||
model.set(key, prop) for key, prop of @properties if @properties?
|
model.set(key, prop) for key, prop of @properties if @properties?
|
||||||
|
|
150
test/app/views/core/CocoView.spec.coffee
Normal file
150
test/app/views/core/CocoView.spec.coffee
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
CocoView = require 'views/core/CocoView'
|
||||||
|
User = require 'models/User'
|
||||||
|
|
||||||
|
BlandView = class BlandView extends CocoView
|
||||||
|
template: ->
|
||||||
|
return if @specialMessage then '<div id="content">custom message</div>' else '<div id="content">normal message</div>'
|
||||||
|
|
||||||
|
initialize: ->
|
||||||
|
@user1 = new User({_id: _.uniqueId()})
|
||||||
|
@supermodel.loadModel(@user1)
|
||||||
|
@user2 = new User({_id: _.uniqueId()})
|
||||||
|
@supermodel.loadModel(@user2)
|
||||||
|
|
||||||
|
onResourceLoadFailed: (e) ->
|
||||||
|
resource = e.resource
|
||||||
|
if resource.jqxhr.status is 400 and resource.model is @user1
|
||||||
|
@specialMessage = true
|
||||||
|
@render()
|
||||||
|
else
|
||||||
|
super(arguments...)
|
||||||
|
|
||||||
|
|
||||||
|
describe 'CocoView', ->
|
||||||
|
describe 'network error handling', ->
|
||||||
|
view = null
|
||||||
|
respond = (code, index=0) ->
|
||||||
|
view.render()
|
||||||
|
requests = jasmine.Ajax.requests.all()
|
||||||
|
requests[index].respondWith({status: code, responseText: JSON.stringify({})})
|
||||||
|
|
||||||
|
beforeEach ->
|
||||||
|
view = new BlandView()
|
||||||
|
|
||||||
|
|
||||||
|
describe 'when the view overrides onResourceLoadFailed', ->
|
||||||
|
beforeEach ->
|
||||||
|
view.render()
|
||||||
|
expect(view.$('#content').hasClass('hidden')).toBe(true)
|
||||||
|
respond(400)
|
||||||
|
|
||||||
|
it 'can show a custom message for a given error and model', ->
|
||||||
|
expect(view.$('#content').hasClass('hidden')).toBe(false)
|
||||||
|
expect(view.$('#content').text()).toBe('custom message')
|
||||||
|
respond(200, 1)
|
||||||
|
expect(view.$('#content').hasClass('hidden')).toBe(false)
|
||||||
|
expect(view.$('#content').text()).toBe('custom message')
|
||||||
|
|
||||||
|
it '(demo)', -> jasmine.demoEl(view.$el)
|
||||||
|
|
||||||
|
|
||||||
|
describe 'when the server returns 401', ->
|
||||||
|
beforeEach ->
|
||||||
|
me.set('anonymous', true)
|
||||||
|
respond(401)
|
||||||
|
|
||||||
|
it 'shows a login button which opens the AuthModal', ->
|
||||||
|
button = view.$el.find('.login-btn')
|
||||||
|
expect(button.length).toBe(3) # including the two in the links section
|
||||||
|
spyOn(view, 'openModalView').and.callFake (modal) -> expect(modal.mode).toBe('login')
|
||||||
|
button.click()
|
||||||
|
expect(view.openModalView).toHaveBeenCalled()
|
||||||
|
|
||||||
|
it 'shows a create account button which opens the AuthModal', ->
|
||||||
|
button = view.$el.find('#create-account-btn')
|
||||||
|
expect(button.length).toBe(1)
|
||||||
|
spyOn(view, 'openModalView').and.callFake (modal) -> expect(modal.mode).toBe('signup')
|
||||||
|
button.click()
|
||||||
|
expect(view.openModalView).toHaveBeenCalled()
|
||||||
|
|
||||||
|
it 'says "Login Required"', ->
|
||||||
|
expect(view.$('[data-i18n="loading_error.login_required"]').length).toBeTruthy()
|
||||||
|
|
||||||
|
it '(demo)', -> jasmine.demoEl(view.$el)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
describe 'when the server returns 402', ->
|
||||||
|
|
||||||
|
beforeEach -> respond(402)
|
||||||
|
|
||||||
|
it 'does nothing, because it is up to the view to handle payment next steps'
|
||||||
|
|
||||||
|
|
||||||
|
describe 'when the server returns 403', ->
|
||||||
|
|
||||||
|
beforeEach ->
|
||||||
|
me.set('anonymous', false)
|
||||||
|
respond(403)
|
||||||
|
|
||||||
|
it 'includes a logout button which logs out the account', ->
|
||||||
|
button = view.$el.find('#logout-btn')
|
||||||
|
expect(button.length).toBe(1)
|
||||||
|
button.click()
|
||||||
|
request = jasmine.Ajax.requests.mostRecent()
|
||||||
|
expect(request.url).toBe('/auth/logout')
|
||||||
|
|
||||||
|
it '(demo)', -> jasmine.demoEl(view.$el)
|
||||||
|
|
||||||
|
|
||||||
|
describe 'when the server returns 404', ->
|
||||||
|
|
||||||
|
beforeEach -> respond(404)
|
||||||
|
|
||||||
|
it 'includes one of the 404 images', ->
|
||||||
|
img = view.$el.find('#not-found-img')
|
||||||
|
expect(img.length).toBe(1)
|
||||||
|
|
||||||
|
it '(demo)', -> jasmine.demoEl(view.$el)
|
||||||
|
|
||||||
|
|
||||||
|
describe 'when the server returns 408', ->
|
||||||
|
|
||||||
|
beforeEach -> respond(408)
|
||||||
|
|
||||||
|
it 'includes "Server Timeout" in the header', ->
|
||||||
|
expect(view.$('[data-i18n="loading_error.timeout"]').length).toBeTruthy()
|
||||||
|
|
||||||
|
it 'shows a message encouraging refreshing the page or following links', ->
|
||||||
|
expect(view.$('[data-i18n="loading_error.general_desc"]').length).toBeTruthy()
|
||||||
|
|
||||||
|
it '(demo)', -> jasmine.demoEl(view.$el)
|
||||||
|
|
||||||
|
|
||||||
|
describe 'when no connection is made', ->
|
||||||
|
|
||||||
|
beforeEach ->
|
||||||
|
respond()
|
||||||
|
|
||||||
|
it 'shows "Connection Failed"', ->
|
||||||
|
expect(view.$('[data-i18n="loading_error.connection_failure"]').length).toBeTruthy()
|
||||||
|
|
||||||
|
it '(demo)', -> jasmine.demoEl(view.$el)
|
||||||
|
|
||||||
|
|
||||||
|
describe 'when the server returns any other number >= 400', ->
|
||||||
|
|
||||||
|
beforeEach -> respond(9001)
|
||||||
|
|
||||||
|
it 'includes "Unknown Error" in the header', ->
|
||||||
|
expect(view.$('[data-i18n="loading_error.unknown"]').length).toBeTruthy()
|
||||||
|
|
||||||
|
it 'shows a message encouraging refreshing the page or following links', ->
|
||||||
|
expect(view.$('[data-i18n="loading_error.general_desc"]').length).toBeTruthy()
|
||||||
|
|
||||||
|
it '(demo)', -> jasmine.demoEl(view.$el)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ describe 'CourseVictoryModal', ->
|
||||||
expect(_.size(modal.views)).toBe(1)
|
expect(_.size(modal.views)).toBe(1)
|
||||||
expect(modal.views[0] instanceof ProgressView).toBe(true)
|
expect(modal.views[0] instanceof ProgressView).toBe(true)
|
||||||
|
|
||||||
xit '(demo)', -> currentView.openModalView(modal)
|
it '(demo)', -> jasmine.demoModal(modal)
|
||||||
|
|
||||||
describe 'its ProgressView', ->
|
describe 'its ProgressView', ->
|
||||||
it 'has a next level button which navigates to the next level on click', ->
|
it 'has a next level button which navigates to the next level on click', ->
|
||||||
|
@ -93,7 +93,7 @@ describe 'CourseVictoryModal', ->
|
||||||
button.click()
|
button.click()
|
||||||
expect(application.router.navigate).toHaveBeenCalled()
|
expect(application.router.navigate).toHaveBeenCalled()
|
||||||
|
|
||||||
xit '(demo)', -> currentView.openModalView(modal)
|
it '(demo)', -> jasmine.demoModal(modal)
|
||||||
|
|
||||||
|
|
||||||
describe 'given a course level with a new item', ->
|
describe 'given a course level with a new item', ->
|
||||||
|
@ -121,4 +121,4 @@ describe 'CourseVictoryModal', ->
|
||||||
modal.$el.find('#continue-btn').click()
|
modal.$el.find('#continue-btn').click()
|
||||||
expect(modal.currentView instanceof ProgressView).toBe(true)
|
expect(modal.currentView instanceof ProgressView).toBe(true)
|
||||||
|
|
||||||
xit '(demo)', -> currentView.openModalView(modal)
|
it '(demo)', -> jasmine.demoModal(modal)
|
||||||
|
|
Loading…
Reference in a new issue