Merge pull request #1253 from codecombat/master

Master into production
This commit is contained in:
Michael Schmatz 2014-07-03 16:42:04 -07:00
commit db5c135349
17 changed files with 445 additions and 248 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 B

View file

@ -1,7 +1,61 @@
#employers-view
h1, h2, h3
font: Arial
button
background: #fce232 /* Old browsers */
background: -moz-linear-gradient(top, #fce232 0%, #ea8e2b 100%)
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#fce232), color-stop(100%,#ea8e2b))
background: -webkit-linear-gradient(top, #fce232 0%,#ea8e2b 100%)
background: -o-linear-gradient(top, #fce232 0%,#ea8e2b 100%)
background: -ms-linear-gradient(top, #fce232 0%,#ea8e2b 100%)
background: linear-gradient(to bottom, #fce232 0%,#ea8e2b 100%)
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fce232', endColorstr='#ea8e2b',GradientType=0 )
vertical-align: text-bottom
margin-left: 30px
//filter panels
#filter
margin-bottom: 10px
.panel-heading
background-color: darkgrey
.panel-body
background-color: darkgrey
#filters
.filter_section
width: 16%
display: inline-block
vertical-align: top
margin-bottom: 10px
.get-started-button
vertical-align: text-bottom
margin-left: 10px
#filter-button, #create-alert-button
float: right
#login-link, #logout-button
float: right
color: #333333
display: inline-block
:visited
color: #333333
#logout-button:hover
cursor: pointer
#tagline, .hiring-call-to-action
width: 100%
text-align: center
display: inline-block
margin-top: 20px
h1, h2, h3
display: inline-block
button
display: inline-block
h1, h2, h3, h4
font-family: Arial, Helvetica, sans-serif
color: #333333
#tagline
margin-bottom: 20px
.see-candidates-header
margin: 30px
@ -10,23 +64,85 @@
#see-candidates
cursor: pointer
.employer_icon
width: 125px
float: left
margin: 0px 15px 15px 0px
.reasons
height: 275px
margin-bottom: 25px
width: 100%
.information_row
height: 150px
padding-right: 15px
#leftside
width: 500px
float: left
#rightside
width: 500px
float: left
.information_row
height: 150px
padding-right: 15px
.reason
width: 33%
padding-left: 3%
height: 150px
display: inline-block
.employer_icon
width: 125px
margin: 0px auto
.reason_long
width: 50%
padding-left: 3%
display: inline-block
.employer_icon
display: inline-block
width: 25%
max-width: 125px
vertical-align: text-bottom
.reason_text
display: inline-block
width: 75%
#bottom_row
height: auto
#candidate-table
width: 96%
margin-left: 2%
margin-right: 2%
background-color: #E7E7E7
table
cursor: pointer
width: 96%
margin-left: 2%
margin-right: 2%
margin-bottom: 30px
.tag_column
width: 25%
display: inline-block
.location_column
display: inline-block
width: 25%
.education_column
display: inline-block
width: 25%
.work_column
display: inline-block
width: 25%
tr
.candidate-picture
width: 50px
height: 50px
border-radius: 5px
overflow: hidden
margin-right: 10px
.candidate-description
width: 100%
vertical-align: bottom
td
margin-bottom: 10px
margin-top: 10px
padding-bottom: 5px
padding-top: 10px
.border_row
border-bottom: 1px solid #d3d3d3
vertical-align: bottom
padding-top: 0px
#results
display: inline-block
.tablesorter
//img
// display: none
@ -68,7 +184,7 @@
#employers-view, #profile-view.viewed-by-employer
#outer-content-wrapper, #intermediate-content-wrapper, #inner-content-wrapper
background: #949494
background: #B4B4B4
.main-content-area
background-color: #EAEAEA

View file

@ -0,0 +1,21 @@
@import "bootstrap/variables"
@import "bootstrap/mixins"
@import "base"
#employers-wrapper
background-color: #B4B4B4
height: 100%
#outer-content-wrapper, #intermediate-content-wrapper, #inner-content-wrapper
background: #B4B4B4
.navbar, #top-nav, .content.clearfix
background-color: #B4B4B4
.footer
border-top: none
background-color: #B4B4B4
padding-bottom: 50px
#employer-content-area
margin: auto

View file

@ -79,9 +79,6 @@ block content
li
a(href="/contribute#ambassador", data-i18n="classes.ambassador_title")
| : support our community of educators and coders.
li
a(href="/contribute#counselor", data-i18n="classes.counselor_title")
| : offer your advice and business acumen to the founders.
| Check out the
a(href="/contribute", data-i18n="nav.contribute")

View file

@ -179,23 +179,4 @@ block content
.contributor-signup(data-contributor-class-id="support", data-contributor-class-name="ambassador")
#counselor.header-scrolling-fix
.class_image
img.img-responsive(src="/images/pages/contribute/counselor.png", alt="")
h3.header-scrolling-fix
span(data-i18n="classes.counselor_title") Counselor
span
span(data-i18n="classes.counselor_title_description") (Expert/Teacher)
p(data-i18n="contribute.counselor_summary")
| None of the above roles fit what you are interested in? Do not worry, we are on the
| lookout for anybody who wants a hand in the development of CodeCombat! If you are
| interested in teaching, game development, open source management, or anything else
| that you think will be relevant to us, then this class is for you.
a(href="/contribute/counselor")
p.lead(data-i18n="contribute.more_about_counselor")
| Learn More About Becoming a Counselor
div.clearfix

View file

@ -30,9 +30,4 @@ ul.contribute_class.affix.nav.nav-list.nav-pills#contribute-nav
a(href=navPrefix + "#ambassador")
span(data-i18n="classes.ambassador_title") Ambassador
span
span(data-i18n="classes.ambassador_title_description") (Support)
li
a(href=navPrefix + "#counselor")
span(data-i18n="classes.counselor_title") Counselor
span
span(data-i18n="classes.counselor_title_description") (Expert/Teacher)
span(data-i18n="classes.ambassador_title_description") (Support)

View file

@ -1,49 +0,0 @@
extends /templates/base
block content
div.contribute_class
include /templates/contribute/contribute_nav
div.class-main#sounselor-main
.class_image
img.img-responsive(src="/images/pages/contribute/counselor.png", alt="")
h2
span(data-i18n="classes.counselor_title") Counselor
span
span(data-i18n="classes.counselor_title_description") (Expert/Teacher)
p(data-i18n="contribute.counselor_introduction_1")
| Do you have life experience?
| A different perspective on things that can help us decide how to shape CodeCombat?
| Of all these roles, this will probably take the least time, but
| individually you may make the most difference.
| We're on the lookout for wisened sages, particularly in areas like: teaching,
| game development, open source project management, technical recruiting, entrepreneurship,
| or design.
p(data-i18n="contribute.counselor_introduction_2")
| Or really anything that is relevant to the development of CodeCombat.
| If you have knowledge and want to share it to help grow this project, then
| this class might be for you.
h4(data-i18n="contribute.class_attributes") Class Attributes
ul
li(data-i18n="contribute.counselor_attribute_1")
| Experience, in any of the areas above or something you think might be helpful.
li(data-i18n="contribute.counselor_attribute_2")
| A little bit of free time!
h4(data-i18n="contribute.how_to_join") How to Join
p
a(title='Contact', tabindex=-1, data-toggle="coco-modal", data-target="modal/contact", data-i18n="contribute.contact_us_url")
| Contact us
span ,
span(data-i18n="contribute.counselor_join_desc")
| tell us a little about yourself, what you've done and what you'd
| be interested in doing. We'll put you in our contact list and be in touch
| when we could use advice (not too often).
div.clearfix

View file

@ -1,140 +1,175 @@
extends /templates/base
extends /templates/recruitment_base
block content
h1(data-i18n="employers.want_to_hire_our_players") Hire CodeCombat Players
if me.get('anonymous')
a#login-link Login
br
if !isEmployer && !me.isAdmin()
#tagline
h1(data-i18n="employers.hire_developers_not_credentials") Hire developers, not credentials.
button.btn.get-started-button Get started
else
if !me.get('anonymous')
a#logout-button(data-i18n="login.log_out") Logout
br
#filter
.panel-group#filter_panel
a#filter-link(data-toggle="collapse" data-target="#collapseOne")
.panel.panel-default
.panel-heading
h4.panel-title
span.glyphicon.glyphicon-folder-open#folder-icon
| Filter
.panel-collapse.collapse.in#collapseOne
.panel-body
form#filters
.filter_section#screened_filter
h4 Screened
input(type="checkbox" name="phoneScreenFilter" value="true")
| Phone Screened
br
input(type="checkbox" name="phoneScreenFilter" value="false")
| Not Phone Screened
.filter_section#visa_filter
h4 Visa
input(type="checkbox" name="visa" value="Authorized to work in the US")
| US Authorized
br
input(type="checkbox" name="visa" value="Need visa sponsorship")
| Not Authorized
.filter_section#school_filter
h4 School
input(type="checkbox" name="schoolFilter" value="Top 20 Eng.")
| Top 20 Eng.
br
input(type="checkbox" name="schoolFilter" value="Other US")
| Other US
br
input(type="checkbox" name="schoolFilter" value="Other Intl.")
| Other Intl.
.filter_section#location_filter
h4 Location
input(type="checkbox" name="locationFilter" value="Bay Area")
| Bay Area
br
input(type="checkbox" name="locationFilter" value="New York")
| New York
br
input(type="checkbox" name="locationFilter" value="Other US")
| Other US
br
input(type="checkbox" name="locationFilter" value="International")
| International
.filter_section#role_filter
h4 Role
input(type="checkbox" name="roleFilter" value="Web Developer")
| Web Developer
br
input(type="checkbox" name="roleFilter" value="Software Developer")
| Software Developer
br
input(type="checkbox" name="roleFilter" value="iOS Developer")
| iOS Developer
br
input(type="checkbox" name="roleFilter" value="Android Developer")
| Android Developer
br
input(type="checkbox" name="roleFilter" value="Project Manager")
| Project Developer
.filter_section#seniority_filter
h4 Seniority
input(type="checkbox" name="seniorityFilter" value="College Student")
| College Student
br
input(type="checkbox" name="seniorityFilter" value="Recent Grad")
| Recent Grad
br
input(type="checkbox" name="seniorityFilter" value="Junior")
| Junior
br
input(type="checkbox" name="seniorityFilter" value="Senior")
| Senior
br
input(type="checkbox" name="seniorityFilter" value="Management")
| Management
//input#select_all_checkbox(type="checkbox" name="select_all" checked)
//| Select all
button.btn#filter-button Filter
p#results #{numberOfCandidates} results
//button.btn#create-alert-button Create Alert
if candidates.length
#candidate-table
table
tbody
for candidate, index in featuredCandidates
- var profile = candidate.get('jobProfile');
- var authorized = candidate.id; // If we have the id, then we are authorized.
- var profileAge = (new Date() - new Date(profile.updated)) / 86400 / 1000;
- var expired = profileAge > 2 * 30.4;
- var curated = profile.curated;
tr.candidate-row(data-candidate-id=candidate.id, id=candidate.id, class=expired ? "expired" : "")
td(rowspan=2)
.candidate-picture
img(src=candidate.getPhotoURL(50), alt=profile.name, title=profile.name, width=50)
if curated && curated.shortDescription
td.candidate-description #{curated.shortDescription}
else
td.candidate-description #{profile.shortDescription}
tr.border_row(data-candidate-id=candidate.id)
if curated
- var workHistory = curated.workHistory.join(",");
td.tag_column
img(src="/images/pages/employer/tag.png")
| #{curated.mainTag}
td.location_column
img(src="/images/pages/employer/location.png")
| #{curated.location}
td.education_column
img(src="/images/pages/employer/education.png")
| #{curated.education}
td.work_column
img(src="/images/pages/employer/briefcase.png")
| #{workHistory}
else
td Hi
if !isEmployer && !me.isAdmin()
div#info_wrapper
div#leftside
div.information_row
img(class="employer_icon" src="/images/pages/employer/employer_icon1.png")
h2(data-i18n="employers.what") What is CodeCombat?
p(data-i18n="employers.what_blurb") CodeCombat is a multiplayer browser programming game. Players write code to control their forces in battle against other developers. We support JavaScript, Python, Lua, Clojure, CoffeeScript, and Io.
div.information_row
span.hiring-call-to-action
h2#start-hiring(data-i18n="employers.start_hiring") Start hiring.
button.btn.get-started-button Get started
h2#hiring-reasons.hiring-call-to-action(data-i18n="employers.reasons") 3 reasons you should hire through us:
.reasons#top_row
.reason
img.employer_icon(src="/images/pages/employer/employer_icon2.png")
h3(data-i18n="employers.everyone_looking") Everyone here is looking for work.
p(data-i18n="employers.everyone_looking_blurb") Forget about 20% LinkedIn InMail response rates. Everyone that we list on this site wants to find their next position and will respond to your request for an introduction.
.reason
img.employer_icon(src="/images/pages/employer/employer_icon6.png")
h3(data-i18n="employers.weeding") We've done the weeding for you.
//this will break in i18n. Fix the inlining
p(data-i18n="employers.weeding_blurb")
| Every candidate that has a
span.glyphicon.glyphicon-earphone
| icon has already gone through a phone screen with us. We only feature developers that we would work with.
.reason
img(class="employer_icon" src="/images/pages/employer/employer_icon3.png")
h2(data-i18n="employers.who") Who Are the Players?
p(data-i18n="employers.who_blurb") CodeCombateers are CTOs, VPs of Engineering, and graduates of top 20 engineering schools. No junior developers here. Our players enjoy playing with code and solving problems.
div.information_row
img(class="employer_icon" src="/images/pages/employer/employer_icon5.png")
h2(data-i18n="employers.cost") Who Are the Players?
p(data-i18n="employers.cost_blurb") CodeCombateers are CTOs, VPs of Engineering, and graduates of top 20 engineering schools. No junior developers here. Our players enjoy playing with code and solving problems.
div#rightside
div.information_row
img(class="employer_icon" src="/images/pages/employer/employer_icon2.png")
h2(data-i18n="employers.how") How Much Do we Charge?
p(data-i18n="employers.how_blurb") We charge 15% of first year's salary and offer a 100% money back guarantee for 90 days. We don't charge for candidates who are already actively being interviewed at your company.
div.information_row
img(class="employer_icon" src="/images/pages/employer/employer_icon4.png")
h2(data-i18n="employers.why") Why Hire Through Us?
p
span(data-i18n="employers.why_blurb_1") We will save you time. Every CodeCombateer we feaure is
strong(data-i18n="employers.why_blurb_2") looking for work
span(data-i18n="employers.why_blurb_3") , has
strong(data-i18n="employers.why_blurb_4") demonstrated top notch technical skills
span(data-i18n="employers.why_blurb_5") , and has been
strong(data-i18n="employers.why_blurb_6") personally screened by us
span(data-i18n="employers.why_blurb_7") . Stop screening and start hiring.
div.information_row
img(class="employer_icon" src="/images/pages/employer/employer_icon6.png")
h2(data-i18n="employers.response") What's the Response Rate?
p(data-i18n="employers.response_blurb") Almost every developer you contact on CodeCombat will respond to inquires whether or not they want to interivew. If you would like help finding a candidate for your role, we can make recommendations.
if candidates.length
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()
th(data-i18n="employers.candidate_who") Who
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.
- var profileAge = (new Date() - new Date(profile.updated)) / 86400 / 1000;
- var expired = profileAge > 2 * 30.4;
tr(data-candidate-id=candidate.id, id=candidate.id, class=expired ? "expired" : "")
td
if authorized
img(src=candidate.getPhotoURL(50), alt=profile.name, title=profile.name, height=50)
if profile.name
p= profile.name
else if me.isAdmin()
p (#{candidate.get('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
code= skill
span
td= profile.experience
td(data-profile-age=profileAge)= moment(profile.updated).fromNow()
if me.isAdmin()
td= remarks[candidate.id] ? remarks[candidate.id].get('contactName') : ''
if me.isAdmin() && area.id == 'inactive-candidates'
if candidate.get('jobProfileApproved')
td ✓
else
td ✗
h3(data-i18n="employers.pass_screen") They will pass your technical screen.
p(data-i18n="employers.pass_screen_blurb") All of these developers have ranked in our programming competitions. One employer found that 5x as many of our devs passed their technical screen than hiring from Hacker News.
span.hiring-call-to-action
h2(data-i18n="employers.make_hiring_easier") Make my hiring easier, please.
button.btn.get-started-button Get started
.reasons#bottom_row
.reason_long
img.employer_icon(src="/images/pages/employer/employer_icon1.png")
.reason_text
h3(data-i18n="employers.what") What is CodeCombat?
p(data-i18n="employers.what_blurb") CodeCombat is a multiplayer browser programming game. Players write code to control their forces in battle against other developers. We support JavaScript, Python, Lua, Clojure, CoffeeScript, and Io.
.reason_long
img.employer_icon(src="/images/pages/employer/employer_icon5.png")
.reason_text
h3(data-i18n="employers.cost") Who Are the Players?
p(data-i18n="employers.cost_blurb") CodeCombateers are CTOs, VPs of Engineering, and graduates of top 20 engineering schools. No junior developers here. Our players enjoy playing with code and solving problems.

View file

@ -0,0 +1,21 @@
body
#fb-root
#employers-wrapper
block header
.nav
.content.clearfix
.navbar-header
a.navbar-brand(href='/')
img(src="/images/pages/base/recruitment_logo.png", title="CodeCombat - Learn how to code by playing a game", alt="CodeCombat")
block outer_content
#outer-content-wrapper
#intermediate-content-wrapper
#inner-content-wrapper
.main-content-area#employer-content-area
block content
p If this is showing, you dun goofed
block footer
.footer

View file

@ -1,8 +0,0 @@
ContributeClassView = require 'views/contribute/contribute_class_view'
template = require 'templates/contribute/counselor'
{me} = require('lib/auth')
module.exports = class CounselorView extends ContributeClassView
id: "counselor-view"
template: template
contributorClassName: 'counselor'

View file

@ -21,11 +21,20 @@ module.exports = class EmployersView extends View
events:
'click tbody tr': 'onCandidateClicked'
'change #filters input': 'onFilterChanged'
'click #filter-button': 'applyFilters'
'change #select_all_checkbox': 'handleSelectAllChange'
'click .get-started-button': 'openSignupModal'
'click .navbar-brand': 'restoreBodyColor'
'click #login-link': 'onClickAuthbutton'
'click #filter-link': 'swapFolderIcon'
constructor: (options) ->
super options
@getCandidates()
@setFilterDefaults()
afterRender: ->
super()
@sortTable() if @candidates.models.length
@ -33,19 +42,98 @@ module.exports = class EmployersView extends View
afterInsert: ->
super()
_.delay @checkForEmployerSignupHash, 500
#fairly hacky, change this in the future
@originalBackgroundColor = $("body").css 'background-color'
$("body").css 'background-color', '#B4B4B4'
restoreBodyColor: ->
$("body").css 'background-color', @originalBackgroundColor
swapFolderIcon: ->
$("#folder-icon").toggleClass("glyphicon-folder-close").toggleClass("glyphicon-folder-open")
onFilterChanged: ->
@resetFilters()
that = @
$("#filters :input").each ->
input = $(this)
checked = input.prop 'checked'
name = input.attr 'name'
value = input.val()
if name is "phoneScreenFilter"
value = JSON.parse(input.prop 'value')
if checked
that.filters[name] = _.union that.filters[name], [value]
else
that.filters[name] = _.difference that.filters[name], [value]
for filterName, filterValues of @filters
if filterValues.length is 0
@filters[filterName] = @defaultFilters[filterName]
openSignupModal: ->
@openModalView new EmployerSignupView
handleSelectAllChange: (e) ->
checkedState = e.currentTarget.checked
$("#filters :input").each ->
$(this).prop 'checked', checkedState
@onFilterChanged()
resetFilters: ->
for filterName, filterValues of @filters
@filters[filterName] = []
applyFilters: ->
candidateList = _.sortBy @candidates.models, (c) -> c.get('jobProfile').updated
candidateList = _.filter candidateList, (c) -> c.get('jobProfileApproved')
filteredCandidates = candidateList
for filterName, filterValues of @filters
if filterName is "visa"
filteredCandidates = _.difference filteredCandidates, _.filter(filteredCandidates, (c) ->
fieldValue = c.get('jobProfile').visa
return not (_.contains filterValues, fieldValue)
)
else
filteredCandidates = _.difference filteredCandidates, _.filter(filteredCandidates, (c) ->
unless c.get('jobProfile').curated then return true
fieldValue = c.get('jobProfile').curated?[filterName]
return not (_.contains filterValues, fieldValue)
)
candidateIDsToShow = _.pluck filteredCandidates, 'id'
$("#candidate-table tr").each -> $(this).hide()
candidateIDsToShow.forEach (id) ->
$("[data-candidate-id=#{id}]").show()
$("#results").text(candidateIDsToShow.length + " results")
return filteredCandidates
setFilterDefaults: ->
@filters =
phoneScreenFilter: [true, false]
visa: ['Authorized to work in the US', 'Need visa sponsorship']
schoolFilter: ['Top 20 Eng.', 'Other US', 'Other Intl.']
locationFilter: ['Bay Area', 'New York', 'Other US', 'International']
roleFilter: ['Web Developer', 'Software Developer', 'iOS Developer', 'Android Developer', 'Project Manager']
seniorityFilter: ['College Student', 'Recent Grad', 'Junior', 'Senior', 'Management']
@defaultFilters = _.cloneDeep @filters
getRenderData: ->
ctx = super()
ctx.isEmployer = @isEmployer()
ctx.candidates = _.sortBy @candidates.models, (c) -> c.get('jobProfile').updated
ctx.candidates = _.sortBy @candidates.models, (c) -> -1 * c.get('jobProfile').experience
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')
unless @isEmployer() or me.isAdmin()
ctx.featuredCandidates = _.filter ctx.featuredCandidates, (c) -> c.get('jobProfile').curated
ctx.featuredCandidates = ctx.featuredCandidates.slice(0,7)
ctx.otherCandidates = _.reject ctx.activeCandidates, (c) -> c.get('jobProfileApproved')
ctx.remarks = {}
ctx.remarks[remark.get('user')] = remark for remark in @remarks.models
ctx.moment = moment
ctx._ = _
ctx.numberOfCandidates = ctx.featuredCandidates.length
ctx
isEmployer: ->
@ -64,10 +152,10 @@ module.exports = class EmployersView extends View
renderCandidatesAndSetupScrolling: =>
@render()
$(".nano").nanoScroller()
if window.history?.state?.lastViewedCandidateID
$(".nano").nanoScroller({scrollTo:$("#" + window.history.state.lastViewedCandidateID)})
else if window.location.hash.length is 25
$(".nano").nanoScroller({scrollTo:$(window.location.hash)})
#if window.history?.state?.lastViewedCandidateID
# $(".nano").nanoScroller({scrollTo:$("#" + window.history.state.lastViewedCandidateID)})
#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"))
@ -194,7 +282,7 @@ module.exports = class EmployersView extends View
onCandidateClicked: (e) ->
id = $(e.target).closest('tr').data('candidate-id')
if id
if id and (@isEmployer() or me.isAdmin())
if window.history
oldState = _.cloneDeep window.history.state ? {}
oldState["lastViewedCandidateID"] = id

View file

@ -321,10 +321,10 @@ UserHandler = class UserHandler extends Handler
@sendSuccess(res, candidates)
formatCandidate: (authorized, document) ->
fields = if authorized then ['name', 'jobProfile', 'jobProfileApproved', 'photoURL', '_id'] else ['jobProfile', 'jobProfileApproved']
fields = if authorized then ['name', 'jobProfile', 'jobProfileApproved', 'photoURL', '_id'] else ['_id','jobProfile', 'jobProfileApproved']
obj = _.pick document.toObject(), fields
obj.photoURL ||= obj.jobProfile.photoURL if authorized
subfields = ['country', 'city', 'lookingFor', 'jobTitle', 'skills', 'experience', 'updated', 'active']
obj.photoURL ||= obj.jobProfile.photoURL #if authorized
subfields = ['country', 'city', 'lookingFor', 'jobTitle', 'skills', 'experience', 'updated', 'active', 'shortDescription', 'curated', 'visa']
if authorized
subfields = subfields.concat ['name']
obj.jobProfile = _.pick obj.jobProfile, subfields