Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add salary range #31

Merged
merged 4 commits into from
Aug 22, 2017
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
API_URL='127.0.0.1:3000/'

# Mailgun
# Create a free account at https://app.mailgun.com/new/signup/, Use the sandbox domain SMTP user/pass
MAILGUN_USERNAME=''
Expand Down
1 change: 1 addition & 0 deletions client/components/Jobs/Add.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(
initialValues: {
type: "fulltime",
experience_range: 100,
salary_range: 30,
remote_available: false,
recruiter: false,
description: DESCRIPTION_TEMPLATE
Expand Down
27 changes: 20 additions & 7 deletions client/components/Jobs/Form/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,20 @@ export const TYPE_OPTIONS = [
];

export const EXPERIENCE_OPTIONS = [
{ label: "", value: "" },
{ value: "", label: "" },
{ value: 100, label: "Junior (Learner: 1-3 Years)" },
{ value: 200, label: "Midlevel (Producer: 3-5 Years)" },
{ value: 300, label: "Senior (Multiplier: 5+ Years)" }
];

export const SALARY_OPTIONS = [
{ value: "", label: "" },
{ value: 30, label: "$30,000 - $50,000" },
{ value: 50, label: "$50,000 - $80,000" },
{ value: 80, label: "$80,000 - $100,000" },
{ value: 100, label: "$100,000+" }
];

function _getValue(options) {
return value => {
const option = options.find(o => o.value === value);
Expand All @@ -27,6 +35,7 @@ function _getValue(options) {

export const getType = _getValue(TYPE_OPTIONS);
export const getExperience = _getValue(EXPERIENCE_OPTIONS);
export const getSalary = _getValue(SALARY_OPTIONS);

export const CompanyField = props =>
(<Field
Expand All @@ -36,6 +45,7 @@ export const CompanyField = props =>
label="Company"
help={companyHelp()}
/>);

export const TypeField = () =>
(<Field
name="type"
Expand All @@ -52,6 +62,14 @@ export const ExperienceField = () =>
label="Experience Range"
/>);

export const SalaryField = () =>
(<Field
name="salary_range"
component={Dropdown}
options={SALARY_OPTIONS}
label="Salary Range"
/>);

const descHelp = () =>
(<span>
Tip: You can use{" "}
Expand Down Expand Up @@ -100,12 +118,7 @@ export const JobForm = props => {
<fieldset>
<legend>Experience and Compensation</legend>
<ExperienceField />
<Field
name="salary_range"
component={Input}
type="number"
label="Salary Range"
/>
<SalaryField />
</fieldset>
<fieldset>
<legend>Contact Information</legend>
Expand Down
8 changes: 3 additions & 5 deletions client/components/Jobs/View.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Link } from "react-router";
import { connect } from "react-redux";
import capitalize from "lodash/capitalize";
import MarkdownViewer from "../Markdown/Viewer";
import { getExperience, getType } from "./Form";
import { getExperience, getType, getSalary } from "./Form";

import { getJob } from "../../actions/jobs";
import Messages from "../Messages";
Expand Down Expand Up @@ -35,13 +35,11 @@ class JobView extends Component {
className="job-tag job-type"
title={`${capitalize(job.type)} employment.`}
>
{getType(job.type)} @ ${job.salary_range
.toString()
.replace(/\B(?=(\d{3})+(?!\d))/g, ",")}/yr
{getType(job.type)} @ {getSalary(job.salary_range)}
</div>
<div
className="job-tag job-experience"
title={`${capitalize(getExperience(job.experience))}`}
title={`${capitalize(getSalary(job.salary_range))}`}
>
XP: {getExperience(job.experience_range)}
</div>
Expand Down
5 changes: 2 additions & 3 deletions server/controllers/job.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@ exports.create = async function(req, res, next) {
.assert("experience_range", "Please enter a valid experience range.")
.isInt();
req
.assert("salary_range", "Salaries Must be at least $30,000.")
.assert("lower_salary", "Please enter a valid salary range.")
.isInt()
.gte(30000);
req
.assert(
"remote_available",
Expand Down Expand Up @@ -99,7 +98,7 @@ exports.update = async function(req, res, next) {
req
.assert("experience_range", "Please enter a valid experience_range")
.isInt();
req.assert("salary_range", "Please enter a valid salary_range").isInt();
req.assert("salary_range", "Please enter a valid lower_salary").isInt();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this read "Please enter a valid salary range."?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙈 Yes, it should.

req
.assert("remote_available", "Please enter a valid remote_available")
.isBoolean();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ exports.up = function(knex, Promise) {
exports.down = function(knex, Promise) {
return Promise.all([
knex.schema.table("companies", function(table) {
table.dropColumn("user_id");
table.dropForeign("user_id");
table.dropColumn("user_id");
})
]);
};
21 changes: 21 additions & 0 deletions server/db/migrations/20170815115709_add_salary_range_to_jobs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
exports.up = function(knex, Promise) {
return Promise.all([
knex("jobs")
.whereBetween("salary_range", [30000, 49999])
.update({salary_range: 30}),
knex("jobs")
.whereBetween("salary_range", [50000, 79999])
.update({salary_range: 50}),
knex("jobs")
.whereBetween("salary_range", [80000, 99999])
.update({salary_range: 80}),
knex("jobs")
.whereBetween("salary_range", [100000, 999999])
.update({salary_range: 100})
]);
};

exports.down = function(knex, Promise) {
return Promise.all([
]);
};
59 changes: 59 additions & 0 deletions server/db/seeds/seed_dev_data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
var bcrypt = require("bcrypt-nodejs");

exports.seed = function (knex, Promise) {
return Promise.all([
knex('jobs').del().then(),
knex('companies').del().then(),
knex('users').del().then(),
new Promise(function (resolve, reject) {
bcrypt.genSalt(10, function (err, salt) {
bcrypt.hash('nashdev', salt, null, function (err, hash) {
return knex('users').insert([
{
id: 1,
name: 'Nashville Developer',
email: 'jobs@nashdev.org',
location: 'Nashville',
password: hash
},
]).then(function () {
return knex('companies').insert([
{
id: 1,
name: 'Nashville Company',
location: 'Nashville',
phone: '(615) 555-5555',
size: '20',
description: 'We develop software in Nashville.',
user_id: 1
},
])
})
.then(function () {
return knex('jobs').insert([
{
id: 1,
user_id: 1,
company_id: 1,
title: "Half Stack Web Developer",
description: "Pick your favorite.",
status: "open",
type: "fulltime",
recruiter: false,
location: "Nashville",
contact_email: "jobs@nashdev.org",
contact_website: "jobs.nashdev.org",
contact_person: "Dev Jobs",
experience_range: 100,
salary_range: 40000,
remote_available: true
}
])
})
})
})
})
])
}


5 changes: 4 additions & 1 deletion server/knexfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ module.exports = {
database: process.env.DB_NAME
},
migrations: {
directory: "./server/migrations"
directory: "./db/migrations"
},
seeds: {
directory: './db/seeds'
}
};
13 changes: 13 additions & 0 deletions server/models/Company.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
var Bookshelf = require("../config/bookshelf");
/*
+------------------+--------------------------+-----------------------+
| Column | Type | Modifiers |
|------------------+--------------------------+-----------------------|
| id | integer | |
| name | character varying(255) | unique |
| location | character varying(255) | |
| phone | character varying(255) | |
| size | text | |
| description | text | |
| user_id | integer | references user.id |
+------------------+--------------------------+-----------------------+
*/

var Company = Bookshelf.Model.extend(
{
Expand Down
22 changes: 22 additions & 0 deletions server/models/User.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,28 @@ var crypto = require("crypto");
var bcrypt = require("bcrypt-nodejs");
var Bookshelf = require("../config/bookshelf");

/*
+-----------------------+--------------------------+--------------+
| Column | Type | Modifiers |
|-----------------------+--------------------------+--------------|
| id | integer | |
| name | character varying(255) | |
| email | character varying(255) | unique |
| password | character varying(255) | |
| passwordResetToken | character varying(255) | |
| passwordResetExpires | timestamp with time zone | |
| gender | character varying(255) | |
| location | character varying(255) | |
| website | character varying(255) | |
| picture | character varying(255) | |
| facebook | character varying(255) | |
| github | character varying(255) | |
| twitter | character varying(255) | |
| google | character varying(255) | |
| vk | character varying(255) | |
+-----------------------+--------------------------+--------------+
*/

var User = Bookshelf.Model.extend({
tableName: "users",
hasTimestamps: true,
Expand Down