From 15d949ee5f2b64cfe89802ebdad048093b730913 Mon Sep 17 00:00:00 2001 From: jmcpeak Date: Tue, 27 Feb 2018 16:00:53 -0500 Subject: [PATCH 1/6] First whack at the assignment --- src/containers/about/index.js | 10 +- src/containers/app/index.js | 31 +++-- src/containers/history/index.js | 26 ++++ src/containers/home/index.js | 84 +++++++------ src/index.css | 32 +++-- src/index.js | 31 +++-- src/modules/counter.js | 203 +++++++++++++++++++------------- src/modules/index.js | 10 +- src/store.js | 39 +++--- 9 files changed, 283 insertions(+), 183 deletions(-) create mode 100644 src/containers/history/index.js diff --git a/src/containers/about/index.js b/src/containers/about/index.js index d8216f5..78a7b49 100644 --- a/src/containers/about/index.js +++ b/src/containers/about/index.js @@ -1,10 +1,10 @@ import React from 'react' const About = () => ( -
-

About Page

-

Did you get here via Redux?

-
-) +
+

About Page

+

Did you get here via Redux?

+
+); export default About diff --git a/src/containers/app/index.js b/src/containers/app/index.js index b4d0a65..e7ceda3 100644 --- a/src/containers/app/index.js +++ b/src/containers/app/index.js @@ -1,20 +1,27 @@ import React from 'react'; -import { Route, Link } from 'react-router-dom' +import {Link, Route} from 'react-router-dom' import Home from '../home' import About from '../about' +import History from '../history' + +export const HOME_PATH = '/'; +export const ABOUT_PATH = '/about'; +export const HISTORY_PATH = '/history'; const App = () => ( -
-
- Home - About -
+
+
+ Home + About + History +
-
- - -
-
-) +
+ + + +
+
+); export default App diff --git a/src/containers/history/index.js b/src/containers/history/index.js new file mode 100644 index 0000000..0ceebc4 --- /dev/null +++ b/src/containers/history/index.js @@ -0,0 +1,26 @@ +import React from 'react' +import {connect} from "react-redux"; + +const History = props => ( + props.clickHistory.length ? +

History

+ + + + + + {props.clickHistory.map((entry, index) => + ( + + + ))} +
Click onDate time
{entry.name}{entry.dateTime}
+
: +

History

+); + +const mapStateToProps = state => ({ + clickHistory: state.counter.clickHistory +}); + +export default connect(mapStateToProps)(History) diff --git a/src/containers/home/index.js b/src/containers/home/index.js index 2384644..b0b03a5 100644 --- a/src/containers/home/index.js +++ b/src/containers/home/index.js @@ -1,48 +1,56 @@ -import React from 'react' -import { push } from 'react-router-redux' -import { bindActionCreators } from 'redux' -import { connect } from 'react-redux' +import React from 'react'; +import {bindActionCreators} from 'redux'; +import {connect} from 'react-redux'; import { - increment, - incrementAsync, - decrement, - decrementAsync -} from '../../modules/counter' + boundAbout, + boundDecrement, + boundDecrementAsync, + boundIncrement, + boundIncrementAsync, + boundReset +} from '../../modules/counter'; +import {withRouter} from 'react-router'; const Home = props => ( -
-

Home

-

Count: {props.count}

+
+

Home

+

Count: {props.count}

-

- - -

+

+ + +

-

- - -

+

+ + +

-

-
-) +

+ +

+ +

+ +

+
+); const mapStateToProps = state => ({ - count: state.counter.count, - isIncrementing: state.counter.isIncrementing, - isDecrementing: state.counter.isDecrementing -}) + count: state.counter.count, + isIncrementing: state.counter.isIncrementing, + isDecrementing: state.counter.isDecrementing +}); const mapDispatchToProps = dispatch => bindActionCreators({ - increment, - incrementAsync, - decrement, - decrementAsync, - changePage: () => push('/about-us') -}, dispatch) - -export default connect( - mapStateToProps, - mapDispatchToProps -)(Home) + increment: boundIncrement, + incrementAsync: boundIncrementAsync, + decrement: boundDecrement, + decrementAsync: boundDecrementAsync, + about: boundAbout, + reset: boundReset +}, dispatch); + +export default withRouter( + connect(mapStateToProps, mapDispatchToProps)(Home) +); diff --git a/src/index.css b/src/index.css index c180748..436dbe4 100644 --- a/src/index.css +++ b/src/index.css @@ -1,15 +1,33 @@ html { - font-size: 100%; + font-size: 100%; } body { - margin: 0; - padding: 0; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; - font-size: 1rem; - line-height: 1.5; + margin: 0; + padding: 0; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; + font-size: 1rem; + line-height: 1.5; } button:disabled { - opacity: 0.5; + opacity: 0.5; +} + +a { + margin-right: 15px; +} + +table { + margin-left: 10px; +} + +td, th { + border: 1px solid black; + text-align: left; + padding: 8px; +} + +tr:nth-child(even) { + background-color: #dddddd; } diff --git a/src/index.js b/src/index.js index 69a6603..37ec8e9 100644 --- a/src/index.js +++ b/src/index.js @@ -1,22 +1,19 @@ -import React from 'react' -import { render } from 'react-dom' -import { Provider } from 'react-redux' -import { ConnectedRouter } from 'react-router-redux' -import store, { history } from './store' -import App from './containers/app' - +import React from 'react'; +import {render} from 'react-dom'; +import {Provider} from 'react-redux'; +import {ConnectedRouter} from 'react-router-redux'; +import store, {history} from './store'; +import App from './containers/app'; import 'sanitize.css/sanitize.css' import './index.css' -const target = document.querySelector('#root') +const target = document.getElementById('root'); render( - - -
- -
-
-
, - target -) + + + + + , + target +); diff --git a/src/modules/counter.js b/src/modules/counter.js index d2d14a4..b58f818 100644 --- a/src/modules/counter.js +++ b/src/modules/counter.js @@ -1,95 +1,138 @@ -export const INCREMENT_REQUESTED = 'counter/INCREMENT_REQUESTED' -export const INCREMENT = 'counter/INCREMENT' -export const DECREMENT_REQUESTED = 'counter/DECREMENT_REQUESTED' -export const DECREMENT = 'counter/DECREMENT' - -const initialState = { - count: 0, - isIncrementing: false, - isDecrementing: false -} +import {push} from 'react-router-redux'; +import {ABOUT_PATH} from '../containers/app/index' + +export const INCREMENT_REQUESTED = 'counter/INCREMENT_REQUESTED'; +export const INCREMENT = 'counter/INCREMENT'; +export const DECREMENT_REQUESTED = 'counter/DECREMENT_REQUESTED'; +export const DECREMENT = 'counter/DECREMENT'; +export const ABOUT = 'counter/ABOUT'; +export const RESET = 'counter/RESET'; + +const + options = { + weekday: 'long', + year: 'numeric', + month: 'long', + day: 'numeric', + timeZone: 'EST' + }, + initialState = { + count: 0, + isIncrementing: false, + isDecrementing: false, + isResetting: false, + clickHistory: [] + }, + addClickHistory = (state, name) => state.clickHistory.concat({ + dateTime: new Date().toLocaleTimeString('en-US', options), + name: name + }); export default (state = initialState, action) => { - switch (action.type) { - case INCREMENT_REQUESTED: - return { - ...state, - isIncrementing: true - } - - case INCREMENT: - return { - ...state, - count: state.count + 1, - isIncrementing: !state.isIncrementing - } - - case DECREMENT_REQUESTED: - return { - ...state, - isDecrementing: true - } - - case DECREMENT: - return { - ...state, - count: state.count - 1, - isDecrementing: !state.isDecrementing - } - - default: - return state - } + + switch (action.type) { + case INCREMENT_REQUESTED: + return { + ...state, + isIncrementing: true + }; + + case INCREMENT: + return { + ...state, + count: state.count + 1, + isIncrementing: !state.isIncrementing, + clickHistory: addClickHistory(state, action.name) + }; + + case DECREMENT_REQUESTED: + return { + ...state, + isDecrementing: true + }; + + case DECREMENT: + return { + ...state, + count: state.count - 1, + isDecrementing: !state.isDecrementing, + clickHistory: addClickHistory(state, action.name) + }; + + case ABOUT: + return { + ...state, + clickHistory: addClickHistory(state, action.name) + }; + + case RESET: + return { + ...state, + count: state.count = 0, + clickHistory: addClickHistory(state, action.name) + }; + + default: + return state + } } -export const increment = () => { - return dispatch => { +export const boundIncrement = () => dispatch => { dispatch({ - type: INCREMENT_REQUESTED - }) + type: INCREMENT_REQUESTED + }); dispatch({ - type: INCREMENT - }) - } -} + type: INCREMENT, + name: 'Increment' + }); +}; -export const incrementAsync = () => { - return dispatch => { +export const boundIncrementAsync = () => dispatch => { dispatch({ - type: INCREMENT_REQUESTED - }) - - return setTimeout(() => { - dispatch({ - type: INCREMENT - }) - }, 3000) - } -} + type: INCREMENT_REQUESTED + }); + + return setTimeout(() => dispatch({ + type: INCREMENT, + name: 'Increment Async' + }), 2000); +}; -export const decrement = () => { - return dispatch => { +export const boundDecrement = () => dispatch => { dispatch({ - type: DECREMENT_REQUESTED - }) + type: DECREMENT_REQUESTED + }); dispatch({ - type: DECREMENT - }) - } -} + type: DECREMENT, + name: 'Decrement' + }); +}; -export const decrementAsync = () => { - return dispatch => { +export const boundDecrementAsync = () => dispatch => { dispatch({ - type: DECREMENT_REQUESTED - }) - - return setTimeout(() => { - dispatch({ - type: DECREMENT - }) - }, 3000) - } -} + type: DECREMENT_REQUESTED + }); + + return setTimeout(() => dispatch({ + type: DECREMENT, + name: 'Decrement Async' + }), 2000); +}; + +export const boundAbout = () => dispatch => { + dispatch({ + type: ABOUT, + name: 'Go to about page via redux' + }); + + dispatch(push(ABOUT_PATH)); +}; + +export const boundReset = () => dispatch => { + dispatch({ + type: RESET, + name: 'Reset' + }); +}; diff --git a/src/modules/index.js b/src/modules/index.js index b3881fe..a021e0f 100644 --- a/src/modules/index.js +++ b/src/modules/index.js @@ -1,8 +1,8 @@ -import { combineReducers } from 'redux' -import { routerReducer } from 'react-router-redux' -import counter from './counter' +import {combineReducers} from 'redux'; +import {routerReducer} from 'react-router-redux'; +import counter from './counter'; export default combineReducers({ - router: routerReducer, - counter + router: routerReducer, + counter }) diff --git a/src/store.js b/src/store.js index 46dae36..db40893 100644 --- a/src/store.js +++ b/src/store.js @@ -1,33 +1,34 @@ -import { createStore, applyMiddleware, compose } from 'redux' -import { routerMiddleware } from 'react-router-redux' +import {applyMiddleware, compose, createStore} from 'redux' +import {routerMiddleware} from 'react-router-redux' import thunk from 'redux-thunk' import createHistory from 'history/createBrowserHistory' import rootReducer from './modules' -export const history = createHistory() +export const history = createHistory(); -const initialState = {} -const enhancers = [] -const middleware = [ - thunk, - routerMiddleware(history) -] +const + initialState = {}, + enhancers = [], + middleware = [ + thunk, + routerMiddleware(history) + ]; if (process.env.NODE_ENV === 'development') { - const devToolsExtension = window.devToolsExtension + const devToolsExtension = window.devToolsExtension; - if (typeof devToolsExtension === 'function') { - enhancers.push(devToolsExtension()) - } + if (typeof devToolsExtension === 'function') { + enhancers.push(devToolsExtension()) + } } const composedEnhancers = compose( - applyMiddleware(...middleware), - ...enhancers -) + applyMiddleware(...middleware), + ...enhancers +); export default createStore( - rootReducer, - initialState, - composedEnhancers + rootReducer, + initialState, + composedEnhancers ) From bc0d844cdb03507c2ae3588bc71b3fdf1b40c221 Mon Sep 17 00:00:00 2001 From: jmcpeak Date: Tue, 27 Feb 2018 18:52:20 -0500 Subject: [PATCH 2/6] Little cleanup - put default at the bottom for readability --- src/modules/counter.js | 98 +++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/src/modules/counter.js b/src/modules/counter.js index b58f818..4fa573a 100644 --- a/src/modules/counter.js +++ b/src/modules/counter.js @@ -28,55 +28,6 @@ const name: name }); -export default (state = initialState, action) => { - - switch (action.type) { - case INCREMENT_REQUESTED: - return { - ...state, - isIncrementing: true - }; - - case INCREMENT: - return { - ...state, - count: state.count + 1, - isIncrementing: !state.isIncrementing, - clickHistory: addClickHistory(state, action.name) - }; - - case DECREMENT_REQUESTED: - return { - ...state, - isDecrementing: true - }; - - case DECREMENT: - return { - ...state, - count: state.count - 1, - isDecrementing: !state.isDecrementing, - clickHistory: addClickHistory(state, action.name) - }; - - case ABOUT: - return { - ...state, - clickHistory: addClickHistory(state, action.name) - }; - - case RESET: - return { - ...state, - count: state.count = 0, - clickHistory: addClickHistory(state, action.name) - }; - - default: - return state - } -} - export const boundIncrement = () => dispatch => { dispatch({ type: INCREMENT_REQUESTED @@ -136,3 +87,52 @@ export const boundReset = () => dispatch => { name: 'Reset' }); }; + +export default (state = initialState, action) => { + + switch (action.type) { + case INCREMENT_REQUESTED: + return { + ...state, + isIncrementing: true + }; + + case INCREMENT: + return { + ...state, + count: state.count + 1, + isIncrementing: !state.isIncrementing, + clickHistory: addClickHistory(state, action.name) + }; + + case DECREMENT_REQUESTED: + return { + ...state, + isDecrementing: true + }; + + case DECREMENT: + return { + ...state, + count: state.count - 1, + isDecrementing: !state.isDecrementing, + clickHistory: addClickHistory(state, action.name) + }; + + case ABOUT: + return { + ...state, + clickHistory: addClickHistory(state, action.name) + }; + + case RESET: + return { + ...state, + count: state.count = 0, + clickHistory: addClickHistory(state, action.name) + }; + + default: + return state + } +}; From c1d34c9e8e92f6ef588c3bf187ffbf764a533076 Mon Sep 17 00:00:00 2001 From: jmcpeak Date: Wed, 28 Feb 2018 11:40:22 -0500 Subject: [PATCH 3/6] Use spread operator instead of concat --- src/modules/counter.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/counter.js b/src/modules/counter.js index 4fa573a..56404f2 100644 --- a/src/modules/counter.js +++ b/src/modules/counter.js @@ -23,10 +23,10 @@ const isResetting: false, clickHistory: [] }, - addClickHistory = (state, name) => state.clickHistory.concat({ + addClickHistory = (state, name) => state.clickHistory = [...state.clickHistory, { dateTime: new Date().toLocaleTimeString('en-US', options), name: name - }); + }]; export const boundIncrement = () => dispatch => { dispatch({ From 2536a173ea4eabc5bcaf4258dc7d33124782fee5 Mon Sep 17 00:00:00 2001 From: jmcpeak Date: Mon, 5 Mar 2018 17:15:05 -0500 Subject: [PATCH 4/6] Fix for Chrome --- src/modules/counter.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/counter.js b/src/modules/counter.js index 56404f2..d76f9b7 100644 --- a/src/modules/counter.js +++ b/src/modules/counter.js @@ -14,7 +14,7 @@ const year: 'numeric', month: 'long', day: 'numeric', - timeZone: 'EST' + timeZone: 'America/New_York' }, initialState = { count: 0, @@ -23,10 +23,10 @@ const isResetting: false, clickHistory: [] }, - addClickHistory = (state, name) => state.clickHistory = [...state.clickHistory, { + addClickHistory = (state, name) => state.clickHistory.concat({ dateTime: new Date().toLocaleTimeString('en-US', options), name: name - }]; + }); export const boundIncrement = () => dispatch => { dispatch({ From 0bec9728b4a4f6c2c39de8ba08fa5afa86b99015 Mon Sep 17 00:00:00 2001 From: jmcpeak Date: Tue, 6 Mar 2018 10:04:21 -0500 Subject: [PATCH 5/6] Refactor based on Eli's feedback --- src/modules/counter.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/modules/counter.js b/src/modules/counter.js index d76f9b7..5e4cb8f 100644 --- a/src/modules/counter.js +++ b/src/modules/counter.js @@ -23,10 +23,10 @@ const isResetting: false, clickHistory: [] }, - addClickHistory = (state, name) => state.clickHistory.concat({ + addClickHistory = (clickHistory, name) => [...clickHistory, { dateTime: new Date().toLocaleTimeString('en-US', options), name: name - }); + }]; export const boundIncrement = () => dispatch => { dispatch({ @@ -102,7 +102,7 @@ export default (state = initialState, action) => { ...state, count: state.count + 1, isIncrementing: !state.isIncrementing, - clickHistory: addClickHistory(state, action.name) + clickHistory: addClickHistory(state.clickHistory, action.name) }; case DECREMENT_REQUESTED: @@ -116,20 +116,20 @@ export default (state = initialState, action) => { ...state, count: state.count - 1, isDecrementing: !state.isDecrementing, - clickHistory: addClickHistory(state, action.name) + clickHistory: addClickHistory(state.clickHistory, action.name) }; case ABOUT: return { ...state, - clickHistory: addClickHistory(state, action.name) + clickHistory: addClickHistory(state.clickHistory, action.name) }; case RESET: return { ...state, count: state.count = 0, - clickHistory: addClickHistory(state, action.name) + clickHistory: addClickHistory(state.clickHistory, action.name) }; default: From a43773d382e0dbc254c9ed7c7aeb1db7412b879e Mon Sep 17 00:00:00 2001 From: jmcpeak Date: Tue, 6 Mar 2018 22:28:06 -0500 Subject: [PATCH 6/6] JSX if --- src/containers/history/index.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/containers/history/index.js b/src/containers/history/index.js index 0ceebc4..1e98602 100644 --- a/src/containers/history/index.js +++ b/src/containers/history/index.js @@ -2,8 +2,8 @@ import React from 'react' import {connect} from "react-redux"; const History = props => ( - props.clickHistory.length ? -

History

+

History

+ {props.clickHistory.length > 0 && ( @@ -15,8 +15,8 @@ const History = props => ( ))}
Click on{entry.dateTime}
-
: -

History

+ )} +
); const mapStateToProps = state => ({