refactor: use cert-slugs where possible (#57505)

This commit is contained in:
Oliver Eyton-Williams
2024-12-13 22:15:41 +01:00
committed by GitHub
parent cf18718fcc
commit 1690afeb95
10 changed files with 165 additions and 270 deletions
@@ -1,34 +0,0 @@
import { uniq } from 'lodash';
import {
currentCertifications,
upcomingCertifications,
legacyCertifications
} from '../../shared/config/certification-settings';
import {
currentCertTitles,
upcomingCertTitles,
legacyCertTitles
} from './cert-and-project-map';
describe('cert-and-project-map', () => {
describe('currentCertTitles', () => {
it('should correspond to the currentCertifications config', () => {
expect(currentCertTitles).toHaveLength(uniq(currentCertTitles).length);
expect(currentCertTitles).toHaveLength(currentCertifications.length);
});
});
describe('upcomingCertTitles', () => {
it('should correspond to the upcomingCertifications config', () => {
expect(upcomingCertTitles).toHaveLength(uniq(upcomingCertTitles).length);
expect(upcomingCertTitles).toHaveLength(upcomingCertifications.length);
});
});
describe('legacyCertTitles', () => {
it('should correspond to the legacyCertifications config', () => {
expect(legacyCertTitles).toHaveLength(uniq(legacyCertTitles).length);
expect(legacyCertTitles).toHaveLength(legacyCertifications.length);
});
});
});
+3 -13
View File
@@ -881,29 +881,19 @@ const liveCerts = showUpcomingChanges
: [...currentCerts, ...legacyCerts, fullstackCert];
type CertsToProjects = Record<
(typeof allStandardCerts)[number]['title'],
(typeof allStandardCerts)[number]['certSlug'],
(typeof allStandardCerts)[number]['projects']
>;
const certsToProjects = allStandardCerts.reduce((acc, curr) => {
return {
...acc,
[curr.title]: curr.projects
[curr.certSlug]: curr.projects
};
}, {} as CertsToProjects);
const currentCertTitles = currentCerts.map(({ title }) => title);
const legacyCertTitles = legacyCerts.map(({ title }) => title);
const upcomingCertTitles = upcomingCerts.map(({ title }) => title);
export type CertTitle =
| (typeof liveCerts)[number]['title']
| 'Legacy Full Stack';
export {
currentCertTitles,
legacyCertTitles,
upcomingCertTitles,
liveCerts,
certsToProjects
};
export { liveCerts, certsToProjects };
+44 -44
View File
@@ -1047,50 +1047,50 @@
}
},
"title": {
"Responsive Web Design": "Responsive Web Design",
"responsive-web-design": "Responsive Web Design Certification",
"JavaScript Algorithms and Data Structures": "Legacy JavaScript Algorithms and Data Structures",
"javascript-algorithms-and-data-structures": "Legacy JavaScript Algorithms and Data Structures Certification",
"javascript-algorithms-and-data-structures-v8": "JavaScript Algorithms and Data Structures (Beta) Certification",
"Front End Development Libraries": "Front End Development Libraries",
"front-end-development-libraries": "Front End Development Libraries Certification",
"Data Visualization": "Data Visualization",
"data-visualization": "Data Visualization Certification",
"Relational Database": "Relational Database",
"relational-database-v8": "Relational Database Certification",
"Back End Development and APIs": "Back End Development and APIs",
"back-end-development-and-apis": "Back End Development and APIs Certification",
"Quality Assurance": "Quality Assurance",
"quality-assurance-v7": "Quality Assurance Certification",
"Scientific Computing with Python": "Scientific Computing with Python",
"scientific-computing-with-python-v7": "Scientific Computing with Python Certification",
"Data Analysis with Python": "Data Analysis with Python",
"data-analysis-with-python-v7": "Data Analysis with Python Certification",
"Information Security": "Information Security",
"information-security-v7": "Information Security Certification",
"Machine Learning with Python": "Machine Learning with Python",
"machine-learning-with-python-v7": "Machine Learning with Python Certification",
"College Algebra with Python": "College Algebra with Python",
"college-algebra-with-python-v8": "College Algebra with Python Certification",
"Foundational C# with Microsoft": "Foundational C# with Microsoft",
"foundational-c-sharp-with-microsoft": "Foundational C# with Microsoft Certification",
"A2 English for Developers": "A2 English for Developers",
"a2-english-for-developers": "A2 English for Developers Certification",
"B1 English for Developers": "B1 English for Developers",
"b1-english-for-developers": "B1 English for Developers Certification",
"Full Stack Developer": "Full Stack Developer",
"full-stack-developer-v9": "Certified Full Stack Developer",
"Legacy Front End": "Legacy Front End",
"legacy-front-end": "Legacy Front End Certification",
"Legacy Back End": "Legacy Back End",
"legacy-back-end": "Legacy Back End Certification",
"Legacy Data Visualization": "Legacy Data Visualization",
"legacy-data-visualization": "Legacy Data Visualization Certification",
"Legacy Information Security and Quality Assurance": "Legacy Information Security and Quality Assurance",
"information-security-and-quality-assurance": "Legacy Information Security and Quality Assurance Certification",
"Legacy Full Stack Certification": "Legacy Full Stack Certification",
"Legacy Full Stack": "Legacy Full Stack",
"full-stack": "Legacy Full Stack Certification"
"responsive-web-design": "Responsive Web Design",
"responsive-web-design-cert": "Responsive Web Design Certification",
"javascript-algorithms-and-data-structures": "Legacy JavaScript Algorithms and Data Structures",
"javascript-algorithms-and-data-structures-cert": "Legacy JavaScript Algorithms and Data Structures Certification",
"javascript-algorithms-and-data-structures-v8": "JavaScript Algorithms and Data Structures (Beta)",
"javascript-algorithms-and-data-structures-v8-cert": "JavaScript Algorithms and Data Structures (Beta) Certification",
"front-end-development-libraries": "Front End Development Libraries",
"front-end-development-libraries-cert": "Front End Development Libraries Certification",
"data-visualization": "Data Visualization",
"data-visualization-cert": "Data Visualization Certification",
"relational-database-v8": "Relational Database",
"relational-database-v8-cert": "Relational Database Certification",
"back-end-development-and-apis": "Back End Development and APIs",
"back-end-development-and-apis-cert": "Back End Development and APIs Certification",
"quality-assurance-v7": "Quality Assurance",
"quality-assurance-v7-cert": "Quality Assurance Certification",
"scientific-computing-with-python-v7": "Scientific Computing with Python",
"scientific-computing-with-python-v7-cert": "Scientific Computing with Python Certification",
"data-analysis-with-python-v7": "Data Analysis with Python",
"data-analysis-with-python-v7-cert": "Data Analysis with Python Certification",
"information-security-v7": "Information Security",
"information-security-v7-cert": "Information Security Certification",
"machine-learning-with-python-v7": "Machine Learning with Python",
"machine-learning-with-python-v7-cert": "Machine Learning with Python Certification",
"college-algebra-with-python-v8": "College Algebra with Python",
"college-algebra-with-python-v8-cert": "College Algebra with Python Certification",
"foundational-c-sharp-with-microsoft": "Foundational C# with Microsoft",
"foundational-c-sharp-with-microsoft-cert": "Foundational C# with Microsoft Certification",
"a2-english-for-developers": "A2 English for Developers",
"a2-english-for-developers-cert": "A2 English for Developers Certification",
"b1-english-for-developers": "B1 English for Developers",
"b1-english-for-developers-cert": "B1 English for Developers Certification",
"full-stack-developer-v9": "Full Stack Developer",
"full-stack-developer-v9-cert": "Full Stack Developer Certification",
"legacy-front-end": "Legacy Front End",
"legacy-front-end-cert": "Legacy Front End Certification",
"legacy-back-end": "Legacy Back End",
"legacy-back-end-cert": "Legacy Back End Certification",
"legacy-data-visualization": "Legacy Data Visualization",
"legacy-data-visualization-cert": "Legacy Data Visualization Certification",
"information-security-and-quality-assurance": "Legacy Information Security and Quality Assurance",
"information-security-and-quality-assurance-cert": "Legacy Information Security and Quality Assurance Certification",
"full-stack": "Legacy Full Stack",
"full-stack-cert": "Legacy Full Stack Certification"
}
},
"certification-card": {
@@ -35,9 +35,8 @@ import {
import { PaymentContext } from '../../../shared/config/donation-settings';
import ribbon from '../assets/images/ribbon.svg';
import {
Certification,
CertSlug,
certTypes,
certTypeTitleMap,
linkedInCredentialIds
} from '../../../shared/config/certification-settings';
import MultiTierDonationForm from '../components/Donation/multi-tier-donation-form';
@@ -327,8 +326,7 @@ const ShowCertification = (props: ShowCertificationProps): JSX.Element => {
</Row>
);
const isMicrosoftCert =
certTitle === certTypeTitleMap[certTypes.foundationalCSharpV8];
const isMicrosoftCert = certSlug === Certification.FoundationalCSharp;
return (
<Container className='certificate-outer-wrapper'>
@@ -376,7 +374,7 @@ const ShowCertification = (props: ShowCertificationProps): JSX.Element => {
? 'certification.fulltextNoHours'
: 'certification.fulltext'
}
title={certTitle}
title={t(`certification.title.${certSlug}`, certTitle)}
>
<h3>placeholder</h3>
<h1>
@@ -388,7 +386,7 @@ const ShowCertification = (props: ShowCertificationProps): JSX.Element => {
<h1 data-playwright-test-label='certification-title'>
<strong>
{{
title: t(`certification.title.${certTitle}`, certTitle)
title: t(`certification.title.${certSlug}`, certTitle)
}}
</strong>
</h1>
@@ -487,7 +485,7 @@ const ShowCertification = (props: ShowCertificationProps): JSX.Element => {
<Spacer size='l' />
{signedInUserName === username ? shareCertBtns : ''}
<Spacer size='l' />
<ShowProjectLinks certName={certTitle} name={displayName} user={user} />
<ShowProjectLinks certSlug={certSlug} name={displayName} user={user} />
<Spacer size='l' />
</div>
</Container>
@@ -7,10 +7,7 @@ import { Table, Spacer } from '@freecodecamp/ui';
import { Link } from '../components/helpers';
import ProjectModal from '../components/SolutionViewer/project-modal';
import type { CompletedChallenge, User } from '../redux/prop-types';
import {
certsToProjects,
type CertTitle
} from '../../config/cert-and-project-map';
import { certsToProjects } from '../../config/cert-and-project-map';
import { SolutionDisplayWidget } from '../components/solution-display-widget';
import ProjectPreviewModal from '../templates/Challenges/components/project-preview-modal';
@@ -20,8 +17,9 @@ import { openModal } from '../templates/Challenges/redux/actions';
import { regeneratePathAndHistory } from '../../../shared/utils/polyvinyl';
import '../components/layouts/project-links.css';
import { Certification } from '../../../shared/config/certification-settings';
interface ShowProjectLinksProps {
certName: string;
certSlug: Certification;
name: string;
user: User;
openModal: (arg: string) => void;
@@ -101,28 +99,27 @@ const ShowProjectLinks = (props: ShowProjectLinksProps): JSX.Element => {
);
};
const ProjectsFor = ({ certName }: { certName: CertTitle }) => {
if (certName === 'Legacy Full Stack') {
const ProjectsFor = ({ certSlug }: { certSlug: Certification }) => {
if (certSlug === Certification.LegacyFullStack) {
const certs = [
{ title: 'Responsive Web Design' },
{ title: 'Legacy JavaScript Algorithms and Data Structures' },
{ title: 'Front End Development Libraries' },
{ title: 'Data Visualization' },
{ title: 'Back End Development and APIs' },
{ title: 'Legacy Information Security and Quality Assurance' }
{ name: Certification.RespWebDesign },
{ name: Certification.JsAlgoDataStruct },
{ name: Certification.LegacyFrontEnd },
{ name: Certification.LegacyDataVis },
{ name: Certification.LegacyBackEnd },
{ name: Certification.LegacyInfoSecQa }
] as const;
return (
<>
{certs.map((cert, ind) => {
const projects = certsToProjects[cert.title];
const { certSlug } = projects[0];
const certLocation = `/certification/${username}/${certSlug}`;
const certLocation = `/certification/${username}/${cert.name}`;
return (
<tr key={ind}>
<td>
<Link className='project-link' to={certLocation} external>
{t(`certification.title.${cert.title}`, cert.title)}
{t(`certification.title.${cert.name}`)}
</Link>
</td>
</tr>
@@ -132,7 +129,7 @@ const ShowProjectLinks = (props: ShowProjectLinksProps): JSX.Element => {
);
}
const projects = certsToProjects[certName];
const projects = certsToProjects[certSlug];
return (
<>
{projects.map(({ link, title, id }) => (
@@ -150,17 +147,17 @@ const ShowProjectLinks = (props: ShowProjectLinksProps): JSX.Element => {
};
const {
certName,
certSlug,
name,
user: { username }
} = props;
const { completedChallenge, showCode, projectTitle } = solutionState;
const examResults = completedChallenge?.examResults;
const getCertHeading = (certName: string) => {
if (certName == 'Legacy Full Stack') {
const getCertHeading = (cert: Certification) => {
if (cert === Certification.LegacyFullStack) {
return 'certification.project.heading-legacy-full-stack';
} else if (certName == 'Foundational C# with Microsoft') {
} else if (cert === Certification.FoundationalCSharp) {
return 'certification.project.heading-exam';
} else {
return 'certification.project.heading';
@@ -177,15 +174,9 @@ const ShowProjectLinks = (props: ShowProjectLinksProps): JSX.Element => {
}
: null;
const isCertName = (maybeCertName: string): maybeCertName is CertTitle => {
if (maybeCertName === 'Legacy Full Stack') return true;
return maybeCertName in certsToProjects;
};
if (!isCertName(certName)) return <div> Unknown Certification</div>;
return (
<div data-playwright-test-label='project-links'>
{t(getCertHeading(certName), { user: name })}
{t(getCertHeading(certSlug), { user: name })}
<Spacer size='m' />
<Table striped>
<thead>
@@ -196,7 +187,7 @@ const ShowProjectLinks = (props: ShowProjectLinksProps): JSX.Element => {
</tr>
</thead>
<tbody>
<ProjectsFor certName={certName} />
<ProjectsFor certSlug={certSlug} />
</tbody>
</Table>
<Spacer size='m' />
@@ -216,7 +207,7 @@ const ShowProjectLinks = (props: ShowProjectLinksProps): JSX.Element => {
/>
<ExamResultsModal projectTitle={projectTitle} examResults={examResults} />
{certName != 'Foundational C# with Microsoft' && (
{certSlug !== Certification.FoundationalCSharp && (
<Trans i18nKey='certification.project.footnote'>
If you suspect that any of these projects violate the{' '}
<a
@@ -54,7 +54,7 @@ function CertButton({ username, cert }: CertButtonProps): JSX.Element {
href={`/certification/${username}/${cert.certSlug}`}
>
{t('buttons.view-cert-title', {
certTitle: t(`certification.title.${cert.certSlug}`)
certTitle: t(`certification.title.${cert.certSlug}-cert`)
})}
</ButtonLink>
<Spacer size='xs' />
@@ -267,7 +267,7 @@ function useIdToNameMap(t: TFunction): Map<string, NameMap> {
const idToNameMap = new Map();
for (const id of getCertIds()) {
const certPath = getPathFromID(id);
const certName = t(`certification.title.${certPath}`);
const certName = t(`certification.title.${certPath}-cert`);
idToNameMap.set(id, {
challengeTitle: certName,
certPath: certPath
+68 -118
View File
@@ -2,7 +2,6 @@ import { find } from 'lodash-es';
import React, { MouseEvent, useState } from 'react';
import { withTranslation } from 'react-i18next';
import type { TFunction } from 'i18next';
import { createSelector } from 'reselect';
import ScrollableAnchor, { configureAnchors } from 'react-scrollable-anchor';
import { connect } from 'react-redux';
import { Table, Button, Spacer } from '@freecodecamp/ui';
@@ -11,20 +10,17 @@ import { regeneratePathAndHistory } from '../../../../shared/utils/polyvinyl';
import ProjectPreviewModal from '../../templates/Challenges/components/project-preview-modal';
import ExamResultsModal from '../SolutionViewer/exam-results-modal';
import { openModal } from '../../templates/Challenges/redux/actions';
import {
currentCertTitles,
legacyCertTitles,
upcomingCertTitles,
certsToProjects,
type CertTitle
} from '../../../config/cert-and-project-map';
import { certsToProjects } from '../../../config/cert-and-project-map';
import { FlashMessages } from '../Flash/redux/flash-messages';
import ProjectModal from '../SolutionViewer/project-modal';
import { FullWidthRow, Link } from '../helpers';
import { SolutionDisplayWidget } from '../solution-display-widget';
import {
Certification,
certSlugTypeMap
certSlugTypeMap,
currentCertifications,
legacyCertifications,
upcomingCertifications
} from '../../../../shared/config/certification-settings';
import env from '../../../config/env.json';
@@ -48,39 +44,18 @@ const mapDispatchToProps = {
openModal
};
const isCertSelector = ({
const createCertifiedMap = ({
is2018DataVisCert,
isApisMicroservicesCert,
isJsAlgoDataStructCert,
isBackEndCert,
isDataVisCert,
isFrontEndCert,
isInfosecQaCert,
isQaCertV7,
isInfosecCertV7,
isFrontEndLibsCert,
isFullStackCert,
isRespWebDesignCert,
isSciCompPyCertV7,
isDataAnalysisPyCertV7,
isMachineLearningPyCertV7,
isRelationalDatabaseCertV8,
isCollegeAlgebraPyCertV8,
isFoundationalCSharpCertV8,
isJsAlgoDataStructCertV8
}: ClaimedCertifications) => ({
is2018DataVisCert,
isApisMicroservicesCert,
isJsAlgoDataStructCert,
isBackEndCert,
isDataVisCert,
isFrontEndCert,
isInfosecQaCert,
isQaCertV7,
isInfosecCertV7,
isFrontEndLibsCert,
isFullStackCert,
isRespWebDesignCert,
isDataVisCert,
isFrontEndCert,
isBackEndCert,
isSciCompPyCertV7,
isDataAnalysisPyCertV7,
isMachineLearningPyCertV7,
@@ -88,56 +63,36 @@ const isCertSelector = ({
isCollegeAlgebraPyCertV8,
isFoundationalCSharpCertV8,
isJsAlgoDataStructCertV8
}: ClaimedCertifications): Record<
Exclude<Certification, Certification.LegacyFullStack>,
boolean
> => ({
[Certification.RespWebDesign]: isRespWebDesignCert,
[Certification.JsAlgoDataStruct]: isJsAlgoDataStructCert,
[Certification.FrontEndDevLibs]: isFrontEndLibsCert,
[Certification.DataVis]: is2018DataVisCert,
[Certification.BackEndDevApis]: isApisMicroservicesCert,
[Certification.QualityAssurance]: isQaCertV7,
[Certification.InfoSec]: isInfosecCertV7,
[Certification.SciCompPy]: isSciCompPyCertV7,
[Certification.DataAnalysisPy]: isDataAnalysisPyCertV7,
[Certification.MachineLearningPy]: isMachineLearningPyCertV7,
[Certification.RelationalDb]: isRelationalDatabaseCertV8,
[Certification.CollegeAlgebraPy]: isCollegeAlgebraPyCertV8,
[Certification.FoundationalCSharp]: isFoundationalCSharpCertV8,
[Certification.LegacyFrontEnd]: isFrontEndCert,
[Certification.LegacyDataVis]: isDataVisCert,
[Certification.LegacyBackEnd]: isBackEndCert,
[Certification.LegacyInfoSecQa]: isInfosecQaCert,
// LegacyFullStack cannot be handled by this because there are no projects to
// be rendered. The new FullStackDeveloper certification is a normal
// certification with projects.
[Certification.FullStackDeveloper]: false,
[Certification.A2English]: false,
[Certification.B1English]: false,
[Certification.JsAlgoDataStructNew]: isJsAlgoDataStructCertV8
});
const isCertMapSelector = createSelector(
isCertSelector,
({
is2018DataVisCert,
isApisMicroservicesCert,
isJsAlgoDataStructCert,
isInfosecQaCert,
isQaCertV7,
isInfosecCertV7,
isFrontEndLibsCert,
isRespWebDesignCert,
isDataVisCert,
isFrontEndCert,
isBackEndCert,
isSciCompPyCertV7,
isDataAnalysisPyCertV7,
isMachineLearningPyCertV7,
isRelationalDatabaseCertV8,
isCollegeAlgebraPyCertV8,
isFoundationalCSharpCertV8,
isJsAlgoDataStructCertV8
}) => ({
'Responsive Web Design': isRespWebDesignCert,
'Legacy JavaScript Algorithms and Data Structures': isJsAlgoDataStructCert,
'Front End Development Libraries': isFrontEndLibsCert,
'Data Visualization': is2018DataVisCert,
'Back End Development and APIs': isApisMicroservicesCert,
'Quality Assurance': isQaCertV7,
'Information Security': isInfosecCertV7,
'Scientific Computing with Python': isSciCompPyCertV7,
'Data Analysis with Python': isDataAnalysisPyCertV7,
'Machine Learning with Python': isMachineLearningPyCertV7,
'Relational Database': isRelationalDatabaseCertV8,
'College Algebra with Python': isCollegeAlgebraPyCertV8,
'Foundational C# with Microsoft': isFoundationalCSharpCertV8,
'Legacy Front End': isFrontEndCert,
'Legacy Data Visualization': isDataVisCert,
'Legacy Back End': isBackEndCert,
'Legacy Information Security and Quality Assurance': isInfosecQaCert,
// Certification.
'Certified Full Stack Developer': false,
'Upcoming Python Certification': false,
'A2 English for Developers': false,
'B1 English for Developers': false,
'JavaScript Algorithms and Data Structures (Beta)': isJsAlgoDataStructCertV8
})
);
const honestyInfoMessage = {
type: 'info',
message: FlashMessages.HonestFirst
@@ -192,27 +147,21 @@ const LegacyFullStack = (props: CertificationSettingsProps) => {
<FullWidthRow key={certSlug}>
<Spacer size='m' />
<h3 className='text-center'>
{t('certification.title.Legacy Full Stack Certification')}
{t(`certification.title.${Certification.LegacyFullStack}-cert`)}
</h3>
<div>
<p>
{t('settings.claim-legacy', {
cert: t('certification.title.Legacy Full Stack Certification')
cert: t(`certification.title.${Certification.LegacyFullStack}-cert`)
})}
</p>
<ul>
<li>{t('certification.title.Responsive Web Design')}</li>
<li>
{t('certification.title.JavaScript Algorithms and Data Structures')}
</li>
<li>{t('certification.title.Front End Development Libraries')}</li>
<li>{t('certification.title.Data Visualization')}</li>
<li>{t('certification.title.Back End Development and APIs')}</li>
<li>
{t(
'certification.title.Legacy Information Security and Quality Assurance'
)}
</li>
<li>{t(`certification.title.${Certification.RespWebDesign}`)}</li>
<li>{t(`certification.title.${Certification.JsAlgoDataStruct}`)}</li>
<li>{t(`certification.title.${Certification.LegacyFrontEnd}`)}</li>
<li>{t(`certification.title.${Certification.LegacyDataVis}`)}</li>
<li>{t(`certification.title.${Certification.LegacyBackEnd}`)}</li>
<li>{t(`certification.title.${Certification.LegacyInfoSecQa}`)}</li>
</ul>
</div>
@@ -228,7 +177,7 @@ const LegacyFullStack = (props: CertificationSettingsProps) => {
>
{t('buttons.show-cert')}{' '}
<span className='sr-only'>
{t('certification.title.Legacy Full Stack')}
{t(`certification.title.${Certification.LegacyFullStack}`)}
</span>
</Button>
) : (
@@ -242,7 +191,7 @@ const LegacyFullStack = (props: CertificationSettingsProps) => {
>
{t('buttons.claim-cert')}{' '}
<span className='sr-only'>
{t('certification.title.Legacy Full Stack')}
{t(`certification.title.${Certification.LegacyFullStack}`)}
</span>
</Button>
)}
@@ -273,8 +222,7 @@ function CertificationSettings(props: CertificationSettingsProps) {
const handleSolutionModalHide = () => initialiseState();
const getUserIsCertMap = () => isCertMapSelector(props);
const isCertifiedMap = createCertifiedMap(props);
const getProjectSolution = (projectId: string, projectTitle: string) => {
const { completedChallenges, openModal } = props;
const completedProject = find(
@@ -327,20 +275,19 @@ function CertificationSettings(props: CertificationSettingsProps) {
};
const Certification = ({
certName,
certSlug,
t
}: {
certName: Exclude<CertTitle, 'Legacy Full Stack'>;
certSlug: Exclude<Certification, Certification.LegacyFullStack>;
t: TFunction;
}) => {
const { certSlug } = certsToProjects[certName][0];
return (
<ScrollableAnchor id={`cert-${certSlug}`}>
<section>
<FullWidthRow>
<Spacer size='m' />
<h3 className='text-center'>
{t(`certification.title.${certName}`, certName)}
{t(`certification.title.${certSlug}`, certSlug)}
</h3>
<Table>
<thead>
@@ -351,8 +298,8 @@ function CertificationSettings(props: CertificationSettingsProps) {
</thead>
<tbody>
<ProjectsFor
certName={certName}
isCert={getUserIsCertMap()[certName]}
certSlug={certSlug}
isCert={isCertifiedMap[certSlug]}
/>
</tbody>
</Table>
@@ -363,14 +310,13 @@ function CertificationSettings(props: CertificationSettingsProps) {
};
function ProjectsFor({
certName,
certSlug,
isCert
}: {
certName: Exclude<CertTitle, 'Legacy Full Stack'>;
certSlug: Exclude<Certification, Certification.LegacyFullStack>;
isCert: boolean;
}) {
const { username, isHonest, createFlashMessage, t, verifyCert } = props;
const { certSlug } = certsToProjects[certName][0];
const certLocation = `/certification/${username}/${certSlug}`;
const handleClaim = (e: MouseEvent<HTMLButtonElement>) => {
@@ -383,7 +329,7 @@ function CertificationSettings(props: CertificationSettingsProps) {
return (
<>
{certsToProjects[certName].map(({ link, title, id }) => (
{certsToProjects[certSlug].map(({ link, title, id }) => (
<tr className='project-row' key={id}>
<td className='project-title col-xs-8'>
<Link to={link}>
@@ -400,12 +346,16 @@ function CertificationSettings(props: CertificationSettingsProps) {
{isCert ? (
<Button block={true} variant='primary' href={certLocation}>
{t('buttons.show-cert')}{' '}
<span className='sr-only'>{certName}</span>
<span className='sr-only'>
{t(`certification.title.${certSlug}`)}
</span>
</Button>
) : (
<Button block={true} variant='primary' onClick={handleClaim}>
{t('buttons.claim-cert')}{' '}
<span className='sr-only'>{certName}</span>
<span className='sr-only'>
{t(`certification.title.${certSlug}`)}
</span>
</Button>
)}
</td>
@@ -419,18 +369,18 @@ function CertificationSettings(props: CertificationSettingsProps) {
return (
<section className='certification-settings'>
<SectionHeader>{t('settings.headings.certs')}</SectionHeader>
{currentCertTitles.map(title => (
<Certification key={title} certName={title} t={t} />
{currentCertifications.map(cert => (
<Certification key={cert} certSlug={cert} t={t} />
))}
<Spacer size='m' />
<SectionHeader>{t('settings.headings.legacy-certs')}</SectionHeader>
<LegacyFullStack {...props} />
{legacyCertTitles.map(title => (
<Certification key={title} certName={title} t={t} />
{legacyCertifications.map(cert => (
<Certification key={cert} certSlug={cert} t={t} />
))}
{showUpcomingChanges &&
upcomingCertTitles.map(title => (
<Certification key={title} certName={title} t={t} />
upcomingCertifications.map(cert => (
<Certification key={cert} certSlug={cert} t={t} />
))}
<ProjectModal
{...{
+2 -2
View File
@@ -35,7 +35,7 @@ test.describe('Certification page - Non Microsoft', () => {
await expect(certInfoContainer).toBeVisible();
const certTitle = certInfoContainer.getByTestId('certification-title');
await expect(certTitle).toHaveText(
translations.certification.title['Responsive Web Design']
translations.certification.title['responsive-web-design']
);
const footer = certWrapper.getByTestId('cert-footer');
@@ -195,7 +195,7 @@ test.describe('Certification page - Microsoft', () => {
await expect(certInfoContainer).toBeVisible();
const certTitle = certInfoContainer.getByTestId('certification-title');
await expect(certTitle).toHaveText(
translations.certification.title['Foundational C# with Microsoft']
translations.certification.title['foundational-c-sharp-with-microsoft']
);
const footer = certWrapper.getByTestId('cert-footer');
+19 -19
View File
@@ -22,28 +22,28 @@ const settingsObject = {
};
const certifications = [
translations.certification.title['Responsive Web Design'],
translations.certification.title['JavaScript Algorithms and Data Structures'],
translations.certification.title['Front End Development Libraries'],
translations.certification.title['Data Visualization'],
translations.certification.title['Relational Database'],
translations.certification.title['Back End Development and APIs'],
translations.certification.title['Quality Assurance'],
translations.certification.title['Scientific Computing with Python'],
translations.certification.title['Data Analysis with Python'],
translations.certification.title['Information Security'],
translations.certification.title['Machine Learning with Python'],
translations.certification.title['College Algebra with Python'],
translations.certification.title['Foundational C# with Microsoft']
translations.certification.title['responsive-web-design'],
translations.certification.title[
'javascript-algorithms-and-data-structures-v8'
],
translations.certification.title['front-end-development-libraries'],
translations.certification.title['data-visualization'],
translations.certification.title['relational-database-v8'],
translations.certification.title['back-end-development-and-apis'],
translations.certification.title['quality-assurance-v7'],
translations.certification.title['scientific-computing-with-python-v7'],
translations.certification.title['data-analysis-with-python-v7'],
translations.certification.title['information-security-v7'],
translations.certification.title['machine-learning-with-python-v7'],
translations.certification.title['college-algebra-with-python-v8'],
translations.certification.title['foundational-c-sharp-with-microsoft']
];
const legacyCertifications = [
translations.certification.title['Legacy Front End'],
translations.certification.title['Legacy Back End'],
translations.certification.title['Legacy Data Visualization'],
translations.certification.title[
'Legacy Information Security and Quality Assurance'
]
translations.certification.title['legacy-front-end'],
translations.certification.title['legacy-back-end'],
translations.certification.title['legacy-data-visualization'],
translations.certification.title['information-security-and-quality-assurance']
];
test.describe('Settings - Certified User', () => {