From ae65f07e7ed1f55698f5232554458947293bc927 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Fri, 11 Apr 2014 12:49:44 -0700 Subject: [PATCH] Added some i18n and improved employer page. --- app/locale/en.coffee | 35 +++++++++-- app/styles/employers.sass | 11 ++++ app/templates/account/job_profile.jade | 4 +- app/templates/account/profile.jade | 22 ++++--- app/templates/employers.jade | 65 ++++++-------------- app/templates/modal/job_profile_contact.jade | 2 +- app/views/employers_view.coffee | 9 +-- app/views/kinds/CocoView.coffee | 3 +- app/views/modal/employer_signup_modal.coffee | 7 +++ server/users/user_handler.coffee | 4 +- 10 files changed, 93 insertions(+), 69 deletions(-) create mode 100644 app/views/modal/employer_signup_modal.coffee diff --git a/app/locale/en.coffee b/app/locale/en.coffee index 68b5fec67..f96d7de60 100644 --- a/app/locale/en.coffee +++ b/app/locale/en.coffee @@ -116,7 +116,7 @@ module.exports = nativeDescription: "English", englishDescription: "English", tr forum_suffix: " instead." send: "Send Feedback" contact_candidate: "Contact Candidate" - recruitment_reminder: "Use this form to get in touch with candidates you are interested in interviewing. Remember that CodeCombat charges 18% of first-year salary for any full-time candidate you hire who stays 90 days, but that part-timers, remote employees, contractors, and interns are free." + recruitment_reminder: "Use this form to reach out to candidates you are interested in interviewing. Remember that CodeCombat charges 18% of first-year salary. The fee is due upon hiring the employee and is refundable for 90 days if the employee does not remain employed. Part time, remote, and contract employees are free, as are interns." diplomat_suggestion: title: "Help translate CodeCombat!" @@ -151,6 +151,7 @@ module.exports = nativeDescription: "English", englishDescription: "English", tr wizard_tab: "Wizard" password_tab: "Password" emails_tab: "Emails" + job_profile_tab: "Job Profile!!!" admin: "Admin" wizard_color: "Wizard Clothes Color" new_password: "New Password" @@ -168,11 +169,37 @@ module.exports = nativeDescription: "English", englishDescription: "English", tr error_saving: "Error Saving" saved: "Changes Saved" password_mismatch: "Password does not match." + job_profile: "Job Profile!!!" + job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks.!!!" + job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job.!!!" account_profile: - edit_settings: "Edit Settings" - profile_for_prefix: "Profile for " - profile_for_suffix: "" + edit_settings: "Edit Settings!!!" + profile_for_prefix: "Profile for !!!" + profile_for_suffix: "!!!" + approved: "Approved!!!" + not_approved: "Not Approved!!!" + looking_for: "Looking for:!!!" + last_updated: "Last updated:!!!" + contact: "Contact!!!" + work_experience: "Work Experience!!!" + education: "Education!!!" + our_notes: "Our Notes!!!" + projects: "Projects!!!" + + employers: + want_to_hire_our_players: "Want to hire expert CodeCombat players?" + contact_george: "Contact George to see our candidates" + candidates_count_prefix: "We currently have " + candidates_count_many: "many" + candidates_count_suffix: "highly skilled and vetted developers looking for work." + candidate_name: "Name" + candidate_location: "Location" + candidate_looking_for: "Looking For" + candidate_role: "Role" + candidate_top_skills: "Top Skills" + candidate_years_experience: "Yrs Exp" + candidate_last_updated: "Last Updated" play_level: level_load_error: "Level could not be loaded: " diff --git a/app/styles/employers.sass b/app/styles/employers.sass index 2d61d81fa..6e64b44a0 100644 --- a/app/styles/employers.sass +++ b/app/styles/employers.sass @@ -7,6 +7,10 @@ cursor: pointer &:hover color: black + + &:first-child + // Make sure that "Developer #56" doesn't wrap onto second row + min-width: 110px .tablesorter-headerAsc background-color: #cfc @@ -16,3 +20,10 @@ tr cursor: pointer + + code + background-color: rgb(220, 220, 220) + color: #555 + margin: 2px 0 + display: inline-block + text-transform: lowercase diff --git a/app/templates/account/job_profile.jade b/app/templates/account/job_profile.jade index a5eff46d3..491ea8b9c 100644 --- a/app/templates/account/job_profile.jade +++ b/app/templates/account/job_profile.jade @@ -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. Hungry employers will see it until you mark it inactive or it is stale for two months. + p.lead(data-i18n="account_settings.job_profile_approved") Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks. else - 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. + p.lead(data-i18n="account_settings.job_profile_explanation") Hi! Fill this out, and we will get in touch about finding you a software developer job. #job-profile-treema \ No newline at end of file diff --git a/app/templates/account/profile.jade b/app/templates/account/profile.jade index 5ef74256e..6fee4c8af 100644 --- a/app/templates/account/profile.jade +++ b/app/templates/account/profile.jade @@ -36,10 +36,16 @@ block content div= profile.city + ', ' + profile.country div= profile.visa - div Looking for: #{profile.lookingFor} - div Last updated #{moment(profile.updated).fromNow()} + div + span(data-i18n="account_profile.looking_for") Looking for: + | #{profile.lookingFor} + div + span(data-i18n="account_profile.last_updated") Last updated: + | #{moment(profile.updated).fromNow()} - button#contact-candidate.btn.btn-large.btn-inverse.flat-button Contact #{profile.name.split(' ')[0]} + button#contact-candidate.btn.btn-large.btn-inverse.flat-button + span(data-i18n="account_profile.contact") Contact + | #{profile.name.split(' ')[0]} .middle-column.full-height-column h3= profile.name @@ -53,7 +59,7 @@ block content if profile.work.length h3.experience-header img.header-icon(src="/images/pages/account/profile/work.png", alt="") - | Work Experience + span(data-i18n="account_profile.work_experience") Work Experience each job in profile.work div.duration.pull-right= job.duration | #{job.role} at #{job.employer} @@ -62,14 +68,14 @@ block content if profile.education.length h3.experience-header img.header-icon(src="/images/pages/account/profile/education.png", alt="") - | Education + span(data-i18n="account_profile.work_experience") Education each school in profile.education div.duration.pull-right= school.duration | #{school.degree} at #{school.school} .clearfix if user.get('jobProfileNotes') || me.isAdmin() - h3.experience-header Our Notes + h3.experience-header(data-i18n="account_profile.our_notes") Our Notes - var notes = user.get('jobProfileNotes') || ''; if me.isAdmin() textarea#job-profile-notes!= notes @@ -78,7 +84,7 @@ block content .right-column.full-height-column if profile.projects.length - h3 Projects + h3(data-i18n="account_profile.projects") Projects ul.projects each project in profile.projects li @@ -97,4 +103,4 @@ block content img.profile-photo(src=user.getPhotoURL(256)) h2 TODO - p Public user profiles are not ready yet. \ No newline at end of file + p Public user profiles are not ready yet. If you are seeing this, we probably have a bug leading to a broken link. \ No newline at end of file diff --git a/app/templates/employers.jade b/app/templates/employers.jade index d242a7d77..efeb59429 100644 --- a/app/templates/employers.jade +++ b/app/templates/employers.jade @@ -2,48 +2,30 @@ extends /templates/base block content - .row + h1(data-i18n="employers.want_to_hire_our_players") Want to hire expert CodeCombat players? - .col-md-6 - - h2 CodeCombat for Employers - - p.lead Want to hire expert CodeCombat players? - - p - | CodeCombat doesn't just have beginners. We also have expert software developers who play our - a(href="http://blog.codecombat.com/beat-this-level-get-a-programming-job") developer challenge levels - | . If your company is seeking technical talent, then we'd be happy to help place candidates with you. - - p We were actually overwhelmed by how many talented developers rushed to site, crushed our version of the algorithm in the Gridmancer challenge, and were looking for job opportunities, especially in the SF Bay Area where CodeCombat is located. So if you're an employer, now's a great time to get in touch and meet some amazing programmers. - - p If this sounds interesting, then let's get in touch, find out what you're looking for, talk about recruitment terms, and see what we can do for you. Don't worry–we are not your traditional recruiter. We're a tech company like you who happens to have a ton of great programmers looking to us for help with the job search. - - h3 - a(title='Contact', tabindex=-1, data-toggle="coco-modal", data-target="modal/contact") Contact Us + p + span(data-i18n="employers.candidates_count_prefix") We currently have + if candidates.length + | #{candidates.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. + h3 + a(title='Contact', tabindex=-1, data-toggle="coco-modal", data-target="modal/employer_signup", data-i18n="employers.contact_george") Contact George to see our candidates - .span5 - - h2 Candidate Statistics - - h4 Resumes: 46 - h4 Ages: 16 - 45 - h4 Experience: 0 - 30 years - h4 Skill: from interns and entry level to senior developers and management - h4 Technologies: just about everything - h4 Countries: USA, Canada, Australia, and many more - if candidates.length table.table.table-condensed.table-hover.table-responsive.tablesorter thead tr - th Name - th Location - th Looking For - th Top 5 Skills - th Yrs Exp - th Last Updated - th Current Job + 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 ✓? @@ -64,20 +46,13 @@ block content else td= profile.country td= profile.lookingFor + td= profile.jobTitle td - each skill in profile.skills.slice(0, 5) + each skill in profile.skills.slice(0, 10) code= skill span td= profile.experience td= moment(profile.updated).fromNow() - if authorized - if profile.work.length - td= profile.work[0].role + ' at ' + profile.work[0].employer - else - td - else - td - em Employer sign-up required. if me.isAdmin() if candidate.get('jobProfileApproved') td ✓ diff --git a/app/templates/modal/job_profile_contact.jade b/app/templates/modal/job_profile_contact.jade index 87120f033..33a02d34d 100644 --- a/app/templates/modal/job_profile_contact.jade +++ b/app/templates/modal/job_profile_contact.jade @@ -4,7 +4,7 @@ block modal-header-content h3(data-i18n="contact.contact_candidate") Contact Candidate block modal-body-content - p(data-i18n="contact.recruitment_reminder") Use this form to get in touch with candidates you are interested in interviewing. Remember that CodeCombat charges 18% of first-year salary for any full-time candidate you hire who stays 90 days, but that part-timers, remote employees, contractors, and interns are free. + p(data-i18n="contact.recruitment_reminder") Use this form to reach out to candidates you are interested in interviewing. Remember that CodeCombat charges 18% of first-year salary. The fee is due upon hiring the employee and is refundable for 90 days if the employee does not remain employed. Part time, remote, and contract employees are free, as are interns. .form .form-group label.control-label(for="contact-email", data-i18n="general.email") Email diff --git a/app/views/employers_view.coffee b/app/views/employers_view.coffee index a43bbf70a..744db1954 100644 --- a/app/views/employers_view.coffee +++ b/app/views/employers_view.coffee @@ -3,8 +3,7 @@ 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' +EmployerSignupView = require 'views/modal/employer_signup_modal' class CandidatesCollection extends CocoCollection url: '/db/user/x/candidates' @@ -81,10 +80,8 @@ module.exports = class EmployersView extends View onCandidateClicked: (e) -> id = $(e.target).closest('tr').data('candidate-id') - if id + if not id url = "/account/profile/#{id}" app.router.navigate url, {trigger: true} else - employerSignupModal = new ModalView() - employerSignupModal.template = employerSignupTemplate - @openModalView employerSignupModal + @openModalView new EmployerSignupView diff --git a/app/views/kinds/CocoView.coffee b/app/views/kinds/CocoView.coffee index 01f236154..ed9ad844a 100644 --- a/app/views/kinds/CocoView.coffee +++ b/app/views/kinds/CocoView.coffee @@ -210,6 +210,7 @@ module.exports = class CocoView extends Backbone.View return unless elem.data('toggle') is 'coco-modal' target = elem.data('target') view = application.router.getView(target, '_modal') # could set up a system for loading cached modals, if told to + console.log "got target", target, "which gave view", view @openModalView(view) openModalView: (modalView, softly=false) -> @@ -227,7 +228,7 @@ module.exports = class CocoView extends Backbone.View $('#modal-wrapper .modal').modal(modalOptions).on 'hidden.bs.modal', @modalClosed window.currentModal = modalView @getRootView().stopListeningToShortcuts(true) - # setTimeout -> + # setTimeout -> # $('.modal').nanoScroller({contentClass:'modal-dialog'}) # , 1000 diff --git a/app/views/modal/employer_signup_modal.coffee b/app/views/modal/employer_signup_modal.coffee new file mode 100644 index 000000000..de66c007d --- /dev/null +++ b/app/views/modal/employer_signup_modal.coffee @@ -0,0 +1,7 @@ +View = require 'views/kinds/ModalView' +template = require 'templates/modal/employer_signup_modal' + +module.exports = class EmployerSignupView extends View + id: "employer-signup" + template: template + closeButton: true diff --git a/server/users/user_handler.coffee b/server/users/user_handler.coffee index cd78dad9e..e176e7a41 100644 --- a/server/users/user_handler.coffee +++ b/server/users/user_handler.coffee @@ -232,9 +232,9 @@ UserHandler = class UserHandler extends Handler obj = _.pick document.toObject(), fields obj.photoURL ||= obj.jobProfile.photoURL if authorized obj.photoURL ||= @buildGravatarURL document if authorized - subfields = ['country', 'city', 'lookingFor', 'skills', 'experience', 'updated'] + subfields = ['country', 'city', 'lookingFor', 'jobTitle', 'skills', 'experience', 'updated'] if authorized - subfields = subfields.concat ['name', 'work'] + subfields = subfields.concat ['name'] obj.jobProfile = _.pick obj.jobProfile, subfields obj