Finished most of basic features for job profiles.

This commit is contained in:
Nick Winter 2014-04-07 17:58:02 -07:00
parent 9af6694054
commit b96bca8c18
12 changed files with 88 additions and 16 deletions

View file

@ -28,3 +28,10 @@
ul.projects
li
margin-top: 20px
.approved, .not-approved
display: none
#job-profile-notes
width: 100%
height: 100px

View file

@ -1,8 +1,8 @@
h3(data-i18n="account_settings.job_profile") Job Profile
if me.get('jobProfileApproved')
p.lead(data-i18n="account_settings.job_profile_approved") Your job profile has been approved by CodeCombat.
p.lead(data-i18n="account_settings.job_profile_approved") Your job profile has been approved by CodeCombat. Hungry employers will see it until you mark it inactive or it is stale for two months.
else
p.lead(data-i18n="account_settings.job_profile_explanation") Fill this out, and we will try to find you a job, and stuff.
p.lead(data-i18n="account_settings.job_profile_explanation") Hi! Fill this out, and if we think we can find you a software developer job, we will get in touch to approve your profile.
#job-profile-treema

View file

@ -9,6 +9,12 @@ block content
span(data-i18n="account_profile.edit_settings") Edit Settings
if user.get('jobProfile')
if me.isAdmin()
button.btn#toggle-job-profile-approved
i.icon-cog
span(data-i18n='account_profile.approved').approved Approved
span(data-i18n='account_profile.approved').not-approved Not Approved
- var profile = user.get('jobProfile');
.profile-header-container
img(src=photoURL).img-thumbnail.pull-left
@ -52,6 +58,14 @@ block content
strong #{school.degree} at #{school.school}
.clearfix
if user.get('jobProfileNotes') || me.isAdmin()
h3 Our Notes
- var notes = user.get('jobProfileNotes') || '';
if me.isAdmin()
textarea#job-profile-notes!= notes
else
p!= marked(notes)
.col-md-4
if profile.projects.length
h2 Projects

View file

@ -21,7 +21,7 @@ block content
a(href="#password-pane", data-toggle="tab", data-i18n="account_settings.password_tab") Password
li
a(href="#email-pane", data-toggle="tab", data-i18n="account_settings.emails_tab") Emails
if me.isAdmin()
if showsJobProfileTab
li
a(href="#job-profile-pane", data-toggle="tab", data-i18n="account_settings.job_profile_tab") Job Profile

View file

@ -44,6 +44,8 @@ block content
th Yrs Exp
th Last Updated
th Current Job
if me.isAdmin()
th ✓?
tbody
for candidate, index in candidates
@ -52,10 +54,11 @@ block content
tr(data-candidate-id=candidate.id)
td
if authorized
img(src=candidate.getPhotoURL(), alt=profile.name, title=profile.name, width=50)
// Want image, but it doesn't work without loading every Gravatar profile
//img(src=candidate.getPhotoURL(), alt=profile.name, title=profile.name, width=50)
p= profile.name
else
img(src="/images/pages/contribute/archmage.png", alt="", title="Sign up as an employer to see our candidates", width=50)
//img(src="/images/pages/contribute/archmage.png", alt="", title="Sign up as an employer to see our candidates", width=50)
p Developer ##{index + 1}
if profile.country == 'USA'
td= profile.city
@ -76,3 +79,8 @@ block content
else
td
em Employer sign-up required.
if me.isAdmin()
if candidate.get('jobProfileApproved')
td ✓
else
td ✗

View file

@ -1,7 +1,7 @@
extends /templates/modal/modal_base
block modal-header-content
h3(data-i18n="diplomat_suggestion.title")
h3(data-i18n="diplomat_suggestion.title") Help translate CodeCombat!
block modal-body-content
h4(data-i18n="diplomat_suggestion.sub_heading") We need your language skills.

View file

@ -0,0 +1,9 @@
extends /templates/modal/modal_base
block modal-header-content
h3(data-i18n="employer_signup.title") Hire CodeCombat Players
block modal-body-content
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.

View file

@ -7,7 +7,12 @@ module.exports = class ProfileView extends View
template: template
loadingProfile: true
events:
'click #toggle-job-profile-approved': 'toggleJobProfileApproved'
'keyup #job-profile-notes': 'onJobProfileNotesChanged'
constructor: (options, @userID) ->
@onJobProfileNotesChanged = _.debounce @onJobProfileNotesChanged, 1000
super options
@user = User.getByID(@userID)
@loadingProfile = false if 'gravatarProfile' of @user
@ -36,3 +41,23 @@ module.exports = class ProfileView extends View
context.marked = marked
context.moment = moment
context
afterRender: ->
super()
@updateProfileApproval() if me.isAdmin()
updateProfileApproval: ->
approved = @user.get 'jobProfileApproved'
@$el.find('.approved').toggle Boolean(approved)
@$el.find('.not-approved').toggle not approved
toggleJobProfileApproved: ->
approved = not @user.get 'jobProfileApproved'
@user.set 'jobProfileApproved', approved
@user.save()
@updateProfileApproval()
onJobProfileNotesChanged: (e) =>
notes = @$el.find("#job-profile-notes").val()
@user.set 'jobProfileNotes', notes
@user.save()

View file

@ -73,6 +73,7 @@ module.exports = class SettingsView extends View
c.chosenPhoto = me.getPhotoURL()
c.subs = {}
c.subs[sub] = 1 for sub in c.me.get('emailSubscriptions') or ['announcement', 'notification', 'tester', 'level_creator', 'developer']
c.showsJobProfileTab = me.isAdmin() or me.get('jobProfile') or location.hash.search('job-profile-') isnt -1
c
getSubscriptions: ->

View file

@ -3,6 +3,8 @@ template = require 'templates/employers'
app = require 'application'
User = require 'models/User'
CocoCollection = require 'models/CocoCollection'
employerSignupTemplate = require 'templates/modal/employer_signup_modal'
ModalView = require 'views/kinds/ModalView'
class CandidatesCollection extends CocoCollection
url: '/db/user/x/candidates'
@ -13,7 +15,7 @@ module.exports = class EmployersView extends View
template: template
events:
'click tr': 'onCandidateClicked'
'click tbody tr': 'onCandidateClicked'
constructor: (options) ->
super options
@ -83,5 +85,6 @@ module.exports = class EmployersView extends View
url = "/account/profile/#{id}"
app.router.navigate url, {trigger: true}
else
console.log 'gotta prompt them to sign up'
alert 'sign up for dat my twisted archon'
employerSignupModal = new ModalView()
employerSignupModal.template = employerSignupTemplate
@openModalView employerSignupModal

View file

@ -16,7 +16,7 @@ privateProperties = [
'gplusID', 'music', 'volume', 'aceConfig'
]
candidateProperties = [
'jobProfile', 'jobProfileApproved'
'jobProfile', 'jobProfileApproved', 'jobProfileNotes'
]
UserHandler = class UserHandler extends Handler
@ -35,14 +35,18 @@ UserHandler = class UserHandler extends Handler
super(arguments...)
@editableProperties.push('permissions') unless config.isProduction
getEditableProperties: (req, document) ->
props = super req, document
props.push 'jobProfileApproved', 'jobProfileNotes' if req.user.isAdmin()
props
formatEntity: (req, document) ->
return null unless document?
obj = document.toObject()
delete obj[prop] for prop in serverProperties
includePrivates = req.user and (req.user.isAdmin() or req.user._id.equals(document._id))
delete obj[prop] for prop in privateProperties unless includePrivates
#includeCandidate = includePrivates or (obj.jobProfileApproved and req.user and ('employer' in (req.user.permissions ? [])))
includeCandidate = includePrivates or (req.user and ('employer' in (req.user.permissions ? []))) # testing
includeCandidate = includePrivates or (obj.jobProfileApproved and req.user and ('employer' in (req.user.permissions ? [])))
delete obj[prop] for prop in candidateProperties unless includeCandidate
obj.emailHash = @buildEmailHash document
return obj
@ -221,16 +225,17 @@ UserHandler = class UserHandler extends Handler
since = (new Date((new Date()) - 2 * 30.4 * 86400 * 1000)).toISOString()
#query = {'jobProfileApproved': true, 'jobProfile.active': true, 'jobProfile.updated': {$gt: since}}
query = {'jobProfile.active': true, 'jobProfile.updated': {$gt: since}} # testing
query.jobProfileApproved = true unless req.user.isAdmin()
selection = 'jobProfile'
if authorized
selection += ' email'
selection += ' email' if authorized
selection += ' jobProfileApproved' if req.user.isAdmin()
User.find(query).select(selection).exec (err, documents) =>
return @sendDatabaseError(res, err) if err
candidates = (@formatCandidate(authorized, doc) for doc in documents)
@sendSuccess(res, candidates)
formatCandidate: (authorized, document) ->
fields = if authorized then ['jobProfile', '_id'] else ['jobProfile']
fields = if authorized then ['jobProfile', 'jobProfileApproved', '_id'] else ['jobProfile']
obj = _.pick document.toObject(), fields
obj.emailHash = @buildEmailHash document
subfields = ['country', 'city', 'lookingFor', 'skills', 'experience', 'updated']

View file

@ -90,7 +90,7 @@ UserSchema = c.object {},
name: {type: 'string', maxLength: 30, title: 'Link Name', description: 'What are you linking to? Ex: "Personal Website", "Twitter"'}
link: c.url {title: 'Link', description: 'The URL.', default: 'http://codecombat.com'}
jobProfileApproved: {title: 'Job Profile Approved', type: 'boolean', description: 'Whether your profile has been approved by CodeCombat.'}
jobProfileNotes: {type: 'string', maxLength: 1000, title: 'Our Notes', description: "CodeCombat's notes on the candidate.", format: 'markdown', default: ''}
c.extendBasicProperties UserSchema, 'user'
module.exports = UserSchema