import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { bindActionCreators } from 'redux'; import { connect } from 'react-redux'; import { find, first } from 'lodash'; import { Table, Button, DropdownButton, MenuItem, Modal } from '@freecodecamp/react-bootstrap'; import { Link, navigate } from 'gatsby'; import { createSelector } from 'reselect'; import { updateLegacyCertificate } from '../../redux/settings'; import { projectMap, legacyProjectMap } from '../../resources/certProjectMap'; import SectionHeader from './SectionHeader'; import SolutionViewer from './SolutionViewer'; import { FullWidthRow, Spacer } from '../helpers'; import { Form } from '../formHelpers'; import { maybeUrlRE } from '../../utils'; import './certification.css'; const mapDispatchToProps = dispatch => bindActionCreators({ updateLegacyCertificate }, dispatch); 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 }) ), createFlashMessage: PropTypes.func.isRequired, is2018DataVisCert: PropTypes.bool, isApisMicroservicesCert: PropTypes.bool, isBackEndCert: PropTypes.bool, isDataVisCert: PropTypes.bool, isFrontEndCert: PropTypes.bool, isFrontEndLibsCert: PropTypes.bool, isFullStackCert: PropTypes.bool, isHonest: PropTypes.bool, isInfosecQaCert: PropTypes.bool, isJsAlgoDataStructCert: PropTypes.bool, isRespWebDesignCert: PropTypes.bool, updateLegacyCertificate: PropTypes.func.isRequired, username: PropTypes.string, verifyCert: PropTypes.func.isRequired }; const certifications = Object.keys(projectMap); const legacyCertifications = Object.keys(legacyProjectMap); const isCertSelector = ({ is2018DataVisCert, isApisMicroservicesCert, isJsAlgoDataStructCert, isBackEndCert, isDataVisCert, isFrontEndCert, isInfosecQaCert, isFrontEndLibsCert, isFullStackCert, isRespWebDesignCert }) => ({ is2018DataVisCert, isApisMicroservicesCert, isJsAlgoDataStructCert, isBackEndCert, isDataVisCert, isFrontEndCert, isInfosecQaCert, isFrontEndLibsCert, isFullStackCert, isRespWebDesignCert }); const isCertMapSelector = createSelector( isCertSelector, ({ is2018DataVisCert, isApisMicroservicesCert, isJsAlgoDataStructCert, isInfosecQaCert, isFrontEndLibsCert, isRespWebDesignCert, isDataVisCert, isFrontEndCert, isBackEndCert }) => ({ 'Responsive Web Design': isRespWebDesignCert, 'JavaScript Algorithms and Data Structures': isJsAlgoDataStructCert, 'Front End Libraries': isFrontEndLibsCert, 'Data Visualization': is2018DataVisCert, "API's and Microservices": isApisMicroservicesCert, 'Information Security And Quality Assurance': isInfosecQaCert, 'Legacy Front End': isFrontEndCert, 'Legacy Data Visualization': isDataVisCert, 'Legacy Back End': isBackEndCert }) ); const initialState = { solutionViewer: { projectTitle: '', files: null, solution: null, isOpen: false } }; class CertificationSettings extends Component { constructor(props) { super(props); this.state = { ...initialState }; this.handleSubmit = this.handleSubmit.bind(this); } createHandleLinkButtonClick = to => e => { e.preventDefault(); return navigate(to); }; handleSolutionModalHide = () => this.setState({ ...initialState }); getUserIsCertMap = () => isCertMapSelector(this.props); 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 ( ); } if (githubLink) { return (
Front End Back End
); } if (maybeUrlRE.test(solution)) { return ( ); } return ( ); }; renderCertifications = certName => (

{certName}

{this.renderProjectsFor(certName, this.getUserIsCertMap()[certName])}
Project Name Solution
); renderProjectsFor = (certName, isCert) => { const { username, isHonest, createFlashMessage, verifyCert } = this.props; const { superBlock } = first(projectMap[certName]); const certLocation = `/certification/${username}/${superBlock}`; const createClickHandler = superBlock => e => { e.preventDefault(); if (isCert) { return navigate(certLocation); } return isHonest ? verifyCert(superBlock) : createFlashMessage({ type: 'info', message: 'To claim a certification, you must first accept our academic ' + 'honesty policy' }); }; return projectMap[certName] .map(({ link, title, id }) => ( {title} {this.getProjectSolution(id, title)} )) .concat([ ]); }; // legacy projects rendering handleSubmit(values) { const { updateLegacyCertificate } = this.props; updateLegacyCertificate(values); } renderLegacyCertifications = certName => { const { username, isHonest, createFlashMessage, verifyCert } = this.props; const { superBlock } = first(legacyProjectMap[certName]); const certLocation = `/certification/${username}/${superBlock}`; const challengeTitles = legacyProjectMap[certName].map(item => item.title); const { completedChallenges } = this.props; const isCertClaimed = this.getUserIsCertMap()[certName]; const initialObject = {}; let filledforms = 0; legacyProjectMap[certName].forEach(element => { let completedProject = find(completedChallenges, function(challenge) { return challenge['id'] === element['id']; }); if (!completedProject) { initialObject[element.title] = ''; } else { initialObject[element.title] = completedProject.solution; filledforms++; } }); const options = challengeTitles.reduce( (options, current) => { options.types[current] = 'url'; return options; }, { types: {} } ); const fullForm = filledforms === challengeTitles.length; const createClickHandler = superBlock => e => { e.preventDefault(); if (isCertClaimed) { return navigate(certLocation); } return isHonest ? verifyCert(superBlock) : createFlashMessage({ type: 'info', message: 'To claim a certification, you must first accept our academic ' + 'honesty policy' }); }; const buttonStyle = { marginBottom: '1.45rem' }; return (

{certName}

{isCertClaimed ? (
) : null} ); }; render() { const { solutionViewer: { files, solution, isOpen, projectTitle } } = this.state; return (
Certifications {certifications.map(this.renderCertifications)} Legacy Certifications {legacyCertifications.map(this.renderLegacyCertifications)} {isOpen ? ( Solution for {projectTitle} ) : null}
); } } CertificationSettings.displayName = 'CertificationSettings'; CertificationSettings.propTypes = propTypes; export default connect( null, mapDispatchToProps )(CertificationSettings);