refactor(client): make ShowCertification functional (#39735)
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
/* eslint-disable react/jsx-sort-props */
|
/* eslint-disable react/jsx-sort-props */
|
||||||
import React, { Component } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { bindActionCreators } from 'redux';
|
import { bindActionCreators } from 'redux';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
@ -83,37 +83,27 @@ const mapStateToProps = (state, { certName }) => {
|
|||||||
const mapDispatchToProps = dispatch =>
|
const mapDispatchToProps = dispatch =>
|
||||||
bindActionCreators({ createFlashMessage, showCert, executeGA }, dispatch);
|
bindActionCreators({ createFlashMessage, showCert, executeGA }, dispatch);
|
||||||
|
|
||||||
class ShowCertification extends Component {
|
const ShowCertification = props => {
|
||||||
constructor(...args) {
|
const [isDonationSubmitted, setIsDonationSubmitted] = useState(false);
|
||||||
super(...args);
|
const [isDonationDisplayed, setIsDonationDisplayed] = useState(false);
|
||||||
|
const [isDonationClosed, setIsDonationClosed] = useState(false);
|
||||||
|
|
||||||
this.state = {
|
useEffect(() => {
|
||||||
isDonationSubmitted: false,
|
const { username, certName, validCertName, showCert } = props;
|
||||||
isDonationDisplayed: false,
|
|
||||||
isDonationClosed: false
|
|
||||||
};
|
|
||||||
|
|
||||||
this.hideDonationSection = this.hideDonationSection.bind(this);
|
|
||||||
this.handleProcessing = this.handleProcessing.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
const { username, certName, validCertName, showCert } = this.props;
|
|
||||||
if (validCertName) {
|
if (validCertName) {
|
||||||
return showCert({ username, certName });
|
showCert({ username, certName });
|
||||||
}
|
}
|
||||||
return null;
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}
|
}, []);
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps) {
|
useEffect(() => {
|
||||||
const {
|
const {
|
||||||
userFetchState: { complete: userComplete },
|
userFetchState: { complete: userComplete },
|
||||||
signedInUserName,
|
signedInUserName,
|
||||||
isDonating,
|
isDonating,
|
||||||
cert: { username = '' },
|
cert: { username = '' },
|
||||||
executeGA
|
executeGA
|
||||||
} = nextProps;
|
} = props;
|
||||||
const { isDonationDisplayed } = this.state;
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!isDonationDisplayed &&
|
!isDonationDisplayed &&
|
||||||
@ -122,9 +112,7 @@ class ShowCertification extends Component {
|
|||||||
signedInUserName === username &&
|
signedInUserName === username &&
|
||||||
!isDonating
|
!isDonating
|
||||||
) {
|
) {
|
||||||
this.setState({
|
setIsDonationDisplayed(true);
|
||||||
isDonationDisplayed: true
|
|
||||||
});
|
|
||||||
|
|
||||||
executeGA({
|
executeGA({
|
||||||
type: 'event',
|
type: 'event',
|
||||||
@ -135,15 +123,19 @@ class ShowCertification extends Component {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return true;
|
}, [isDonationDisplayed, props]);
|
||||||
}
|
|
||||||
|
|
||||||
hideDonationSection() {
|
const hideDonationSection = () => {
|
||||||
this.setState({ isDonationDisplayed: false, isDonationClosed: true });
|
setIsDonationDisplayed(false);
|
||||||
}
|
setIsDonationClosed(true);
|
||||||
|
};
|
||||||
|
|
||||||
handleProcessing(duration, amount, action = 'stripe form submission') {
|
const handleProcessing = (
|
||||||
this.props.executeGA({
|
duration,
|
||||||
|
amount,
|
||||||
|
action = 'stripe form submission'
|
||||||
|
) => {
|
||||||
|
props.executeGA({
|
||||||
type: 'event',
|
type: 'event',
|
||||||
data: {
|
data: {
|
||||||
category: 'donation',
|
category: 'donation',
|
||||||
@ -152,185 +144,177 @@ class ShowCertification extends Component {
|
|||||||
value: amount
|
value: amount
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.setState({ isDonationSubmitted: true });
|
setIsDonationSubmitted(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const {
|
||||||
|
cert,
|
||||||
|
fetchState,
|
||||||
|
validCertName,
|
||||||
|
createFlashMessage,
|
||||||
|
signedInUserName,
|
||||||
|
location: { pathname }
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
if (!validCertName) {
|
||||||
|
createFlashMessage(standardErrorMessage);
|
||||||
|
return <RedirectHome />;
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
const { pending, complete, errored } = fetchState;
|
||||||
const {
|
|
||||||
cert,
|
|
||||||
fetchState,
|
|
||||||
validCertName,
|
|
||||||
createFlashMessage,
|
|
||||||
signedInUserName,
|
|
||||||
location: { pathname }
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
const {
|
if (pending) {
|
||||||
isDonationSubmitted,
|
return <Loader fullScreen={true} />;
|
||||||
isDonationDisplayed,
|
}
|
||||||
isDonationClosed
|
|
||||||
} = this.state;
|
|
||||||
|
|
||||||
if (!validCertName) {
|
if (!pending && errored) {
|
||||||
createFlashMessage(standardErrorMessage);
|
createFlashMessage(standardErrorMessage);
|
||||||
return <RedirectHome />;
|
return <RedirectHome />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { pending, complete, errored } = fetchState;
|
if (!pending && !complete && !errored) {
|
||||||
|
createFlashMessage(reallyWeirdErrorMessage);
|
||||||
|
return <RedirectHome />;
|
||||||
|
}
|
||||||
|
|
||||||
if (pending) {
|
const {
|
||||||
return <Loader fullScreen={true} />;
|
date,
|
||||||
}
|
name: userFullName,
|
||||||
|
username,
|
||||||
|
certTitle,
|
||||||
|
completionTime
|
||||||
|
} = cert;
|
||||||
|
|
||||||
if (!pending && errored) {
|
const certDate = new Date(date);
|
||||||
createFlashMessage(standardErrorMessage);
|
const certYear = certDate.getFullYear();
|
||||||
return <RedirectHome />;
|
const certMonth = certDate.getMonth();
|
||||||
}
|
const certURL = `https://freecodecamp.org${pathname}`;
|
||||||
|
|
||||||
if (!pending && !complete && !errored) {
|
const donationCloseBtn = (
|
||||||
createFlashMessage(reallyWeirdErrorMessage);
|
<div>
|
||||||
return <RedirectHome />;
|
<Button
|
||||||
}
|
block={true}
|
||||||
|
bsSize='sm'
|
||||||
|
bsStyle='primary'
|
||||||
|
onClick={hideDonationSection}
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
const {
|
let donationSection = (
|
||||||
date,
|
<Grid className='donation-section'>
|
||||||
name: userFullName,
|
{!isDonationSubmitted && (
|
||||||
username,
|
|
||||||
certTitle,
|
|
||||||
completionTime
|
|
||||||
} = cert;
|
|
||||||
|
|
||||||
const certDate = new Date(date);
|
|
||||||
const certYear = certDate.getFullYear();
|
|
||||||
const certMonth = certDate.getMonth();
|
|
||||||
const certURL = `https://freecodecamp.org${pathname}`;
|
|
||||||
|
|
||||||
const donationCloseBtn = (
|
|
||||||
<div>
|
|
||||||
<Button
|
|
||||||
block={true}
|
|
||||||
bsSize='sm'
|
|
||||||
bsStyle='primary'
|
|
||||||
onClick={this.hideDonationSection}
|
|
||||||
>
|
|
||||||
Close
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
let donationSection = (
|
|
||||||
<Grid className='donation-section'>
|
|
||||||
{!isDonationSubmitted && (
|
|
||||||
<Row>
|
|
||||||
<Col lg={8} lgOffset={2} sm={10} smOffset={1} xs={12}>
|
|
||||||
<p>
|
|
||||||
Only you can see this message. Congratulations on earning this
|
|
||||||
certification. It’s no easy task. Running freeCodeCamp isn’t
|
|
||||||
easy either. Nor is it cheap. Help us help you and many other
|
|
||||||
people around the world. Make a tax-deductible supporting
|
|
||||||
donation to our nonprofit today.
|
|
||||||
</p>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
)}
|
|
||||||
<DonateForm
|
|
||||||
handleProcessing={this.handleProcessing}
|
|
||||||
defaultTheme='light'
|
|
||||||
isMinimalForm={true}
|
|
||||||
/>
|
|
||||||
<Row>
|
<Row>
|
||||||
<Col sm={4} smOffset={4} xs={6} xsOffset={3}>
|
<Col lg={8} lgOffset={2} sm={10} smOffset={1} xs={12}>
|
||||||
{isDonationSubmitted && donationCloseBtn}
|
<p>
|
||||||
|
Only you can see this message. Congratulations on earning this
|
||||||
|
certification. It’s no easy task. Running freeCodeCamp isn’t easy
|
||||||
|
either. Nor is it cheap. Help us help you and many other people
|
||||||
|
around the world. Make a tax-deductible supporting donation to our
|
||||||
|
nonprofit today.
|
||||||
|
</p>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</Grid>
|
)}
|
||||||
);
|
<DonateForm
|
||||||
|
handleProcessing={handleProcessing}
|
||||||
const shareCertBtns = (
|
defaultTheme='light'
|
||||||
<Row className='text-center'>
|
isMinimalForm={true}
|
||||||
<Spacer size={2} />
|
/>
|
||||||
<Button
|
<Row>
|
||||||
block={true}
|
<Col sm={4} smOffset={4} xs={6} xsOffset={3}>
|
||||||
bsSize='lg'
|
{isDonationSubmitted && donationCloseBtn}
|
||||||
bsStyle='primary'
|
</Col>
|
||||||
target='_blank'
|
|
||||||
href={`https://www.linkedin.com/profile/add?startTask=CERTIFICATION_NAME&name=${certTitle}&organizationId=4831032&issueYear=${certYear}&issueMonth=${certMonth}&certUrl=${certURL}`}
|
|
||||||
>
|
|
||||||
Add this certification to my LinkedIn profile
|
|
||||||
</Button>
|
|
||||||
<Spacer />
|
|
||||||
<Button
|
|
||||||
block={true}
|
|
||||||
bsSize='lg'
|
|
||||||
bsStyle='primary'
|
|
||||||
target='_blank'
|
|
||||||
href={`https://twitter.com/intent/tweet?text=I just earned the ${certTitle} certification @freeCodeCamp! Check it out here: ${certURL}`}
|
|
||||||
>
|
|
||||||
Share this certification on Twitter
|
|
||||||
</Button>
|
|
||||||
</Row>
|
</Row>
|
||||||
);
|
</Grid>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
const shareCertBtns = (
|
||||||
<div className='certificate-outer-wrapper'>
|
<Row className='text-center'>
|
||||||
{isDonationDisplayed && !isDonationClosed ? donationSection : ''}
|
<Spacer size={2} />
|
||||||
<Grid className='certificate-wrapper certification-namespace'>
|
<Button
|
||||||
<Row>
|
block={true}
|
||||||
<header>
|
bsSize='lg'
|
||||||
<Col md={5} sm={12}>
|
bsStyle='primary'
|
||||||
<div className='logo'>
|
target='_blank'
|
||||||
<FreeCodeCampLogo />
|
href={`https://www.linkedin.com/profile/add?startTask=CERTIFICATION_NAME&name=${certTitle}&organizationId=4831032&issueYear=${certYear}&issueMonth=${certMonth}&certUrl=${certURL}`}
|
||||||
</div>
|
>
|
||||||
</Col>
|
Add this certification to my LinkedIn profile
|
||||||
<Col md={7} sm={12}>
|
</Button>
|
||||||
<div data-cy='issue-date' className='issue-date'>
|
<Spacer />
|
||||||
Issued
|
<Button
|
||||||
<strong>{format(certDate, 'MMMM d, y')}</strong>
|
block={true}
|
||||||
</div>
|
bsSize='lg'
|
||||||
</Col>
|
bsStyle='primary'
|
||||||
</header>
|
target='_blank'
|
||||||
|
href={`https://twitter.com/intent/tweet?text=I just earned the ${certTitle} certification @freeCodeCamp! Check it out here: ${certURL}`}
|
||||||
|
>
|
||||||
|
Share this certification on Twitter
|
||||||
|
</Button>
|
||||||
|
</Row>
|
||||||
|
);
|
||||||
|
|
||||||
<main className='information'>
|
return (
|
||||||
<div className='information-container'>
|
<div className='certificate-outer-wrapper'>
|
||||||
<h3>This certifies that</h3>
|
{isDonationDisplayed && !isDonationClosed ? donationSection : ''}
|
||||||
<h1>
|
<Grid className='certificate-wrapper certification-namespace'>
|
||||||
<strong>{userFullName}</strong>
|
<Row>
|
||||||
</h1>
|
<header>
|
||||||
<h3>has successfully completed the freeCodeCamp.org</h3>
|
<Col md={5} sm={12}>
|
||||||
<h1>
|
<div className='logo'>
|
||||||
<strong>{certTitle}</strong>
|
<FreeCodeCampLogo />
|
||||||
</h1>
|
|
||||||
<h4>
|
|
||||||
Developer Certification, representing approximately{' '}
|
|
||||||
{completionTime} hours of coursework
|
|
||||||
</h4>
|
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</Col>
|
||||||
<footer>
|
<Col md={7} sm={12}>
|
||||||
<div className='row signatures'>
|
<div data-cy='issue-date' className='issue-date'>
|
||||||
<Image
|
Issued
|
||||||
alt="Quincy Larson's Signature"
|
<strong>{format(certDate, 'MMMM d, y')}</strong>
|
||||||
src={
|
|
||||||
'https://cdn.freecodecamp.org' +
|
|
||||||
'/platform/english/images/quincy-larson-signature.svg'
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<p>
|
|
||||||
<strong>Quincy Larson</strong>
|
|
||||||
</p>
|
|
||||||
<p>Executive Director, freeCodeCamp.org</p>
|
|
||||||
</div>
|
</div>
|
||||||
<Row>
|
</Col>
|
||||||
<p className='verify'>Verify this certification at {certURL}</p>
|
</header>
|
||||||
</Row>
|
|
||||||
</footer>
|
<main className='information'>
|
||||||
</Row>
|
<div className='information-container'>
|
||||||
</Grid>
|
<h3>This certifies that</h3>
|
||||||
{signedInUserName === username ? shareCertBtns : ''}
|
<h1>
|
||||||
</div>
|
<strong>{userFullName}</strong>
|
||||||
);
|
</h1>
|
||||||
}
|
<h3>has successfully completed the freeCodeCamp.org</h3>
|
||||||
}
|
<h1>
|
||||||
|
<strong>{certTitle}</strong>
|
||||||
|
</h1>
|
||||||
|
<h4>
|
||||||
|
Developer Certification, representing approximately{' '}
|
||||||
|
{completionTime} hours of coursework
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
<footer>
|
||||||
|
<div className='row signatures'>
|
||||||
|
<Image
|
||||||
|
alt="Quincy Larson's Signature"
|
||||||
|
src={
|
||||||
|
'https://cdn.freecodecamp.org' +
|
||||||
|
'/platform/english/images/quincy-larson-signature.svg'
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<p>
|
||||||
|
<strong>Quincy Larson</strong>
|
||||||
|
</p>
|
||||||
|
<p>Executive Director, freeCodeCamp.org</p>
|
||||||
|
</div>
|
||||||
|
<Row>
|
||||||
|
<p className='verify'>Verify this certification at {certURL}</p>
|
||||||
|
</Row>
|
||||||
|
</footer>
|
||||||
|
</Row>
|
||||||
|
</Grid>
|
||||||
|
{signedInUserName === username ? shareCertBtns : ''}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
ShowCertification.displayName = 'ShowCertification';
|
ShowCertification.displayName = 'ShowCertification';
|
||||||
ShowCertification.propTypes = propTypes;
|
ShowCertification.propTypes = propTypes;
|
||||||
|
Reference in New Issue
Block a user