Skip to content

Commit 9088a3c

Browse files
authored
Merge pull request #18 from mldangelo/private-cv
User Authentication + Private CV
2 parents 02a23d9 + abbe91f commit 9088a3c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+1767
-893
lines changed

.eslintrc

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }],
1414
"react/jsx-wrap-multilines": [1, {declaration: true, assignment: true, return: true}],
1515
"jsx-a11y/no-static-element-interactions": 0,
16+
"no-underscore-dangle": 0,
1617
},
1718
"plugins": [
1819
"mocha",

.travis.yml

+15-26
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,28 @@
11
sudo: false
22
language: node_js
3-
3+
services: mongodb
44
cache:
55
yarn: true
6-
76
env:
87
global:
98
- secure: RMzwEd88VFWIw8R5j2RMkpFeiLGUM6tpoVooi30SOu/AkC0YxYNcxskIxDo0lfSuckvvggBxDq30WSXLrGaxCegCM5N5EyCdt/J67hnoD5C0x+hGFOrzp+nps/xfNerc47MLxVjG+Nglc8wk+gJNohG+l5AbEf33zwrVxARWqAPsqiUFyYGRcCSNMdFbUQnQtYrHFfxVpKU/MQMvsVPDvR8jNKjllIgCHHupYPtvfNP1/e33iWduJmEwP2k2kY7kJuEjy15RClrdW0y8k+uUibyKrjJQ0UhnAom0vwwIKbOZw8hBKRhvaGlJmvNRWBtsetpD60/xHo8s0POHMM12pfD7YQ2NZdriDXDdpArontMw5V0u6zUzWPV92yS99WXk/ufZIvCQl03nHEb6dK+8NPKquUmqZWWQYJylZc/tjzJJNliX03erDwNhYl2S4u+o5Br6iMMtxfIv1j7rBUk0sCHQwERWsYFm1HegvW2rwdOKBOcn2fOMBvKHZPSbLfDbJtJPSTetsT5MWyGIOPx8C+JIhobUNq5VpynOw+EInPfqG+qAV8HXJrZxoss/48o8IyjTBz0MTxNKrZD3v4R/pZrerq/+Jx/meCi6xHuMg4MEUnzj2o1DdSJB8C1vFindq2QrMah8u0wDscSNr2ihZg6treAnKCMeLe2PToqnlB0=
109
- secure: Pw7qEKKiSACRYWFrGA4Nej6ZWTHDEnZbLO111H36+jkpg3n/dAghzWwn9qxjfH4z7lEZ5dvIGAh8SAiAQGkhuhZ22S5Hl98SF+6akZPbpf3xfWvDZn5cwpJljcFJG8/gDwP9mM/zfkMVhnmvDs3Q9saHG+7OnnobDQd8clRWbqJnyWizOAXhelGg8oiS/3NwstHFIR0+0nGWL/Zc5r9Y0vIaOiR5ePa7CgRiWbhjf9l6x91wFFSx2/BpPIijHbtN+rsRxMzE2Dxr7Id35rhGmUx7y0KER87It8CYgzudrQLzyRVN33Uju2Sh/kjhVOJ8Afl8xIwc2sQfn9ChHDN7NZM2rzvh/Aajk/ShYDHARlqSy9ZrzVQh2DtMkcEwJZFD4WqbHE2OjIABKdO53YAUBXDlng8ght4kL8QVrvM1pEoKGu4LKZnrmuBWaV/lztBwx/2RHER42XVXWAk+FMR1h8fPBpSON2HIHx3h68SDSAHzjibMiI4e+JcA0VgeFBR8xTx9wdBDXlNSk2i/hlTuMMhp4lyS3MSNP4bXPwQ6KK4HvD+U+s765/tc5pFRr+xrCfBlMeHWSiGWDCPbCDycuU8lb3e3CApY2Sg5SyERRopGXS6CZGPqbqPGLtC1jGOgOgUcFhOCLUnhe7BKNHTgZDiC7OdpmUWp1P+ehnEA2X4=
1110
- secure: J3CiJWSSJGZJMgzWR5ESQMFXLDY3MRq0zJ0inthQY0YbDYxS44FU94ayPzF15pn3BjvJij32xZepnGiNSl3aDR0g1mbcKWI3tGojuaGPNSP5jG8BOiRu74iilUv5kFW8Ku2DumTfET45T13xsY/aIexnAe2JOc9NUzD+UuOIDlzGgTB38vC/hPVn+bRBmUH3iA+uuPtnDMMXpwczVOHJ4ekmvju28nXMwXFqSJcDE0sN5zhdfFaT63/nTYEGUg5VSfwWzNSkjDMGnq2Ed3919VMxoZbQIwCWPW6KZiwq+zw74dh1tD4GirnJFcVuLfYxr3I+LONojjYE3lLRCQWZeZkAggxkdAspE1RmMUDHaspFfPFBN2p2izpzcvAyRVDS3ZgW0mP3GXoNRse7Z02lELmrndvF8a5Acyqhgx7qCZOBrG4I0uv0LNH1TWnFqpz2KHYV86AZT82TvkNi7aiddnabokOtA4HfD//VYIa+lR/JReBRlctT33RVZpVObpYbKC9p1bFOhopGssljVnWxZ2JMCS4IiwCLIUbT2Rd7Xs7N1yBuFRXhBSwuraSdXgqYEWHYl8yZmSxkKraG0bHETAQCcfzRthQTBfoKshT2GRorgSF/hpzrSwbVBY14VMOlqpo2THNAOime4MAPIkZ07N+TORcM4SBtBGKjcY/q7aQ=
12-
11+
- secure: NjjJblwWbnmclNYvei4sn8RHjsbhsYJJUur6Tlo1bE1iQbU2Z9txI0SI2zhyZqNJLBPkQp06VihHzZUkG8cnorK1C6zXwcRa72gdLUJDyYcuibT0P+odJEM5D0BbzaUe7z29ul6uOjVEKdzWPfCAKVh1pV7B2jTjRGo6KaZ+6ue26rlEC9xat9eJeeBRAVwK+0NAKFKvIZ6lKIhdxbZypIX/gEZQ73NgYrJju8+m47YeddDdHBOPjIzFEtFzSOoz/6HZTCdT9rfMG/8KQnVMlvpAMPxj5pwsFrQItQKUhF2PXn5JtfndFbV/VOyTJsl4lMyTvmvHyAekZ8G7EL1G5w3ETcU7A87KGdFm7DGpj3BWECK7UQ+1Ucnwo1LRUoR9ZjpZdaOsxewf5cNcLjbnaxVvyT/+dtA6NeIEcj2lGl881GFsrQimtPmVsjiAemXMHa+9LbTRyblHIVtUPBiYVUWI8pCZ9yduze8TeIhY669YTtgThpOmPMw4ywVtn+MSBPwEcSLcFTtpCM6JXgD42dWjYrSouljmJ8aX4RkygEOti6cZMgyTN41uh35u+RFxsXWEAmncyNh3xNxQRFq22WML4LWpq1581iuUJPo01e4BZNlhPWTSQfOlLLrl9asD4ByhW0yb6XJaDVw3wVvRB/su99uWvv9aKdon/8IidGE=
12+
- secure: DBWxOpBhlAzO5zza4mJZkZa/XAIJdUlMVIqpCGJVGJsdjUIXlTdF/Vw+Q5U5ZUR2MQN1fbpvqOzllsBwHkQiND2lpztDXDn95UjW3SK8Fhb8+1TVfwR4HXXW4XV3nYQhGYXkPcJ1kTVtTLqkp4WCmXulkQ1WqQT1zGPmvu73Mj6QgowTGaHf0DrbfQQouQyt+ji1bn1RLwvaZuNmgoYw1N/8NVssQEeJqb0X8cK2cQv3iGk0lnTXc+k4nWTa+IOLBHbmCyRMoVRBt2CnIKc9SuG3dZRi6g7FIhlBEF21oyxC7vYOw7Hvgr4T6dLfZaArAd+th1RiKl1trXtz6es+KofWo/Fzw3NcSxrknA3HzDr+LjRUgWj+Bi0WF3o6G5EdUbaIZgolVy76xj4P9ZN4mDKIvrtS6ZoiPssT3zM3eNSzrqkvCZAgRO198oepUDG/9RGxnQrCZCJxIRWcCl5NybiKd+3Nk9hRT2ZdTDeskhH7h2as73IkVN9+Um0TszvaJMzZbyOAOFInJwZfcpS0uWX+3+bpahx3UDLqhDltSLV5O/THzhDoP2TselXZ5ZFzQ/U4MHxwesuRfEE37e0Uc2adoyzuVFtFNL+6S3G1kzJFO7kyAkJ4u5Sg+Qsw1r/WTZbvFvmnPr4wE9Mu4r1/AbHzcG1MJu8MfTRbRYTsKnA=
1313
matrix:
1414
include:
15-
- os: linux
16-
node_js: "7"
17-
env: NODE_ENV=development
18-
- os: linux
19-
node_js: "7"
20-
env: NODE_ENV=production
15+
- os: linux
16+
node_js: '7'
17+
env: NODE_ENV=development
18+
- os: linux
19+
node_js: '7'
20+
env: NODE_ENV=production
2121
fast_finish: true
22-
2322
addons:
24-
code_climate:
25-
repo_token: 321ece2c9941bf30bb07f0555343ad772bdbbc6235c866478afc7af46558a8b4
26-
23+
apt:
24+
packages:
25+
- xvfb
2726
before_install:
2827
- curl -o- -L https://yarnpkg.com/install.sh | bash
2928
- export PATH=$HOME/.yarn/bin:$PATH
@@ -32,29 +31,19 @@ before_install:
3231
- npm --version
3332
- gcc --version
3433
- g++ --version
35-
36-
addons:
37-
apt:
38-
packages:
39-
- xvfb
40-
4134
install:
42-
- export DISPLAY=':99.0'
43-
- Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
44-
- NODE_ENV=development yarn
45-
35+
- export DISPLAY=':99.0'
36+
- Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
37+
- NODE_ENV=development yarn
4638
before_script:
4739
- npm run lint
4840
- sleep 5
49-
5041
script:
5142
- npm run build-dev
5243
- npm run build
5344
- npm test
54-
5545
notifications:
5646
email:
5747
58-
5948
git:
6049
depth: 10

app/components/About/LinkRenderer.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { PropTypes } from 'react';
2-
import { Link } from 'react-router';
2+
import { Link } from 'react-router-dom';
33

44
const LinkRenderer = (props) => {
55
if (props.href.match(/^(https?:)?\/\//)) {

app/components/Resume/Courses.js

+17-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import React from 'react';
1+
import React, { PropTypes } from 'react';
22

33
import Course from './Courses/Course';
4-
import courses from '../../data/courses';
54

6-
const getRows = () => courses.sort((a, b) => {
5+
const getRows = courses => courses.sort((a, b) => {
76
let ret = 0;
87
if (a.university > b.university) ret = -1;
98
else if (a.unversity < b.university) ret = 1;
@@ -18,16 +17,29 @@ const getRows = () => courses.sort((a, b) => {
1817
/>
1918
));
2019

21-
const Courses = () => (
20+
const Courses = props => (
2221
<div className="courses">
2322
<div className="link-to" id="courses" />
2423
<div className="title">
2524
<h3>Selected Courses</h3>
2625
</div>
2726
<ul className="course-list">
28-
{getRows()}
27+
{getRows(props.data)}
2928
</ul>
3029
</div>
3130
);
3231

32+
Courses.propTypes = {
33+
data: PropTypes.arrayOf(PropTypes.shape({
34+
title: PropTypes.string,
35+
number: PropTypes.string,
36+
link: PropTypes.string,
37+
univerity: PropTypes.string,
38+
})),
39+
};
40+
41+
Courses.defaultProps = {
42+
data: [],
43+
};
44+
3345
export default Courses;

app/components/Resume/Education.js

+18-5
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,36 @@
1-
import React from 'react';
1+
import React, { PropTypes } from 'react';
22

33
import Degree from './Education/Degree';
4-
import degrees from '../../data/degrees';
54

6-
const getRows = () => degrees.map(degree => (
5+
const getRows = degrees => degrees.map(degree => (
76
<Degree
87
data={degree}
98
key={degree.school}
109
/>
1110
));
1211

13-
const Education = () => (
12+
const Education = props => (
1413
<div className="education">
1514
<div className="link-to" id="education" />
1615
<div className="title">
1716
<h3>Education</h3>
1817
</div>
19-
{getRows()}
18+
{getRows(props.data)}
2019
</div>
2120
);
2221

22+
Education.propTypes = {
23+
data: PropTypes.arrayOf(PropTypes.shape({
24+
school: PropTypes.string,
25+
degree: PropTypes.string,
26+
link: PropTypes.string,
27+
year: PropTypes.number,
28+
})),
29+
};
30+
31+
Education.defaultProps = {
32+
data: [],
33+
};
34+
35+
2336
export default Education;

app/components/Resume/Experience.js

+19-5
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,37 @@
1-
import React from 'react';
1+
import React, { PropTypes } from 'react';
22

33
import Job from './Experience/Job';
4-
import positions from '../../data/positions';
54

6-
const getRows = () => positions.map(job => (
5+
const getRows = positions => positions.map(job => (
76
<Job
87
data={job}
98
key={job.company}
109
/>
1110
));
1211

13-
const Experience = () => (
12+
const Experience = props => (
1413
<div className="experience">
1514
<div className="link-to" id="experience" />
1615
<div className="title">
1716
<h3>Experience</h3>
1817
</div>
19-
{getRows()}
18+
{getRows(props.data)}
2019
</div>
2120
);
2221

22+
Experience.propTypes = {
23+
data: PropTypes.arrayOf(PropTypes.shape({
24+
company: PropTypes.string,
25+
position: PropTypes.string,
26+
link: PropTypes.string,
27+
daterange: PropTypes.string,
28+
points: PropTypes.arrayOf(PropTypes.string),
29+
})),
30+
};
31+
32+
Experience.defaultProps = {
33+
data: [],
34+
};
35+
36+
2337
export default Experience;

app/components/Resume/References.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import { Link } from 'react-router';
2+
import { Link } from 'react-router-dom';
33

44
const References = () => (
55
<div className="references">

app/components/Resume/Skills.js

+34-5
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,35 @@
1-
import React, { Component } from 'react';
1+
import React, { Component, PropTypes } from 'react';
22

33
import CategoryButton from './Skills/CategoryButton';
44
import SkillBar from './Skills/SkillBar';
55

6-
import { skills, categories } from '../../data/skills';
7-
86
class Skills extends Component {
97

108
constructor(props) {
119
super(props);
1210
this.state = {
13-
buttons: Object.keys(categories).sort().reduce((obj, key) => ({
11+
buttons: props.categories.map(cat => cat.name).reduce((obj, key) => ({
1412
...obj,
1513
[key]: false,
1614
}), { All: true }),
17-
skills: skills.map(skill =>
15+
skills: props.skills.map(skill =>
1816
Object.assign(skill, { category: skill.category.sort() }),
1917
),
2018
};
2119
}
2220

21+
componentWillReceiveProps(nextProps) {
22+
this.setState({
23+
buttons: nextProps.categories.map(cat => cat.name).reduce((obj, key) => ({
24+
...obj,
25+
[key]: false,
26+
}), { All: true }),
27+
skills: nextProps.skills.map(skill =>
28+
Object.assign(skill, { category: skill.category.sort() }),
29+
),
30+
});
31+
}
32+
2333
getRows() {
2434
// search for true active categorys
2535
const actCat = Object.keys(this.state.buttons).reduce((cat, key) => (
@@ -38,6 +48,7 @@ class Skills extends Component {
3848
}).filter(skill => (actCat === 'All' || skill.category.includes(actCat)))
3949
.map(skill => (
4050
<SkillBar
51+
categories={this.props.categories}
4152
data={skill}
4253
key={skill.title}
4354
/>
@@ -85,4 +96,22 @@ class Skills extends Component {
8596
}
8697
}
8798

99+
Skills.propTypes = {
100+
skills: PropTypes.arrayOf(PropTypes.shape({
101+
title: PropTypes.string,
102+
compentency: PropTypes.number,
103+
category: PropTypes.arrayOf(PropTypes.string),
104+
})),
105+
categories: PropTypes.arrayOf(PropTypes.shape({
106+
name: PropTypes.string,
107+
color: PropTypes.string,
108+
})),
109+
};
110+
111+
Skills.defaultProps = {
112+
skills: [],
113+
categories: [],
114+
};
115+
116+
88117
export default Skills;
+41-22
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,54 @@
1-
import React, { PropTypes } from 'react';
1+
import React, { Component, PropTypes } from 'react';
22

3-
import { categories } from '../../../data/skills';
3+
class SkillBar extends Component {
44

5-
// TODO: Consider averaging colors
6-
const getColor = types => Object.keys(categories)
7-
.filter(key => types.includes(key))
8-
.map(key => categories[key])[0];
5+
constructor(props) {
6+
super(props);
7+
this.state = {
8+
data: props.data,
9+
categories: props.categories,
10+
};
11+
}
912

10-
const SkillBar = (props) => {
11-
const titleStyle = {
12-
background: getColor(props.data.category),
13-
};
14-
const barStyle = {
15-
background: getColor(props.data.category),
16-
width: `${String(Math.min(100, Math.max((props.data.compentency / 5.0) * 100.0, 0)))}%`,
17-
};
18-
return (
19-
<div className="skillbar clearfix">
20-
<div className="skillbar-title" style={titleStyle}><span>{props.data.title}</span></div>
21-
<div className="skillbar-bar" style={barStyle} />
22-
<div className="skill-bar-percent">{props.data.compentency} / 5</div>
23-
</div>
24-
);
25-
};
13+
// TODO: Consider averaging colors
14+
getColor() {
15+
return this.state.categories
16+
.filter(cat => this.state.data.category.includes(cat.name))
17+
.map(cat => cat.color)[0];
18+
}
19+
20+
render() {
21+
const titleStyle = {
22+
background: this.getColor(),
23+
};
24+
const barStyle = {
25+
...titleStyle,
26+
width: `${String(Math.min(100, Math.max((this.state.data.compentency / 5.0) * 100.0, 0)))}%`,
27+
};
28+
return (
29+
<div className="skillbar clearfix">
30+
<div className="skillbar-title" style={titleStyle}><span>{this.state.data.title}</span></div>
31+
<div className="skillbar-bar" style={barStyle} />
32+
<div className="skill-bar-percent">{this.state.data.compentency} / 5</div>
33+
</div>
34+
);
35+
}
36+
}
2637

2738
SkillBar.propTypes = {
2839
data: PropTypes.shape({
2940
category: PropTypes.arrayOf(PropTypes.string).isRequired,
3041
compentency: PropTypes.number.isRequired,
3142
title: PropTypes.string.isRequired,
3243
}).isRequired,
44+
categories: PropTypes.arrayOf(PropTypes.shape({
45+
name: PropTypes.string,
46+
color: PropTypes.string,
47+
})),
48+
};
49+
50+
SkillBar.defaultProps = {
51+
categories: [],
3352
};
3453

3554
export default SkillBar;

0 commit comments

Comments
 (0)