Update licenses needed form

Ensure the needed licenses are in the subject resulting email.
This commit is contained in:
Matt Lott 2016-06-17 15:40:03 -07:00
parent 514fce349a
commit 4622337d82
8 changed files with 59 additions and 52 deletions

View file

@ -815,6 +815,7 @@
more_info_1: "Our" more_info_1: "Our"
more_info_2: "teachers forum" more_info_2: "teachers forum"
more_info_3: "is a good place to connect with fellow educators who are using CodeCombat." more_info_3: "is a good place to connect with fellow educators who are using CodeCombat."
licenses_needed: "Licenses needed"
teachers_quote: teachers_quote:
name: "Demo Form" name: "Demo Form"

View file

@ -101,9 +101,6 @@ mixin addCredits
button#request-sent-btn.btn-lg.btn.btn-forest(disabled=true, data-i18n="teacher.request_sent") button#request-sent-btn.btn-lg.btn.btn-forest(disabled=true, data-i18n="teacher.request_sent")
else else
p(data-i18n="teacher.num_enrollments_needed") p(data-i18n="teacher.num_enrollments_needed")
div.m-t-2
input#students-input.enrollment-count.text-center(value=view.state.get('numberOfStudents') type='number')
strong(data-i18n="teacher.credits")
p.m-y-2(data-i18n="teacher.get_enrollments_blurb") p.m-y-2(data-i18n="teacher.get_enrollments_blurb")
button#contact-us-btn.btn-lg.btn.btn-forest(data-i18n="contribute.contact_us_url") button#contact-us-btn.btn-lg.btn.btn-forest(data-i18n="contribute.contact_us_url")

View file

@ -1,5 +1,7 @@
extends /templates/core/modal-base-flat extends /templates/core/modal-base-flat
//- TODO: i18n
block modal-header-content block modal-header-content
.text-center .text-center
h3 Contact Our Classroom Team h3 Contact Our Classroom Team
@ -11,26 +13,36 @@ block modal-body-content
- var sent = view.state.get('sendingState') === 'sent'; - var sent = view.state.get('sendingState') === 'sent';
- var values = view.state.get('formValues'); - var values = view.state.get('formValues');
- var errors = view.state.get('formErrors'); - var errors = view.state.get('formErrors');
.form-group(class=errors.name ? 'has-error' : '')
label.control-label(for="name" data-i18n="general.name")
+formErrors(errors.name)
input.form-control(name="name", type="text", value=values.name || '', tabindex=1, disabled=sending || sent)
.form-group(class=errors.email ? 'has-error' : '') .form-group(class=errors.email ? 'has-error' : '')
label.control-label(for="email" data-i18n="general.email") label.control-label(for="email" data-i18n="general.email")
+formErrors(errors.email) +formErrors(errors.email)
input.form-control(name="email", type="email", value=values.email || '', tabindex=1, disabled=sending || sent) input.form-control(name="email", type="email", value=values.email || '', tabindex=1, disabled=sending || sent)
.form-group(class=errors.licensesNeeded ? 'has-error' : '')
label.control-label(for="licensesNeeded" data-i18n="teachers.licenses_needed")
+formErrors(errors.licensesNeeded)
input.form-control(name="licensesNeeded", type="text", value=values.licensesNeeded || '', tabindex=1, disabled=sending || sent)
.form-group(class=errors.message ? 'has-error' : '') .form-group(class=errors.message ? 'has-error' : '')
label.control-label(for="message" data-i18n="general.message") label.control-label(for="message" data-i18n="general.message")
+formErrors(errors.message) +formErrors(errors.message)
textarea.form-control(name="message", tabindex=1 disabled=sending || sent)= values.message textarea.form-control(name="message", tabindex=1 disabled=sending || sent)= values.message
if view.state.get('sendingState') === 'error' if view.state.get('sendingState') === 'error'
.alert.alert-danger Could not send message. .alert.alert-danger Could not send message.
if sent if sent
.alert.alert-success Message sent! .alert.alert-success Message sent!
.text-right .text-right
button#submit-btn.btn.btn-navy.btn-lg(type='submit' disabled=sending || sent) Submit button#submit-btn.btn.btn-navy.btn-lg(type='submit' disabled=sending || sent) Submit
block modal-footer block modal-footer
mixin formErrors(errors) mixin formErrors(errors)

View file

@ -14,7 +14,6 @@ module.exports = class EnrollmentsView extends RootView
template: template template: template
events: events:
'input #students-input': 'onInputStudentsInput'
'click #enroll-students-btn': 'onClickEnrollStudentsButton' 'click #enroll-students-btn': 'onClickEnrollStudentsButton'
'click #how-to-enroll-link': 'onClickHowToEnrollLink' 'click #how-to-enroll-link': 'onClickHowToEnrollLink'
'click #contact-us-btn': 'onClickContactUsButton' 'click #contact-us-btn': 'onClickContactUsButton'
@ -96,17 +95,8 @@ module.exports = class EnrollmentsView extends RootView
@openModalView(new HowToEnrollModal()) @openModalView(new HowToEnrollModal())
onClickContactUsButton: -> onClickContactUsButton: ->
window.tracker?.trackEvent 'Classes Licenses Contact Us', category: 'Teachers', enrollmentsNeeded: @state.get('numberOfStudents'), ['Mixpanel'] window.tracker?.trackEvent 'Classes Licenses Contact Us', category: 'Teachers', ['Mixpanel']
@openModalView(new TeachersContactModal({ enrollmentsNeeded: @state.get('numberOfStudents') })) @openModalView(new TeachersContactModal())
onInputStudentsInput: ->
input = @$('#students-input').val()
if input isnt "" and (parseFloat(input) isnt parseInt(input) or _.isNaN parseInt(input))
@$('#students-input').val(@state.get('numberOfStudents'))
else
@state.set({'numberOfStudents': Math.max(parseInt(@$('#students-input').val()) or 0, 0)}, {silent: true}) # do not re-render
numberOfStudentsIsValid: -> 0 < @get('numberOfStudents') < 100000
onClickEnrollStudentsButton: -> onClickEnrollStudentsButton: ->
window.tracker?.trackEvent 'Classes Licenses Enroll Students', category: 'Teachers', ['Mixpanel'] window.tracker?.trackEvent 'Classes Licenses Enroll Students', category: 'Teachers', ['Mixpanel']

View file

@ -7,20 +7,22 @@ contact = require 'core/contact'
module.exports = class TeachersContactModal extends ModalView module.exports = class TeachersContactModal extends ModalView
id: 'teachers-contact-modal' id: 'teachers-contact-modal'
template: require 'templates/teachers/teachers-contact-modal' template: require 'templates/teachers/teachers-contact-modal'
defaultLicenses: 15
events: events:
'submit form': 'onSubmitForm' 'submit form': 'onSubmitForm'
initialize: (options={}) -> initialize: (options={}) ->
@state = new State({ @state = new State({
formValues: { formValues: {
name: ''
email: '' email: ''
licensesNeeded: @defaultLicenses
message: '' message: ''
} }
formErrors: {} formErrors: {}
sendingState: 'standby' # 'sending', 'sent', 'error' sendingState: 'standby' # 'sending', 'sent', 'error'
}) })
@enrollmentsNeeded = options.enrollmentsNeeded or '-'
@trialRequests = new TrialRequests() @trialRequests = new TrialRequests()
@supermodel.trackRequest @trialRequests.fetchOwn() @supermodel.trackRequest @trialRequests.fetchOwn()
@state.on 'change', @render, @ @state.on 'change', @render, @
@ -28,41 +30,46 @@ module.exports = class TeachersContactModal extends ModalView
onLoaded: -> onLoaded: ->
trialRequest = @trialRequests.first() trialRequest = @trialRequests.first()
props = trialRequest?.get('properties') or {} props = trialRequest?.get('properties') or {}
message = """ name = if props.firstName and props.lastName then "#{props.firstName} #{props.lastName}" else me.get('name') ? ''
Name of School/District: #{props.organization or ''}
Your Name: #{props.name || ''}
Enrollments Needed: #{@enrollmentsNeeded}
Message: Hi CodeCombat! I want to learn more about the Classroom experience and get licenses so that my students can access Computer Science 2 and on.
"""
email = props.email or me.get('email') or '' email = props.email or me.get('email') or ''
@state.set('formValues', { email, message }) message = """
Hi CodeCombat! I want to learn more about the Classroom experience and get licenses so that my students can access Computer Science 2 and on.
Name of School/District: #{props.organization or ''}
Role: #{props.role or ''}
Phone Number: #{props.phoneNumber or ''}
"""
@state.set('formValues', { name, email, licensesNeeded: @defaultLicenses, message })
super() super()
onSubmitForm: (e) -> onSubmitForm: (e) ->
e.preventDefault() e.preventDefault()
return if @state.get('sendingState') is 'sending' return if @state.get('sendingState') is 'sending'
formValues = forms.formToObject @$el formValues = forms.formToObject @$el
@state.set('formValues', formValues) @state.set('formValues', formValues)
formErrors = {} formErrors = {}
if not forms.validateEmail(formValues.email) unless formValues.name
formErrors.name = 'Name required.'
unless forms.validateEmail(formValues.email)
formErrors.email = 'Invalid email.' formErrors.email = 'Invalid email.'
if not formValues.message unless parseInt(formValues.licensesNeeded) > 0
formErrors.licensesNeeded = 'Licenses needed is required.'
unless formValues.message
formErrors.message = 'Message required.' formErrors.message = 'Message required.'
@state.set({ formErrors, formValues, sendingState: 'standby' }) @state.set({ formErrors, formValues, sendingState: 'standby' })
return unless _.isEmpty(formErrors) return unless _.isEmpty(formErrors)
@state.set('sendingState', 'sending') @state.set('sendingState', 'sending')
data = _.extend({ country: me.get('country'), recipientID: 'schools@codecombat.com', enrollmentsNeeded: @enrollmentsNeeded }, formValues) data = _.extend({ country: me.get('country'), recipientID: 'schools@codecombat.com' }, formValues)
contact.send({ contact.send({
data data
context: @ context: @
success: -> success: ->
@state.set({ sendingState: 'sent' }) @state.set({ sendingState: 'sent' })
me.set('enrollmentRequestSent', true) me.set('enrollmentRequestSent', true)
setTimeout(=> setTimeout(=>
@hide?() @hide?()
, 3000) , 3000)
error: -> @state.set({ sendingState: 'error' }) error: -> @state.set({ sendingState: 'error' })

View file

@ -25,11 +25,11 @@ module.exports.setup = (app) ->
createMailContent = (req, fromAddress, done) -> createMailContent = (req, fromAddress, done) ->
country = req.body.country country = req.body.country
enrollmentsNeeded = req.body.enrollmentsNeeded licensesNeeded = req.body.licensesNeeded
message = req.body.message message = req.body.message
user = req.user user = req.user
subject = switch subject = switch
when enrollmentsNeeded then "#{enrollmentsNeeded} Licenses needed for #{fromAddress}" when licensesNeeded then "#{licensesNeeded} Licenses needed for #{fromAddress}"
when req.body.subject then req.body.subject when req.body.subject then req.body.subject
else "Contact Us Form: #{fromAddress}" else "Contact Us Form: #{fromAddress}"
level = if user?.get('points') > 0 then Math.floor(5 * Math.log((1 / 100) * (user.get('points') + 100))) + 1 else 0 level = if user?.get('points') > 0 then Math.floor(5 * Math.log((1 / 100) * (user.get('points') + 100))) + 1 else 0

View file

@ -66,16 +66,6 @@ describe 'EnrollmentsView', ->
fail('There should be an #action-col, other tests depend on it.') fail('There should be an #action-col, other tests depend on it.')
describe '"Get Licenses" area', -> describe '"Get Licenses" area', ->
describe '"Contact Us" button', ->
it 'opens a TeachersContactModal, passing in the number of licenses', ->
spyOn(@view, 'openModalView')
@view.state.set('numberOfStudents', 20)
@view.$('#contact-us-btn').click()
expect(view.openModalView).toHaveBeenCalled()
args = view.openModalView.calls.argsFor(0)
expect(args[0] instanceof TeachersContactModal).toBe(true)
expect(args[0].enrollmentsNeeded).toBe(20)
describe 'when the teacher has made contact', -> describe 'when the teacher has made contact', ->
beforeEach -> beforeEach ->

View file

@ -4,18 +4,28 @@ factories = require 'test/app/factories'
describe 'TeachersContactModal', -> describe 'TeachersContactModal', ->
beforeEach (done) -> beforeEach (done) ->
@modal = new TeachersContactModal({ enrollmentsNeeded: 10 }) @modal = new TeachersContactModal()
@modal.render() @modal.render()
trialRequests = new TrialRequests([factories.makeTrialRequest()]) trialRequests = new TrialRequests([factories.makeTrialRequest()])
@modal.trialRequests.fakeRequests[0].respondWith({ status: 200, responseText: trialRequests.stringify() }) @modal.trialRequests.fakeRequests[0].respondWith({ status: 200, responseText: trialRequests.stringify() })
@modal.supermodel.once('loaded-all', done) @modal.supermodel.once('loaded-all', done)
jasmine.demoModal(@modal) jasmine.demoModal(@modal)
it 'shows an error when the name is empty and the form is submitted', ->
@modal.$('input[name="name"]').val('')
@modal.$('form').submit()
expect(@modal.$('input[name="name"]').closest('.form-group').hasClass('has-error')).toBe(true)
it 'shows an error when the email is invalid and the form is submitted', -> it 'shows an error when the email is invalid and the form is submitted', ->
@modal.$('input[name="email"]').val('not an email') @modal.$('input[name="email"]').val('not an email')
@modal.$('form').submit() @modal.$('form').submit()
expect(@modal.$('input[name="email"]').closest('.form-group').hasClass('has-error')).toBe(true) expect(@modal.$('input[name="email"]').closest('.form-group').hasClass('has-error')).toBe(true)
it 'shows an error when licensesNeeded is not > 0 and the form is submitted', ->
@modal.$('input[name="licensesNeeded"]').val('')
@modal.$('form').submit()
expect(@modal.$('input[name="licensesNeeded"]').closest('.form-group').hasClass('has-error')).toBe(true)
it 'shows an error when the message is empty and the form is submitted', -> it 'shows an error when the message is empty and the form is submitted', ->
@modal.$('textarea[name="message"]').val('') @modal.$('textarea[name="message"]').val('')
@modal.$('form').submit() @modal.$('form').submit()