diff --git a/app/locale/en.coffee b/app/locale/en.coffee index fd3c88b93..2ea5da40b 100644 --- a/app/locale/en.coffee +++ b/app/locale/en.coffee @@ -198,8 +198,8 @@ done_editing: "Done Editing" profile_for_prefix: "Profile for " profile_for_suffix: "" - approved: "Approved" - not_approved: "Not Approved" + featured: "Featured" + not_featured: "Not Featured" looking_for: "Looking for:" last_updated: "Last updated:" contact: "Contact" @@ -295,7 +295,6 @@ project_link: "Link" project_link_help: "Link to the project." - employers: want_to_hire_our_players: "Want to hire expert CodeCombat players?" see_candidates: "Click here to see our candidates" @@ -309,8 +308,9 @@ candidate_top_skills: "Top Skills" candidate_years_experience: "Yrs Exp" candidate_last_updated: "Last Updated" - candidate_approved: "Us?" - candidate_active: "Them?" + featured_developers: "Featured Developers" + other_developers: "Other Developers" + inactive_developers: "Inactive Developers" play_level: done: "Done" diff --git a/app/styles/employers.sass b/app/styles/employers.sass index 1c7538cf2..6615a597d 100644 --- a/app/styles/employers.sass +++ b/app/styles/employers.sass @@ -1,6 +1,10 @@ #employers-view - #see-candidates - cursor: pointer + .see-candidates-header + margin-bottom: 30px + + #see-candidates + cursor: pointer + .tablesorter //img // display: none diff --git a/app/templates/account/profile.jade b/app/templates/account/profile.jade index 58c88944f..c96beff16 100644 --- a/app/templates/account/profile.jade +++ b/app/templates/account/profile.jade @@ -37,11 +37,11 @@ block content if profileApproved button.btn.btn-success#toggle-job-profile-approved(disabled=!me.isAdmin()) i.icon-eye-open - span(data-i18n='account_profile.approved') Approved + span(data-i18n='account_profile.featured') Featured else if me.isAdmin() button.btn#toggle-job-profile-approved i.icon-eye-close - span(data-i18n='account_profile.not_approved') Not Approved + span(data-i18n='account_profile.not_featured') Not Featured if me.isAdmin() && !myProfile button.btn.edit-settings-button#enter-espionage-mode 007 //if editing && myProfile diff --git a/app/templates/employers.jade b/app/templates/employers.jade index dcb6d2cac..f981962bb 100644 --- a/app/templates/employers.jade +++ b/app/templates/employers.jade @@ -6,62 +6,77 @@ block content p span(data-i18n="employers.candidates_count_prefix") We currently have - if candidates.length - | #{candidates.length} + if activeCandidates.length + | #{activeCandidates.length} else span(data-i18n="employers.candidates_count_many") many | span(data-i18n="employers.candidates_count_suffix") highly skilled and vetted developers looking for work. - if !isEmployer - - h3 + + if !isEmployer && !me.isAdmin() + h3.see-candidates-header a#see-candidates(title='Contact', tabindex=-1, data-toggle="coco-modal", data-target="modal/employer_signup", data-i18n="employers.see_candidates") Click here to see our candidates - + if candidates.length - table.table.table-condensed.table-hover.table-responsive.tablesorter - thead - tr - th(data-i18n="general.name") Name - th(data-i18n="employers.candidate_location") Location - th(data-i18n="employers.candidate_looking_for") Looking For - th(data-i18n="employers.candidate_role") Role - th(data-i18n="employers.candidate_top_skills") Top Skills - th(data-i18n="employers.candidate_years_experience") Yrs Exp - th(data-i18n="employers.candidate_last_updated") Last Updated - if me.isAdmin() - th(data-i18n="employers.candidate_approved") Us? - th(data-i18n="employers.candidate_active") Them? - - tbody - for candidate, index in candidates - - var profile = candidate.get('jobProfile'); - - var authorized = candidate.id; // If we have the id, then we are authorized. - tr(data-candidate-id=candidate.id, id=candidate.id) - td - if authorized - img(src=candidate.getPhotoURL(50), alt=profile.name, title=profile.name, height=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) - p Developer ##{index + 1} - if profile.country == 'USA' - td= profile.city - else - td= profile.country - td= profile.lookingFor - td= profile.jobTitle - td - each skill in profile.skills.slice(0, 10) - code= skill - span - td= profile.experience - td(data-profile-age=(new Date() - new Date(profile.updated)) / 86400 / 1000)= moment(profile.updated).fromNow() - if me.isAdmin() - if candidate.get('jobProfileApproved') - td ✓ - else - td ✗ - if profile.active - td ✓ - else - td ✗ \ No newline at end of file + + ul.nav.nav-pills + li.active + a(href="#featured-candidates", data-toggle="tab") + span(data-i18n="employers.featured_developers") Featured Developers + | (#{featuredCandidates.length}) + if otherCandidates.length + li + a(href="#other-candidates", data-toggle="tab") + span(data-i18n="employers.other_developers") Other Developers + | (#{otherCandidates.length}) + if me.isAdmin() && inactiveCandidates.length + li + a(href="#inactive-candidates", data-toggle="tab") + span(data-i18n="employers.inactive_developers") Inactive Developers + | (#{inactiveCandidates.length}) + + div.tab-content + for area, tabIndex in [{id: "featured-candidates", candidates: featuredCandidates}, {id: "other-candidates", candidates: otherCandidates}, {id: "inactive-candidates", candidates: inactiveCandidates}] + div(class="tab-pane well" + (tabIndex ? "" : " active"), id=area.id) + table.table.table-condensed.table-hover.table-responsive.tablesorter + thead + tr + th(data-i18n="general.name") Name + th(data-i18n="employers.candidate_location") Location + th(data-i18n="employers.candidate_looking_for") Looking For + th(data-i18n="employers.candidate_role") Role + th(data-i18n="employers.candidate_top_skills") Top Skills + th(data-i18n="employers.candidate_years_experience") Yrs Exp + th(data-i18n="employers.candidate_last_updated") Last Updated + if me.isAdmin() && area.id == 'inactive-candidates' + th ✓? + + tbody + for candidate, index in area.candidates + - var profile = candidate.get('jobProfile'); + - var authorized = candidate.id; // If we have the id, then we are authorized. + tr(data-candidate-id=candidate.id, id=candidate.id) + td + if authorized + img(src=candidate.getPhotoURL(50), alt=profile.name, title=profile.name, height=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) + p Developer ##{index + 1 + (area.id == 'featured-candidates' ? 0 : featuredCandidates.length)} + if profile.country == 'USA' + td= profile.city + else + td= profile.country + td= profile.lookingFor + td= profile.jobTitle + td + each skill in profile.skills.slice(0, 10) + code= skill + span + td= profile.experience + td(data-profile-age=(new Date() - new Date(profile.updated)) / 86400 / 1000)= moment(profile.updated).fromNow() + if me.isAdmin() && area.id == 'inactive-candidates' + if candidate.get('jobProfileApproved') + td ✓ + else + td ✗ diff --git a/app/views/employers_view.coffee b/app/views/employers_view.coffee index f7cddaa4e..25e006f99 100644 --- a/app/views/employers_view.coffee +++ b/app/views/employers_view.coffee @@ -20,10 +20,7 @@ module.exports = class EmployersView extends View constructor: (options) -> super options @getCandidates() - checkForEmployerSignupHash: => - if window.location.hash is "#employerSignupLoggingIn" and not ("employer" in me.get("permissions")) - @openModalView application.router.getView("modal/employer_signup","_modal") - window.location.hash = "" + afterRender: -> super() @sortTable() if @candidates.models.length @@ -33,13 +30,20 @@ module.exports = class EmployersView extends View _.delay @checkForEmployerSignupHash, 500 getRenderData: -> - c = super() - c.candidates = @candidates.models - userPermissions = me.get('permissions') ? [] + ctx = super() + ctx.isEmployer = @isEmployer() + ctx.candidates = _.sortBy @candidates.models, (c) -> c.get('jobProfile').updated + ctx.activeCandidates = _.filter ctx.candidates, (c) -> c.get('jobProfile').active + ctx.inactiveCandidates = _.reject ctx.candidates, (c) -> c.get('jobProfile').active + ctx.featuredCandidates = _.filter ctx.activeCandidates, (c) -> c.get('jobProfileApproved') + ctx.otherCandidates = _.reject ctx.activeCandidates, (c) -> c.get('jobProfileApproved') + ctx.moment = moment + ctx._ = _ + ctx - c.isEmployer = _.contains userPermissions, "employer" - c.moment = moment - c + isEmployer: -> + userPermissions = me.get('permissions') ? [] + _.contains userPermissions, "employer" getCandidates: -> @candidates = new CandidatesCollection() @@ -55,6 +59,11 @@ module.exports = class EmployersView extends View else if window.location.hash.length is 25 $(".nano").nanoScroller({scrollTo:$(window.location.hash)}) + checkForEmployerSignupHash: => + if window.location.hash is "#employerSignupLoggingIn" and not ("employer" in me.get("permissions")) + @openModalView application.router.getView("modal/employer_signup","_modal") + window.location.hash = "" + sortTable: -> # http://mottie.github.io/tablesorter/docs/example-widget-bootstrap-theme.html $.extend $.tablesorter.themes.bootstrap, @@ -110,7 +119,7 @@ module.exports = class EmployersView extends View n *= -1 days.push n days[0] - days[1] - sortList: [[6, 0]] + sortList: if @isEmployer() or me.isAdmin() then [[6, 0]] else [[0, 1]] # widget code contained in the jquery.tablesorter.widgets.js file # use the zebra stripe widget if you plan on hiding any rows (filter widget) widgets: ["uitheme", "zebra", "filter"] diff --git a/server/users/user_handler.coffee b/server/users/user_handler.coffee index 508578785..dfd3ecbb1 100644 --- a/server/users/user_handler.coffee +++ b/server/users/user_handler.coffee @@ -278,13 +278,11 @@ UserHandler = class UserHandler extends Handler getCandidates: (req, res) -> authorized = req.user.isAdmin() or ('employer' in req.user.get('permissions')) since = (new Date((new Date()) - 2 * 30.4 * 86400 * 1000)).toISOString() - #query = {'jobProfile.active': true, 'jobProfile.updated': {$gt: since}} query = {'jobProfile.updated': {$gt: since}} - query.jobProfileApproved = true unless req.user.isAdmin() + #query.jobProfileApproved = true unless req.user.isAdmin() # We split into featured and other now. query['jobProfile.active'] = true unless req.user.isAdmin() - selection = 'jobProfile' + selection = 'jobProfile jobProfileApproved' 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 = (candidate for candidate in documents when @employerCanViewCandidate req.user, candidate.toObject()) @@ -292,7 +290,7 @@ UserHandler = class UserHandler extends Handler @sendSuccess(res, candidates) formatCandidate: (authorized, document) -> - fields = if authorized then ['jobProfile', 'jobProfileApproved', 'photoURL', '_id'] else ['jobProfile'] + fields = if authorized then ['jobProfile', 'jobProfileApproved', 'photoURL', '_id'] else ['jobProfile', 'jobProfileApproved'] obj = _.pick document.toObject(), fields obj.photoURL ||= obj.jobProfile.photoURL if authorized subfields = ['country', 'city', 'lookingFor', 'jobTitle', 'skills', 'experience', 'updated', 'active']