fix(client): do not unmount default layout on navigate

This commit is contained in:
Valeriy 2019-01-23 00:53:35 +03:00 committed by Stuart Taylor
parent a284b296fc
commit 28ee458ceb
16 changed files with 143 additions and 130 deletions

View File

@ -5,6 +5,7 @@ import { Provider } from 'react-redux';
import { createStore } from './src/redux/createStore'; import { createStore } from './src/redux/createStore';
import AppMountNotifier from './src/components/AppMountNotifier'; import AppMountNotifier from './src/components/AppMountNotifier';
import GuideNavContextProvider from './src/contexts/GuideNavigationContext'; import GuideNavContextProvider from './src/contexts/GuideNavigationContext';
import DefaultLayout from './src/components/layouts/Default';
const store = createStore(); const store = createStore();
@ -21,3 +22,23 @@ export const wrapRootElement = ({ element }) => {
wrapRootElement.propTypes = { wrapRootElement.propTypes = {
element: PropTypes.any element: PropTypes.any
}; };
export const wrapPageElement = ({ element, props }) => {
const {
location: { pathname }
} = props;
if (pathname === '/') {
return (
<DefaultLayout disableSettings={true} landingPage={true}>
{element}
</DefaultLayout>
);
}
return <DefaultLayout>{element}</DefaultLayout>;
};
wrapPageElement.propTypes = {
element: PropTypes.any,
location: PropTypes.objectOf({ pathname: PropTypes.string }),
props: PropTypes.any
};

View File

@ -7,6 +7,7 @@ import headComponents from './src/head';
import { createStore } from './src/redux/createStore'; import { createStore } from './src/redux/createStore';
import GuideNavContextProvider from './src/contexts/GuideNavigationContext'; import GuideNavContextProvider from './src/contexts/GuideNavigationContext';
import DefaultLayout from './src/components/layouts/Default';
const store = createStore(); const store = createStore();
@ -22,6 +23,26 @@ wrapRootElement.propTypes = {
element: PropTypes.any element: PropTypes.any
}; };
export const wrapPageElement = ({ element, props }) => {
const {
location: { pathname }
} = props;
if (pathname === '/') {
return (
<DefaultLayout disableSettings={true} landingPage={true}>
{element}
</DefaultLayout>
);
}
return <DefaultLayout>{element}</DefaultLayout>;
};
wrapPageElement.propTypes = {
element: PropTypes.any,
location: PropTypes.objectOf({ pathname: PropTypes.string }),
props: PropTypes.any
};
export const onRenderBody = ({ setHeadComponents, setPostBodyComponents }) => { export const onRenderBody = ({ setHeadComponents, setPostBodyComponents }) => {
setHeadComponents([...headComponents]); setHeadComponents([...headComponents]);
setPostBodyComponents( setPostBodyComponents(

View File

@ -5,7 +5,6 @@ import { connect } from 'react-redux';
import { isEmpty } from 'lodash'; import { isEmpty } from 'lodash';
import Loader from '../components/helpers/Loader'; import Loader from '../components/helpers/Loader';
import Layout from '../components/layouts/Default';
import { import {
userByNameSelector, userByNameSelector,
userProfileFetchStateSelector, userProfileFetchStateSelector,
@ -61,11 +60,9 @@ class ShowFourOhFour extends Component {
// We don't know if /:maybeUser is a user or not, we will show the loader // We don't know if /:maybeUser is a user or not, we will show the loader
// until we get a response from the API // until we get a response from the API
return ( return (
<Layout> <div className='loader-wrapper'>
<div className='loader-wrapper'> <Loader />
<Loader /> </div>
</div>
</Layout>
); );
} }
if (isEmpty(requestedUser)) { if (isEmpty(requestedUser)) {

View File

@ -1,4 +1,4 @@
import React from 'react'; import React, { Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
@ -16,7 +16,6 @@ import {
import { submitNewAbout, updateUserFlag, verifyCert } from '../redux/settings'; import { submitNewAbout, updateUserFlag, verifyCert } from '../redux/settings';
import { createFlashMessage } from '../components/Flash/redux'; import { createFlashMessage } from '../components/Flash/redux';
import Layout from '../components/layouts/Default';
import Spacer from '../components/helpers/Spacer'; import Spacer from '../components/helpers/Spacer';
import Loader from '../components/helpers/Loader'; import Loader from '../components/helpers/Loader';
import FullWidthRow from '../components/helpers/FullWidthRow'; import FullWidthRow from '../components/helpers/FullWidthRow';
@ -167,11 +166,9 @@ function ShowSettings(props) {
if (showLoading) { if (showLoading) {
return ( return (
<Layout> <div className='loader-wrapper'>
<div className='loader-wrapper'> <Loader />
<Loader /> </div>
</div>
</Layout>
); );
} }
@ -180,7 +177,7 @@ function ShowSettings(props) {
} }
return ( return (
<Layout> <Fragment>
<Helmet> <Helmet>
<title>Settings | freeCodeCamp.org</title> <title>Settings | freeCodeCamp.org</title>
</Helmet> </Helmet>
@ -264,7 +261,7 @@ function ShowSettings(props) {
{/* <DangerZone /> */} {/* <DangerZone /> */}
</main> </main>
</Grid> </Grid>
</Layout> </Fragment>
); );
} }

View File

@ -1,10 +1,9 @@
import React from 'react'; import React, { Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Grid, Panel, Button } from '@freecodecamp/react-bootstrap'; import { Grid, Panel, Button } from '@freecodecamp/react-bootstrap';
import Helmet from 'react-helmet'; import Helmet from 'react-helmet';
import env from '../../config/env.json'; import env from '../../config/env.json';
import Layout from '../components/layouts/Default';
import FullWidthRow from '../components/helpers/FullWidthRow'; import FullWidthRow from '../components/helpers/FullWidthRow';
import { Spacer } from '../components/helpers'; import { Spacer } from '../components/helpers';
@ -12,7 +11,7 @@ const { apiLocation } = env;
function ShowUnsubscribed({ unsubscribeId }) { function ShowUnsubscribed({ unsubscribeId }) {
return ( return (
<Layout> <Fragment>
<Helmet> <Helmet>
<title>You have been unsubscribed | freeCodeCamp.org</title> <title>You have been unsubscribed | freeCodeCamp.org</title>
</Helmet> </Helmet>
@ -41,7 +40,7 @@ function ShowUnsubscribed({ unsubscribeId }) {
) : null} ) : null}
</main> </main>
</Grid> </Grid>
</Layout> </Fragment>
); );
} }

View File

@ -1,4 +1,4 @@
import React, { Component } from 'react'; import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
import { Link, navigate } from 'gatsby'; import { Link, navigate } from 'gatsby';
@ -20,7 +20,6 @@ import {
userSelector, userSelector,
reportUser reportUser
} from '../redux'; } from '../redux';
import Layout from '../components/layouts/Default';
import { Spacer, Loader, FullWidthRow } from '../components/helpers'; import { Spacer, Loader, FullWidthRow } from '../components/helpers';
const propTypes = { const propTypes = {
@ -91,52 +90,48 @@ class ShowUser extends Component {
const { pending, complete, errored } = userFetchState; const { pending, complete, errored } = userFetchState;
if (pending && !complete) { if (pending && !complete) {
return ( return (
<Layout> <div className='loader-wrapper'>
<div className='loader-wrapper'> <Loader />
<Loader /> </div>
</div>
</Layout>
); );
} }
if ((complete || errored) && !isSignedIn) { if ((complete || errored) && !isSignedIn) {
this.setNavigationTimer(); this.setNavigationTimer();
return ( return (
<Layout> <main>
<main> <FullWidthRow>
<FullWidthRow> <Spacer />
<Spacer /> <Spacer />
<Spacer /> <Panel bsStyle='info'>
<Panel bsStyle='info'> <Panel.Heading>
<Panel.Heading> <Panel.Title componentClass='h3'>
<Panel.Title componentClass='h3'> You need to be signed in to report a user
You need to be signed in to report a user </Panel.Title>
</Panel.Title> </Panel.Heading>
</Panel.Heading> <Panel.Body className='text-center'>
<Panel.Body className='text-center'> <Spacer />
<Spacer /> <p>
<p> You will be redirected to sign in to freeCodeCamp.org
You will be redirected to sign in to freeCodeCamp.org automatically in 5 seconds
automatically in 5 seconds </p>
</p> <p>
<p> <Link to='/signin'>
<Link to='/signin'> Or you can here if you do not want to wait
Or you can here if you do not want to wait </Link>
</Link> </p>
</p> <Spacer />
<Spacer /> </Panel.Body>
</Panel.Body> </Panel>
</Panel> </FullWidthRow>
</FullWidthRow> </main>
</main>
</Layout>
); );
} }
const { textarea } = this.state; const { textarea } = this.state;
return ( return (
<Layout> <Fragment>
<Helmet> <Helmet>
<title>Report a users profile | freeCodeCamp.org</title> <title>Report a users profile | freeCodeCamp.org</title>
</Helmet> </Helmet>
@ -170,7 +165,7 @@ class ShowUser extends Component {
</form> </form>
</Col> </Col>
</FullWidthRow> </FullWidthRow>
</Layout> </Fragment>
); );
} }
} }

View File

@ -3,8 +3,6 @@ import Helmet from 'react-helmet';
import Spinner from 'react-spinkit'; import Spinner from 'react-spinkit';
import { Link } from 'gatsby'; import { Link } from 'gatsby';
import Layout from '../layouts/Default';
import notFoundLogo from '../../images/freeCodeCamp-404.svg'; import notFoundLogo from '../../images/freeCodeCamp-404.svg';
import { quotes } from '../../resources/quotes.json'; import { quotes } from '../../resources/quotes.json';
@ -30,33 +28,31 @@ class NotFoundPage extends Component {
render() { render() {
return ( return (
<Layout> <div className='notfound-page-wrapper'>
<div className='notfound-page-wrapper'> <Helmet title='Page Not Found | freeCodeCamp' />
<Helmet title='Page Not Found | freeCodeCamp' /> <img alt='404 Not Found' src={notFoundLogo} />
<img alt='404 Not Found' src={notFoundLogo} /> <h1>NOT FOUND</h1>
<h1>NOT FOUND</h1> {this.state.randomQuote ? (
{this.state.randomQuote ? ( <div>
<div> <p>
<p> We couldn&#x27;t find what you were looking for, but here is a
We couldn&#x27;t find what you were looking for, but here is a quote:
quote: </p>
<div className='quote-wrapper'>
<p className='quote'>
<span>&#8220;</span>
{this.state.randomQuote.quote}
</p> </p>
<div className='quote-wrapper'> <p className='author'>- {this.state.randomQuote.author}</p>
<p className='quote'>
<span>&#8220;</span>
{this.state.randomQuote.quote}
</p>
<p className='author'>- {this.state.randomQuote.author}</p>
</div>
</div> </div>
) : ( </div>
<Spinner color='#006400' name='ball-clip-rotate-multiple' /> ) : (
)} <Spinner color='#006400' name='ball-clip-rotate-multiple' />
<Link className='btn-curriculum' to='/learn'> )}
View the Curriculum <Link className='btn-curriculum' to='/learn'>
</Link> View the Curriculum
</div> </Link>
</Layout> </div>
); );
} }
} }

View File

@ -1,10 +1,9 @@
import React from 'react'; import React, { Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { StaticQuery, graphql } from 'gatsby'; import { StaticQuery, graphql } from 'gatsby';
import { Grid, Col, Row } from '@freecodecamp/react-bootstrap'; import { Grid, Col, Row } from '@freecodecamp/react-bootstrap';
import { NavigationContext } from '../../contexts/GuideNavigationContext'; import { NavigationContext } from '../../contexts/GuideNavigationContext';
import DefaultLayout from './Default';
import SideNav from './components/guide/SideNav'; import SideNav from './components/guide/SideNav';
import Spacer from '../helpers/Spacer'; import Spacer from '../helpers/Spacer';
@ -59,7 +58,7 @@ const Layout = ({ children }) => (
expandedState, expandedState,
toggleExpandedState toggleExpandedState
}) => ( }) => (
<DefaultLayout> <Fragment>
<Spacer size={2} /> <Spacer size={2} />
<Grid> <Grid>
<Row> <Row>
@ -87,7 +86,7 @@ const Layout = ({ children }) => (
</Col> </Col>
</Row> </Row>
</Grid> </Grid>
</DefaultLayout> </Fragment>
)} )}
</NavigationContext> </NavigationContext>
); );

View File

@ -1,7 +1,6 @@
import React, { Fragment } from 'react'; import React, { Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import DefaultLayout from './Default';
import DonationModal from '../Donation'; import DonationModal from '../Donation';
import 'prismjs/themes/prism.css'; import 'prismjs/themes/prism.css';
@ -11,9 +10,7 @@ import './learn.css';
function LearnLayout({ children }) { function LearnLayout({ children }) {
return ( return (
<Fragment> <Fragment>
<DefaultLayout> <main id='learn-app-wrapper'>{children}</main>
<main id='learn-app-wrapper'>{children}</main>
</DefaultLayout>
<DonationModal /> <DonationModal />
</Fragment> </Fragment>
); );

View File

@ -4,7 +4,6 @@ import { Alert, Button, Grid, Row, Col } from '@freecodecamp/react-bootstrap';
import Helmet from 'react-helmet'; import Helmet from 'react-helmet';
import { Link } from 'gatsby'; import { Link } from 'gatsby';
import Layout from '../layouts/Default';
import CurrentChallengeLink from '../helpers/CurrentChallengeLink'; import CurrentChallengeLink from '../helpers/CurrentChallengeLink';
import FullWidthRow from '../helpers/FullWidthRow'; import FullWidthRow from '../helpers/FullWidthRow';
import Spacer from '../helpers/Spacer'; import Spacer from '../helpers/Spacer';
@ -44,7 +43,7 @@ function TakeMeToTheChallenges() {
function renderIsLocked(username) { function renderIsLocked(username) {
return ( return (
<Layout> <Fragment>
<Helmet> <Helmet>
<title>{username} | freeCodeCamp.org</title> <title>{username} | freeCodeCamp.org</title>
</Helmet> </Helmet>
@ -67,7 +66,7 @@ function renderIsLocked(username) {
<TakeMeToTheChallenges /> <TakeMeToTheChallenges />
</FullWidthRow> </FullWidthRow>
</Grid> </Grid>
</Layout> </Fragment>
); );
} }
@ -131,7 +130,7 @@ function Profile({ user, isSessionUser }) {
return renderIsLocked(username); return renderIsLocked(username);
} }
return ( return (
<Layout> <Fragment>
<Helmet> <Helmet>
<title>{username} | freeCodeCamp.org</title> <title>{username} | freeCodeCamp.org</title>
</Helmet> </Helmet>
@ -166,7 +165,7 @@ function Profile({ user, isSessionUser }) {
/> />
) : null} ) : null}
</Grid> </Grid>
</Layout> </Fragment>
); );
} }

View File

@ -1,16 +1,15 @@
import React from 'react'; import React, { Fragment } from 'react';
import { Grid } from '@freecodecamp/react-bootstrap'; import { Grid } from '@freecodecamp/react-bootstrap';
import Helmet from 'react-helmet'; import Helmet from 'react-helmet';
import honesty from '../resources/honesty-policy'; import honesty from '../resources/honesty-policy';
import Layout from '../components/layouts/Default';
import Spacer from '../components/helpers/Spacer'; import Spacer from '../components/helpers/Spacer';
import FullWidthRow from '../components/helpers/FullWidthRow'; import FullWidthRow from '../components/helpers/FullWidthRow';
function AcademicHonesty() { function AcademicHonesty() {
return ( return (
<Layout> <Fragment>
<Helmet> <Helmet>
<title>Academic Honesty Policy | freeCodeCamp.org</title> <title>Academic Honesty Policy | freeCodeCamp.org</title>
</Helmet> </Helmet>
@ -22,7 +21,7 @@ function AcademicHonesty() {
{honesty} {honesty}
</FullWidthRow> </FullWidthRow>
</Grid> </Grid>
</Layout> </Fragment>
); );
} }

View File

@ -1,4 +1,4 @@
import React, { Component } from 'react'; import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
@ -13,7 +13,6 @@ import {
} from '@freecodecamp/react-bootstrap'; } from '@freecodecamp/react-bootstrap';
import Helmet from 'react-helmet'; import Helmet from 'react-helmet';
import Layout from '../components/layouts/Default';
import { ButtonSpacer, Spacer } from '../components/helpers'; import { ButtonSpacer, Spacer } from '../components/helpers';
import { acceptTerms, userSelector } from '../redux'; import { acceptTerms, userSelector } from '../redux';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
@ -71,7 +70,7 @@ class AcceptPrivacyTerms extends Component {
} }
const { privacyPolicy, termsOfService, quincyEmail } = this.state; const { privacyPolicy, termsOfService, quincyEmail } = this.state;
return ( return (
<Layout> <Fragment>
<Helmet> <Helmet>
<title>Privacy Policy and Terms of Service | freeCodeCamp.org</title> <title>Privacy Policy and Terms of Service | freeCodeCamp.org</title>
</Helmet> </Helmet>
@ -165,7 +164,7 @@ class AcceptPrivacyTerms extends Component {
</Col> </Col>
</Row> </Row>
</Grid> </Grid>
</Layout> </Fragment>
); );
} }
} }

View File

@ -1,4 +1,4 @@
import React from 'react'; import React, { Fragment } from 'react';
import { Grid, Row, Col, Image } from '@freecodecamp/react-bootstrap'; import { Grid, Row, Col, Image } from '@freecodecamp/react-bootstrap';
import FontAwesomeIcon from '@fortawesome/react-fontawesome'; import FontAwesomeIcon from '@fortawesome/react-fontawesome';
import { import {
@ -13,7 +13,6 @@ import { faDatabase } from '@fortawesome/free-solid-svg-icons';
import Helmet from 'react-helmet'; import Helmet from 'react-helmet';
import { Spacer } from '../components/helpers'; import { Spacer } from '../components/helpers';
import Layout from '../components/layouts/Default';
import Login from '../components/Header/components/Login'; import Login from '../components/Header/components/Login';
import './index.css'; import './index.css';
@ -27,7 +26,7 @@ const BigCallToAction = () => (
); );
const IndexPage = () => ( const IndexPage = () => (
<Layout disableSettings={true} landingPage={true}> <Fragment>
<Helmet> <Helmet>
<title>Learn to code | freeCodeCamp.org</title> <title>Learn to code | freeCodeCamp.org</title>
</Helmet> </Helmet>
@ -246,7 +245,7 @@ const IndexPage = () => (
<Spacer /> <Spacer />
<Spacer /> <Spacer />
</Grid> </Grid>
</Layout> </Fragment>
); );
export default IndexPage; export default IndexPage;

View File

@ -1,14 +1,13 @@
import React from 'react'; import React, { Fragment } from 'react';
import { Grid } from '@freecodecamp/react-bootstrap'; import { Grid } from '@freecodecamp/react-bootstrap';
import Helmet from 'react-helmet'; import Helmet from 'react-helmet';
import Layout from '../components/layouts/Default';
import FullWidthRow from '../components/helpers/FullWidthRow'; import FullWidthRow from '../components/helpers/FullWidthRow';
import { Spacer } from '../components/helpers'; import { Spacer } from '../components/helpers';
function SoftwareResourcesForNonProfits() { function SoftwareResourcesForNonProfits() {
return ( return (
<Layout> <Fragment>
<Helmet> <Helmet>
<title>Software Resources for Nonprofits | freeCodeCamp.org</title> <title>Software Resources for Nonprofits | freeCodeCamp.org</title>
</Helmet> </Helmet>
@ -312,7 +311,7 @@ function SoftwareResourcesForNonProfits() {
</ul> </ul>
</FullWidthRow> </FullWidthRow>
</Grid> </Grid>
</Layout> </Fragment>
); );
} }

View File

@ -1,4 +1,4 @@
import React, { Component } from 'react'; import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Link } from 'gatsby'; import { Link } from 'gatsby';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
@ -18,7 +18,6 @@ import Helmet from 'react-helmet';
import isEmail from 'validator/lib/isEmail'; import isEmail from 'validator/lib/isEmail';
import { isString } from 'lodash'; import { isString } from 'lodash';
import Layout from '../components/layouts/Default';
import { Spacer } from '../components/helpers'; import { Spacer } from '../components/helpers';
import './update-email.css'; import './update-email.css';
import { userSelector } from '../redux'; import { userSelector } from '../redux';
@ -79,7 +78,7 @@ class UpdateEmail extends Component {
render() { render() {
const { isNewEmail } = this.props; const { isNewEmail } = this.props;
return ( return (
<Layout> <Fragment>
<Helmet> <Helmet>
<title>Update your email address | freeCodeCamp.org</title> <title>Update your email address | freeCodeCamp.org</title>
</Helmet> </Helmet>
@ -127,7 +126,7 @@ class UpdateEmail extends Component {
</Col> </Col>
</Row> </Row>
</Grid> </Grid>
</Layout> </Fragment>
); );
} }
} }

View File

@ -1,4 +1,4 @@
import React from 'react'; import React, { Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { navigate } from 'gatsby'; import { navigate } from 'gatsby';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
@ -9,7 +9,6 @@ import Helmet from 'react-helmet';
import { Loader, Spacer } from '../components/helpers'; import { Loader, Spacer } from '../components/helpers';
import CurrentChallengeLink from '../components/helpers/CurrentChallengeLink'; import CurrentChallengeLink from '../components/helpers/CurrentChallengeLink';
import Layout from '../components/layouts/Default';
import Supporters from '../components/Supporters'; import Supporters from '../components/Supporters';
import { import {
userSelector, userSelector,
@ -70,11 +69,9 @@ function Welcome({
}) { }) {
if (pending && !complete) { if (pending && !complete) {
return ( return (
<Layout> <div className='loader-wrapper'>
<div className='loader-wrapper'> <Loader />
<Loader /> </div>
</div>
</Layout>
); );
} }
@ -90,7 +87,7 @@ function Welcome({
const { quote, author } = randomQuote(); const { quote, author } = randomQuote();
return ( return (
<Layout> <Fragment>
<Helmet> <Helmet>
<title>Welcome {name ? name : 'Camper'} | freeCodeCamp.org</title> <title>Welcome {name ? name : 'Camper'} | freeCodeCamp.org</title>
</Helmet> </Helmet>
@ -147,17 +144,17 @@ function Welcome({
<Spacer /> <Spacer />
<Row> <Row>
<Col sm={8} smOffset={2} xs={12}> <Col sm={8} smOffset={2} xs={12}>
<CurrentChallengeLink> <CurrentChallengeLink>
<Button block={true} bsStyle='primary' className='btn-cta-big'> <Button block={true} bsStyle='primary' className='btn-cta-big'>
Go to my next challenge Go to my next challenge
</Button> </Button>
</CurrentChallengeLink> </CurrentChallengeLink>
</Col> </Col>
</Row> </Row>
<Spacer size={4} /> <Spacer size={4} />
</Grid> </Grid>
</main> </main>
</Layout> </Fragment>
); );
} }