mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-04-27 14:33:59 -04:00
Implemented George's jobs page design.
This commit is contained in:
parent
b96bca8c18
commit
f17775cc10
12 changed files with 230 additions and 76 deletions
app
assets/images/pages/account/profile
education.pngicon_facebook.pngicon_github.pngicon_gplus.pngicon_linkedin.pngicon_twitter.pngwork.png
styles/account
templates/account
views/account
server/users
BIN
app/assets/images/pages/account/profile/education.png
Normal file
BIN
app/assets/images/pages/account/profile/education.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 559 B |
BIN
app/assets/images/pages/account/profile/icon_facebook.png
Normal file
BIN
app/assets/images/pages/account/profile/icon_facebook.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 684 B |
BIN
app/assets/images/pages/account/profile/icon_github.png
Normal file
BIN
app/assets/images/pages/account/profile/icon_github.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 890 B |
BIN
app/assets/images/pages/account/profile/icon_gplus.png
Normal file
BIN
app/assets/images/pages/account/profile/icon_gplus.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 1.2 KiB |
BIN
app/assets/images/pages/account/profile/icon_linkedin.png
Normal file
BIN
app/assets/images/pages/account/profile/icon_linkedin.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 750 B |
BIN
app/assets/images/pages/account/profile/icon_twitter.png
Normal file
BIN
app/assets/images/pages/account/profile/icon_twitter.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 791 B |
BIN
app/assets/images/pages/account/profile/work.png
Normal file
BIN
app/assets/images/pages/account/profile/work.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 563 B |
|
@ -1,37 +1,160 @@
|
|||
#profile-view
|
||||
button
|
||||
float: right
|
||||
i
|
||||
margin-right: 5px
|
||||
.profile-control-bar
|
||||
background-color: rgb(78, 78, 78)
|
||||
width: 100%
|
||||
text-align: center
|
||||
|
||||
button.edit-settings-button
|
||||
margin: 2px
|
||||
i
|
||||
margin-right: 5px
|
||||
|
||||
|
||||
img.img-thumbnail
|
||||
margin: 5px 20px 20px 20px
|
||||
|
||||
ul.links, ul.projects
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
li
|
||||
list-style: none
|
||||
|
||||
.profile-header-container
|
||||
h1
|
||||
margin-bottom: 0px
|
||||
|
||||
.project-image
|
||||
width: 360px
|
||||
height: 270px
|
||||
background-size: cover
|
||||
background-repeat: no-repeat
|
||||
background-position: center
|
||||
|
||||
ul.projects
|
||||
li
|
||||
margin-top: 20px
|
||||
|
||||
.approved, .not-approved
|
||||
display: none
|
||||
|
||||
#job-profile-notes
|
||||
width: 100%
|
||||
height: 100px
|
||||
.main-content-area
|
||||
padding: 0
|
||||
|
||||
.flat-button
|
||||
width: 100%
|
||||
margin-bottom: 10px
|
||||
background: rgb(78, 78, 78)
|
||||
border: 0
|
||||
border-radius: 0
|
||||
padding: 10px
|
||||
|
||||
.job-profile-container
|
||||
width: 100%
|
||||
height: 100%
|
||||
padding: 0
|
||||
display: table
|
||||
|
||||
h1, h2, h3, h4, h5, h6
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif
|
||||
color: #555
|
||||
|
||||
ul.links, ul.projects
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
li
|
||||
list-style: none
|
||||
|
||||
.job-profile-row
|
||||
height: 100%
|
||||
display: table-row
|
||||
|
||||
.full-height-column
|
||||
height: 100%
|
||||
padding: 5px
|
||||
display: table-cell
|
||||
vertical-align: top
|
||||
|
||||
h3:first-child
|
||||
margin: 5px 0 5px 0
|
||||
|
||||
.left-column
|
||||
width: 250px
|
||||
padding: 5px
|
||||
background-color: rgb(220, 220, 220)
|
||||
|
||||
.profile-photo-container
|
||||
position: relative
|
||||
margin-bottom: 10px
|
||||
|
||||
img.profile-photo
|
||||
width: 240px
|
||||
border-radius: 6px
|
||||
|
||||
.profile-caption
|
||||
background-color: rgba(0, 0, 0, 0.5)
|
||||
color: white
|
||||
border-bottom-right-radius: 6px
|
||||
border-bottom-left-radius: 6px
|
||||
position: absolute
|
||||
width: 100%
|
||||
bottom: 0px
|
||||
text-align: center
|
||||
|
||||
ul.links
|
||||
li.has-icon
|
||||
display: inline-block
|
||||
img
|
||||
margin: 0 0 10px 0
|
||||
li.has-icon:not(:nth-child(5))
|
||||
img
|
||||
margin: 0 10px 10px 0
|
||||
|
||||
#contact-candidate
|
||||
margin-top: 20px
|
||||
background-color: rgb(177, 55, 25)
|
||||
padding: 15px
|
||||
font-size: 20px
|
||||
|
||||
.middle-column
|
||||
width: 524px
|
||||
background-color: white
|
||||
padding-left: 20px
|
||||
padding-right: 20px
|
||||
|
||||
code
|
||||
background-color: rgb(220, 220, 220)
|
||||
color: #555
|
||||
margin: 2px 0
|
||||
display: inline-block
|
||||
text-transform: lowercase
|
||||
|
||||
.long-description
|
||||
margin-top: 10px
|
||||
img
|
||||
max-width: 524px - 60px
|
||||
|
||||
.header-icon
|
||||
margin-right: 10px
|
||||
width: 32px
|
||||
height: 32px
|
||||
|
||||
.duration
|
||||
margin-left: 10px
|
||||
margin-bottom: 10px
|
||||
|
||||
#job-profile-notes
|
||||
width: 100%
|
||||
height: 100px
|
||||
|
||||
.right-column
|
||||
width: 250px
|
||||
background-color: white
|
||||
|
||||
ul.projects
|
||||
li
|
||||
margin-bottom: 10px
|
||||
padding: 5px 5px
|
||||
border: 2px solid rgb(220, 220, 220)
|
||||
|
||||
.project-image
|
||||
width: 230px
|
||||
height: 115px
|
||||
background-size: cover
|
||||
background-repeat: no-repeat
|
||||
background-position: center
|
||||
|
||||
-webkit-filter: grayscale(100%)
|
||||
-webkit-transition: .5s ease-in-out
|
||||
-moz-filter: grayscale(100%)
|
||||
-moz-transition: .5s ease-in-out
|
||||
-o-filter: grayscale(100%)
|
||||
-o-transition: .5s ease-in-out
|
||||
filter: grayscale(100%)
|
||||
transition: .5s ease-in-out
|
||||
|
||||
li:hover
|
||||
.project-image
|
||||
-webkit-filter: grayscale(0%)
|
||||
-moz-filter: grayscale(0%)
|
||||
-o-filter: grayscale(0%)
|
||||
filter: grayscale(0%)
|
||||
|
|
|
@ -2,60 +2,70 @@ extends /templates/base
|
|||
|
||||
block content
|
||||
|
||||
if myProfile
|
||||
a(href="/account/settings")
|
||||
button.btn
|
||||
i.icon-cog
|
||||
span(data-i18n="account_profile.edit_settings") Edit Settings
|
||||
if myProfile || (me.isAdmin() && user.get('jobProfile'))
|
||||
.profile-control-bar
|
||||
if myProfile
|
||||
a(href="/account/settings")
|
||||
button.btn.edit-settings-button
|
||||
i.icon-cog
|
||||
span(data-i18n="account_profile.edit_settings") Edit Settings
|
||||
if me.isAdmin() && user.get('jobProfile')
|
||||
button.btn.edit-settings-button#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
|
||||
|
||||
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
|
||||
h1= profile.name
|
||||
p.lead= profile.shortDescription
|
||||
.clearfix
|
||||
.container
|
||||
.row
|
||||
.col-md-2
|
||||
h2 Info
|
||||
.job-profile-container
|
||||
.job-profile-row
|
||||
.left-column.full-height-column
|
||||
.profile-photo-container
|
||||
img.profile-photo(src=photoURL)
|
||||
.profile-caption= profile.jobTitle || 'Software Developer'
|
||||
|
||||
if profileLinks.length
|
||||
ul.links
|
||||
each link in profileLinks
|
||||
li(title=profile.name + " on " + link.name, class=link.icon ? "has-icon" : "")
|
||||
a(href=link.link)
|
||||
if link.icon
|
||||
img(src=link.icon.url, alt=link.icon.name)
|
||||
else
|
||||
button.btn.btn-large.btn-inverse.flat-button= link.name
|
||||
|
||||
div= profile.city + ', ' + profile.country
|
||||
div= profile.visa
|
||||
div Looking for: #{profile.lookingFor}
|
||||
div Profile last updated #{moment(profile.updated).fromNow()}
|
||||
h3 Skills
|
||||
div Last updated #{moment(profile.updated).fromNow()}
|
||||
|
||||
button#contact-candidate.btn.btn-large.btn-inverse.flat-button Contact #{profile.name.split(' ')[0]}
|
||||
|
||||
.middle-column.full-height-column
|
||||
h3= profile.name
|
||||
p= profile.shortDescription
|
||||
|
||||
each skill in profile.skills
|
||||
code= skill
|
||||
span
|
||||
if profile.links.length
|
||||
h3 Links
|
||||
ul.links
|
||||
each link in profile.links
|
||||
li
|
||||
a(href=link.link) #{link.name}
|
||||
|
||||
.col-md-4
|
||||
h2 About
|
||||
div!= marked(profile.longDescription)
|
||||
div.long-description!= marked(profile.longDescription)
|
||||
|
||||
if profile.work.length
|
||||
h3 Work Experience
|
||||
h3
|
||||
img.header-icon(src="/images/pages/account/profile/work.png", alt="")
|
||||
| Work Experience
|
||||
each job in profile.work
|
||||
div.pull-right= job.duration
|
||||
strong #{job.role} at #{job.employer}
|
||||
div.duration.pull-right= job.duration
|
||||
| #{job.role} at #{job.employer}
|
||||
.clearfix
|
||||
|
||||
if profile.education.length
|
||||
h3 Education
|
||||
h3
|
||||
img.header-icon(src="/images/pages/account/profile/education.png", alt="")
|
||||
| Education
|
||||
each school in profile.education
|
||||
div.pull-right= school.duration
|
||||
strong #{school.degree} at #{school.school}
|
||||
div.duration.pull-right= school.duration
|
||||
| #{school.degree} at #{school.school}
|
||||
.clearfix
|
||||
|
||||
if user.get('jobProfileNotes') || me.isAdmin()
|
||||
|
@ -66,16 +76,17 @@ block content
|
|||
else
|
||||
p!= marked(notes)
|
||||
|
||||
.col-md-4
|
||||
.right-column.full-height-column
|
||||
if profile.projects.length
|
||||
h2 Projects
|
||||
h3 Projects
|
||||
ul.projects
|
||||
each project in profile.projects
|
||||
a(href="#{project.link}")
|
||||
li
|
||||
h3 #{project.name}
|
||||
.project-image(style="background-image: url(/file/" + project.picture + ")")
|
||||
a(href=project.link)
|
||||
.project-image(style="background-image: url(/file/" + project.picture + ")")
|
||||
p= project.name
|
||||
p!= marked(project.description)
|
||||
a(href=project.link).btn.btn-large.btn-inverse.flat-button Check it out
|
||||
|
||||
else
|
||||
h2
|
||||
|
|
|
@ -8,7 +8,7 @@ module.exports = class JobProfileView extends CocoView
|
|||
|
||||
editableSettings: [
|
||||
'lookingFor', 'active', 'name', 'city', 'country', 'skills', 'experience', 'shortDescription', 'longDescription',
|
||||
'work', 'education', 'visa', 'projects', 'links'
|
||||
'work', 'education', 'visa', 'projects', 'links', 'jobTitle'
|
||||
]
|
||||
readOnlySettings: [
|
||||
'updated'
|
||||
|
|
|
@ -40,6 +40,11 @@ module.exports = class ProfileView extends View
|
|||
context[key] = addedContext[key] for key of addedContext
|
||||
context.marked = marked
|
||||
context.moment = moment
|
||||
context.iconForLink = @iconForLink
|
||||
if links = @user.get('jobProfile')?.links
|
||||
links = ($.extend(true, {}, link) for link in links)
|
||||
link.icon = @iconForLink link for link in links
|
||||
context.profileLinks = _.sortBy links, (link) -> not link.icon # icons first
|
||||
context
|
||||
|
||||
afterRender: ->
|
||||
|
@ -61,3 +66,17 @@ module.exports = class ProfileView extends View
|
|||
notes = @$el.find("#job-profile-notes").val()
|
||||
@user.set 'jobProfileNotes', notes
|
||||
@user.save()
|
||||
|
||||
iconForLink: (link) ->
|
||||
icons = [
|
||||
{icon: 'facebook', name: 'Facebook', domain: 'facebook.com', match: /facebook/i}
|
||||
{icon: 'twitter', name: 'Twitter', domain: 'twitter.com', match: /twitter/i}
|
||||
{icon: 'github', name: 'GitHub', domain: 'github.com', match: /github/i}
|
||||
{icon: 'gplus', name: 'Google Plus', domain: 'plus.google.com', match: /(google|^g).?(\+|plus)/i}
|
||||
{icon: 'linkedin', name: 'LinkedIn', domain: 'linkedin.com', match: /(google|^g).?(\+|plus)/i}
|
||||
]
|
||||
for icon in icons
|
||||
if (link.name.search(icon.match) isnt -1) or (link.link.search(icon.domain) isnt -1)
|
||||
icon.url = "/images/pages/account/profile/icon_#{icon.icon}.png"
|
||||
return icon
|
||||
null
|
||||
|
|
|
@ -56,8 +56,9 @@ UserSchema = c.object {},
|
|||
simulatedBy: {type: 'integer', minimum: 0, default: 0}
|
||||
simulatedFor: {type: 'integer', minimum: 0, default: 0}
|
||||
|
||||
jobProfile: c.object {title: 'Job Profile', required: ['lookingFor', 'active', 'name', 'city', 'country', 'skills', 'experience', 'shortDescription', 'longDescription', 'visa', 'work', 'education', 'projects', 'links']},
|
||||
jobProfile: c.object {title: 'Job Profile', required: ['lookingFor', 'jobTitle', 'active', 'name', 'city', 'country', 'skills', 'experience', 'shortDescription', 'longDescription', 'visa', 'work', 'education', 'projects', 'links']},
|
||||
lookingFor: {title: 'Looking For', type: 'string', enum: ['Full-time', 'Part-time', 'Remote', 'Contracting', 'Internship'], default: 'Full-time', description: 'What kind of developer position do you want?'}
|
||||
jobTitle: {type: 'string', maxLength: 50, title: 'Desired Job Title', description: 'What role are you looking for? Ex.: "Full Stack Engineer", "Front-End Developer", "iOS Developer"', default: 'Software Developer'}
|
||||
active: {title: 'Active', type: 'boolean', description: 'Want interview offers right now?'}
|
||||
updated: c.date {title: 'Last Updated', description: 'How fresh your profile appears to employers. The fresher, the better. Profiles go inactive after 30 days.'}
|
||||
name: c.shortString {title: 'Name', description: 'Name you want employers to see, like "Nick Winter".'}
|
||||
|
@ -67,7 +68,7 @@ UserSchema = c.object {},
|
|||
{type: 'string', minLength: 1, maxLength: 20, description: 'Ex.: "objective-c", "mongodb", "rails", "android", "javascript"'}
|
||||
experience: {type: 'integer', title: 'Years of Experience', minimum: 0, description: 'How many years of professional experience (getting paid) developing software do you have?'}
|
||||
shortDescription: {type: 'string', maxLength: 140, title: 'Short Description', description: 'Who are you, and what are you looking for? 140 characters max.', default: 'Programmer seeking to build great software.'}
|
||||
longDescription: {type: 'string', maxLength: 2000, title: 'Long Description', description: 'What are you looking for? Give employeers more details. Highlight your stunning personality. Markdown okay. 2000 characters max.', format: 'markdown', default: '* I write great code.\n* You need great code?\n* Great!'}
|
||||
longDescription: {type: 'string', maxLength: 600, title: 'Description', description: 'What are you looking for? Give employeers more details. Highlight your stunning personality. Tasteful markdown okay. 600 characters max.', format: 'markdown', default: '* I write great code.\n* You need great code?\n* Great!'}
|
||||
visa: c.shortString {title: 'US Work Status', description: 'Are you authorized to work in the US, or do you need visa sponsorship?', enum: ['Authorized to work in the US', 'Need visa sponsorship'], default: 'Authorized to work in the US'}
|
||||
work: c.array {title: 'Work Experience', description: 'List your relevant work experience, most recent first.'},
|
||||
c.object {title: 'Job', description: 'Some work experience you had.', required: ['employer', 'role', 'duration']},
|
||||
|
@ -83,7 +84,7 @@ UserSchema = c.object {},
|
|||
c.object {title: 'Project', description: 'A project you created.', required: ['name', 'description', 'picture', 'link']},
|
||||
name: c.shortString {title: 'Project Name', description: 'What was the project called?'}
|
||||
description: {type: 'string', title: 'Description', description: 'Briefly describe the project.', maxLength: 400, format: 'markdown'}
|
||||
picture: {type: 'string', title: 'Picture', format: 'image-file', description: 'Upload a 360x270px or larger image showing off the project.'}
|
||||
picture: {type: 'string', title: 'Picture', format: 'image-file', description: 'Upload a 230x115px or larger image showing off the project.'}
|
||||
link: c.url {title: 'Link', description: 'Link to the project.', default: 'http://codecombat.com'}
|
||||
links: c.array {title: 'Links', description: 'Link any other sites or profiles you want to highlight, like your GitHub, your LinkedIn, or your blog.'},
|
||||
c.object {title: 'Link', description: 'A link to another site you want to highlight, like your GitHub, your LinkedIn, or your blog.', required: ['name', 'link']},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue