<!DOCTYPE html>
<html>

  <head>
    <link data-require="bootstrap@4.0.5" data-semver="4.0.5" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" />
    <link rel="stylesheet" href="style.css" />
    <script data-require="lodash.js@4.17.4" data-semver="4.17.4" src="https://cdn.jsdelivr.net/npm/lodash@4.17.4/lodash.min.js"></script>
    <script src="https://jspm.io/system@0.18.js"></script>
    <script src="config.js"></script>
    <script>
      System.import('app').catch(console.error.bind(console));
    </script>
  </head>

  <body>
    <div id="app"></div>
  </body>

</html>
.list-group,
.book-details {
  margin: 30px auto;
}

.book-details {
  padding: 30px;
}

.list-group-item {
  cursor: pointer;
}

.list-group-item:hover {
  background-color: #eee;
}
/*global System */
'use strict';

System.config({
  transpiler: 'babel',
  map: {
    'react': 'https://unpkg.com/react@15.3.2/dist/react.min.js',
    'react-dom': 'https://unpkg.com/react-dom@15.3.2/dist/react-dom.min.js',
    'redux': 'https://unpkg.com/redux@3.7.2/dist/redux.min.js',
    'react-redux': 'https://unpkg.com/react-redux@5.0.6/dist/react-redux.min.js',
    //'axios': 'https://unpkg.com/axios/dist/axios.min.js',
    'app': './src'
  },
  packages: {
    app: {
      main: './index.jsx',
      defaultExtension: false,
    },
  }
});

import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { createStore } from "redux";

import App from "./components/app.jsx";
import reducers from "./reducers/index.jsx";

ReactDOM.render(
  <Provider store={createStore(reducers)}>
    <App />
  </Provider>,
  document.querySelector("#app")
);
import React, { Component } from "react";
import { connect } from "react-redux";
import { selectBook } from "../actions/index.jsx";
import { bindActionCreators } from "redux";

class BookList extends Component {
  renderList() {
    return this.props.books.map(book => {
      return (
        <li
          key={book.title}
          onClick={() => this.props.selectBook(book)}
          className="list-group-item"
        >
          {book.title}
        </li>
      );
    });
  }

  render() {
    return (
      <ul className="list-group col-sm-4">
        {this.renderList()}
      </ul>
    );
  }
}

function mapStateToProps(state) {
  // Whatever is returned will show up as props
  // inside of BookList
  return {
    books: state.books
  };
}

// Anything returned from this function will end up as props
// on the BookList container
function mapDispatchToProps(dispatch) {
  // Whenever selectBook is called, the result shoudl be passed
  // to all of our reducers
  return bindActionCreators({ selectBook: selectBook }, dispatch);
}

// Promote BookList from a component to a container - it needs to know
// about this new dispatch method, selectBook. Make it available
// as a prop.
export default connect(mapStateToProps, mapDispatchToProps)(BookList);
import React from "react";
import { Component } from "react";

import BookList from "../containers/book-list.jsx";
import BookDetail from "../containers/book-detail.jsx";

export default class App extends Component {
  render() {
    return (
      <div>
        <BookList />
        <BookDetail />
      </div>
    );
  }
}
export function selectBook(book) {
  // selectBook is an ActionCreator, it needs to return an action,
  // an object with a type property.
  return {
    type    : "BOOK_SELECTED",
    payload : book
  };
}
import { combineReducers } from "redux";
import BooksReducer from "./reducer_books.jsx";
import ActiveBook from "./reducer_active_book.jsx";

const rootReducer = combineReducers({
  books       : BooksReducer,
  activeBook  : ActiveBook
});

export default rootReducer;
export default function() {
  return [
    { title: "Javascript: The Good Parts", pages: 101 },
    { title: "Harry Potter", pages: 39 },
    { title: "The Dark Tower", pages: 85 },
    { title: "Eloquent Ruby", pages: 1 }
  ];
}
// State argument is not application state, only the state
// this reducer is responsible for
export default function(state = null, action) {
  switch (action.type) {
    case "BOOK_SELECTED":
      return action.payload;
  }

  return state;
}
import React, { Component } from "react";
import { connect } from "react-redux";

class BookDetail extends Component {
  render() {
    if (!this.props.book) {
      return (
        <div className="book-details">
          Please select a book from above to get started.
        </div>
      );
    }

    return (
      <div className="book-details">
        <h3>Details for:</h3>
        <div>Title: {this.props.book.title}</div>
        <div>Pages: {this.props.book.pages}</div>
      </div>
    );
  }
}

function mapStateToProps(state) {
  return {
    book: state.activeBook
  };
}

export default connect(mapStateToProps)(BookDetail);