import { Table, Button, DropdownButton, MenuItem } from '@freecodecamp/react-bootstrap'; import { Link, navigate } from 'gatsby'; import { find, first } from 'lodash-es'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; import { withTranslation } from 'react-i18next'; import { createSelector } from 'reselect'; import { projectMap, legacyProjectMap } from '../../resources/cert-and-project-map'; import { maybeUrlRE } from '../../utils'; import ProjectModal from '../SolutionViewer/ProjectModal'; import { FullWidthRow, Spacer } from '../helpers'; import SectionHeader from './section-header'; import './certification.css'; const propTypes = { completedChallenges: PropTypes.arrayOf( PropTypes.shape({ id: PropTypes.string, solution: PropTypes.string, githubLink: PropTypes.string, challengeType: PropTypes.number, completedDate: PropTypes.number, challengeFiles: PropTypes.array }) ), createFlashMessage: PropTypes.func.isRequired, is2018DataVisCert: PropTypes.bool, isApisMicroservicesCert: PropTypes.bool, isBackEndCert: PropTypes.bool, isDataAnalysisPyCertV7: PropTypes.bool, isDataVisCert: PropTypes.bool, isFrontEndCert: PropTypes.bool, isFrontEndLibsCert: PropTypes.bool, isFullStackCert: PropTypes.bool, isHonest: PropTypes.bool, isInfosecCertV7: PropTypes.bool, isInfosecQaCert: PropTypes.bool, isJsAlgoDataStructCert: PropTypes.bool, isMachineLearningPyCertV7: PropTypes.bool, isQaCertV7: PropTypes.bool, isRespWebDesignCert: PropTypes.bool, isSciCompPyCertV7: PropTypes.bool, t: 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, isQaCertV7, isInfosecCertV7, isFrontEndLibsCert, isFullStackCert, isRespWebDesignCert, isSciCompPyCertV7, isDataAnalysisPyCertV7, isMachineLearningPyCertV7 }) => ({ is2018DataVisCert, isApisMicroservicesCert, isJsAlgoDataStructCert, isBackEndCert, isDataVisCert, isFrontEndCert, isInfosecQaCert, isQaCertV7, isInfosecCertV7, isFrontEndLibsCert, isFullStackCert, isRespWebDesignCert, isSciCompPyCertV7, isDataAnalysisPyCertV7, isMachineLearningPyCertV7 }); const isCertMapSelector = createSelector( isCertSelector, ({ is2018DataVisCert, isApisMicroservicesCert, isJsAlgoDataStructCert, isInfosecQaCert, isQaCertV7, isInfosecCertV7, isFrontEndLibsCert, isRespWebDesignCert, isDataVisCert, isFrontEndCert, isBackEndCert, isSciCompPyCertV7, isDataAnalysisPyCertV7, isMachineLearningPyCertV7 }) => ({ 'Responsive Web Design': isRespWebDesignCert, 'JavaScript Algorithms and Data Structures': isJsAlgoDataStructCert, 'Front End Libraries': isFrontEndLibsCert, 'Data Visualization': is2018DataVisCert, 'APIs and Microservices': isApisMicroservicesCert, 'Quality Assurance': isQaCertV7, 'Information Security': isInfosecCertV7, 'Scientific Computing with Python': isSciCompPyCertV7, 'Data Analysis with Python': isDataAnalysisPyCertV7, 'Machine Learning with Python': isMachineLearningPyCertV7, 'Legacy Front End': isFrontEndCert, 'Legacy Data Visualization': isDataVisCert, 'Legacy Back End': isBackEndCert, 'Legacy Information Security and Quality Assurance': isInfosecQaCert }) ); const honestyInfoMessage = { type: 'info', message: 'flash.honest-first' }; const initialState = { solutionViewer: { projectTitle: '', challengeFiles: null, solution: null, isOpen: false } }; export class CertificationSettings extends Component { constructor(props) { super(props); this.state = { ...initialState }; } createHandleLinkButtonClick = to => e => { e.preventDefault(); return navigate(to); }; handleSolutionModalHide = () => this.setState({ ...initialState }); getUserIsCertMap = () => isCertMapSelector(this.props); getProjectSolution = (projectId, projectTitle) => { const { completedChallenges, t } = this.props; const completedProject = find( completedChallenges, ({ id }) => projectId === id ); if (!completedProject) { return null; } const { solution, githubLink, challengeFiles } = completedProject; const onClickHandler = () => this.setState({ solutionViewer: { projectTitle, challengeFiles, solution, isOpen: true } }); if (challengeFiles?.length) { return ( ); } if (githubLink) { return (
{t('buttons.frontend')} {t('buttons.backend')}
); } if (maybeUrlRE.test(solution)) { return ( ); } return ( ); }; renderCertifications = (certName, projectsMap) => { const { t } = this.props; const { certSlug } = first(projectsMap[certName]); return (

{certName}

{this.renderProjectsFor( certName, this.getUserIsCertMap()[certName], projectsMap )}
{t('settings.labels.project-name')} {t('settings.labels.solution')}
); }; renderProjectsFor = (certName, isCert, projectsMap) => { const { username, isHonest, createFlashMessage, t, verifyCert } = this.props; const { certSlug } = first(projectsMap[certName]); const certLocation = `/certification/${username}/${certSlug}`; const createClickHandler = certSlug => e => { e.preventDefault(); if (isCert) { return navigate(certLocation); } return isHonest ? verifyCert(certSlug) : createFlashMessage(honestyInfoMessage); }; return projectsMap[certName] .map(({ link, title, id }) => ( {title} {this.getProjectSolution(id, title)} )) .concat([ ]); }; renderLegacyFullStack = () => { const { isFullStackCert, username, isHonest, createFlashMessage, verifyCert, is2018DataVisCert, isApisMicroservicesCert, isFrontEndLibsCert, isInfosecQaCert, isJsAlgoDataStructCert, isRespWebDesignCert, t } = this.props; const fullStackClaimable = is2018DataVisCert && isApisMicroservicesCert && isFrontEndLibsCert && isInfosecQaCert && isJsAlgoDataStructCert && isRespWebDesignCert; // Keep the settings page certSlug as full-stack rather than // legacy-full-stack so we don't break existing links const certSlug = 'full-stack'; const certLocation = `/certification/${username}/${certSlug}`; const buttonStyle = { marginBottom: '30px', padding: '6px 12px', fontSize: '18px' }; const createClickHandler = certSlug => e => { e.preventDefault(); if (isFullStackCert) { return navigate(certLocation); } return isHonest ? verifyCert(certSlug) : createFlashMessage(honestyInfoMessage); }; return (

Legacy Full Stack Certification

{t('settings.claim-legacy', { cert: 'Legacy Full Stack Certification' })}

  • Responsive Web Design
  • JavaScript Algorithms and Data Structures
  • Front End Libraries
  • Data Visualization
  • APIs and Microservices
  • Legacy Information Security and Quality Assurance
{fullStackClaimable ? ( ) : ( )}
); }; render() { const { solutionViewer: { challengeFiles, solution, isOpen, projectTitle } } = this.state; const { t } = this.props; return (
{t('settings.headings.certs')} {certifications.map(certName => this.renderCertifications(certName, projectMap) )} {t('settings.headings.legacy-certs')} {this.renderLegacyFullStack()} {legacyCertifications.map(certName => this.renderCertifications(certName, legacyProjectMap) )} {isOpen ? ( ) : null}
); } } CertificationSettings.displayName = 'CertificationSettings'; CertificationSettings.propTypes = propTypes; export default withTranslation()(CertificationSettings);