2019-01-23 00:53:35 +03:00
|
|
|
import React, { Fragment } from 'react';
|
2018-08-24 14:32:54 +01:00
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
import { bindActionCreators } from 'redux';
|
|
|
|
import { connect } from 'react-redux';
|
|
|
|
import { createSelector } from 'reselect';
|
2018-09-05 13:39:23 +01:00
|
|
|
import { Grid, Row, Col, Button } from '@freecodecamp/react-bootstrap';
|
2018-09-14 16:14:35 +01:00
|
|
|
import Helmet from 'react-helmet';
|
2018-08-24 14:32:54 +01:00
|
|
|
|
|
|
|
import { Loader, Spacer } from '../components/helpers';
|
2018-11-20 10:52:22 +00:00
|
|
|
import CurrentChallengeLink from '../components/helpers/CurrentChallengeLink';
|
2018-11-29 13:29:07 +00:00
|
|
|
import Supporters from '../components/Supporters';
|
2018-10-24 00:24:48 +01:00
|
|
|
import {
|
|
|
|
userSelector,
|
|
|
|
userFetchStateSelector,
|
2018-11-29 14:24:17 +00:00
|
|
|
isSignedInSelector,
|
|
|
|
activeDonationsSelector
|
2018-10-24 00:24:48 +01:00
|
|
|
} from '../redux';
|
2018-08-24 14:32:54 +01:00
|
|
|
import { randomQuote } from '../utils/get-words';
|
2019-02-14 15:27:05 +03:00
|
|
|
import createRedirect from '../components/createRedirect';
|
|
|
|
import RedirectHome from '../components/RedirectHome';
|
2018-08-24 14:32:54 +01:00
|
|
|
|
|
|
|
import './welcome.css';
|
|
|
|
|
|
|
|
const propTypes = {
|
2018-11-29 16:10:48 +00:00
|
|
|
activeDonations: PropTypes.number,
|
2018-08-24 14:32:54 +01:00
|
|
|
fetchState: PropTypes.shape({
|
|
|
|
pending: PropTypes.bool,
|
|
|
|
complete: PropTypes.bool,
|
|
|
|
errored: PropTypes.bool
|
|
|
|
}),
|
2018-10-24 00:24:48 +01:00
|
|
|
isSignedIn: PropTypes.bool,
|
2018-08-24 14:32:54 +01:00
|
|
|
user: PropTypes.shape({
|
2018-08-25 00:24:19 +01:00
|
|
|
acceptedPrivacyTerms: PropTypes.bool,
|
2018-08-24 14:32:54 +01:00
|
|
|
completedCertCount: PropTypes.number,
|
2019-07-19 19:28:04 +05:30
|
|
|
completedChallengeCount: PropTypes.number,
|
2018-11-29 13:29:07 +00:00
|
|
|
completedLegacyCertCount: PropTypes.number,
|
2019-07-19 19:28:04 +05:30
|
|
|
completedProjectCount: PropTypes.number,
|
|
|
|
isDonating: PropTypes.bool,
|
|
|
|
name: PropTypes.string,
|
|
|
|
username: PropTypes.string
|
2018-08-24 14:32:54 +01:00
|
|
|
})
|
|
|
|
};
|
|
|
|
|
|
|
|
const mapStateToProps = createSelector(
|
|
|
|
userFetchStateSelector,
|
2018-10-24 00:24:48 +01:00
|
|
|
isSignedInSelector,
|
2018-08-24 14:32:54 +01:00
|
|
|
userSelector,
|
2018-11-29 14:24:17 +00:00
|
|
|
activeDonationsSelector,
|
|
|
|
(fetchState, isSignedIn, user, activeDonations) => ({
|
|
|
|
activeDonations,
|
|
|
|
fetchState,
|
|
|
|
isSignedIn,
|
|
|
|
user
|
|
|
|
})
|
2018-08-24 14:32:54 +01:00
|
|
|
);
|
|
|
|
const mapDispatchToProps = dispatch => bindActionCreators({}, dispatch);
|
2019-02-14 15:27:05 +03:00
|
|
|
const RedirectAcceptPrivacyTerm = createRedirect('/accept-privacy-terms');
|
2018-08-24 14:32:54 +01:00
|
|
|
|
|
|
|
function Welcome({
|
|
|
|
fetchState: { pending, complete },
|
2018-10-24 00:24:48 +01:00
|
|
|
isSignedIn,
|
2018-08-24 14:32:54 +01:00
|
|
|
user: {
|
2018-08-25 00:24:19 +01:00
|
|
|
acceptedPrivacyTerms,
|
|
|
|
name = '',
|
2018-10-24 00:24:48 +01:00
|
|
|
completedChallengeCount: completedChallenges = 0,
|
2018-08-25 00:24:19 +01:00
|
|
|
completedProjectCount = 0,
|
|
|
|
completedCertCount = 0,
|
2018-11-29 13:29:07 +00:00
|
|
|
completedLegacyCertCount: completedLegacyCerts = 0,
|
|
|
|
isDonating
|
2018-11-29 14:24:17 +00:00
|
|
|
},
|
|
|
|
activeDonations
|
2018-08-24 14:32:54 +01:00
|
|
|
}) {
|
|
|
|
if (pending && !complete) {
|
2019-02-26 12:00:36 +00:00
|
|
|
return <Loader fullScreen={true} />;
|
2018-08-24 14:32:54 +01:00
|
|
|
}
|
|
|
|
|
2018-10-24 00:24:48 +01:00
|
|
|
if (!isSignedIn) {
|
2019-02-14 15:27:05 +03:00
|
|
|
return <RedirectHome />;
|
2018-10-24 00:24:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (isSignedIn && !acceptedPrivacyTerms) {
|
2019-02-14 15:27:05 +03:00
|
|
|
return <RedirectAcceptPrivacyTerm />;
|
2018-08-25 00:24:19 +01:00
|
|
|
}
|
|
|
|
|
2018-08-24 14:32:54 +01:00
|
|
|
const { quote, author } = randomQuote();
|
|
|
|
return (
|
2019-01-23 00:53:35 +03:00
|
|
|
<Fragment>
|
2018-09-14 16:14:35 +01:00
|
|
|
<Helmet>
|
2019-02-27 10:12:06 +03:00
|
|
|
<title>Welcome | freeCodeCamp.org</title>
|
2018-09-14 16:14:35 +01:00
|
|
|
</Helmet>
|
2018-10-04 14:47:55 +01:00
|
|
|
<main>
|
2018-10-24 00:24:48 +01:00
|
|
|
<Grid className='text-center'>
|
|
|
|
<Row>
|
|
|
|
<Col xs={12}>
|
|
|
|
<Spacer />
|
|
|
|
<h1 className='big-heading'>Welcome {name ? name : 'Camper'}!</h1>
|
|
|
|
</Col>
|
|
|
|
</Row>
|
|
|
|
<Spacer />
|
2018-11-29 14:24:17 +00:00
|
|
|
<Supporters
|
|
|
|
activeDonations={activeDonations}
|
|
|
|
isDonating={isDonating}
|
|
|
|
/>
|
2018-11-29 13:29:07 +00:00
|
|
|
<Spacer size={2} />
|
2018-10-24 00:24:48 +01:00
|
|
|
<Spacer />
|
|
|
|
<Row className='quote-partial'>
|
|
|
|
<Col sm={10} smOffset={1} xs={12}>
|
|
|
|
<blockquote className='blockquote'>
|
|
|
|
<span>
|
|
|
|
<q>{quote}</q>
|
|
|
|
<footer className='quote-author blockquote-footer'>
|
|
|
|
<cite>{author}</cite>
|
|
|
|
</footer>
|
|
|
|
</span>
|
|
|
|
</blockquote>
|
|
|
|
</Col>
|
|
|
|
</Row>
|
|
|
|
<Spacer />
|
|
|
|
<Row>
|
|
|
|
<Col sm={8} smOffset={2} xs={12}>
|
|
|
|
<p className='stats'>
|
|
|
|
You have completed <span>{completedChallenges}</span> of{' '}
|
|
|
|
<span>1408</span> coding challenges.
|
|
|
|
</p>
|
|
|
|
<p className='stats'>
|
|
|
|
You have built <span>{completedProjectCount}</span> of{' '}
|
|
|
|
<span>30</span> projects.
|
|
|
|
</p>
|
|
|
|
{completedLegacyCerts ? (
|
|
|
|
<p className='stats'>
|
|
|
|
You have earned <span>{completedLegacyCerts}</span> of{' '}
|
|
|
|
<span>4</span> legacy certifications.
|
|
|
|
</p>
|
|
|
|
) : null}
|
2018-08-24 14:32:54 +01:00
|
|
|
<p className='stats'>
|
2018-10-24 00:24:48 +01:00
|
|
|
You have earned <span>{completedCertCount}</span> of{' '}
|
|
|
|
<span>6</span> certifications.
|
2018-08-24 14:32:54 +01:00
|
|
|
</p>
|
2018-10-24 00:24:48 +01:00
|
|
|
</Col>
|
|
|
|
</Row>
|
|
|
|
<Spacer />
|
|
|
|
<Row>
|
2019-02-25 22:33:42 +05:30
|
|
|
<Col sm={6} smOffset={3} xs={12}>
|
2019-01-23 00:53:35 +03:00
|
|
|
<CurrentChallengeLink>
|
|
|
|
<Button block={true} bsStyle='primary' className='btn-cta-big'>
|
|
|
|
Go to my next challenge
|
|
|
|
</Button>
|
|
|
|
</CurrentChallengeLink>
|
2018-10-24 00:24:48 +01:00
|
|
|
</Col>
|
|
|
|
</Row>
|
|
|
|
<Spacer size={4} />
|
|
|
|
</Grid>
|
2018-10-04 14:47:55 +01:00
|
|
|
</main>
|
2019-01-23 00:53:35 +03:00
|
|
|
</Fragment>
|
2018-08-24 14:32:54 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
Welcome.displayName = 'Welcome';
|
|
|
|
Welcome.propTypes = propTypes;
|
|
|
|
|
|
|
|
export default connect(
|
|
|
|
mapStateToProps,
|
|
|
|
mapDispatchToProps
|
|
|
|
)(Welcome);
|