import React from 'react'; import PropTypes from 'prop-types'; import { createSelector } from 'reselect'; import { graphql } from 'gatsby'; import Helmet from 'react-helmet'; import { connect } from 'react-redux'; import { Row, Col } from '@freecodecamp/react-bootstrap'; import { userFetchStateSelector, isSignedInSelector } from '../redux'; import LearnLayout from '../components/layouts/Learn'; import Login from '../components/Header/components/Login'; import { Link, Spacer, Loader } from '../components/helpers'; import Map from '../components/Map'; import './learn.css'; import { ChallengeNode, AllChallengeNode, AllMarkdownRemark } from '../redux/propTypes'; const mapStateToProps = createSelector( userFetchStateSelector, isSignedInSelector, (fetchState, isSignedIn) => ({ fetchState, isSignedIn }) ); const propTypes = { data: PropTypes.shape({ challengeNode: ChallengeNode, allChallengeNode: AllChallengeNode, allMarkdownRemark: AllMarkdownRemark }), fetchState: PropTypes.shape({ pending: PropTypes.bool, complete: PropTypes.bool, errored: PropTypes.bool }), isSignedIn: PropTypes.bool }; const BigCallToAction = isSignedIn => { if (!isSignedIn) { return ( <> Sign in to save progress. ); } return ''; }; const IndexPage = ({ fetchState: { pending, complete }, isSignedIn, data: { challengeNode: { fields: { slug } }, allChallengeNode: { edges }, allMarkdownRemark: { edges: mdEdges } } }) => { if (pending && !complete) { return ; } return (
{BigCallToAction(isSignedIn)}

Welcome to the freeCodeCamp curriculum

We have thousands of coding lessons to help you improve your skills.

You can earn each certification by completing its 5 final projects.

And yes - all of this is 100% free, thanks to the thousands of campers who{' '} donate {' '} to our nonprofit.

If you are new to coding, we recommend you{' '} start at the beginning.

node)} nodes={edges .map(({ node }) => node) .filter(({ isPrivate }) => !isPrivate)} />
); }; IndexPage.displayName = 'IndexPage'; IndexPage.propTypes = propTypes; export default connect(mapStateToProps)(IndexPage); export const query = graphql` query FirstChallenge { challengeNode(order: { eq: 0 }, challengeOrder: { eq: 0 }) { fields { slug } } allChallengeNode(sort: { fields: [superOrder, order, challengeOrder] }) { edges { node { fields { slug blockName } id block title isRequired superBlock dashedName } } } allMarkdownRemark(filter: { frontmatter: { block: { ne: null } } }) { edges { node { frontmatter { title block } fields { slug } } } } } `;