diff --git a/client/src/client-only-routes/show-project-links.tsx b/client/src/client-only-routes/show-project-links.tsx index 1522691d60..15ece65c64 100644 --- a/client/src/client-only-routes/show-project-links.tsx +++ b/client/src/client-only-routes/show-project-links.tsx @@ -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 => { ) ); - /* 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} diff --git a/client/src/components/SolutionViewer/ProjectModal.js b/client/src/components/SolutionViewer/ProjectModal.tsx similarity index 59% rename from client/src/components/SolutionViewer/ProjectModal.js rename to client/src/components/SolutionViewer/ProjectModal.tsx index f12e3c9915..670a5b991f 100644 --- a/client/src/components/SolutionViewer/ProjectModal.js +++ b/client/src/components/SolutionViewer/ProjectModal.tsx @@ -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 { - isOpen, - projectTitle, - challengeFiles, - solution, - handleSolutionModalHide - } = props; +const ProjectModal = ({ + isOpen, + projectTitle, + challengeFiles, + solution, + handleSolutionModalHide +}: ProjectModalProps): JSX.Element => { const { t } = useTranslation(); return ( { ); }; -ProjectModal.propTypes = propTypes; ProjectModal.displayName = 'ProjectModal'; export default ProjectModal; diff --git a/client/src/components/SolutionViewer/SolutionViewer.js b/client/src/components/SolutionViewer/SolutionViewer.js deleted file mode 100644 index 34ab2db6af..0000000000 --- a/client/src/components/SolutionViewer/SolutionViewer.js +++ /dev/null @@ -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 => ( - - {challengeFile.ext.toUpperCase()} - -
-            
-          
-
-
- )) - ) : ( - - JS - -
-          
-        
-
-
- ); - -SolutionViewer.displayName = 'SolutionViewer'; -SolutionViewer.propTypes = { - challengeFiles: PropTypes.array, - solution: PropTypes.string -}; - -export default SolutionViewer; diff --git a/client/src/components/SolutionViewer/SolutionViewer.tsx b/client/src/components/SolutionViewer/SolutionViewer.tsx new file mode 100644 index 0000000000..8c977096ac --- /dev/null +++ b/client/src/components/SolutionViewer/SolutionViewer.tsx @@ -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) => ( + + {challengeFile.ext.toUpperCase()} + + +
+                
+              
+
+
+ )) + ) : ( + + JS + +
+              
+            
+
+
+ )} + + ); +} +export default SolutionViewer;