Skip to content

Commit

Permalink
Add routes
Browse files Browse the repository at this point in the history
  • Loading branch information
isnifer committed Oct 31, 2016
1 parent 65a5650 commit 2654706
Show file tree
Hide file tree
Showing 19 changed files with 299 additions and 25 deletions.
1 change: 1 addition & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<head>
<meta charset="UTF-8" />
<title>react-hot-env</title>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<div id="react-root"></div>
Expand Down
1 change: 0 additions & 1 deletion less/_main.less
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
@import '../node_modules/normalize.css/normalize.css';
@import 'global';
@import 'awesome-component';
6 changes: 0 additions & 6 deletions less/awesome-component.less

This file was deleted.

10 changes: 8 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
"babel-eslint": "^7.1.0",
"babel-loader": "^6.2.4",
"babel-plugin-react-transform": "^2.0.2",
"babel-polyfill": "^6.7.4",
"babel-preset-es2015": "^6.6.0",
"babel-preset-react": "^6.5.0",
"babel-preset-stage-1": "^6.5.0",
Expand All @@ -50,6 +49,7 @@
"eslint-plugin-jsx-a11y": "^2.2.3",
"eslint-plugin-react": "^6.4.1",
"express": "^4.13.4",
"extract-text-webpack-plugin": "^1.0.1",
"istanbul": "^0.4.3",
"jsdom": "^9.8.3",
"less": "^2.6.1",
Expand All @@ -67,9 +67,15 @@
"webpack-hot-middleware": "^2.10.0"
},
"dependencies": {
"babel-polyfill": "^6.16.0",
"isomorphic-fetch": "^2.2.1",
"keymirror": "^0.1.1",
"normalize.css": "^5.0.0",
"react": "^15.0.2",
"react-dom": "^15.0.2",
"react-router": "^3.0.0"
"react-redux": "^4.4.5",
"react-router": "^3.0.0",
"redux": "^3.6.0",
"redux-logger": "^2.7.4"
}
}
2 changes: 1 addition & 1 deletion server.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ app.use(require('webpack-dev-middleware')(compiler, {
app.use(require('webpack-hot-middleware')(compiler));

app.get('*', function(req, res) {
res.sendFile(path.join(__dirname, 'index.html'));
res.sendFile(path.join(__dirname, 'index.html'));
});

app.listen(8181, 'localhost', function (err) {
Expand Down
34 changes: 34 additions & 0 deletions src/actions/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import ActionTypes from '../constants';

export function loadPosts() {
return {
type: ActionTypes.LOAD_POSTS,
payload: {
posts: [
{title: 'Title 1', content: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Deserunt dolores perferendis cum nobis, doloribus, ex nisi quibusdam omnis numquam minus illum sint veritatis repellat distinctio accusantium quo fuga quam. Itaque.'},
{title: 'Title 2', content: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Deserunt dolores perferendis cum nobis, doloribus, ex nisi quibusdam omnis numquam minus illum sint veritatis repellat distinctio accusantium quo fuga quam. Itaque.'},
{title: 'Title 3', content: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Deserunt dolores perferendis cum nobis, doloribus, ex nisi quibusdam omnis numquam minus illum sint veritatis repellat distinctio accusantium quo fuga quam. Itaque.'},
{title: 'Title 4', content: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Deserunt dolores perferendis cum nobis, doloribus, ex nisi quibusdam omnis numquam minus illum sint veritatis repellat distinctio accusantium quo fuga quam. Itaque.'},
{title: 'Title 5', content: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Deserunt dolores perferendis cum nobis, doloribus, ex nisi quibusdam omnis numquam minus illum sint veritatis repellat distinctio accusantium quo fuga quam. Itaque.'},
]
}
};
}

export function loadUserProfile(user, password) {
return {
type: ActionTypes.LOGIN,
payload: {
user: {
id: 42,
name: user,
},
}
};
}

export function badLoadUserProfile() {
return {
type: ActionTypes.UNAUTH_LOGIN,
}
}
20 changes: 20 additions & 0 deletions src/common/utils/checkAuthHelper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { browserHistory } from 'react-router';

export default function checkAuthHelper(store, checker, baseUrl, loginUrl) {
return async ({location: {pathname, search}}, replace, done) => {
const { payload } = await store.dispatch(checker());

if (!payload && pathname !== loginUrl) {
replace({
pathname: loginUrl,
state: { nextPagePathname: `${pathname}${search}` }
});
}

if (payload && pathname === loginUrl) {
replace(baseUrl);
}

done();
};
}
7 changes: 7 additions & 0 deletions src/constants/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import keymirror from 'keymirror';

export default keymirror({
LOGIN: null,
LOAD_POSTS: null,
UNAUTH_LOGIN: null,
});
32 changes: 30 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,34 @@
import '../less/_main.less';
import React from 'react';
import { render } from 'react-dom';
import AwesomeComponent from './components/AwesomeComponent.jsx';
import { Router, Route, IndexRoute, browserHistory } from 'react-router';
import { Provider } from 'react-redux';
import checkAuthHelper from './common/utils/checkAuthHelper';
import { badLoadUserProfile } from './actions';
import store from './store';
import Wrapper from './pages/Wrapper';
import Admin from './pages/Admin';
import Login from './pages/Login';
import Posts from './pages/Posts';
import NotFound from './pages/NotFound';

render(React.createElement(AwesomeComponent), document.getElementById('react-root'));
const baseUrl = '/';
const loginUrl = `${baseUrl}login`;
const checkAuth = checkAuthHelper(store, badLoadUserProfile, baseUrl, loginUrl);

function MyReactApp () {
return (
<Provider store={store}>
<Router history={browserHistory}>
<Route path={baseUrl} component={Wrapper} onEnter={checkAuth}>
<IndexRoute component={Admin} />
<Route path="login" component={Login} />
<Route path="posts" component={Posts} />
<Route path="*" component={NotFound} />
</Route>
</Router>
</Provider>
);
}

render(React.createElement(MyReactApp), document.getElementById('react-root'));
14 changes: 14 additions & 0 deletions src/pages/Admin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React, { Component } from 'react';
import { Link } from 'react-router';

export default class Admin extends Component {
render() {
return (
<div className="admin-page">
<h1>Admin Page</h1>

<Link to="/posts">Posts</Link>
</div>
);
}
}
53 changes: 53 additions & 0 deletions src/pages/Login.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { loadUserProfile } from '../actions';

class Login extends Component {
state = {
user: '',
password: '',
}

onChange = ({target: {value, name}}) => this.setState({[name]: value})

onSubmit = async event => {
event.preventDefault();

await Promise.resolve()
.then(() => this.props.loadUserProfile(this.state.user, this.state.password))
.then(() => {
console.log(this.props)
if (this.props.user && this.props.user.name) {
this.props.router.replace(this.props.location.state.nextPagePathname);
}
});
}

render() {
return (
<div>
<form onSubmit={this.onSubmit}>
<div>
<input
type="text"
name="user"
placeholder="username"
onChange={this.onChange}
/>
</div>
<div>
<input
type="password"
name="password"
placeholder="password"
onChange={this.onChange}
/>
</div>
<button type="submit">Login</button>
</form>
</div>
);
}
}

export default connect(({user}) => ({user}), { loadUserProfile })(Login);
7 changes: 7 additions & 0 deletions src/pages/NotFound.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from 'react';

export default function NotFound() {
return (
<h1>There is no handler for that page</h1>
);
}
30 changes: 30 additions & 0 deletions src/pages/Posts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { loadPosts } from '../actions';

class Posts extends Component {
componentDidMount() {
this.props.loadPosts();
}

render() {
return (
<div>
<h1>Posts Page</h1>

<div className="posts">
{this.props.posts.map((post, i) => {
return (
<div className="posts__item" key={`post_${i}`}>
<div className="posts__title">{post.title}</div>
<div className="posts__content">{post.content}</div>
</div>
);
})}
</div>
</div>
);
}
}

export default connect(({posts}) => ({posts}), {loadPosts})(Posts);
21 changes: 21 additions & 0 deletions src/pages/Wrapper/Wrapper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';
import { Link } from 'react-router';
import style from './Wrapper.less';

export default function Wrapper({children}) {
return (
<div className={style.wrapper}>
<div className={style.header}>
<h1>
<Link to="/" className={style.headerLink}>Header</Link>
</h1>
</div>
<div className={style.content}>
{children}
</div>
<div className={style.footer}>
<h1>Footer</h1>
</div>
</div>
);
}
23 changes: 23 additions & 0 deletions src/pages/Wrapper/Wrapper.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
:local {
.wrapper {
max-width: 1080px;
}

.header {
margin: 0 auto;
width: 100%;
}

.headerLink {
color: red;
font-size: 20px;
}

.content {
margin: 0 auto;
}

.footer {
margin: 0 auto;
}
}
1 change: 1 addition & 0 deletions src/pages/Wrapper/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default from './Wrapper';
17 changes: 17 additions & 0 deletions src/reducers/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import ActionTypes from '../constants';

export function user(state = {}, {type, payload}) {
if (type === ActionTypes.LOGIN) {
return payload.user;
}

return state;
}

export function posts(state = [], {type, payload}) {
if (type === ActionTypes.LOAD_POSTS) {
return payload.posts;
}

return state;
}
13 changes: 13 additions & 0 deletions src/store/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { createStore, applyMiddleware, combineReducers } from 'redux';
import logger from 'redux-logger';
import { user, posts } from '../reducers';

const { NODE_ENV } = process.env;
const common = [];
const middleware = NODE_ENV === 'production' ? [...common] : [...common, logger()];
const createStoreWithMiddleware = applyMiddleware(...middleware)(createStore);

export default createStoreWithMiddleware(combineReducers({
user,
posts,
}));

0 comments on commit 2654706

Please sign in to comment.