feat(Certs): Initial Cert Settings
parent
a6f3e6f66c
commit
d698d52794
|
@ -2966,6 +2966,17 @@
|
|||
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
|
||||
"integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk="
|
||||
},
|
||||
"clipboard": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.1.tgz",
|
||||
"integrity": "sha512-7yhQBmtN+uYZmfRjjVjKa0dZdWuabzpSKGtyQZN+9C8xlC788SSJjOHWh7tzurfwTqTD5UDYAhIv5fRJg3sHjQ==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"good-listener": "1.2.2",
|
||||
"select": "1.1.2",
|
||||
"tiny-emitter": "2.0.2"
|
||||
}
|
||||
},
|
||||
"cliui": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
|
||||
|
@ -3780,6 +3791,12 @@
|
|||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
|
||||
},
|
||||
"delegate": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz",
|
||||
"integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==",
|
||||
"optional": true
|
||||
},
|
||||
"delegates": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
||||
|
@ -6670,6 +6687,15 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"good-listener": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz",
|
||||
"integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"delegate": "3.2.0"
|
||||
}
|
||||
},
|
||||
"got": {
|
||||
"version": "6.7.1",
|
||||
"resolved": "http://registry.npmjs.org/got/-/got-6.7.1.tgz",
|
||||
|
@ -10263,6 +10289,14 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"prismjs": {
|
||||
"version": "1.15.0",
|
||||
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.15.0.tgz",
|
||||
"integrity": "sha512-Lf2JrFYx8FanHrjoV5oL8YHCclLQgbJcVZR+gikGGMqz6ub5QVWDTM6YIwm3BuPxM/LOV+rKns3LssXNLIf+DA==",
|
||||
"requires": {
|
||||
"clipboard": "2.0.1"
|
||||
}
|
||||
},
|
||||
"private": {
|
||||
"version": "0.1.8",
|
||||
"resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
|
||||
|
@ -11455,6 +11489,12 @@
|
|||
"invariant": "2.2.4"
|
||||
}
|
||||
},
|
||||
"select": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
|
||||
"integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=",
|
||||
"optional": true
|
||||
},
|
||||
"select-hose": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
|
||||
|
@ -12473,6 +12513,12 @@
|
|||
"resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
|
||||
"integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q="
|
||||
},
|
||||
"tiny-emitter": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.0.2.tgz",
|
||||
"integrity": "sha512-2NM0auVBGft5tee/OxP4PI3d8WItkDM+fPnaRAVo6xTDI2knbz9eC5ArWGqtGlYqiH3RU5yMpdyTTO7MguC4ow==",
|
||||
"optional": true
|
||||
},
|
||||
"tmp": {
|
||||
"version": "0.0.31",
|
||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz",
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
"gatsby-plugin-sitemap": "^2.0.0-rc.1",
|
||||
"lodash": "^4.17.10",
|
||||
"nanoid": "^1.2.2",
|
||||
"prismjs": "^1.15.0",
|
||||
"query-string": "^6.1.0",
|
||||
"react": "^16.4.2",
|
||||
"react-dom": "^16.4.2",
|
||||
|
|
|
@ -19,82 +19,70 @@ import Email from '../components/settings/Email';
|
|||
import Internet from '../components/settings/Internet';
|
||||
import Portfolio from '../components/settings/Portfolio';
|
||||
import Honesty from '../components/settings/Honesty';
|
||||
import Certification from '../components/settings/Certification';
|
||||
|
||||
const propTypes = {
|
||||
about: PropTypes.string,
|
||||
email: PropTypes.string,
|
||||
githubProfile: PropTypes.string,
|
||||
isEmailVerified: PropTypes.bool,
|
||||
isHonest: PropTypes.bool,
|
||||
linkedin: PropTypes.string,
|
||||
location: PropTypes.string,
|
||||
name: PropTypes.string,
|
||||
picture: PropTypes.string,
|
||||
points: PropTypes.number,
|
||||
portfolio: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
title: PropTypes.string,
|
||||
url: PropTypes.string,
|
||||
image: PropTypes.string,
|
||||
description: PropTypes.string
|
||||
})
|
||||
),
|
||||
sendQuincyEmail: PropTypes.bool,
|
||||
showLoading: PropTypes.bool,
|
||||
submitNewAbout: PropTypes.func.isRequired,
|
||||
theme: PropTypes.string,
|
||||
toggleNightMode: PropTypes.func.isRequired,
|
||||
twitter: PropTypes.string,
|
||||
updateInternetSettings: PropTypes.func.isRequired,
|
||||
updateIsHonest: PropTypes.func.isRequired,
|
||||
updatePortfolio: PropTypes.func.isRequired,
|
||||
updateQuincyEmail: PropTypes.func.isRequired,
|
||||
username: PropTypes.string,
|
||||
website: PropTypes.string
|
||||
user: PropTypes.shape({
|
||||
about: PropTypes.string,
|
||||
completedChallenges: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
id: PropTypes.string,
|
||||
solution: PropTypes.string,
|
||||
githubLink: PropTypes.string,
|
||||
challengeType: PropTypes.number,
|
||||
completedDate: PropTypes.number,
|
||||
files: PropTypes.array
|
||||
})
|
||||
),
|
||||
email: PropTypes.string,
|
||||
githubProfile: PropTypes.string,
|
||||
is2018DataVisCert: PropTypes.bool,
|
||||
isApisMicroservicesCert: PropTypes.bool,
|
||||
isBackEndCert: PropTypes.bool,
|
||||
isDataVisCert: PropTypes.bool,
|
||||
isEmailVerified: PropTypes.bool,
|
||||
isFrontEndCert: PropTypes.bool,
|
||||
isFrontEndLibsCert: PropTypes.bool,
|
||||
isFullStackCert: PropTypes.bool,
|
||||
isHonest: PropTypes.bool,
|
||||
isInfosecQaCert: PropTypes.bool,
|
||||
isJsAlgoDataStructCert: PropTypes.bool,
|
||||
isRespWebDesignCert: PropTypes.bool,
|
||||
linkedin: PropTypes.string,
|
||||
location: PropTypes.string,
|
||||
name: PropTypes.string,
|
||||
picture: PropTypes.string,
|
||||
points: PropTypes.number,
|
||||
portfolio: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
title: PropTypes.string,
|
||||
url: PropTypes.string,
|
||||
image: PropTypes.string,
|
||||
description: PropTypes.string
|
||||
})
|
||||
),
|
||||
sendQuincyEmail: PropTypes.bool,
|
||||
theme: PropTypes.string,
|
||||
twitter: PropTypes.string,
|
||||
username: PropTypes.string,
|
||||
website: PropTypes.string
|
||||
})
|
||||
};
|
||||
|
||||
const mapStateToProps = createSelector(
|
||||
signInLoadingSelector,
|
||||
userSelector,
|
||||
(
|
||||
(showLoading, user) => ({
|
||||
showLoading,
|
||||
{
|
||||
username = '',
|
||||
about,
|
||||
email,
|
||||
sendQuincyEmail,
|
||||
isEmailVerified,
|
||||
isHonest,
|
||||
picture,
|
||||
points,
|
||||
name,
|
||||
location,
|
||||
theme,
|
||||
githubProfile,
|
||||
linkedin,
|
||||
twitter,
|
||||
website,
|
||||
portfolio
|
||||
}
|
||||
) => ({
|
||||
email,
|
||||
sendQuincyEmail,
|
||||
isEmailVerified,
|
||||
isHonest,
|
||||
showLoading,
|
||||
username,
|
||||
about,
|
||||
picture,
|
||||
points,
|
||||
name,
|
||||
theme,
|
||||
location,
|
||||
githubProfile,
|
||||
linkedin,
|
||||
twitter,
|
||||
website,
|
||||
portfolio
|
||||
user
|
||||
})
|
||||
);
|
||||
|
||||
|
@ -113,27 +101,39 @@ const mapDispatchToProps = dispatch =>
|
|||
|
||||
function ShowSettings(props) {
|
||||
const {
|
||||
email,
|
||||
isEmailVerified,
|
||||
isHonest,
|
||||
sendQuincyEmail,
|
||||
showLoading,
|
||||
username,
|
||||
about,
|
||||
picture,
|
||||
points,
|
||||
theme,
|
||||
location,
|
||||
name,
|
||||
submitNewAbout,
|
||||
toggleNightMode,
|
||||
user: {
|
||||
completedChallenges,
|
||||
email,
|
||||
is2018DataVisCert,
|
||||
isApisMicroservicesCert,
|
||||
isJsAlgoDataStructCert,
|
||||
isBackEndCert,
|
||||
isDataVisCert,
|
||||
isFrontEndCert,
|
||||
isInfosecQaCert,
|
||||
isFrontEndLibsCert,
|
||||
isFullStackCert,
|
||||
isEmailVerified,
|
||||
isHonest,
|
||||
sendQuincyEmail,
|
||||
username,
|
||||
about,
|
||||
picture,
|
||||
points,
|
||||
theme,
|
||||
location,
|
||||
name,
|
||||
githubProfile,
|
||||
linkedin,
|
||||
twitter,
|
||||
website,
|
||||
portfolio
|
||||
},
|
||||
showLoading,
|
||||
updateQuincyEmail,
|
||||
githubProfile,
|
||||
linkedin,
|
||||
twitter,
|
||||
website,
|
||||
updateInternetSettings,
|
||||
portfolio,
|
||||
updatePortfolio,
|
||||
updateIsHonest
|
||||
} = props;
|
||||
|
@ -208,11 +208,22 @@ function ShowSettings(props) {
|
|||
<Spacer />
|
||||
<Portfolio portfolio={portfolio} updatePortfolio={updatePortfolio} />
|
||||
<Spacer />
|
||||
<Honesty isHonest={isHonest} updateIsHonest={updateIsHonest}/>
|
||||
<Honesty isHonest={isHonest} updateIsHonest={updateIsHonest} />
|
||||
<Spacer />
|
||||
{/* <CertificationSettings />
|
||||
<Certification
|
||||
completedChallenges={completedChallenges}
|
||||
is2018DataVisCert={is2018DataVisCert}
|
||||
isApisMicroservicesCert={isApisMicroservicesCert}
|
||||
isBackEndCert={isBackEndCert}
|
||||
isDataVisCert={isDataVisCert}
|
||||
isFrontEndCert={isFrontEndCert}
|
||||
isFrontEndLibsCert={isFrontEndLibsCert}
|
||||
isFullStackCert={isFullStackCert}
|
||||
isInfosecQaCert={isInfosecQaCert}
|
||||
isJsAlgoDataStructCert={isJsAlgoDataStructCert}
|
||||
/>
|
||||
<Spacer />
|
||||
<DangerZone /> */}
|
||||
{/* <DangerZone /> */}
|
||||
</Grid>
|
||||
</Layout>
|
||||
);
|
||||
|
|
|
@ -0,0 +1,196 @@
|
|||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { find } from 'lodash';
|
||||
import {
|
||||
Table,
|
||||
Button,
|
||||
DropdownButton,
|
||||
MenuItem,
|
||||
Modal
|
||||
} from '@freecodecamp/react-bootstrap';
|
||||
import { Link, navigate } from 'gatsby';
|
||||
|
||||
import { projectMap } from '../../resources/certProjectMap';
|
||||
|
||||
import SectionHeader from './SectionHeader';
|
||||
import SolutionViewer from './SolutionViewer';
|
||||
import { FullWidthRow } from '../helpers';
|
||||
import { maybeUrlRE } from '../../utils';
|
||||
|
||||
const propTypes = {
|
||||
completedChallenges: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
id: PropTypes.string,
|
||||
solution: PropTypes.string,
|
||||
githubLink: PropTypes.string,
|
||||
challengeType: PropTypes.number,
|
||||
completedDate: PropTypes.number,
|
||||
files: PropTypes.array
|
||||
})
|
||||
)
|
||||
};
|
||||
|
||||
const certifications = Object.keys(projectMap);
|
||||
const initialState = {
|
||||
solutionViewer: {
|
||||
projectTitle: '',
|
||||
files: null,
|
||||
solution: null,
|
||||
isOpen: false
|
||||
}
|
||||
};
|
||||
|
||||
class CertificationSettings extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = { ...initialState };
|
||||
}
|
||||
|
||||
createHandleLinkButtonClick = to => e => {
|
||||
e.preventDefault();
|
||||
return navigate(to);
|
||||
};
|
||||
handleSolutionModalHide = () => this.setState({ ...initialState });
|
||||
|
||||
getProjectSolution = (projectId, projectTitle) => {
|
||||
const { completedChallenges } = this.props;
|
||||
const completedProject = find(
|
||||
completedChallenges,
|
||||
({ id }) => projectId === id
|
||||
);
|
||||
if (!completedProject) {
|
||||
return null;
|
||||
}
|
||||
const { solution, githubLink, files } = completedProject;
|
||||
const onClickHandler = () =>
|
||||
this.setState({
|
||||
solutionViewer: {
|
||||
projectTitle,
|
||||
files,
|
||||
solution,
|
||||
isOpen: true
|
||||
}
|
||||
});
|
||||
if (files && files.length) {
|
||||
return (
|
||||
<Button
|
||||
bsStyle='primary'
|
||||
className='btn-invert'
|
||||
onClick={onClickHandler}
|
||||
>
|
||||
Show Code
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
if (githubLink) {
|
||||
return (
|
||||
<DropdownButton
|
||||
bsStyle='primary'
|
||||
className='btn-invert'
|
||||
id={`dropdown-for-${projectId}`}
|
||||
title='Show Solutions'
|
||||
>
|
||||
<MenuItem
|
||||
bsStyle='primary'
|
||||
href={solution}
|
||||
rel='noopener noreferrer'
|
||||
target='_blank'
|
||||
>
|
||||
Front End
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
bsStyle='primary'
|
||||
href={githubLink}
|
||||
rel='noopener noreferrer'
|
||||
target='_blank'
|
||||
>
|
||||
Back End
|
||||
</MenuItem>
|
||||
</DropdownButton>
|
||||
);
|
||||
}
|
||||
if (maybeUrlRE.test(solution)) {
|
||||
return (
|
||||
<Button
|
||||
bsStyle='primary'
|
||||
className='btn-invert'
|
||||
href={solution}
|
||||
rel='noopener noreferrer'
|
||||
target='_blank'
|
||||
>
|
||||
Show Solution
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Button bsStyle='primary' className='btn-invert' onClick={onClickHandler}>
|
||||
Show Code
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
renderCertifications = certName => (
|
||||
<FullWidthRow key={certName}>
|
||||
<h3>{certName}</h3>
|
||||
<Table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Project Name</th>
|
||||
<th>Solution</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>{this.renderProjectsFor(certName)}</tbody>
|
||||
</Table>
|
||||
</FullWidthRow>
|
||||
);
|
||||
|
||||
renderProjectsFor = certName =>
|
||||
projectMap[certName].map(({ link, title, id }) => (
|
||||
<tr className='project-row' key={id}>
|
||||
<td className='project-title col-sm-8'>
|
||||
<Link to={link}>{title}</Link>
|
||||
</td>
|
||||
<td className='project-solution col-sm-4'>
|
||||
{this.getProjectSolution(id, title)}
|
||||
</td>
|
||||
</tr>
|
||||
));
|
||||
|
||||
render() {
|
||||
const {
|
||||
solutionViewer: { files, solution, isOpen, projectTitle }
|
||||
} = this.state;
|
||||
return (
|
||||
<section id='certifcation-settings'>
|
||||
<SectionHeader>Certifications</SectionHeader>
|
||||
{certifications.map(this.renderCertifications)}
|
||||
{isOpen ? (
|
||||
<Modal
|
||||
aria-labelledby='solution-viewer-modal-title'
|
||||
bsSize='large'
|
||||
onHide={this.handleSolutionModalHide}
|
||||
show={isOpen}
|
||||
>
|
||||
<Modal.Header className='this-one?' closeButton={true}>
|
||||
<Modal.Title id='solution-viewer-modal-title'>
|
||||
Solution for {projectTitle}
|
||||
</Modal.Title>
|
||||
</Modal.Header>
|
||||
<Modal.Body>
|
||||
<SolutionViewer files={files} solution={solution} />
|
||||
</Modal.Body>
|
||||
<Modal.Footer>
|
||||
<Button onClick={this.handleSolutionModalHide}>Close</Button>
|
||||
</Modal.Footer>
|
||||
</Modal>
|
||||
) : null}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
CertificationSettings.displayName = 'CertificationSettings';
|
||||
CertificationSettings.propTypes = propTypes;
|
||||
|
||||
export default CertificationSettings;
|
|
@ -0,0 +1,79 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Panel } from '@freecodecamp/react-bootstrap';
|
||||
import Prism from 'prismjs';
|
||||
import Helmet from 'react-helmet';
|
||||
|
||||
import './solution-viewer.css';
|
||||
|
||||
const prismLang = {
|
||||
css: 'css',
|
||||
js: 'javascript',
|
||||
jsx: 'javascript',
|
||||
html: 'markup'
|
||||
};
|
||||
|
||||
function SolutionViewer({
|
||||
files,
|
||||
solution = '// The solution is not available for this project'
|
||||
}) {
|
||||
const solutions =
|
||||
files && Array.isArray(files) && files.length ? (
|
||||
files.map(file => (
|
||||
<Panel bsStyle='primary' className='solution-viewer' key={file.ext}>
|
||||
<Panel.Heading>{file.ext.toUpperCase()}</Panel.Heading>
|
||||
<Panel.Body>
|
||||
<pre>
|
||||
<code
|
||||
className={`language-${prismLang[file.ext]}`}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: Prism.highlight(
|
||||
file.contents.trim(),
|
||||
Prism.languages[prismLang[file.ext]]
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</pre>
|
||||
</Panel.Body>
|
||||
</Panel>
|
||||
))
|
||||
) : (
|
||||
<Panel
|
||||
bsStyle='primary'
|
||||
className='solution-viewer'
|
||||
key={solution.slice(0, 10)}
|
||||
>
|
||||
<Panel.Heading>JS</Panel.Heading>
|
||||
<Panel.Body>
|
||||
<pre>
|
||||
<code
|
||||
className='language-markup'
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: Prism.highlight(
|
||||
solution.trim(),
|
||||
Prism.languages.js,
|
||||
'javascript'
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</pre>
|
||||
</Panel.Body>
|
||||
</Panel>
|
||||
);
|
||||
return (
|
||||
<div>
|
||||
<Helmet>
|
||||
<link href='/css/prism.css' rel='stylesheet' />
|
||||
</Helmet>
|
||||
{solutions}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
SolutionViewer.displayName = 'SolutionViewer';
|
||||
SolutionViewer.propTypes = {
|
||||
files: PropTypes.arrayOf(PropTypes.objectOf(PropTypes.string)),
|
||||
solution: PropTypes.string
|
||||
};
|
||||
|
||||
export default SolutionViewer;
|
|
@ -0,0 +1,13 @@
|
|||
#certifcation-settings .project-title {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#certifcation-settings .project-solution {
|
||||
display: flex;
|
||||
|
||||
}
|
||||
|
||||
#certifcation-settings .project-row {
|
||||
display: flex;
|
||||
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
.solution-viewer, .solution-viewer pre {
|
||||
margin-bottom: 0px;
|
||||
}
|
|
@ -0,0 +1,177 @@
|
|||
const responsiveWebBase =
|
||||
'/learn/responsive-web-design/responsive-web-design-projects';
|
||||
const jsAlgoBase =
|
||||
'/learn/javascript-algorithms-and-data-structures/' +
|
||||
'javascript-algorithms-and-data-structures-projects';
|
||||
const feLibsBase = '/learn/front-end-libraries/front-end-libraries-projects';
|
||||
const dataVisBase = '/learn/data-visualization/data-visualization-projects';
|
||||
const apiMicroBase =
|
||||
'/learn/apis-and-microservices/apis-and-microservices-projects';
|
||||
const infoSecBase =
|
||||
'/learn/information-security-and-quality-assurance/' +
|
||||
'information-security-and-quality-assurance-projects';
|
||||
|
||||
export const projectMap = {
|
||||
'Responsive Web Design': [
|
||||
{
|
||||
id: 'bd7158d8c442eddfaeb5bd18',
|
||||
title: 'Build a Tribute Page',
|
||||
link: `${responsiveWebBase}/build-a-tribute-page`
|
||||
},
|
||||
{
|
||||
id: '587d78af367417b2b2512b03',
|
||||
title: 'Build a Survey Form',
|
||||
link: `${responsiveWebBase}/build-a-survey-form`
|
||||
},
|
||||
{
|
||||
id: '587d78af367417b2b2512b04',
|
||||
title: 'Build a Product Landing Page',
|
||||
link: `${responsiveWebBase}/build-a-product-landing-page`
|
||||
},
|
||||
{
|
||||
id: '587d78b0367417b2b2512b05',
|
||||
title: 'Build a Technical Documentation Page',
|
||||
link: `${responsiveWebBase}/build-a-technical-documentation-page`
|
||||
},
|
||||
{
|
||||
id: 'bd7158d8c242eddfaeb5bd13',
|
||||
title: 'Build a Personal Portfolio Webpage',
|
||||
link: `${responsiveWebBase}/build-a-personal-portfolio-webpage`
|
||||
}
|
||||
],
|
||||
'JavaScript Algorithms and Data Structures': [
|
||||
{
|
||||
id: 'aaa48de84e1ecc7c742e1124',
|
||||
title: 'Palindrome Checker',
|
||||
link: `${jsAlgoBase}/palindrome-checker`
|
||||
},
|
||||
{
|
||||
id: 'a7f4d8f2483413a6ce226cac',
|
||||
title: 'Roman Numeral Converter',
|
||||
link: `${jsAlgoBase}/roman-numeral-converter`
|
||||
},
|
||||
{
|
||||
id: '56533eb9ac21ba0edf2244e2',
|
||||
title: 'Caesars Cipher',
|
||||
link: `${jsAlgoBase}/caesars-cipher`
|
||||
},
|
||||
{
|
||||
id: 'aff0395860f5d3034dc0bfc9',
|
||||
title: 'Telephone Number Validator',
|
||||
link: `${jsAlgoBase}/telephone-number-validator`
|
||||
},
|
||||
{
|
||||
id: 'aa2e6f85cab2ab736c9a9b24',
|
||||
title: 'Cash Register',
|
||||
link: `${jsAlgoBase}/cash-register`
|
||||
}
|
||||
],
|
||||
'Front End Libraries': [
|
||||
{
|
||||
id: 'bd7158d8c442eddfaeb5bd13',
|
||||
title: 'Build a Random Quote Machine',
|
||||
link: `${feLibsBase}/build-a-random-quote-machine`
|
||||
},
|
||||
{
|
||||
id: 'bd7157d8c242eddfaeb5bd13',
|
||||
title: 'Build a Markdown Previewer',
|
||||
link: `${feLibsBase}/build-a-markdown-previewer`
|
||||
},
|
||||
{
|
||||
id: '587d7dbc367417b2b2512bae',
|
||||
title: 'Build a Drum Machine',
|
||||
link: `${feLibsBase}/build-a-drum-machine`
|
||||
},
|
||||
{
|
||||
id: 'bd7158d8c442eddfaeb5bd17',
|
||||
title: 'Build a JavaScript Calculator',
|
||||
link: `${feLibsBase}/build-a-javascript-calculator`
|
||||
},
|
||||
{
|
||||
id: 'bd7158d8c442eddfaeb5bd0f',
|
||||
title: 'Build a Pomodoro Clock',
|
||||
link: `${feLibsBase}/build-a-pomodoro-clock`
|
||||
}
|
||||
],
|
||||
'Data Visualization': [
|
||||
{
|
||||
id: 'bd7168d8c242eddfaeb5bd13',
|
||||
title: 'Visualize Data with a Bar Chart',
|
||||
link: `${dataVisBase}/visualize-data-with-a-bar-chart`
|
||||
},
|
||||
{
|
||||
id: 'bd7178d8c242eddfaeb5bd13',
|
||||
title: 'Visualize Data with a Scatterplot Graph',
|
||||
link: `${dataVisBase}/visualize-data-with-a-scatterplot-graph`
|
||||
},
|
||||
{
|
||||
id: 'bd7188d8c242eddfaeb5bd13',
|
||||
title: 'Visualize Data with a Heat Map',
|
||||
link: `${dataVisBase}/visualize-data-with-a-heat-map`
|
||||
},
|
||||
{
|
||||
id: '587d7fa6367417b2b2512bbf',
|
||||
title: 'Visualize Data with a Choropleth Map',
|
||||
link: `${dataVisBase}/visualize-data-with-a-choropleth-map`
|
||||
},
|
||||
{
|
||||
id: '587d7fa6367417b2b2512bc0',
|
||||
title: 'Visualize Data with a Treemap Diagram',
|
||||
link: `${dataVisBase}/visualize-data-with-a-treemap-diagram`
|
||||
}
|
||||
],
|
||||
"API's and Microservices": [
|
||||
{
|
||||
id: 'bd7158d8c443edefaeb5bdef',
|
||||
title: 'Timestamp Microservice',
|
||||
link: `${apiMicroBase}/timestamp-microservice`
|
||||
},
|
||||
{
|
||||
id: 'bd7158d8c443edefaeb5bdff',
|
||||
title: 'Request Header Parser Microservice',
|
||||
link: `${apiMicroBase}/request-header-parser-microservice`
|
||||
},
|
||||
{
|
||||
id: 'bd7158d8c443edefaeb5bd0e',
|
||||
title: 'URL Shortener Microservice',
|
||||
link: `${apiMicroBase}/url-shortener-microservice`
|
||||
},
|
||||
{
|
||||
id: '5a8b073d06fa14fcfde687aa',
|
||||
title: 'Exercise Tracker',
|
||||
link: `${apiMicroBase}/exercise-tracker`
|
||||
},
|
||||
{
|
||||
id: 'bd7158d8c443edefaeb5bd0f',
|
||||
title: 'File Metadata Microservice',
|
||||
link: `${apiMicroBase}/file-metadata-microservice`
|
||||
}
|
||||
],
|
||||
'Information Security And Quality Assurance': [
|
||||
{
|
||||
id: '587d8249367417b2b2512c41',
|
||||
title: 'Metric-Imperial Converter',
|
||||
link: `${infoSecBase}/metric-imperial-converter`
|
||||
},
|
||||
{
|
||||
id: '587d8249367417b2b2512c42',
|
||||
title: 'Issue Tracker',
|
||||
link: `${infoSecBase}/issue-tracker`
|
||||
},
|
||||
{
|
||||
id: '587d824a367417b2b2512c43',
|
||||
title: 'Personal Library',
|
||||
link: `${infoSecBase}/personal-library`
|
||||
},
|
||||
{
|
||||
id: '587d824a367417b2b2512c44',
|
||||
title: 'Stock Price Checker',
|
||||
link: `${infoSecBase}/stock-price-checker`
|
||||
},
|
||||
{
|
||||
id: '587d824a367417b2b2512c45',
|
||||
title: 'Anonymous Message Board',
|
||||
link: `${infoSecBase}/anonymous-message-board`
|
||||
}
|
||||
]
|
||||
};
|
|
@ -0,0 +1,138 @@
|
|||
/**
|
||||
* prism.js default theme for JavaScript, CSS and HTML
|
||||
* Based on dabblet (http://dabblet.com)
|
||||
* @author Lea Verou
|
||||
*/
|
||||
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
color: black;
|
||||
background: none;
|
||||
text-shadow: 0 1px white;
|
||||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-break: normal;
|
||||
word-wrap: normal;
|
||||
line-height: 1.5;
|
||||
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
|
||||
code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
|
||||
pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
|
||||
code[class*="language-"]::selection, code[class*="language-"] ::selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
|
||||
@media print {
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
pre[class*="language-"] {
|
||||
padding: 1em;
|
||||
margin: .5em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
:not(pre) > code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
background: #f5f2f0;
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
:not(pre) > code[class*="language-"] {
|
||||
padding: .1em;
|
||||
border-radius: .3em;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: slategray;
|
||||
}
|
||||
|
||||
.token.punctuation {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.namespace {
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.token.property,
|
||||
.token.tag,
|
||||
.token.boolean,
|
||||
.token.number,
|
||||
.token.constant,
|
||||
.token.symbol,
|
||||
.token.deleted {
|
||||
color: #905;
|
||||
}
|
||||
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin,
|
||||
.token.inserted {
|
||||
color: #690;
|
||||
}
|
||||
|
||||
.token.operator,
|
||||
.token.entity,
|
||||
.token.url,
|
||||
.language-css .token.string,
|
||||
.style .token.string {
|
||||
color: #9a6e3a;
|
||||
background: hsla(0, 0%, 100%, .5);
|
||||
}
|
||||
|
||||
.token.atrule,
|
||||
.token.attr-value,
|
||||
.token.keyword {
|
||||
color: #07a;
|
||||
}
|
||||
|
||||
.token.function,
|
||||
.token.class-name {
|
||||
color: #DD4A68;
|
||||
}
|
||||
|
||||
.token.regex,
|
||||
.token.important,
|
||||
.token.variable {
|
||||
color: #e90;
|
||||
}
|
||||
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
Loading…
Reference in New Issue