refactor(client): convert backend to functional component (#57401)

This commit is contained in:
Sem Bauke
2024-12-04 11:50:38 +01:00
committed by GitHub
parent 78e1dee742
commit 882c4314c8
@@ -1,9 +1,5 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
import { graphql } from 'gatsby';
import React, { Component } from 'react';
import React, { useEffect, useRef } from 'react';
import Helmet from 'react-helmet';
import { withTranslation } from 'react-i18next';
import type { TFunction } from 'i18next';
@@ -95,59 +91,18 @@ interface BackEndProps {
updateSolutionFormValues: () => void;
}
// Component
class BackEnd extends Component<BackEndProps> {
static displayName: string;
private container: React.RefObject<HTMLElement> = React.createRef();
const ShowBackEnd = (props: BackEndProps) => {
const container = useRef<HTMLElement>(null);
constructor(props: BackEndProps) {
super(props);
this.state = {};
this.updateDimensions = this.updateDimensions.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
const handleSubmit = ({
showCompletionModal
}: {
showCompletionModal: boolean;
}) => {
props.executeChallenge({ showCompletionModal });
};
componentDidMount() {
this.initializeComponent();
window.addEventListener('resize', () => this.updateDimensions());
this.container.current?.focus();
}
updateDimensions() {
this.setState({ width: window.innerWidth, height: window.innerHeight });
}
componentWillUnmount() {
window.removeEventListener('resize', () => this.updateDimensions());
}
componentDidUpdate(prevProps: BackEndProps) {
const {
data: {
challengeNode: {
challenge: {
title: prevTitle,
fields: { tests: prevTests }
}
}
}
} = prevProps;
const {
data: {
challengeNode: {
challenge: {
title: currentTitle,
fields: { tests: currTests }
}
}
}
} = this.props;
if (prevTitle !== currentTitle || prevTests !== currTests) {
this.initializeComponent();
}
}
initializeComponent() {
useEffect(() => {
const {
challengeMounted,
initConsole,
@@ -164,7 +119,7 @@ class BackEnd extends Component<BackEndProps> {
}
},
pageContext: { challengeMeta }
} = this.props;
} = props;
initConsole();
initTests(tests);
updateChallengeMeta({
@@ -174,112 +129,99 @@ class BackEnd extends Component<BackEndProps> {
helpCategory
});
challengeMounted(challengeMeta.id);
}
container.current?.focus();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
handleSubmit({
showCompletionModal
}: {
showCompletionModal: boolean;
}): void {
this.props.executeChallenge({
showCompletionModal
});
}
render() {
const {
data: {
challengeNode: {
challenge: {
fields: { blockName },
challengeType,
forumTopicId,
title,
description,
instructions,
translationPending,
superBlock,
block
}
const {
data: {
challengeNode: {
challenge: {
fields: { blockName },
challengeType,
forumTopicId,
title,
description,
instructions,
translationPending,
superBlock,
block
}
},
isChallengeCompleted,
output,
pageContext: {
challengeMeta: { nextChallengePath, prevChallengePath }
},
t,
tests,
updateSolutionFormValues
} = this.props;
}
},
isChallengeCompleted,
output,
pageContext: {
challengeMeta: { nextChallengePath, prevChallengePath }
},
t,
tests,
updateSolutionFormValues
} = props;
const blockNameTitle = `${t(
`intro:${superBlock}.blocks.${block}.title`
)} - ${title}`;
const blockNameTitle = `${t(
`intro:${superBlock}.blocks.${block}.title`
)} - ${title}`;
return (
<Hotkeys
containerRef={this.container}
nextChallengePath={nextChallengePath}
prevChallengePath={prevChallengePath}
>
<LearnLayout>
<Helmet
title={`${blockNameTitle} | ${t('learn.learn')} | freeCodeCamp.org`}
/>
<Container>
<Row>
<Col md={8} mdOffset={2} sm={10} smOffset={1} xs={12}>
<Spacer size='m' />
<ChallengeTitle
isCompleted={isChallengeCompleted}
translationPending={translationPending}
>
{title}
</ChallengeTitle>
<ChallengeDescription
description={description}
instructions={instructions}
/>
<Spacer size='m' />
<SolutionForm
challengeType={challengeType}
// eslint-disable-next-line @typescript-eslint/unbound-method
onSubmit={this.handleSubmit}
updateSolutionForm={updateSolutionFormValues}
/>
<ProjectToolPanel
guideUrl={getGuideUrl({ forumTopicId, title })}
/>
<br />
<Output
defaultOutput={`/**
return (
<Hotkeys
containerRef={container}
nextChallengePath={nextChallengePath}
prevChallengePath={prevChallengePath}
>
<LearnLayout>
<Helmet
title={`${blockNameTitle} | ${t('learn.learn')} | freeCodeCamp.org`}
/>
<Container>
<Row>
<Col md={8} mdOffset={2} sm={10} smOffset={1} xs={12}>
<Spacer size='m' />
<ChallengeTitle
isCompleted={isChallengeCompleted}
translationPending={translationPending}
>
{title}
</ChallengeTitle>
<ChallengeDescription
description={description}
instructions={instructions}
/>
<Spacer size='m' />
<SolutionForm
challengeType={challengeType}
onSubmit={handleSubmit}
updateSolutionForm={updateSolutionFormValues}
/>
<ProjectToolPanel
guideUrl={getGuideUrl({ forumTopicId, title })}
/>
<br />
<Output
defaultOutput={`/**
*
* ${t('learn.test-output')}
*
*
*/`}
output={output}
/>
<TestSuite tests={tests} />
<Spacer size='m' />
</Col>
<CompletionModal />
<HelpModal challengeTitle={title} challengeBlock={blockName} />
</Row>
</Container>
</LearnLayout>
</Hotkeys>
);
}
}
BackEnd.displayName = 'BackEnd';
output={output}
/>
<TestSuite tests={tests} />
<Spacer size='m' />
</Col>
<CompletionModal />
<HelpModal challengeTitle={title} challengeBlock={blockName} />
</Row>
</Container>
</LearnLayout>
</Hotkeys>
);
};
export default connect(
mapStateToProps,
mapDispatchToActions
)(withTranslation()(BackEnd));
)(withTranslation()(ShowBackEnd));
export const query = graphql`
query BackendChallenge($id: String!) {