Push for george
This commit is contained in:
parent
628a784ac4
commit
6644c6a9ee
8 changed files with 144 additions and 24 deletions
app
lib
styles
templates/modal
views
server/routes
|
@ -20,6 +20,7 @@ module.exports = LinkedInHandler = class LinkedInHandler extends CocoClass
|
||||||
|
|
||||||
cacheProfileInformation: (profiles) =>
|
cacheProfileInformation: (profiles) =>
|
||||||
@linkedInData = profiles.values[0]
|
@linkedInData = profiles.values[0]
|
||||||
|
me.set("linkedIn", @linkedInData)
|
||||||
console.log "LinkedIn data is #{@linkedInData}"
|
console.log "LinkedIn data is #{@linkedInData}"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,14 @@ module.exports.createUser = (userObject, failure=backboneFailure, nextURL=null)
|
||||||
error: failure,
|
error: failure,
|
||||||
success: -> if nextURL then window.location.href = nextURL else window.location.reload()
|
success: -> if nextURL then window.location.href = nextURL else window.location.reload()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
module.exports.createUserWithoutReload = (userObject, failure=backboneFailure) ->
|
||||||
|
user = new User(userObject)
|
||||||
|
user.save({}, {
|
||||||
|
error: failure
|
||||||
|
success: ->
|
||||||
|
Backbone.Mediator.publish("created-user-without-reload")
|
||||||
|
})
|
||||||
|
|
||||||
module.exports.loginUser = (userObject, failure=genericFailure) ->
|
module.exports.loginUser = (userObject, failure=genericFailure) ->
|
||||||
jqxhr = $.post('/auth/login',
|
jqxhr = $.post('/auth/login',
|
||||||
|
|
|
@ -135,6 +135,11 @@ a[data-toggle="modal"]
|
||||||
border-bottom-color: #ccc
|
border-bottom-color: #ccc
|
||||||
.modal-footer.linkedin
|
.modal-footer.linkedin
|
||||||
text-align: center
|
text-align: center
|
||||||
|
.signin-text
|
||||||
|
font-size: 15px
|
||||||
|
padding-bottom: 10px
|
||||||
|
.login-link
|
||||||
|
cursor: pointer
|
||||||
|
|
||||||
|
|
||||||
// Bigger versions of some Bootstrap icons
|
// Bigger versions of some Bootstrap icons
|
||||||
|
|
|
@ -1,24 +1,60 @@
|
||||||
extends /templates/modal/modal_base
|
extends /templates/modal/modal_base
|
||||||
|
|
||||||
block modal-header-content
|
block modal-header-content
|
||||||
h3(data-i18n="employer_signup.title") Hire CodeCombat Players
|
if userIsAnonymous || !userIsAuthorized
|
||||||
|
h3(data-i18n="employer_signup.title") Sign up to hire CodeCombat players!
|
||||||
|
else
|
||||||
|
h3 Hiring Contract
|
||||||
|
|
||||||
block modal-body-content
|
block modal-body-content
|
||||||
if userIsAuthorized
|
if userIsAnonymous
|
||||||
h4 Contract
|
|
||||||
|
|
||||||
p Check out this fancy-schmancy contract. You should sign it.
|
|
||||||
|
|
||||||
else
|
|
||||||
h4(data-i18n="employer_signup.sub_heading") Let us find your next brilliant developers.
|
h4(data-i18n="employer_signup.sub_heading") Let us find your next brilliant developers.
|
||||||
|
|
||||||
p(data-i18n="employer_signup.pitch_body") When you hire one of our players, you will pay CodeCombat 18% of her first-year salary, payable within 30 days of when she starts working. We will fully refund our placement fee if she leaves or is fired within 90 days. Cool? Email george@codecombat.com to get set up with employer permissions to see our candidates.
|
p Create an account to get started!
|
||||||
|
.form
|
||||||
|
.form-group
|
||||||
|
label.control-label(for="signup-email", data-i18n="general.email") Email
|
||||||
|
input#signup-email.form-control.input-large(name="email",type="email")
|
||||||
|
.form-group
|
||||||
|
label.control-label(for="signup-password", data-i18n="general.password") Password
|
||||||
|
input#signup-password.input-large.form-control(name="password", type="password")
|
||||||
|
else if !userIsAuthorized
|
||||||
|
.modal-footer.linkedin
|
||||||
|
p Please sign into your LinkedIn account to verify your identity.
|
||||||
|
script(type="in/Login" id="linkedInAuthButton" data-onAuth="contractCallback")
|
||||||
|
|
||||||
|
else
|
||||||
|
| We (CodeCombat) are providing you (the Company) access to information about our best players. In exchange, you agree to pay us 15% of the first year's annualized starting base salary for any person that you hire on a full time basis through this site. That 15% is due on the first date that our candidate is employed and is 100% refundable for 90 days after that date if the candidate doesn't remain employed at the company for any reason.
|
||||||
|
br
|
||||||
|
br
|
||||||
|
| We will not bill you for interns and part time hires (remote or onsite) hired through this site, provided they do not become full time hires within 1 year of their start date. If they do become full time hires within 1 year of their start date, we will invoice you 15% of their first year's annualized starting base salary on their first day of full time employment. For these hires, the 90 day guarantee does not apply.
|
||||||
|
br
|
||||||
|
br
|
||||||
|
| You must keep all of the information you access on this site confidential. That means you cannot share it with third parties and will only use it for recruiting.
|
||||||
|
br
|
||||||
|
br
|
||||||
|
| We will invoice this account via email and you agree to pay within 30 days of that email being sent.
|
||||||
|
br
|
||||||
|
br
|
||||||
|
| Neither you or CodeCombat will be liable for any damages that result from this contract.
|
||||||
|
|
||||||
block modal-footer
|
block modal-footer
|
||||||
if userIsAuthorized
|
if userIsAnonymous && !userisAuthorized
|
||||||
|
.modal-footer.linkedin
|
||||||
|
b.signin-text Sign in with LinkedIn to complete the registration process.
|
||||||
|
script(type="in/Login" id="linkedInAuthButton" data-onAuth="contractCallback")
|
||||||
|
br
|
||||||
|
br
|
||||||
|
| Already have a CodeCombat account?
|
||||||
|
a.login-link(data-toggle="coco-modal", data-target="modal/login") Log in to continue!
|
||||||
|
else if !userIsAnonymous && !userIsAuthorized
|
||||||
|
.modal-footer.linkedin
|
||||||
|
| We will record your name and work history for verification purposes.
|
||||||
|
else if userIsAuthorized && !userHasSignedContract
|
||||||
|
.modal-footer.linkedin
|
||||||
|
button.btn.btn-primary(id="contract-agreement-button") I agree
|
||||||
|
else
|
||||||
.modal-footer.linkedin
|
.modal-footer.linkedin
|
||||||
| Thanks #{firstName}! You've already agreed to the contract.
|
| Thanks #{firstName}! You've already agreed to the contract.
|
||||||
else
|
|
||||||
.modal-footer.linkedin
|
|
||||||
script(type="in/Login" id="linkedInAuthButton" data-onAuth="contractCallback")
|
|
||||||
| Thanks, <?js= firstName?>! You've agreed to the contract.
|
|
||||||
|
|
|
@ -207,7 +207,7 @@ class CocoView extends Backbone.View
|
||||||
# Modals
|
# Modals
|
||||||
|
|
||||||
toggleModal: (e) ->
|
toggleModal: (e) ->
|
||||||
return if visibleModal
|
#return if visibleModal
|
||||||
if $(e.currentTarget).prop('target') is '_blank'
|
if $(e.currentTarget).prop('target') is '_blank'
|
||||||
return true
|
return true
|
||||||
# special handler for opening modals that are dynamically loaded, rather than static in the page. It works (or should work) like Bootstrap's modals, except use coco-modal for the data-toggle value.
|
# special handler for opening modals that are dynamically loaded, rather than static in the page. It works (or should work) like Bootstrap's modals, except use coco-modal for the data-toggle value.
|
||||||
|
|
|
@ -1,31 +1,99 @@
|
||||||
View = require 'views/kinds/ModalView'
|
View = require 'views/kinds/ModalView'
|
||||||
template = require 'templates/modal/employer_signup_modal'
|
template = require 'templates/modal/employer_signup_modal'
|
||||||
|
forms = require('lib/forms')
|
||||||
|
User = require 'models/User'
|
||||||
|
auth = require('lib/auth')
|
||||||
|
me = auth.me
|
||||||
|
|
||||||
module.exports = class EmployerSignupView extends View
|
module.exports = class EmployerSignupView extends View
|
||||||
id: "employer-signup"
|
id: "employer-signup"
|
||||||
template: template
|
template: template
|
||||||
closeButton: true
|
closeButton: true
|
||||||
|
|
||||||
|
|
||||||
subscriptions:
|
subscriptions:
|
||||||
'employer-linkedin-auth': 'showContractScreen'
|
"server-error": "onServerError"
|
||||||
|
"created-user-without-reload": "linkedInAuth"
|
||||||
|
|
||||||
|
events:
|
||||||
|
"click #contract-agreement-button": "agreeToContract"
|
||||||
|
|
||||||
|
|
||||||
constructor: (options) ->
|
constructor: (options) ->
|
||||||
super(options)
|
super(options)
|
||||||
@authorizedWithLinkedIn = IN?.User?.isAuthorized()
|
@authorizedWithLinkedIn = IN?.User?.isAuthorized()
|
||||||
window.contractCallback = -> window.Backbone.Mediator.publish("employer-linkedin-auth")
|
#TODO: If IN.User.logout is called after authorizing, then the modal is reopened
|
||||||
|
# and the user reauths, there will be a javascript error due to the
|
||||||
|
# contract callback context not finding @render
|
||||||
|
#window.tracker?.trackEvent 'Started Employer Signup'
|
||||||
|
@reloadWhenClosed = false
|
||||||
|
window.contractCallback = =>
|
||||||
|
@authorizedWithLinkedIn = IN?.User?.isAuthorized()
|
||||||
|
@render()
|
||||||
|
|
||||||
|
onServerError: (e) -> # TODO: work error handling into a separate forms system
|
||||||
|
@disableModalInProgress(@$el)
|
||||||
|
|
||||||
afterInsert: ->
|
afterInsert: ->
|
||||||
super()
|
super()
|
||||||
unless @authorizedWithLinkedIn
|
linkedInButtonParentElement = document.getElementById("linkedInAuthButton")?.parentNode
|
||||||
linkedInButtonParentElement = document.getElementById("linkedInAuthButton").parentNode
|
if linkedInButtonParentElement
|
||||||
IN.parse(linkedInButtonParentElement) if linkedInButtonParentElement
|
IN.parse()
|
||||||
|
if me.get('anonymous')
|
||||||
|
$(".IN-widget").get(0).addEventListener('click', @createAccount, true)
|
||||||
|
console.log "Parsed linkedin button element!"
|
||||||
|
console.log linkedInButtonParentElement
|
||||||
|
|
||||||
showContractScreen: =>
|
|
||||||
@render()
|
|
||||||
getRenderData: ->
|
getRenderData: ->
|
||||||
context = super()
|
context = super()
|
||||||
context.userIsAuthorized = @authorizedWithLinkedIn
|
context.userIsAuthorized = @authorizedWithLinkedIn
|
||||||
|
context.userHasSignedContract = false
|
||||||
|
context.userIsAnonymous = context.me.get('anonymous')
|
||||||
if @authorizedWithLinkedIn
|
if @authorizedWithLinkedIn
|
||||||
context.firstName = application.linkedinHandler.linkedInData.firstName
|
context.firstName = application.linkedinHandler.linkedInData.firstName
|
||||||
context
|
context
|
||||||
|
|
||||||
|
agreeToContract: ->
|
||||||
|
|
||||||
|
createAccount: (e) =>
|
||||||
|
console.log "Tried to create account!"
|
||||||
|
e.stopPropagation()
|
||||||
|
forms.clearFormAlerts(@$el)
|
||||||
|
userObject = forms.formToObject @$el
|
||||||
|
delete userObject.subscribe
|
||||||
|
for key, val of me.attributes when key in ["preferredLanguage", "testGroupNumber", "dateCreated", "wizardColor1", "name", "music", "volume", "emails"]
|
||||||
|
userObject[key] ?= val
|
||||||
|
subscribe = true
|
||||||
|
#TODO: Enable all email subscriptions
|
||||||
|
|
||||||
|
userObject.emails ?= {}
|
||||||
|
userObject.emails.generalNews ?= {}
|
||||||
|
userObject.emails.generalNews.enabled = subscribe
|
||||||
|
res = tv4.validateMultiple userObject, User.schema
|
||||||
|
return forms.applyErrorsToForm(@$el, res.errors) unless res.valid
|
||||||
|
window.tracker?.trackEvent 'Finished Signup'
|
||||||
|
@enableModalInProgress(@$el)
|
||||||
|
auth.createUserWithoutReload userObject, null
|
||||||
|
|
||||||
|
linkedInAuth: (e) =>
|
||||||
|
console.log "Authorizing with linkedin"
|
||||||
|
@listenTo me,"sync", ->
|
||||||
|
IN.User.authorize(@recordUserDetails, @)
|
||||||
|
me.fetch()
|
||||||
|
@reloadWhenClosed = true
|
||||||
|
|
||||||
|
|
||||||
|
recordUserDetails: (e) =>
|
||||||
|
console.log "Record user details here!"
|
||||||
|
@render()
|
||||||
|
|
||||||
|
destroy: ->
|
||||||
|
reloadWhenClosed = @reloadWhenClosed
|
||||||
|
super()
|
||||||
|
if reloadWhenClosed
|
||||||
|
window.location.reload()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ module.exports = class LoginModalView extends View
|
||||||
events:
|
events:
|
||||||
"click #login-button": "loginAccount"
|
"click #login-button": "loginAccount"
|
||||||
"keydown #login-password": "loginAccount"
|
"keydown #login-password": "loginAccount"
|
||||||
|
"click #link-to-signup": "switchToSignup"
|
||||||
|
|
||||||
subscriptions:
|
subscriptions:
|
||||||
'server-error': 'onServerError'
|
'server-error': 'onServerError'
|
||||||
|
|
|
@ -6,6 +6,7 @@ mongoose = require 'mongoose'
|
||||||
module.exports.setup = (app) ->
|
module.exports.setup = (app) ->
|
||||||
# This is hacky and should probably get moved somewhere else, I dunno
|
# This is hacky and should probably get moved somewhere else, I dunno
|
||||||
app.get '/db/cla.submissions', (req, res) ->
|
app.get '/db/cla.submissions', (req, res) ->
|
||||||
|
return errors.unauthorized(res, "You must be an admin to view that information") unless req.user?.isAdmin()
|
||||||
res.setHeader('Content-Type', 'application/json')
|
res.setHeader('Content-Type', 'application/json')
|
||||||
collection = mongoose.connection.db.collection 'cla.submissions', (err, collection) ->
|
collection = mongoose.connection.db.collection 'cla.submissions', (err, collection) ->
|
||||||
return log.error "Couldn't fetch CLA submissions because #{err}" if err
|
return log.error "Couldn't fetch CLA submissions because #{err}" if err
|
||||||
|
|
Reference in a new issue