chore(client): Migration of SolutionViewer component to Typescript. (#43694)

* The Solutionviewer .js file has been migrated into the .tsx file.

* Apply suggestions from code review

I have added the suggestions and before adding them to the commit, I have checked it once locally and it doesn't throw any new error.

Co-authored-by: Nicholas Carrigan (he/him) <nhcarrigan@gmail.com>

* Update the SolutionViewer.tsx 

Added the "null" and "undefined" type to "solution" property.

* Update SolutionViewer.tsx

* Update ProjectModal.tsx

* Update ProjectModal.tsx

* Update SolutionViewer.tsx

* Update ProjectModal.tsx

* Apply suggestions from code review

Co-authored-by: Shaun Hamilton <shauhami020@gmail.com>

* Update client/src/components/SolutionViewer/ProjectModal.tsx

Co-authored-by: Shaun Hamilton <shauhami020@gmail.com>

* Apply suggestions from code review

Co-authored-by: Shaun Hamilton <shauhami020@gmail.com>

* Apply suggestions from code review

Co-authored-by: Nicholas Carrigan (he/him) <nhcarrigan@gmail.com>

* type of solution prop has been changed into "solution?:string;"

* assert solution is not `null` for modal

Co-authored-by: Nicholas Carrigan (he/him) <nhcarrigan@gmail.com>
Co-authored-by: Shaun Hamilton <shauhami020@gmail.com>
This commit is contained in:
Ashis Kumar
2021-10-27 00:46:25 +05:30
committed by GitHub
parent fc868b3201
commit 94079b263a
4 changed files with 89 additions and 101 deletions

View File

@ -32,7 +32,7 @@ type SolutionStateType = {
const initSolutionState: SolutionStateType = {
projectTitle: '',
challengeFiles: null,
solution: null,
solution: '',
isOpen: false
};
@ -156,10 +156,10 @@ const ShowProjectLinks = (props: IShowProjectLinksProps): JSX.Element => {
</li>
)
);
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-return */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-enable @typescript-eslint/no-unsafe-assignment */
/* eslint-enable @typescript-eslint/no-unsafe-call */
/* eslint-enable @typescript-eslint/no-unsafe-return */
/* eslint-enable @typescript-eslint/no-unsafe-member-access */
};
const {
@ -185,7 +185,9 @@ const ShowProjectLinks = (props: IShowProjectLinksProps): JSX.Element => {
handleSolutionModalHide={handleSolutionModalHide}
isOpen={isOpen}
projectTitle={projectTitle}
solution={solution}
// 'solution' is theoretically never 'null', if it a JsAlgoData cert
// which is the only time we use the modal
solution={solution as undefined | string}
/>
) : null}
<Trans i18nKey='certification.project.footnote'>

View File

@ -1,34 +1,24 @@
import { Button, Modal } from '@freecodecamp/react-bootstrap';
import PropTypes from 'prop-types';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { ChallengeFiles } from '../../redux/prop-types';
import SolutionViewer from './SolutionViewer';
const propTypes = {
challengeFiles: PropTypes.array,
// TODO: removed once refactored to TS
// PropTypes.shape({
// contents: PropTypes.string,
// ext: PropTypes.string,
// key: PropTypes.string,
// name: PropTypes.string,
// path: PropTypes.string
// })
// ),
handleSolutionModalHide: PropTypes.func,
isOpen: PropTypes.bool,
projectTitle: PropTypes.string,
solution: PropTypes.string
type ProjectModalProps = {
challengeFiles: ChallengeFiles;
handleSolutionModalHide: () => void;
isOpen: boolean;
projectTitle: string;
solution?: string;
};
const ProjectModal = props => {
const {
const ProjectModal = ({
isOpen,
projectTitle,
challengeFiles,
solution,
handleSolutionModalHide
} = props;
}: ProjectModalProps): JSX.Element => {
const { t } = useTranslation();
return (
<Modal
@ -54,7 +44,6 @@ const ProjectModal = props => {
);
};
ProjectModal.propTypes = propTypes;
ProjectModal.displayName = 'ProjectModal';
export default ProjectModal;

View File

@ -1,70 +0,0 @@
import { Panel } from '@freecodecamp/react-bootstrap';
import Prism from 'prismjs';
import PropTypes from 'prop-types';
import React from 'react';
const prismLang = {
css: 'css',
js: 'javascript',
jsx: 'javascript',
html: 'markup'
};
const SolutionViewer = ({
challengeFiles,
solution = '// The solution is not available for this project'
}) =>
challengeFiles?.length ? (
challengeFiles.map(challengeFile => (
<Panel
bsStyle='primary'
className='solution-viewer'
key={challengeFile.ext}
>
<Panel.Heading>{challengeFile.ext.toUpperCase()}</Panel.Heading>
<Panel.Body>
<pre>
<code
className={`language-${prismLang[challengeFile.ext]}`}
dangerouslySetInnerHTML={{
__html: Prism.highlight(
challengeFile.contents.trim(),
Prism.languages[prismLang[challengeFile.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>
);
SolutionViewer.displayName = 'SolutionViewer';
SolutionViewer.propTypes = {
challengeFiles: PropTypes.array,
solution: PropTypes.string
};
export default SolutionViewer;

View File

@ -0,0 +1,67 @@
import { Panel } from '@freecodecamp/react-bootstrap';
import Prism from 'prismjs';
import React from 'react';
import { ChallengeFile, ChallengeFiles } from '../../redux/prop-types';
type SolutionViewerProps = {
challengeFiles: ChallengeFiles;
solution?: string;
};
function SolutionViewer({
challengeFiles,
solution = '// The solution is not available for this project'
}: SolutionViewerProps): JSX.Element {
return (
<>
{challengeFiles?.length ? (
challengeFiles.map((challengeFile: ChallengeFile) => (
<Panel
bsStyle='primary'
className='solution-viewer'
key={challengeFile}
>
<Panel.Heading>{challengeFile.ext.toUpperCase()}</Panel.Heading>
<Panel.Body>
<pre>
<code
dangerouslySetInnerHTML={{
__html: Prism.highlight(
challengeFile.contents.trim(),
Prism.languages[challengeFile.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>
)}
</>
);
}
export default SolutionViewer;