Skip to content

Commit

Permalink
Merge pull request #18 from mldangelo/private-cv
Browse files Browse the repository at this point in the history
User Authentication + Private CV
  • Loading branch information
mldangelo committed Mar 28, 2017
2 parents 02a23d9 + abbe91f commit 9088a3c
Show file tree
Hide file tree
Showing 65 changed files with 1,767 additions and 893 deletions.
1 change: 1 addition & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }],
"react/jsx-wrap-multilines": [1, {declaration: true, assignment: true, return: true}],
"jsx-a11y/no-static-element-interactions": 0,
"no-underscore-dangle": 0,
},
"plugins": [
"mocha",
Expand Down
41 changes: 15 additions & 26 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
sudo: false
language: node_js

services: mongodb
cache:
yarn: true

env:
global:
- 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=
- 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=
- secure: J3CiJWSSJGZJMgzWR5ESQMFXLDY3MRq0zJ0inthQY0YbDYxS44FU94ayPzF15pn3BjvJij32xZepnGiNSl3aDR0g1mbcKWI3tGojuaGPNSP5jG8BOiRu74iilUv5kFW8Ku2DumTfET45T13xsY/aIexnAe2JOc9NUzD+UuOIDlzGgTB38vC/hPVn+bRBmUH3iA+uuPtnDMMXpwczVOHJ4ekmvju28nXMwXFqSJcDE0sN5zhdfFaT63/nTYEGUg5VSfwWzNSkjDMGnq2Ed3919VMxoZbQIwCWPW6KZiwq+zw74dh1tD4GirnJFcVuLfYxr3I+LONojjYE3lLRCQWZeZkAggxkdAspE1RmMUDHaspFfPFBN2p2izpzcvAyRVDS3ZgW0mP3GXoNRse7Z02lELmrndvF8a5Acyqhgx7qCZOBrG4I0uv0LNH1TWnFqpz2KHYV86AZT82TvkNi7aiddnabokOtA4HfD//VYIa+lR/JReBRlctT33RVZpVObpYbKC9p1bFOhopGssljVnWxZ2JMCS4IiwCLIUbT2Rd7Xs7N1yBuFRXhBSwuraSdXgqYEWHYl8yZmSxkKraG0bHETAQCcfzRthQTBfoKshT2GRorgSF/hpzrSwbVBY14VMOlqpo2THNAOime4MAPIkZ07N+TORcM4SBtBGKjcY/q7aQ=

- secure: NjjJblwWbnmclNYvei4sn8RHjsbhsYJJUur6Tlo1bE1iQbU2Z9txI0SI2zhyZqNJLBPkQp06VihHzZUkG8cnorK1C6zXwcRa72gdLUJDyYcuibT0P+odJEM5D0BbzaUe7z29ul6uOjVEKdzWPfCAKVh1pV7B2jTjRGo6KaZ+6ue26rlEC9xat9eJeeBRAVwK+0NAKFKvIZ6lKIhdxbZypIX/gEZQ73NgYrJju8+m47YeddDdHBOPjIzFEtFzSOoz/6HZTCdT9rfMG/8KQnVMlvpAMPxj5pwsFrQItQKUhF2PXn5JtfndFbV/VOyTJsl4lMyTvmvHyAekZ8G7EL1G5w3ETcU7A87KGdFm7DGpj3BWECK7UQ+1Ucnwo1LRUoR9ZjpZdaOsxewf5cNcLjbnaxVvyT/+dtA6NeIEcj2lGl881GFsrQimtPmVsjiAemXMHa+9LbTRyblHIVtUPBiYVUWI8pCZ9yduze8TeIhY669YTtgThpOmPMw4ywVtn+MSBPwEcSLcFTtpCM6JXgD42dWjYrSouljmJ8aX4RkygEOti6cZMgyTN41uh35u+RFxsXWEAmncyNh3xNxQRFq22WML4LWpq1581iuUJPo01e4BZNlhPWTSQfOlLLrl9asD4ByhW0yb6XJaDVw3wVvRB/su99uWvv9aKdon/8IidGE=
- 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=
matrix:
include:
- os: linux
node_js: "7"
env: NODE_ENV=development
- os: linux
node_js: "7"
env: NODE_ENV=production
- os: linux
node_js: '7'
env: NODE_ENV=development
- os: linux
node_js: '7'
env: NODE_ENV=production
fast_finish: true

addons:
code_climate:
repo_token: 321ece2c9941bf30bb07f0555343ad772bdbbc6235c866478afc7af46558a8b4

apt:
packages:
- xvfb
before_install:
- curl -o- -L https://yarnpkg.com/install.sh | bash
- export PATH=$HOME/.yarn/bin:$PATH
Expand All @@ -32,29 +31,19 @@ before_install:
- npm --version
- gcc --version
- g++ --version

addons:
apt:
packages:
- xvfb

install:
- export DISPLAY=':99.0'
- Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
- NODE_ENV=development yarn

- export DISPLAY=':99.0'
- Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
- NODE_ENV=development yarn
before_script:
- npm run lint
- sleep 5

script:
- npm run build-dev
- npm run build
- npm test

notifications:
email:
- [email protected]

git:
depth: 10
2 changes: 1 addition & 1 deletion app/components/About/LinkRenderer.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { PropTypes } from 'react';
import { Link } from 'react-router';
import { Link } from 'react-router-dom';

const LinkRenderer = (props) => {
if (props.href.match(/^(https?:)?\/\//)) {
Expand Down
22 changes: 17 additions & 5 deletions app/components/Resume/Courses.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import React from 'react';
import React, { PropTypes } from 'react';

import Course from './Courses/Course';
import courses from '../../data/courses';

const getRows = () => courses.sort((a, b) => {
const getRows = courses => courses.sort((a, b) => {
let ret = 0;
if (a.university > b.university) ret = -1;
else if (a.unversity < b.university) ret = 1;
Expand All @@ -18,16 +17,29 @@ const getRows = () => courses.sort((a, b) => {
/>
));

const Courses = () => (
const Courses = props => (
<div className="courses">
<div className="link-to" id="courses" />
<div className="title">
<h3>Selected Courses</h3>
</div>
<ul className="course-list">
{getRows()}
{getRows(props.data)}
</ul>
</div>
);

Courses.propTypes = {
data: PropTypes.arrayOf(PropTypes.shape({
title: PropTypes.string,
number: PropTypes.string,
link: PropTypes.string,
univerity: PropTypes.string,
})),
};

Courses.defaultProps = {
data: [],
};

export default Courses;
23 changes: 18 additions & 5 deletions app/components/Resume/Education.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,36 @@
import React from 'react';
import React, { PropTypes } from 'react';

import Degree from './Education/Degree';
import degrees from '../../data/degrees';

const getRows = () => degrees.map(degree => (
const getRows = degrees => degrees.map(degree => (
<Degree
data={degree}
key={degree.school}
/>
));

const Education = () => (
const Education = props => (
<div className="education">
<div className="link-to" id="education" />
<div className="title">
<h3>Education</h3>
</div>
{getRows()}
{getRows(props.data)}
</div>
);

Education.propTypes = {
data: PropTypes.arrayOf(PropTypes.shape({
school: PropTypes.string,
degree: PropTypes.string,
link: PropTypes.string,
year: PropTypes.number,
})),
};

Education.defaultProps = {
data: [],
};


export default Education;
24 changes: 19 additions & 5 deletions app/components/Resume/Experience.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,37 @@
import React from 'react';
import React, { PropTypes } from 'react';

import Job from './Experience/Job';
import positions from '../../data/positions';

const getRows = () => positions.map(job => (
const getRows = positions => positions.map(job => (
<Job
data={job}
key={job.company}
/>
));

const Experience = () => (
const Experience = props => (
<div className="experience">
<div className="link-to" id="experience" />
<div className="title">
<h3>Experience</h3>
</div>
{getRows()}
{getRows(props.data)}
</div>
);

Experience.propTypes = {
data: PropTypes.arrayOf(PropTypes.shape({
company: PropTypes.string,
position: PropTypes.string,
link: PropTypes.string,
daterange: PropTypes.string,
points: PropTypes.arrayOf(PropTypes.string),
})),
};

Experience.defaultProps = {
data: [],
};


export default Experience;
2 changes: 1 addition & 1 deletion app/components/Resume/References.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { Link } from 'react-router';
import { Link } from 'react-router-dom';

const References = () => (
<div className="references">
Expand Down
39 changes: 34 additions & 5 deletions app/components/Resume/Skills.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,35 @@
import React, { Component } from 'react';
import React, { Component, PropTypes } from 'react';

import CategoryButton from './Skills/CategoryButton';
import SkillBar from './Skills/SkillBar';

import { skills, categories } from '../../data/skills';

class Skills extends Component {

constructor(props) {
super(props);
this.state = {
buttons: Object.keys(categories).sort().reduce((obj, key) => ({
buttons: props.categories.map(cat => cat.name).reduce((obj, key) => ({
...obj,
[key]: false,
}), { All: true }),
skills: skills.map(skill =>
skills: props.skills.map(skill =>
Object.assign(skill, { category: skill.category.sort() }),
),
};
}

componentWillReceiveProps(nextProps) {
this.setState({
buttons: nextProps.categories.map(cat => cat.name).reduce((obj, key) => ({
...obj,
[key]: false,
}), { All: true }),
skills: nextProps.skills.map(skill =>
Object.assign(skill, { category: skill.category.sort() }),
),
});
}

getRows() {
// search for true active categorys
const actCat = Object.keys(this.state.buttons).reduce((cat, key) => (
Expand All @@ -38,6 +48,7 @@ class Skills extends Component {
}).filter(skill => (actCat === 'All' || skill.category.includes(actCat)))
.map(skill => (
<SkillBar
categories={this.props.categories}
data={skill}
key={skill.title}
/>
Expand Down Expand Up @@ -85,4 +96,22 @@ class Skills extends Component {
}
}

Skills.propTypes = {
skills: PropTypes.arrayOf(PropTypes.shape({
title: PropTypes.string,
compentency: PropTypes.number,
category: PropTypes.arrayOf(PropTypes.string),
})),
categories: PropTypes.arrayOf(PropTypes.shape({
name: PropTypes.string,
color: PropTypes.string,
})),
};

Skills.defaultProps = {
skills: [],
categories: [],
};


export default Skills;
63 changes: 41 additions & 22 deletions app/components/Resume/Skills/SkillBar.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,54 @@
import React, { PropTypes } from 'react';
import React, { Component, PropTypes } from 'react';

import { categories } from '../../../data/skills';
class SkillBar extends Component {

// TODO: Consider averaging colors
const getColor = types => Object.keys(categories)
.filter(key => types.includes(key))
.map(key => categories[key])[0];
constructor(props) {
super(props);
this.state = {
data: props.data,
categories: props.categories,
};
}

const SkillBar = (props) => {
const titleStyle = {
background: getColor(props.data.category),
};
const barStyle = {
background: getColor(props.data.category),
width: `${String(Math.min(100, Math.max((props.data.compentency / 5.0) * 100.0, 0)))}%`,
};
return (
<div className="skillbar clearfix">
<div className="skillbar-title" style={titleStyle}><span>{props.data.title}</span></div>
<div className="skillbar-bar" style={barStyle} />
<div className="skill-bar-percent">{props.data.compentency} / 5</div>
</div>
);
};
// TODO: Consider averaging colors
getColor() {
return this.state.categories
.filter(cat => this.state.data.category.includes(cat.name))
.map(cat => cat.color)[0];
}

render() {
const titleStyle = {
background: this.getColor(),
};
const barStyle = {
...titleStyle,
width: `${String(Math.min(100, Math.max((this.state.data.compentency / 5.0) * 100.0, 0)))}%`,
};
return (
<div className="skillbar clearfix">
<div className="skillbar-title" style={titleStyle}><span>{this.state.data.title}</span></div>
<div className="skillbar-bar" style={barStyle} />
<div className="skill-bar-percent">{this.state.data.compentency} / 5</div>
</div>
);
}
}

SkillBar.propTypes = {
data: PropTypes.shape({
category: PropTypes.arrayOf(PropTypes.string).isRequired,
compentency: PropTypes.number.isRequired,
title: PropTypes.string.isRequired,
}).isRequired,
categories: PropTypes.arrayOf(PropTypes.shape({
name: PropTypes.string,
color: PropTypes.string,
})),
};

SkillBar.defaultProps = {
categories: [],
};

export default SkillBar;
Loading

0 comments on commit 9088a3c

Please sign in to comment.