diff --git a/src/components/_Counter/Counter.js b/src/components/_Counter/Counter.js deleted file mode 100644 index 4367fc5..0000000 --- a/src/components/_Counter/Counter.js +++ /dev/null @@ -1,29 +0,0 @@ -import React from 'react'; -import classes from './Counter.scss'; - -export const Counter = (props) => ( -
-

- Counter: - {' '} - - {props.counter} - -

- - {' '} - -
-); - -Counter.propTypes = { - counter: React.PropTypes.number.isRequired, - doubleAsync: React.PropTypes.func.isRequired, - increment: React.PropTypes.func.isRequired, -}; - -export default Counter; diff --git a/src/components/_Counter/Counter.scss b/src/components/_Counter/Counter.scss deleted file mode 100644 index ba88993..0000000 --- a/src/components/_Counter/Counter.scss +++ /dev/null @@ -1,12 +0,0 @@ -.counter { - font-weight: bold; -} - -.counter--green { - composes: counter; - color: rgb(25,200,25); -} - -.counterContainer { - margin: 1em auto; -} diff --git a/src/components/_Counter/index.js b/src/components/_Counter/index.js deleted file mode 100644 index 97f7f53..0000000 --- a/src/components/_Counter/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import Counter from './Counter'; - -export default Counter; diff --git a/src/components/_Header/Header.js b/src/components/_Header/Header.js deleted file mode 100644 index 9a7fd2e..0000000 --- a/src/components/_Header/Header.js +++ /dev/null @@ -1,18 +0,0 @@ -import React from 'react'; -import { IndexLink, Link } from 'react-router'; -import classes from './Header.scss'; - -export const Header = () => ( -
-

React Redux Starter Kit

- - Home - - {' ยท '} - - Counter - -
-); - -export default Header; diff --git a/src/components/_Header/Header.scss b/src/components/_Header/Header.scss deleted file mode 100644 index 1dcd731..0000000 --- a/src/components/_Header/Header.scss +++ /dev/null @@ -1,4 +0,0 @@ -.activeRoute { - font-weight: bold; - text-decoration: underline; -} diff --git a/src/components/_Header/index.js b/src/components/_Header/index.js deleted file mode 100644 index a9ce105..0000000 --- a/src/components/_Header/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import Header from './Header'; - -export default Header; diff --git a/src/components/DisplayPicker/DisplayPicker.js b/src/routes/Home/components/DisplayPicker/DisplayPicker.js similarity index 69% rename from src/components/DisplayPicker/DisplayPicker.js rename to src/routes/Home/components/DisplayPicker/DisplayPicker.js index caba1b2..82439ed 100644 --- a/src/components/DisplayPicker/DisplayPicker.js +++ b/src/routes/Home/components/DisplayPicker/DisplayPicker.js @@ -13,16 +13,25 @@ const DisplayPicker = ({ setCollection, collectionId, ...props }) => ( onChange={setCollection} /> - - - - - + {collectionId? +
+ + + + + +
+ : +
+

Provide a Collection ID

+

EmptyState here

+
+ } ); diff --git a/src/components/DisplayPicker/DisplayPickerEmbedCode.js b/src/routes/Home/components/DisplayPicker/DisplayPickerEmbedCode.js similarity index 100% rename from src/components/DisplayPicker/DisplayPickerEmbedCode.js rename to src/routes/Home/components/DisplayPicker/DisplayPickerEmbedCode.js diff --git a/src/components/DisplayPicker/DisplayPickerNavigation.js b/src/routes/Home/components/DisplayPicker/DisplayPickerNavigation.js similarity index 100% rename from src/components/DisplayPicker/DisplayPickerNavigation.js rename to src/routes/Home/components/DisplayPicker/DisplayPickerNavigation.js diff --git a/src/components/DisplayPicker/DisplayPickerStage.js b/src/routes/Home/components/DisplayPicker/DisplayPickerStage.js similarity index 100% rename from src/components/DisplayPicker/DisplayPickerStage.js rename to src/routes/Home/components/DisplayPicker/DisplayPickerStage.js diff --git a/src/components/DisplayPicker/index.js b/src/routes/Home/components/DisplayPicker/index.js similarity index 100% rename from src/components/DisplayPicker/index.js rename to src/routes/Home/components/DisplayPicker/index.js diff --git a/src/routes/Home/components/HomeView.js b/src/routes/Home/components/HomeView/HomeView.js similarity index 80% rename from src/routes/Home/components/HomeView.js rename to src/routes/Home/components/HomeView/HomeView.js index 221ca67..64336e3 100644 --- a/src/routes/Home/components/HomeView.js +++ b/src/routes/Home/components/HomeView/HomeView.js @@ -1,7 +1,7 @@ import React from 'react'; // import classes from './HomeView.scss'; -import DisplayPickerContainer from '../containers/DisplayPickerContainer'; +import DisplayPickerContainer from '../../containers/DisplayPickerContainer'; export const HomeView = () => (
diff --git a/src/routes/Home/components/HomeView.scss b/src/routes/Home/components/HomeView/HomeView.scss similarity index 100% rename from src/routes/Home/components/HomeView.scss rename to src/routes/Home/components/HomeView/HomeView.scss diff --git a/src/routes/Home/components/HomeView/index.js b/src/routes/Home/components/HomeView/index.js new file mode 100644 index 0000000..37e3f57 --- /dev/null +++ b/src/routes/Home/components/HomeView/index.js @@ -0,0 +1,2 @@ +import HomeView from './HomeView'; +export default HomeView; diff --git a/src/routes/Home/containers/DisplayPickerContainer.js b/src/routes/Home/containers/DisplayPickerContainer.js index 17d2e22..8eb740b 100644 --- a/src/routes/Home/containers/DisplayPickerContainer.js +++ b/src/routes/Home/containers/DisplayPickerContainer.js @@ -2,7 +2,7 @@ import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import { actions as displayActions } from '../modules/display'; -import DisplayPicker from 'components/DisplayPicker'; +import DisplayPicker from '../components/DisplayPicker'; const mapStateToProps = (state) => ({ diff --git a/src/routes/_Counter/containers/CounterContainer.js b/src/routes/_Counter/containers/CounterContainer.js deleted file mode 100644 index c0352b0..0000000 --- a/src/routes/_Counter/containers/CounterContainer.js +++ /dev/null @@ -1,38 +0,0 @@ -import { connect } from 'react-redux'; -import { increment, doubleAsync } from '../modules/counter'; - -/* This is a container component. Notice it does not contain any JSX, - nor does it import React. This component is **only** responsible for - wiring in the actions and state necessary to render a presentational - component - in this case, the counter: */ - -import Counter from 'components/Counter'; - -/* Object of action creators (can also be function that returns object). - Keys will be passed as props to presentational components. Here we are - implementing our wrapper around increment; the component doesn't care */ - -const mapActionCreators = { - increment: () => increment(1), - doubleAsync, -}; - -const mapStateToProps = (state) => ({ - counter: state.counter, -}); - -/* Note: mapStateToProps is where you should use `reselect` to create selectors, ie: - - import { createSelector } from 'reselect' - const counter = (state) => state.counter - const tripleCount = createSelector(counter, (count) => count * 3) - const mapStateToProps = (state) => ({ - counter: tripleCount(state) - }) - - Selectors can compute derived data, allowing Redux to store the minimal possible state. - Selectors are efficient. A selector is not recomputed unless one of its arguments change. - Selectors are composable. They can be used as input to other selectors. - https://github.com/reactjs/reselect */ - -export default connect(mapStateToProps, mapActionCreators)(Counter); diff --git a/src/routes/_Counter/index.js b/src/routes/_Counter/index.js deleted file mode 100644 index e8fcb2d..0000000 --- a/src/routes/_Counter/index.js +++ /dev/null @@ -1,24 +0,0 @@ -import { injectReducer } from '../../store/reducers'; - -export default (store) => ({ - path: 'counter', - /* Async getComponent is only invoked when route matches */ - getComponent(nextState, cb) { - /* Webpack - use 'require.ensure' to create a split point - and embed an async module loader (jsonp) when bundling */ - require.ensure([], (require) => { - /* Webpack - use require callback to define - dependencies for bundling */ - const Counter = require('./containers/CounterContainer').default; - const reducer = require('./modules/counter').default; - - /* Add the reducer to the store on key 'counter' */ - injectReducer(store, { key: 'counter', reducer }); - - /* Return getComponent */ - cb(null, Counter); - - /* Webpack named bundle */ - }, 'counter'); - }, -}); diff --git a/src/routes/_Counter/modules/counter.js b/src/routes/_Counter/modules/counter.js deleted file mode 100644 index 7b23279..0000000 --- a/src/routes/_Counter/modules/counter.js +++ /dev/null @@ -1,53 +0,0 @@ -// ------------------------------------ -// Constants -// ------------------------------------ -export const COUNTER_INCREMENT = 'COUNTER_INCREMENT'; - -// ------------------------------------ -// Actions -// ------------------------------------ -export function increment(value = 1) { - return { - type: COUNTER_INCREMENT, - payload: value, - }; -} - -/* This is a thunk, meaning it is a function that immediately - returns a function for lazy evaluation. It is incredibly useful for - creating async actions, especially when combined with redux-thunk! - - NOTE: This is solely for demonstration purposes. In a real application, - you'd probably want to dispatch an action of COUNTER_DOUBLE and let the - reducer take care of this logic. */ - -export const doubleAsync = () => - (dispatch, getState) => - new Promise((resolve) => { - setTimeout(() => { - dispatch(increment(getState().counter)); - resolve(); - }, 200); - }); - -export const actions = { - increment, - doubleAsync, -}; - -// ------------------------------------ -// Action Handlers -// ------------------------------------ -const ACTION_HANDLERS = { - [COUNTER_INCREMENT]: (state, action) => state + action.payload, -}; - -// ------------------------------------ -// Reducer -// ------------------------------------ -const initialState = 0; -export default function counterReducer(state = initialState, action) { - const handler = ACTION_HANDLERS[action.type]; - - return handler ? handler(state, action) : state; -} diff --git a/src/routes/_Home/assets/Duck.jpg b/src/routes/_Home/assets/Duck.jpg deleted file mode 100644 index f398a1c..0000000 Binary files a/src/routes/_Home/assets/Duck.jpg and /dev/null differ diff --git a/src/routes/_Home/components/HomeView.js b/src/routes/_Home/components/HomeView.js deleted file mode 100644 index 77ed4df..0000000 --- a/src/routes/_Home/components/HomeView.js +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react'; -import DuckImage from '../assets/Duck.jpg'; -import classes from './HomeView.scss'; - -export const HomeView = () => ( -
-

Welcome!

- This is a duck, because Redux! -
-); - -export default HomeView; diff --git a/src/routes/_Home/components/HomeView.scss b/src/routes/_Home/components/HomeView.scss deleted file mode 100644 index 10de960..0000000 --- a/src/routes/_Home/components/HomeView.scss +++ /dev/null @@ -1,5 +0,0 @@ -.duck { - display: block; - width: 120px; - margin: 1.5rem auto; -} diff --git a/src/routes/_Home/index.js b/src/routes/_Home/index.js deleted file mode 100644 index d937c77..0000000 --- a/src/routes/_Home/index.js +++ /dev/null @@ -1,6 +0,0 @@ -import HomeView from './components/HomeView'; - -// Sync route definition -export default { - component: HomeView, -}; diff --git a/src/routes/_index.js b/src/routes/_index.js deleted file mode 100644 index 9227ab9..0000000 --- a/src/routes/_index.js +++ /dev/null @@ -1,36 +0,0 @@ -// We only need to import the modules necessary for initial render -import CoreLayout from '../layouts/CoreLayout/CoreLayout'; -import Home from './Home'; -import CounterRoute from './Counter'; - -/* Note: Instead of using JSX, we recommend using react-router - PlainRoute objects to build route definitions. */ - -export const createRoutes = (store) => ({ - path: '/', - component: CoreLayout, - indexRoute: Home, - childRoutes: [ - new CounterRoute(store), - ], -}); - -/* Note: childRoutes can be chunked or otherwise loaded programmatically - using getChildRoutes with the following signature: - - getChildRoutes (location, cb) { - require.ensure([], (require) => { - cb(null, [ - // Remove imports! - require('./Counter').default(store) - ]) - }) - } - - However, this is not necessary for code-splitting! It simply provides - an API for async route definitions. Your code splitting should occur - inside the route `getComponent` function, since it is only invoked - when the route exists and matches. -*/ - -export default createRoutes; diff --git a/tests/components/Counter/Counter.spec.js b/tests/components/Counter/Counter.spec.js deleted file mode 100644 index 266fe85..0000000 --- a/tests/components/Counter/Counter.spec.js +++ /dev/null @@ -1,80 +0,0 @@ -import React from 'react' -import { bindActionCreators } from 'redux' -import { Counter } from 'components/Counter/Counter' -import { shallow } from 'enzyme' - -describe('(Component) Counter', () => { - let _props, _spies, _wrapper - - beforeEach(() => { - _spies = {} - _props = { - counter: 5, - ...bindActionCreators({ - doubleAsync: (_spies.doubleAsync = sinon.spy()), - increment: (_spies.increment = sinon.spy()) - }, _spies.dispatch = sinon.spy()) - } - _wrapper = shallow() - }) - - it('Should render as a
.', () => { - expect(_wrapper.is('div')).to.equal(true) - }) - - it('Should render with an

that includes Sample Counter text.', () => { - expect(_wrapper.find('h2').text()).to.match(/Counter:/) - }) - - it('Should render props.counter at the end of the sample counter

.', () => { - expect(_wrapper.find('h2').text()).to.match(/5$/) - _wrapper.setProps({ counter: 8 }) - expect(_wrapper.find('h2').text()).to.match(/8$/) - }) - - it('Should render exactly two buttons.', () => { - expect(_wrapper).to.have.descendants('.btn') - }) - // - describe('An increment button...', () => { - let _button - - beforeEach(() => { - _button = _wrapper.find('button').filterWhere(a => a.text() === 'Increment') - }) - - it('has bootstrap classes', () => { - expect(_button.hasClass('btn btn-default')).to.be.true - }) - - it('Should dispatch a `increment` action when clicked', () => { - _spies.dispatch.should.have.not.been.called - - _button.simulate('click') - - _spies.dispatch.should.have.been.called - _spies.increment.should.have.been.called - }); - }) - - describe('A Double (Async) button...', () => { - let _button - - beforeEach(() => { - _button = _wrapper.find('button').filterWhere(a => a.text() === 'Double (Async)') - }) - - it('has bootstrap classes', () => { - expect(_button.hasClass('btn btn-default')).to.be.true - }) - - it('Should dispatch a `doubleAsync` action when clicked', () => { - _spies.dispatch.should.have.not.been.called - - _button.simulate('click') - - _spies.dispatch.should.have.been.called - _spies.doubleAsync.should.have.been.called - }); - }) -}) diff --git a/tests/components/Header/Header.spec.js b/tests/components/Header.spec.js similarity index 100% rename from tests/components/Header/Header.spec.js rename to tests/components/Header.spec.js diff --git a/tests/routes/Counter/components/CounterView.spec.js b/tests/routes/Counter/components/CounterView.spec.js deleted file mode 100644 index e69de29..0000000 diff --git a/tests/routes/Counter/index.spec.js b/tests/routes/Counter/index.spec.js deleted file mode 100644 index c2d78db..0000000 --- a/tests/routes/Counter/index.spec.js +++ /dev/null @@ -1,18 +0,0 @@ -import CounterRoute from 'routes/Counter' - -describe('(Route) Counter', () => { - let _route - - beforeEach(() => { - _route = CounterRoute({}) - }) - - it('Should return a route configuration object', () => { - expect(typeof(_route)).to.equal('object') - }) - - it('Configuration should contain path `counter`', () => { - expect(_route.path).to.equal('counter') - }) - -}) diff --git a/tests/routes/Counter/modules/counter.spec.js b/tests/routes/Counter/modules/counter.spec.js deleted file mode 100644 index 885a20b..0000000 --- a/tests/routes/Counter/modules/counter.spec.js +++ /dev/null @@ -1,125 +0,0 @@ -import { - COUNTER_INCREMENT, - increment, - doubleAsync, - default as counterReducer -} from 'routes/Counter/modules/counter' - -describe('(Redux Module) Counter', () => { - it('Should export a constant COUNTER_INCREMENT.', () => { - expect(COUNTER_INCREMENT).to.equal('COUNTER_INCREMENT') - }) - - describe('(Reducer)', () => { - it('Should be a function.', () => { - expect(counterReducer).to.be.a('function') - }) - - it('Should initialize with a state of 0 (Number).', () => { - expect(counterReducer(undefined, {})).to.equal(0) - }) - - it('Should return the previous state if an action was not matched.', () => { - let state = counterReducer(undefined, {}) - expect(state).to.equal(0) - state = counterReducer(state, {type: '@@@@@@@'}) - expect(state).to.equal(0) - state = counterReducer(state, increment(5)) - expect(state).to.equal(5) - state = counterReducer(state, {type: '@@@@@@@'}) - expect(state).to.equal(5) - }) - }) - - describe('(Action Creator) increment', () => { - it('Should be exported as a function.', () => { - expect(increment).to.be.a('function') - }) - - it('Should return an action with type "COUNTER_INCREMENT".', () => { - expect(increment()).to.have.property('type', COUNTER_INCREMENT) - }) - - it('Should assign the first argument to the "payload" property.', () => { - expect(increment(5)).to.have.property('payload', 5) - }) - - it('Should default the "payload" property to 1 if not provided.', () => { - expect(increment()).to.have.property('payload', 1) - }) - }) - - describe('(Action Creator) doubleAsync', () => { - let _globalState - let _dispatchSpy - let _getStateSpy - - beforeEach(() => { - _globalState = { - counter: counterReducer(undefined, {}) - } - _dispatchSpy = sinon.spy((action) => { - _globalState = { - ..._globalState, - counter: counterReducer(_globalState.counter, action) - } - }) - _getStateSpy = sinon.spy(() => { - return _globalState - }) - }) - - it('Should be exported as a function.', () => { - expect(doubleAsync).to.be.a('function') - }) - - it('Should return a function (is a thunk).', () => { - expect(doubleAsync()).to.be.a('function') - }) - - it('Should return a promise from that thunk that gets fulfilled.', () => { - return doubleAsync()(_dispatchSpy, _getStateSpy).should.eventually.be.fulfilled - }) - - it('Should call dispatch and getState exactly once.', () => { - return doubleAsync()(_dispatchSpy, _getStateSpy) - .then(() => { - _dispatchSpy.should.have.been.calledOnce - _getStateSpy.should.have.been.calledOnce - }) - }) - - it('Should produce a state that is double the previous state.', () => { - _globalState = { counter: 2 } - - return doubleAsync()(_dispatchSpy, _getStateSpy) - .then(() => { - _dispatchSpy.should.have.been.calledOnce - _getStateSpy.should.have.been.calledOnce - expect(_globalState.counter).to.equal(4) - return doubleAsync()(_dispatchSpy, _getStateSpy) - }) - .then(() => { - _dispatchSpy.should.have.been.calledTwice - _getStateSpy.should.have.been.calledTwice - expect(_globalState.counter).to.equal(8) - }) - }) - }) - - // NOTE: if you have a more complex state, you will probably want to verify - // that you did not mutate the state. In this case our state is just a number - // (which cannot be mutated). - describe('(Action Handler) COUNTER_INCREMENT', () => { - it('Should increment the state by the action payload\'s "value" property.', () => { - let state = counterReducer(undefined, {}) - expect(state).to.equal(0) - state = counterReducer(state, increment(1)) - expect(state).to.equal(1) - state = counterReducer(state, increment(2)) - expect(state).to.equal(3) - state = counterReducer(state, increment(-3)) - expect(state).to.equal(0) - }) - }) -}) diff --git a/tests/components/DisplayPicker.spec.js b/tests/routes/Home/components/DisplayPicker.spec.js similarity index 62% rename from tests/components/DisplayPicker.spec.js rename to tests/routes/Home/components/DisplayPicker.spec.js index f3b00e3..914d826 100644 --- a/tests/components/DisplayPicker.spec.js +++ b/tests/routes/Home/components/DisplayPicker.spec.js @@ -1,5 +1,5 @@ import React from 'react' -import DisplayPicker from 'components/DisplayPicker/DisplayPicker' +import DisplayPicker from 'routes/Home/components/DisplayPicker' describe('(Component) DisplayPicker', () => { it('should exist', () => { diff --git a/tests/routes/Home/components/HomeView.spec.js b/tests/routes/Home/components/HomeView.spec.js index c59d3c6..40790b1 100644 --- a/tests/routes/Home/components/HomeView.spec.js +++ b/tests/routes/Home/components/HomeView.spec.js @@ -3,22 +3,10 @@ import { HomeView } from 'routes/Home/components/HomeView' import { render } from 'enzyme' describe('(View) Home', () => { - let _component + // let _component - beforeEach(() => { - _component = render() - }) - - it('Renders a welcome message', () => { - const welcome = _component.find('h4') - expect(welcome).to.exist - expect(welcome.text()).to.match(/Welcome!/) - }) - - it('Renders an awesome duck image', () => { - const duck = _component.find('img') - expect(duck).to.exist - expect(duck.attr('alt')).to.match(/This is a duck, because Redux!/) - }) + // beforeEach(() => { + // _component = render() + // }) }) diff --git a/tests/routes/Home/modules/display.spec.js b/tests/routes/Home/modules/display.spec.js index b6757eb..a175b7a 100644 --- a/tests/routes/Home/modules/display.spec.js +++ b/tests/routes/Home/modules/display.spec.js @@ -1,4 +1,4 @@ -import reducer, { initialState } from 'redux/modules/display' +import reducer, { initialState } from 'routes/Home/modules/display' describe('(Redux) display', () => { describe('(Reducer)', () => {