2018-08-24 14:32:54 +01:00
|
|
|
import React from 'react';
|
|
|
|
import PropTypes from 'prop-types';
|
2018-09-07 13:33:32 +01:00
|
|
|
import { navigate } from 'gatsby';
|
2018-08-24 14:32:54 +01:00
|
|
|
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-09-30 11:37:19 +01:00
|
|
|
import Layout from '../components/layouts/Default';
|
2018-08-24 14:32:54 +01:00
|
|
|
import { userSelector, userFetchStateSelector } from '../redux';
|
|
|
|
import { randomQuote } from '../utils/get-words';
|
|
|
|
|
|
|
|
import './welcome.css';
|
|
|
|
|
|
|
|
const propTypes = {
|
|
|
|
fetchState: PropTypes.shape({
|
|
|
|
pending: PropTypes.bool,
|
|
|
|
complete: PropTypes.bool,
|
|
|
|
errored: PropTypes.bool
|
|
|
|
}),
|
|
|
|
user: PropTypes.shape({
|
2018-08-25 00:24:19 +01:00
|
|
|
acceptedPrivacyTerms: PropTypes.bool,
|
2018-08-24 14:32:54 +01:00
|
|
|
username: PropTypes.string,
|
|
|
|
completedChallengeCount: PropTypes.number,
|
|
|
|
completedProjectCount: PropTypes.number,
|
|
|
|
completedCertCount: PropTypes.number,
|
|
|
|
completedLegacyCertCount: PropTypes.number
|
|
|
|
})
|
|
|
|
};
|
|
|
|
|
|
|
|
const mapStateToProps = createSelector(
|
|
|
|
userFetchStateSelector,
|
|
|
|
userSelector,
|
|
|
|
(fetchState, user) => ({ fetchState, user })
|
|
|
|
);
|
|
|
|
const mapDispatchToProps = dispatch => bindActionCreators({}, dispatch);
|
|
|
|
|
|
|
|
function Welcome({
|
|
|
|
fetchState: { pending, complete },
|
|
|
|
user: {
|
2018-08-25 00:24:19 +01:00
|
|
|
acceptedPrivacyTerms,
|
|
|
|
name = '',
|
|
|
|
completedChallengeCount = 0,
|
|
|
|
completedProjectCount = 0,
|
|
|
|
completedCertCount = 0,
|
|
|
|
completedLegacyCertCount = 0
|
2018-08-24 14:32:54 +01:00
|
|
|
}
|
|
|
|
}) {
|
|
|
|
if (pending && !complete) {
|
|
|
|
return (
|
|
|
|
<Layout>
|
2018-09-07 13:33:32 +01:00
|
|
|
<div className='loader-wrapper'>
|
|
|
|
<Loader />
|
|
|
|
</div>
|
2018-08-24 14:32:54 +01:00
|
|
|
</Layout>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2018-08-25 00:24:19 +01:00
|
|
|
if (!acceptedPrivacyTerms) {
|
2018-09-07 13:33:32 +01:00
|
|
|
navigate('/accept-privacy-terms');
|
2018-08-25 00:24:19 +01:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2018-08-24 14:32:54 +01:00
|
|
|
const { quote, author } = randomQuote();
|
|
|
|
return (
|
|
|
|
<Layout>
|
2018-09-14 16:14:35 +01:00
|
|
|
<Helmet>
|
|
|
|
<title>Welcome {name ? name : 'Camper'} | freeCodeCamp.org</title>
|
|
|
|
</Helmet>
|
2018-10-04 14:47:55 +01:00
|
|
|
<main>
|
2018-08-24 14:32:54 +01:00
|
|
|
<Grid className='text-center'>
|
|
|
|
<Row>
|
|
|
|
<Col xs={12}>
|
|
|
|
<Spacer />
|
|
|
|
<h1 className='big-heading'>Welcome {name ? name : 'Camper'}!</h1>
|
|
|
|
</Col>
|
|
|
|
</Row>
|
|
|
|
<Spacer />
|
|
|
|
<Row>
|
|
|
|
<Col sm={8} smOffset={2} xs={12}>
|
|
|
|
<a
|
|
|
|
className='update-link'
|
|
|
|
href='/n/7gR5pBM-K?refsource=userhome'
|
|
|
|
target='_blank'
|
|
|
|
>
|
|
|
|
We're building a massive open dataset about new coders. Take the
|
|
|
|
2018 New Coder Survey. It only takes 5 minutes.
|
|
|
|
</a>
|
|
|
|
</Col>
|
|
|
|
</Row>
|
|
|
|
<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>{completedChallengeCount}</span> of{' '}
|
|
|
|
<span>1408</span> coding challenges.
|
|
|
|
</p>
|
|
|
|
<p className='stats'>
|
|
|
|
You have built <span>{completedProjectCount}</span> of{' '}
|
|
|
|
<span>30</span> projects.
|
|
|
|
</p>
|
|
|
|
{completedLegacyCertCount ? (
|
|
|
|
<p className='stats'>
|
|
|
|
You have earned <span>{completedLegacyCertCount}</span> of{' '}
|
|
|
|
<span>4</span> legacy certifications.
|
|
|
|
</p>
|
|
|
|
) : null}
|
|
|
|
<p className='stats'>
|
|
|
|
You have earned <span>{completedCertCount}</span> of{' '}
|
|
|
|
<span>6</span> certifications.
|
|
|
|
</p>
|
|
|
|
</Col>
|
|
|
|
</Row>
|
|
|
|
<Spacer />
|
|
|
|
<Row>
|
|
|
|
<Col sm={8} smOffset={2} xs={12}>
|
|
|
|
<Button block={true} bsStyle='primary' className='btn-cta-big'>
|
|
|
|
Go to my next challenge
|
|
|
|
</Button>
|
|
|
|
</Col>
|
|
|
|
</Row>
|
2018-09-14 16:14:35 +01:00
|
|
|
<Spacer size={4} />
|
2018-08-24 14:32:54 +01:00
|
|
|
</Grid>
|
2018-10-04 14:47:55 +01:00
|
|
|
</main>
|
2018-08-24 14:32:54 +01:00
|
|
|
</Layout>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
Welcome.displayName = 'Welcome';
|
|
|
|
Welcome.propTypes = propTypes;
|
|
|
|
|
|
|
|
export default connect(
|
|
|
|
mapStateToProps,
|
|
|
|
mapDispatchToProps
|
|
|
|
)(Welcome);
|