Skip to content

Commit

Permalink
feat(example): Simplify navigation, extract to header (react-boilerpl…
Browse files Browse the repository at this point in the history
  • Loading branch information
sedubois authored and mxstbr committed Nov 2, 2016
1 parent 32cb234 commit 56f3f68
Show file tree
Hide file tree
Showing 16 changed files with 78 additions and 162 deletions.
25 changes: 25 additions & 0 deletions app/components/Header/HeaderLink.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Link } from 'react-router';
import styled from 'styled-components';

export default styled(Link)`
display: inline-flex;
padding: 0.25em 2em;
margin: 1em;
text-decoration: none;
border-radius: 4px;
-webkit-font-smoothing: antialiased;
-webkit-touch-callout: none;
user-select: none;
cursor: pointer;
outline: 0;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-weight: bold;
font-size: 16px;
border: 2px solid #41ADDD;
color: #41ADDD;
&:active {
background: #41ADDD;
color: #FFF;
}
`;
5 changes: 5 additions & 0 deletions app/components/Header/NavBar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import styled from 'styled-components';

export default styled.div`
text-align: center;
`;
20 changes: 17 additions & 3 deletions app/components/Header/index.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,29 @@
import React from 'react';
import { FormattedMessage } from 'react-intl';

import A from './A';
import Img from './Img';
import NavBar from './NavBar';
import HeaderLink from './HeaderLink';
import Banner from './banner.jpg';
import messages from './messages';

class Header extends React.Component { // eslint-disable-line react/prefer-stateless-function
render() {
return (
<A href="https://twitter.com/mxstbr">
<Img src={Banner} alt="react-boilerplate - Logo" />
</A>
<div>
<A href="https://twitter.com/mxstbr">
<Img src={Banner} alt="react-boilerplate - Logo" />
</A>
<NavBar>
<HeaderLink to="/">
<FormattedMessage {...messages.home} />
</HeaderLink>
<HeaderLink to="/features">
<FormattedMessage {...messages.features} />
</HeaderLink>
</NavBar>
</div>
);
}
}
Expand Down
17 changes: 17 additions & 0 deletions app/components/Header/messages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* HomePage Messages
*
* This contains all the text for the HomePage component.
*/
import { defineMessages } from 'react-intl';

export default defineMessages({
home: {
id: 'boilerplate.components.Header.home',
defaultMessage: 'Home',
},
features: {
id: 'boilerplate.components.Header.features',
defaultMessage: 'Features',
},
});
8 changes: 4 additions & 4 deletions app/components/Header/tests/index.test.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import expect from 'expect';
import { render } from 'enzyme';
import { shallow } from 'enzyme';
import React from 'react';

import Header from '../index';

describe('<Header />', () => {
it('should render the logo', () => {
const renderedComponent = render(
it('should render a div', () => {
const renderedComponent = shallow(
<Header />
);
expect(renderedComponent.find('img').length).toEqual(1);
expect(renderedComponent.find('div').length).toEqual(1);
});
});
18 changes: 1 addition & 17 deletions app/containers/FeaturePage/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,16 @@
* List all the features
*/
import React from 'react';
import { connect } from 'react-redux';
import { push } from 'react-router-redux';
import Helmet from 'react-helmet';

import messages from './messages';
import { FormattedMessage } from 'react-intl';
import Button from 'components/Button';
import H1 from 'components/H1';
import List from './List';
import ListItem from './ListItem';
import ListItemTitle from './ListItemTitle';

export class FeaturePage extends React.Component {
openHomePage = () => {
this.props.dispatch(push('/'));
};

export default class FeaturePage extends React.Component { // eslint-disable-line react/prefer-stateless-function
render() {
return (
<div>
Expand Down Expand Up @@ -79,16 +72,7 @@ export class FeaturePage extends React.Component {
</p>
</ListItem>
</List>
<Button handleRoute={this.openHomePage}>
<FormattedMessage {...messages.homeButton} />
</Button>
</div>
);
}
}

FeaturePage.propTypes = {
dispatch: React.PropTypes.func,
};

export default connect()(FeaturePage);
4 changes: 0 additions & 4 deletions app/containers/FeaturePage/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,4 @@ export default defineMessages({
id: 'boilerplate.containers.FeaturePage.internationalization.message',
defaultMessage: 'Scalable apps need to support multiple languages, easily add and support multiple languages with `react-intl`.',
},
homeButton: {
id: 'boilerplate.containers.FeaturePage.home',
defaultMessage: 'Home',
},
});
17 changes: 1 addition & 16 deletions app/containers/FeaturePage/tests/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ import expect from 'expect';
import { shallow } from 'enzyme';
import React from 'react';

import Button from 'components/Button';
import { FormattedMessage } from 'react-intl';
import messages from '../messages';
import { FeaturePage } from '../index';
import FeaturePage from '../index';
import H1 from 'components/H1';

describe('<FeaturePage />', () => {
Expand All @@ -19,18 +18,4 @@ describe('<FeaturePage />', () => {
</H1>
)).toEqual(true);
});

it('should link to "/"', (done) => {
// Spy on the openRoute method of the FeaturePage
const dispatch = (action) => {
expect(action.payload.args).toEqual('/');
done();
};

const renderedComponent = shallow(
<FeaturePage dispatch={dispatch} />
);
const button = renderedComponent.find(Button);
button.prop('handleRoute')();
});
});
24 changes: 0 additions & 24 deletions app/containers/HomePage/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@ import React from 'react';
import Helmet from 'react-helmet';
import { FormattedMessage } from 'react-intl';
import { connect } from 'react-redux';
import { push } from 'react-router-redux';
import { createStructuredSelector } from 'reselect';

import AtPrefix from './AtPrefix';
import Button from 'components/Button';
import CenteredSection from './CenteredSection';
import Form from './Form';
import H2 from 'components/H2';
Expand All @@ -37,21 +35,6 @@ export class HomePage extends React.Component {
this.props.onSubmitForm();
}
}
/**
* Changes the route
*
* @param {string} route The route we want to go to
*/
openRoute = (route) => {
this.props.changeRoute(route);
};

/**
* Changed route to '/features'
*/
openFeaturesPage = () => {
this.openRoute('/features');
};

render() {
let mainContent = null;
Expand Down Expand Up @@ -110,17 +93,13 @@ export class HomePage extends React.Component {
</Form>
{mainContent}
</Section>
<Button handleRoute={this.openFeaturesPage}>
<FormattedMessage {...messages.featuresButton} />
</Button>
</div>
</article>
);
}
}

HomePage.propTypes = {
changeRoute: React.PropTypes.func,
loading: React.PropTypes.bool,
error: React.PropTypes.oneOfType([
React.PropTypes.object,
Expand All @@ -138,13 +117,10 @@ HomePage.propTypes = {
export function mapDispatchToProps(dispatch) {
return {
onChangeUsername: (evt) => dispatch(changeUsername(evt.target.value)),
changeRoute: (url) => dispatch(push(url)),
onSubmitForm: (evt) => {
if (evt !== undefined && evt.preventDefault) evt.preventDefault();
dispatch(loadRepos());
},

dispatch,
};
}

Expand Down
4 changes: 0 additions & 4 deletions app/containers/HomePage/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,4 @@ export default defineMessages({
id: 'boilerplate.containers.HomePage.tryme.atPrefix',
defaultMessage: '@',
},
featuresButton: {
id: 'boilerplate.containers.HomePage.features.Button',
defaultMessage: 'Features',
},
});
37 changes: 0 additions & 37 deletions app/containers/HomePage/tests/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { IntlProvider } from 'react-intl';
import { HomePage, mapDispatchToProps } from '../index';
import { changeUsername } from '../actions';
import { loadRepos } from '../../App/actions';
import { push } from 'react-router-redux';
import RepoListItem from 'containers/RepoListItem';
import List from 'components/List';
import LoadingIndicator from 'components/LoadingIndicator';
Expand Down Expand Up @@ -73,26 +72,6 @@ describe('<HomePage />', () => {
expect(renderedComponent.contains(<List items={repos} component={RepoListItem} />)).toEqual(true);
});

it('should link to /features', () => {
const openRouteSpy = expect.createSpy();

// Spy on the openRoute method of the HomePage
const openRoute = (dest) => {
if (dest === '/features') {
openRouteSpy();
}
};

const renderedComponent = mount(
<IntlProvider locale="en">
<HomePage loading changeRoute={openRoute} />
</IntlProvider>
);
const button = renderedComponent.find('button');
button.simulate('click');
expect(openRouteSpy).toHaveBeenCalled();
});

describe('mapDispatchToProps', () => {
describe('onChangeUsername', () => {
it('should be injected', () => {
Expand All @@ -111,22 +90,6 @@ describe('<HomePage />', () => {
});
});

describe('changeRoute', () => {
it('should be injected', () => {
const dispatch = expect.createSpy();
const result = mapDispatchToProps(dispatch);
expect(result.changeRoute).toExist();
});

it('should dispatch push when called', () => {
const dispatch = expect.createSpy();
const result = mapDispatchToProps(dispatch);
const route = '/';
result.changeRoute(route);
expect(dispatch).toHaveBeenCalledWith(push(route));
});
});

describe('onSubmitForm', () => {
it('should be injected', () => {
const dispatch = expect.createSpy();
Expand Down
19 changes: 1 addition & 18 deletions app/containers/NotFoundPage/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,17 @@
*/

import React from 'react';
import { connect } from 'react-redux';
import { push } from 'react-router-redux';

import messages from './messages';
import { FormattedMessage } from 'react-intl';
import Button from 'components/Button';
import H1 from 'components/H1';

export function NotFound(props) {
export default function NotFound() {
return (
<article>
<H1>
<FormattedMessage {...messages.header} />
</H1>
<Button
handleRoute={function redirect() {
props.dispatch(push('/'));
}}
>
<FormattedMessage {...messages.homeButton} />
</Button>
</article>
);
}

NotFound.propTypes = {
dispatch: React.PropTypes.func,
};

// Wrap the component to inject dispatch and state into it
export default connect()(NotFound);
4 changes: 0 additions & 4 deletions app/containers/NotFoundPage/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,4 @@ export default defineMessages({
id: 'boilerplate.containers.NotFoundPage.header',
defaultMessage: 'Page not found.',
},
homeButton: {
id: 'boilerplate.containers.NotFoundPage.home',
defaultMessage: 'Home',
},
});
24 changes: 1 addition & 23 deletions app/containers/NotFoundPage/tests/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ import { shallow } from 'enzyme';
import React from 'react';

import { FormattedMessage } from 'react-intl';
import { NotFound } from '../index';
import NotFound from '../index';
import H1 from 'components/H1';
import Button from 'components/Button';

describe('<NotFound />', () => {
it('should render the Page Not Found text', () => {
Expand All @@ -24,25 +23,4 @@ describe('<NotFound />', () => {
/>
</H1>)).toEqual(true);
});

it('should render a button', () => {
const renderedComponent = shallow(
<NotFound />
);
const renderedButton = renderedComponent.find(Button);
expect(renderedButton.length).toEqual(1);
});

it('should link to "/"', (done) => {
const dispatch = (action) => {
expect(action.payload.args).toEqual('/');
done();
};

const renderedComponent = shallow(
<NotFound dispatch={dispatch} />
);
const button = renderedComponent.find(Button);
button.prop('handleRoute')();
});
});
Loading

0 comments on commit 56f3f68

Please sign in to comment.