feat(landing-page): Gatsby the landing page

This commit is contained in:
Bouncey
2018-08-24 12:30:29 +01:00
committed by mrugesh mohapatra
parent 57bfc029e4
commit 9f6a2e35f7
19 changed files with 891 additions and 566 deletions

View File

@ -1,6 +0,0 @@
export { default as ButtonSpacer } from './ButtonSpacer.jsx';
export { default as FullWidthRow } from './FullWidthRow.jsx';
export { default as SlimWidthRow } from './SlimWidthRow';
export { default as Loader } from './Loader.jsx';
export { default as SkeletonSprite } from './SkeletonSprite.jsx';
export { default as Spacer } from './Spacer.jsx';

930
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -94,7 +94,6 @@
"react": "^16.4.2",
"react-bootstrap": "^0.32.3",
"react-dom": "^16.4.2",
"react-fontawesome": "^1.6.1",
"react-freecodecamp-search": "^2.0.1",
"react-helmet": "^5.2.0",
"react-media": "^1.8.0",

View File

@ -1,19 +1,26 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Button } from 'react-bootstrap';
function Login() {
import './login.css';
function Login({ children, ...restProps }) {
return (
<Button
{...restProps}
bsStyle='default'
className='btn-cta'
href='https://www.freecodecamp.org/signin'
className={(restProps.block ? 'btn-cta-big' : '') + ' signup-btn btn-cta'}
href='/signin'
target='_blank'
>
Sign In
{children || 'Sign In'}
</Button>
);
}
Login.displayName = 'Login';
Login.propTypes = {
children: PropTypes.any
};
export default Login;

View File

@ -0,0 +1,36 @@
.btn-cta {
background-color: #ffac33;
background-image: linear-gradient(#ffcc4d, #ffac33);
border-color: #f1a02a;
color: #292f33 !important;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
max-height: 38px;
padding: 4px 12px;
}
.btn-cta-big {
max-height: 100%;
height: 70px;
font-size: 40px;
}
.signup-btn.btn {
background-color: #ffac33;
background-image: linear-gradient(#ffcc4d, #ffac33);
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffcc4d, endColorstr=#ffac33, GradientType=0)";
border-color: #f1a02a;
color: #292f33 !important;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
}
.signup-btn:hover, .signup-btn:focus {
background-color: #e99110;
background-image: linear-gradient(#ffcc4d, #e99110);
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffcc4d, endColorstr=#e99110, GradientType=0)";
border-color: #ec8b11;
color: #292f33 !important;
}
.signup-btn:active {
background-color: #f2a330;
background-image: none;
box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.3);
}

View File

@ -15,7 +15,7 @@ function Header({ disableSettings }) {
<a className='home-link' href='https://www.freecodecamp.org'>
<NavLogo />
</a>
<FCCSearch />
{disableSettings ? null : <FCCSearch />}
<ul id='top-right-nav'>
<li>
<Link to='/'>Curriculum</Link>

View File

@ -0,0 +1,7 @@
import React from 'react';
const Spacer = () => (
<div className='spacer' style={{ marginTop: '50px', marginBottom: '50px' }} />
);
export default Spacer;

View File

@ -0,0 +1,6 @@
export { default as ButtonSpacer } from './ButtonSpacer';
export { default as FullWidthRow } from './FullWidthRow';
export { default as SlimWidthRow } from './SlimWidthRow';
export { default as Loader } from './Loader';
export { default as SkeletonSprite } from './SkeletonSprite';
export { default as Spacer } from './Spacer';

View File

@ -60,7 +60,7 @@ dfn {
}
h1 {
font-size: 2em;
margin: .67em 0;
margin: 0.67em 0;
}
mark {
background-color: #ff0;
@ -77,10 +77,10 @@ sup {
vertical-align: baseline;
}
sub {
bottom: -.25em;
bottom: -0.25em;
}
sup {
top: -.5em;
top: -0.5em;
}
img {
border-style: none;
@ -122,29 +122,29 @@ button,
select {
text-transform: none;
}
[type=reset],
[type=submit],
[type='reset'],
[type='submit'],
button,
html [type=button] {
html [type='button'] {
-webkit-appearance: button;
}
[type=button]::-moz-focus-inner,
[type=reset]::-moz-focus-inner,
[type=submit]::-moz-focus-inner,
[type='button']::-moz-focus-inner,
[type='reset']::-moz-focus-inner,
[type='submit']::-moz-focus-inner,
button::-moz-focus-inner {
border-style: none;
padding: 0;
}
[type=button]:-moz-focusring,
[type=reset]:-moz-focusring,
[type=submit]:-moz-focusring,
[type='button']:-moz-focusring,
[type='reset']:-moz-focusring,
[type='submit']:-moz-focusring,
button:-moz-focusring {
outline: 1px dotted ButtonText;
}
fieldset {
border: 1px solid silver;
margin: 0 2px;
padding: .35em .625em .75em;
padding: 0.35em 0.625em 0.75em;
}
legend {
box-sizing: border-box;
@ -157,26 +157,26 @@ legend {
textarea {
overflow: auto;
}
[type=checkbox],
[type=radio] {
[type='checkbox'],
[type='radio'] {
box-sizing: border-box;
padding: 0;
}
[type=number]::-webkit-inner-spin-button,
[type=number]::-webkit-outer-spin-button {
[type='number']::-webkit-inner-spin-button,
[type='number']::-webkit-outer-spin-button {
height: auto;
}
[type=search] {
[type='search'] {
-webkit-appearance: textfield;
outline-offset: -2px;
}
[type=search]::-webkit-search-cancel-button,
[type=search]::-webkit-search-decoration {
[type='search']::-webkit-search-cancel-button,
[type='search']::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-input-placeholder {
color: inherit;
opacity: .54;
opacity: 0.54;
}
::-webkit-file-upload-button {
-webkit-appearance: button;
@ -202,10 +202,10 @@ body {
font-weight: normal;
word-wrap: break-word;
font-kerning: normal;
-moz-font-feature-settings: "kern", "liga", "clig", "calt";
-ms-font-feature-settings: "kern", "liga", "clig", "calt";
-webkit-font-feature-settings: "kern", "liga", "clig", "calt";
font-feature-settings: "kern", "liga", "clig", "calt";
-moz-font-feature-settings: 'kern', 'liga', 'clig', 'calt';
-ms-font-feature-settings: 'kern', 'liga', 'clig', 'calt';
-webkit-font-feature-settings: 'kern', 'liga', 'clig', 'calt';
font-feature-settings: 'kern', 'liga', 'clig', 'calt';
}
img {
max-width: 100%;
@ -228,8 +228,8 @@ h1 {
padding-top: 0;
margin-bottom: 1.45rem;
color: inherit;
font-family: 'Lato', -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
font-family: 'Lato', -apple-system, BlinkMacSystemFont, Segoe UI, Roboto,
Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
font-weight: bold;
text-rendering: optimizeLegibility;
font-size: 2.25rem;
@ -245,8 +245,8 @@ h2 {
padding-top: 0;
margin-bottom: 1.45rem;
color: inherit;
font-family: 'Lato', -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
font-family: 'Lato', -apple-system, BlinkMacSystemFont, Segoe UI, Roboto,
Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
font-weight: bold;
text-rendering: optimizeLegibility;
font-size: 1.62671rem;
@ -262,8 +262,8 @@ h3 {
padding-top: 0;
margin-bottom: 1.45rem;
color: inherit;
font-family: 'Lato', -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
font-family: 'Lato', -apple-system, BlinkMacSystemFont, Segoe UI, Roboto,
Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
font-weight: bold;
text-rendering: optimizeLegibility;
font-size: 1.38316rem;
@ -279,8 +279,8 @@ h4 {
padding-top: 0;
margin-bottom: 1.45rem;
color: inherit;
font-family: 'Lato', -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
font-family: 'Lato', -apple-system, BlinkMacSystemFont, Segoe UI, Roboto,
Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
font-weight: bold;
text-rendering: optimizeLegibility;
font-size: 1rem;
@ -296,8 +296,8 @@ h5 {
padding-top: 0;
margin-bottom: 1.45rem;
color: inherit;
font-family: 'Lato', -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
font-family: 'Lato', -apple-system, BlinkMacSystemFont, Segoe UI, Roboto,
Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
font-weight: bold;
text-rendering: optimizeLegibility;
font-size: 0.85028rem;
@ -313,8 +313,8 @@ h6 {
padding-top: 0;
margin-bottom: 1.45rem;
color: inherit;
font-family: 'Lato', -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
font-family: 'Lato', -apple-system, BlinkMacSystemFont, Segoe UI, Roboto,
Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
font-weight: bold;
text-rendering: optimizeLegibility;
font-size: 0.78405rem;
@ -573,10 +573,10 @@ td,
th {
text-align: left;
border-bottom: 1px solid hsla(0, 0%, 0%, 0.12);
font-feature-settings: "tnum";
-moz-font-feature-settings: "tnum";
-ms-font-feature-settings: "tnum";
-webkit-font-feature-settings: "tnum";
font-feature-settings: 'tnum';
-moz-font-feature-settings: 'tnum';
-ms-font-feature-settings: 'tnum';
-webkit-font-feature-settings: 'tnum';
padding-left: 0.96667rem;
padding-right: 0.96667rem;
padding-top: 0.725rem;
@ -594,8 +594,8 @@ tt,
code {
background-color: hsla(0, 0%, 0%, 0.04);
border-radius: 3px;
font-family: "SFMono-Regular", Consolas, "Roboto Mono", "Droid Sans Mono",
"Liberation Mono", Menlo, Courier, monospace;
font-family: 'SFMono-Regular', Consolas, 'Roboto Mono', 'Droid Sans Mono',
'Liberation Mono', Menlo, Courier, monospace;
padding: 0;
padding-top: 0.2em;
padding-bottom: 0.2em;
@ -609,16 +609,25 @@ code:after,
tt:before,
tt:after {
letter-spacing: -0.2em;
content: " ";
content: ' ';
}
pre code:before,
pre code:after,
pre tt:before,
pre tt:after {
content: "";
content: '';
}
@media only screen and (max-width: 480px) {
html {
font-size: 100%;
}
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: 400;
}

View File

@ -10,7 +10,8 @@ import Header from './Header';
import './layout.css';
const mapStateToProps = () => ({});
const mapDispatchToProps = dispatch => bindActionCreators({fetchUser}, dispatch);
const mapDispatchToProps = dispatch =>
bindActionCreators({ fetchUser }, dispatch);
class Layout extends Component {
constructor(props) {
@ -42,21 +43,9 @@ class Layout extends Component {
{ name: 'keywords', content: 'sample, something' }
]}
title={data.site.siteMetadata.title}
>
<html lang='en' />
<link href='https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css' rel='stylesheet' />
</Helmet>
<Header disableSettings={true} siteTitle={data.site.siteMetadata.title} />
<div
style={{
margin: '38px auto 0',
maxWidth: 960,
padding: '0px 1.0875rem 1.45rem',
paddingTop: 0
}}
>
{children}
</div>
/>
<Header disableSettings={disableSettings} />
<div style={{ marginTop: '38px' }}>{children}</div>
</Fragment>
)}
/>
@ -65,7 +54,12 @@ class Layout extends Component {
}
Layout.propTypes = {
children: PropTypes.node.isRequired
children: PropTypes.node.isRequired,
disableSettings: PropTypes.bool,
fetchUser: PropTypes.func.isRequired
};
export default connect(mapStateToProps, mapDispatchToProps)(Layout);
export default connect(
mapStateToProps,
mapDispatchToProps
)(Layout);

45
src/html.js Normal file
View File

@ -0,0 +1,45 @@
import React from 'react';
import PropTypes from 'prop-types';
export default class HTML extends React.Component {
render() {
return (
<html {...this.props.htmlAttributes} land='en'>
<head>
<meta charSet='utf-8' />
<meta content='ie=edge' httpEquiv='x-ua-compatible' />
<meta
content='width=device-width, initial-scale=1, shrink-to-fit=no'
name='viewport'
/>
<link
href={
'https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/css/' +
'bootstrap.min.css'
}
rel='stylesheet'
/>
{this.props.headComponents}
</head>
<body {...this.props.bodyAttributes}>
{this.props.preBodyComponents}
<div
dangerouslySetInnerHTML={{ __html: this.props.body }}
id='___gatsby'
key={'body'}
/>
{this.props.postBodyComponents}
</body>
</html>
);
}
}
HTML.propTypes = {
body: PropTypes.string,
bodyAttributes: PropTypes.object,
headComponents: PropTypes.array,
htmlAttributes: PropTypes.object,
postBodyComponents: PropTypes.array,
preBodyComponents: PropTypes.array
};

55
src/pages/index.css Normal file
View File

@ -0,0 +1,55 @@
.black-text {
color: #333;
font-weight: 400;
font-size: 40px;
}
.landing-heading {
font-size: 50px !important;
font-weight: 400;
}
.large-p {
font-size: 24px;
}
.img-center {
margin: 0 auto;
}
.landing-icon {
height: 100px;
width: 100px;
}
.landing-skill-icon {
color: #006400;
margin-top: -15px;
padding-bottom: 15px;
height: 150px;
margin-bottom: 1.45rem;
}
.testimonial-image {
border-radius: 5px;
height: 200px;
width: 200px;
color: #006400;
}
.testimonial-copy {
text-align: center;
font-size: 18px !important;
margin-left: 20px;
margin-right: 20px;
}
@media (min-width: 991px) and (max-width: 1199px) {
.testimonial-copy {
height: 150px;
}
}
@media (min-width: 1200px) {
.testimonial-copy {
height: 100px;
}
}

View File

@ -1,15 +1,220 @@
import React from 'react'
import { Link } from 'gatsby'
import React from 'react';
import { Grid, Row, Col, Image } from 'react-bootstrap';
import FontAwesomeIcon from '@fortawesome/react-fontawesome';
import {
faHtml5,
faCss3Alt,
faJs,
faGithub,
faNodeJs,
faReact
} from '@fortawesome/free-brands-svg-icons';
import { faDatabase } from '@fortawesome/free-solid-svg-icons';
import Layout from '../components/layout'
import { Spacer } from '../components/helpers';
import Layout from '../components/layout';
import Login from '../components/Header/components/Login';
import './index.css';
const BigCallToAction = () => (
<Row>
<Col sm={8} smOffset={2} xs={12}>
<Login block={true}>Start coding (it's free)</Login>
</Col>
</Row>
);
const IndexPage = () => (
<Layout>
<h1>Hi people</h1>
<p>Welcome to your new Gatsby site.</p>
<p>Now go build something great.</p>
<Link to="/page-2/">Go to page 2</Link>
<Layout disableSettings={true}>
<Grid className='text-center'>
<Row>
<h1 className='landing-heading'>Learn to code for free.</h1>
<Spacer />
<Col md={4} sm={12}>
<Image
alt={
'Get great references and connections to start your software ' +
'engineer career'
}
className='landing-icon img-center'
responsive={true}
src={
'https://s3.amazonaws.com/freecodecamp/landing-icon-community.svg'
}
/>
<p className='large-p'>
Join a supportive community of millions of coders.
</p>
</Col>
<Col md={4} sm={12}>
<Image
alt='Help nonprofits with bro bono code projects'
className='landing-icon img-center'
responsive={true}
src={
'https://s3.amazonaws.com/freecodecamp/landing-icon-' +
'certificate.svg'
}
/>
<p className='large-p'>
Build projects and earn free certifications.
</p>
</Col>
<Col md={4} sm={12}>
<Image
alt={
'Get hired as a developer and start your software engineer career'
}
className='landing-icon img-center'
responsive={true}
src={
'https://s3.amazonaws.com/freecodecamp/landing-icon-' +
'experience.svg'
}
/>
<p className='large-p'>Get experience by coding for nonprofits.</p>
</Col>
</Row>
<Spacer />
<Spacer />
<BigCallToAction />
<Spacer />
<h2>As featured in:</h2>
<Image
className='img-center'
responsive={true}
src='https://s3.amazonaws.com/freecodecamp/as-seen-on.png'
/>
<Spacer />
<hr />
<Spacer />
<h2>Launch your developer career</h2>
<Spacer />
<Row>
<Col md={4} sm={12}>
<Image
alt="Meta's testimonial image"
className='testimonial-image img-center'
responsive={true}
src='https://i.imgur.com/nsvNixW.jpg'
/>
<p className='testimonial-copy'>
Through freeCodeCamp, I built a robust and highly functional web app
for a nonprofit. This led me to getting a fantastic job.
</p>
<h3>- Meta Hirschl</h3>
</Col>
<Col md={4} sm={12}>
<Image
alt="Brian's testimonial image"
className='testimonial-image img-center'
responsive={true}
src='https://i.imgur.com/QPpjPac.jpg'
/>
<p className='testimonial-copy'>
freeCodeCamp is a great way for disabled veterans like me to
retrain. I'm already receiving software engineering job offers.
</p>
<h3>- Brian Grant</h3>
</Col>
<Col md={4} sm={12}>
<Image
alt="Maxim Orlov's testimonial image"
className='testimonial-image img-center'
responsive={true}
src='https://i.imgur.com/wjlDigg.jpg'
/>
<p className='testimonial-copy'>
I joined freeCodeCamp with zero knowledge of web development. 6
months later, I landed my first job as a back end engineer.
</p>
<h3>- Maxim Orlov</h3>
</Col>
</Row>
<Spacer />
<hr />
<Spacer />
<h2>Learn powerful skills</h2>
<Spacer />
<Row className='text-center'>
<Col md={3} sm={6} xs={12}>
<FontAwesomeIcon
className='landing-skill-icon'
icon={faHtml5}
size='9x'
/>
<h2 className='black-text'>HTML5</h2>
</Col>
<Col md={3} sm={6} xs={12}>
<FontAwesomeIcon
className='landing-skill-icon'
icon={faCss3Alt}
size='9x'
/>
<h2 className='black-text'>CSS3</h2>
</Col>
<Col md={3} sm={6} xs={12}>
<FontAwesomeIcon
className='landing-skill-icon'
icon={faJs}
size='9x'
/>
<h2 className='black-text'>JavaScript</h2>
</Col>
<Col md={3} sm={6} xs={12}>
<FontAwesomeIcon
className='landing-skill-icon'
icon={faDatabase}
size='9x'
/>
<h2 className='black-text'>Databases</h2>
</Col>
</Row>
<Row className='text-center'>
<Col md={3} sm={6} xs={12}>
<FontAwesomeIcon
className='landing-skill-icon'
icon={faGithub}
size='9x'
/>
<h2 className='black-text'>Git & GitHub</h2>
</Col>
<Col md={3} sm={6} xs={12}>
<FontAwesomeIcon
className='landing-skill-icon'
icon={faNodeJs}
size='9x'
/>
<h2 className='black-text'>Node.js</h2>
</Col>
<Col md={3} sm={6} xs={12}>
<FontAwesomeIcon
className='landing-skill-icon'
icon={faReact}
size='9x'
/>
<h2 className='black-text'>React.js</h2>
</Col>
<Col md={3} sm={6} xs={12}>
<Image
alt='The D3.js Logo'
className='landing-skill-icon custom-landing-skill-icon'
src='https://s3.amazonaws.com/freecodecamp/d3-logo.svg'
/>
<h2 className='black-text'>D3.js</h2>
</Col>
</Row>
<Spacer />
<BigCallToAction />
<Spacer />
<Spacer />
<hr />
<Spacer />
<Spacer />
<Spacer />
</Grid>
</Layout>
)
);
export default IndexPage
export default IndexPage;