feat: add intro text to email sign up page (#39409)
Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com> Co-authored-by: Mrugesh Mohapatra <1884376+raisedadead@users.noreply.github.com>
This commit is contained in:
@ -246,9 +246,7 @@ const updatePrivacyTerms = (req, res, next) => {
|
|||||||
}
|
}
|
||||||
return res.status(200).json({
|
return res.status(200).json({
|
||||||
type: 'success',
|
type: 'success',
|
||||||
message:
|
message: `We have updated your preferences.`
|
||||||
'We have updated your preferences. ' +
|
|
||||||
'You can now continue using freeCodeCamp!'
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
70
client/src/components/Intro/components/IntroDescription.js
Normal file
70
client/src/components/Intro/components/IntroDescription.js
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Link, Spacer } from '../../helpers';
|
||||||
|
import { Col } from '@freecodecamp/react-bootstrap';
|
||||||
|
import { forumLocation } from '../../../../config/env.json';
|
||||||
|
|
||||||
|
import '../intro.css';
|
||||||
|
|
||||||
|
function IntroDescription() {
|
||||||
|
return (
|
||||||
|
<Col
|
||||||
|
className='intro-description'
|
||||||
|
md={8}
|
||||||
|
mdOffset={2}
|
||||||
|
sm={10}
|
||||||
|
smOffset={1}
|
||||||
|
xs={12}
|
||||||
|
>
|
||||||
|
<strong>Please slow down and read this.</strong>
|
||||||
|
<Spacer />
|
||||||
|
<p>freeCodeCamp is a proven path to your first software developer job.</p>
|
||||||
|
<p>
|
||||||
|
More than 40,000 people have gotten developer jobs after completing this
|
||||||
|
– including at big companies like Google and Microsoft.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
If you are new to programming, we recommend you start at the beginning
|
||||||
|
and earn these certifications in order.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
To earn each certification, build its 5 required projects and get all
|
||||||
|
their tests to pass.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
You can add these certifications to your résumé or LinkedIn. But more
|
||||||
|
important than the certifications is the practice you get along the way.
|
||||||
|
</p>
|
||||||
|
<p>If you feel overwhelmed, that is normal. Programming is hard.</p>
|
||||||
|
<p>Practice is the key. Practice, practice, practice.</p>
|
||||||
|
<p>
|
||||||
|
And this curriculum will give you thousands of hours of hands-on
|
||||||
|
programming practice.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
And if you want to learn more math and computer science theory, we also
|
||||||
|
have thousands of hours of video courses on{' '}
|
||||||
|
<Link className='inline' to='https://youtube.com/freecodecamp'>
|
||||||
|
freeCodeCamp's YouTube channel
|
||||||
|
</Link>
|
||||||
|
.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
If you want to get a developer job or freelance clients, programming
|
||||||
|
skills will be just part of the puzzle. You also need to build your
|
||||||
|
personal network and your reputation as a developer.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
You can do this on Twitter and GitHub, and also on{' '}
|
||||||
|
<Link className='inline' to={forumLocation}>
|
||||||
|
the freeCodeCamp forum
|
||||||
|
</Link>
|
||||||
|
.
|
||||||
|
</p>
|
||||||
|
<p>Happy coding.</p>
|
||||||
|
</Col>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
IntroDescription.displayName = 'IntroDescription';
|
||||||
|
|
||||||
|
export default IntroDescription;
|
@ -2,9 +2,9 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Link, Spacer, Loader, FullWidthRow } from '../helpers';
|
import { Link, Spacer, Loader, FullWidthRow } from '../helpers';
|
||||||
import { Row, Col } from '@freecodecamp/react-bootstrap';
|
import { Row, Col } from '@freecodecamp/react-bootstrap';
|
||||||
import { forumLocation } from '../../../config/env.json';
|
|
||||||
import { randomQuote } from '../../utils/get-words';
|
import { randomQuote } from '../../utils/get-words';
|
||||||
import CurrentChallengeLink from '../helpers/CurrentChallengeLink';
|
import CurrentChallengeLink from '../helpers/CurrentChallengeLink';
|
||||||
|
import IntroDescription from './components/IntroDescription';
|
||||||
|
|
||||||
import './intro.css';
|
import './intro.css';
|
||||||
import Login from '../Header/components/Login';
|
import Login from '../Header/components/Login';
|
||||||
@ -98,69 +98,16 @@ function Intro({
|
|||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Row className='intro-description'>
|
<Row>
|
||||||
<Col sm={10} smOffset={1} xs={12}>
|
<Col sm={10} smOffset={1} xs={12}>
|
||||||
<Spacer />
|
<Spacer />
|
||||||
<h1 className='big-heading text-center'>
|
<h1 className='big-heading text-center'>
|
||||||
Welcome to freeCodeCamp's curriculum.
|
Welcome to freeCodeCamp's curriculum.
|
||||||
</h1>
|
</h1>
|
||||||
</Col>
|
</Col>
|
||||||
<Col md={8} mdOffset={2} sm={10} smOffset={1} xs={12}>
|
<Spacer size={2} />
|
||||||
<Spacer size={2} />
|
<IntroDescription />
|
||||||
<strong>Please slow down and read this.</strong>
|
<Spacer />
|
||||||
<Spacer />
|
|
||||||
<p>
|
|
||||||
freeCodeCamp is a proven path to your first software developer
|
|
||||||
job.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
More than 40,000 people have gotten developer jobs after
|
|
||||||
completing this – including at big companies like Google and
|
|
||||||
Microsoft.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
If you are new to programming, we recommend you start at the
|
|
||||||
beginning and earn these certifications in order.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
To earn each certification, build its 5 required projects and get
|
|
||||||
all their tests to pass.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
You can add these certifications to your résumé or LinkedIn. But
|
|
||||||
more important than the certifications is the practice you get
|
|
||||||
along the way.
|
|
||||||
</p>
|
|
||||||
<p>If you feel overwhelmed, that is normal. Programming is hard.</p>
|
|
||||||
<p>Practice is the key. Practice, practice, practice.</p>
|
|
||||||
<p>
|
|
||||||
And this curriculum will give you thousands of hours of hands-on
|
|
||||||
programming practice.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
And if you want to learn more math and computer science theory, we
|
|
||||||
also have thousands of hours of video courses on{' '}
|
|
||||||
<Link className='inline' to='https://youtube.com/freecodecamp'>
|
|
||||||
freeCodeCamp's YouTube channel
|
|
||||||
</Link>
|
|
||||||
.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
If you want to get a developer job or freelance clients,
|
|
||||||
programming skills will be just part of the puzzle. You also need
|
|
||||||
to build your personal network and your reputation as a developer.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
You can do this on Twitter and GitHub, and also on{' '}
|
|
||||||
<Link className='inline' to={forumLocation}>
|
|
||||||
the freeCodeCamp forum
|
|
||||||
</Link>
|
|
||||||
.
|
|
||||||
</p>
|
|
||||||
<p>Happy coding.</p>
|
|
||||||
<Spacer />
|
|
||||||
</Col>
|
|
||||||
|
|
||||||
<Col sm={8} smOffset={2} xs={12}>
|
<Col sm={8} smOffset={2} xs={12}>
|
||||||
<Login block={true}>
|
<Login block={true}>
|
||||||
Sign in to save your progress (it's free)
|
Sign in to save your progress (it's free)
|
||||||
|
12
client/src/pages/email-sign-up.css
Normal file
12
client/src/pages/email-sign-up.css
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
.email-sign-up strong,
|
||||||
|
.email-sign-up p {
|
||||||
|
font-family: 'Lato', sans-serif;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 500px) {
|
||||||
|
.email-sign-up strong,
|
||||||
|
.email-sign-up p {
|
||||||
|
font-size: 1.22rem;
|
||||||
|
}
|
||||||
|
}
|
@ -3,23 +3,18 @@ import PropTypes from 'prop-types';
|
|||||||
import { bindActionCreators } from 'redux';
|
import { bindActionCreators } from 'redux';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import SectionHeader from '../components/settings/SectionHeader';
|
import SectionHeader from '../components/settings/SectionHeader';
|
||||||
|
import IntroDescription from '../components/Intro/components/IntroDescription';
|
||||||
|
|
||||||
import {
|
import { Row, Col, Button, Grid } from '@freecodecamp/react-bootstrap';
|
||||||
Row,
|
|
||||||
Col,
|
|
||||||
Button,
|
|
||||||
FormGroup,
|
|
||||||
ControlLabel,
|
|
||||||
Grid,
|
|
||||||
Checkbox
|
|
||||||
} from '@freecodecamp/react-bootstrap';
|
|
||||||
import Helmet from 'react-helmet';
|
import Helmet from 'react-helmet';
|
||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
|
|
||||||
import { ButtonSpacer } from '../components/helpers';
|
import { ButtonSpacer, Spacer } from '../components/helpers';
|
||||||
import { acceptTerms, userSelector } from '../redux';
|
import { acceptTerms, userSelector } from '../redux';
|
||||||
import createRedirect from '../components/createRedirect';
|
import createRedirect from '../components/createRedirect';
|
||||||
|
|
||||||
|
import './email-sign-up.css';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
acceptTerms: PropTypes.func.isRequired,
|
acceptTerms: PropTypes.func.isRequired,
|
||||||
acceptedPrivacyTerms: PropTypes.bool,
|
acceptedPrivacyTerms: PropTypes.bool,
|
||||||
@ -37,30 +32,6 @@ const mapDispatchToProps = dispatch =>
|
|||||||
const RedirectToLearn = createRedirect('/learn');
|
const RedirectToLearn = createRedirect('/learn');
|
||||||
|
|
||||||
class AcceptPrivacyTerms extends Component {
|
class AcceptPrivacyTerms extends Component {
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
quincyEmail: false
|
|
||||||
};
|
|
||||||
this.createHandleChange = this.createHandleChange.bind(this);
|
|
||||||
this.handleSubmit = this.handleSubmit.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
createHandleChange(prop) {
|
|
||||||
return () =>
|
|
||||||
this.setState(prevState => ({
|
|
||||||
[prop]: !prevState[prop]
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
handleSubmit(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
const { quincyEmail } = this.state;
|
|
||||||
|
|
||||||
return this.props.acceptTerms(quincyEmail);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
// if a user navigates away from here we should set acceptedPrivacyTerms
|
// if a user navigates away from here we should set acceptedPrivacyTerms
|
||||||
// to true (so they do not get pulled back) without changing their email
|
// to true (so they do not get pulled back) without changing their email
|
||||||
@ -72,48 +43,67 @@ class AcceptPrivacyTerms extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onClick(isWeeklyEmailAccepted) {
|
||||||
|
this.props.acceptTerms(isWeeklyEmailAccepted);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { acceptedPrivacyTerms } = this.props;
|
const { acceptedPrivacyTerms } = this.props;
|
||||||
if (acceptedPrivacyTerms) {
|
if (acceptedPrivacyTerms) {
|
||||||
return <RedirectToLearn />;
|
return <RedirectToLearn />;
|
||||||
}
|
}
|
||||||
const { quincyEmail } = this.state;
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<Helmet>
|
<Helmet>
|
||||||
<title>Email Sign Up | freeCodeCamp.org</title>
|
<title>Email Sign Up | freeCodeCamp.org</title>
|
||||||
</Helmet>
|
</Helmet>
|
||||||
<Grid className='default-page-wrapper'>
|
<Grid className='default-page-wrapper email-sign-up'>
|
||||||
<SectionHeader>Email Sign Up</SectionHeader>
|
<SectionHeader>Email Sign Up</SectionHeader>
|
||||||
<Row>
|
<Row>
|
||||||
<Col sm={8} smOffset={2} xs={12}>
|
<IntroDescription />
|
||||||
<form onSubmit={this.handleSubmit}>
|
<Col md={8} mdOffset={2} sm={10} smOffset={1} xs={12}>
|
||||||
<FormGroup>
|
<hr />
|
||||||
<ControlLabel htmlFor='quincy-email'>
|
</Col>
|
||||||
Quincy's Emails
|
<Col md={8} mdOffset={2} sm={10} smOffset={1} xs={12}>
|
||||||
</ControlLabel>
|
<strong>
|
||||||
<ButtonSpacer />
|
- Quincy Larson, the teacher who founded freeCodeCamp.org
|
||||||
<Checkbox
|
</strong>
|
||||||
checked={quincyEmail}
|
<Spacer />
|
||||||
id='quincy-email'
|
<p>
|
||||||
inline={true}
|
By the way, each Friday I send an email with 5 links about
|
||||||
onChange={this.createHandleChange('quincyEmail')}
|
programming and computer science. I send these to about 4
|
||||||
>
|
million people. Would you like me to send this to you, too?
|
||||||
I want weekly emails from Quincy, freeCodeCamp.org's
|
</p>
|
||||||
founder.
|
<Spacer />
|
||||||
</Checkbox>
|
</Col>
|
||||||
</FormGroup>
|
|
||||||
<ButtonSpacer />
|
<Col md={4} mdOffset={2} sm={5} smOffset={1} xs={12}>
|
||||||
<Button
|
<Button
|
||||||
block={true}
|
block={true}
|
||||||
bsSize='lg'
|
bsSize='lg'
|
||||||
bsStyle='primary'
|
bsStyle='primary'
|
||||||
className='big-cta-btn'
|
className='big-cta-btn'
|
||||||
type='submit'
|
onClick={() => this.onClick(true)}
|
||||||
>
|
>
|
||||||
Continue to freeCodeCamp.org
|
Yes
|
||||||
</Button>
|
</Button>
|
||||||
</form>
|
<ButtonSpacer />
|
||||||
|
</Col>
|
||||||
|
<Col md={4} sm={5} xs={12}>
|
||||||
|
<Button
|
||||||
|
block={true}
|
||||||
|
bsSize='lg'
|
||||||
|
bsStyle='primary'
|
||||||
|
className='big-cta-btn'
|
||||||
|
onClick={() => this.onClick(false)}
|
||||||
|
>
|
||||||
|
No thanks
|
||||||
|
</Button>
|
||||||
|
<ButtonSpacer />
|
||||||
|
</Col>
|
||||||
|
<Col xs={12}>
|
||||||
|
<Spacer />
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
Reference in New Issue
Block a user