diff --git a/client/client.js b/client/client.js
index 8b13789..2464ca2 100644
--- a/client/client.js
+++ b/client/client.js
@@ -1 +1,28 @@
+import React from 'react';
+import {render} from 'react-dom';
+import App from '../components/App';
+import configureStore from '../redux/store';
+import { Provider } from 'react-redux';
+//configure and create our store
+//var store = createStore (reducers, initialState) // []
+
+let initialState = {
+ todos: [{
+ id: 0,
+ completed: false,
+ text: 'Initial todo for demo purposes'
+ }]
+}
+
+let store = configureStore(initialState)
+
+
+
+render (
+
+
+
+, document.getElementById('app')
+
+)
diff --git a/client/index.html b/client/index.html
index 7a2106d..4c0c135 100644
--- a/client/index.html
+++ b/client/index.html
@@ -5,7 +5,6 @@
React Todo List
- This is not a React app yet!
diff --git a/components/App.js b/components/App.js
index 8b13789..6f50b56 100644
--- a/components/App.js
+++ b/components/App.js
@@ -1 +1,33 @@
+import React, {Component} from 'react';
+import TodoInput from './TodoInput';
+import TodoList from './TodoList';
+import { connect } from 'react-redux';
+import { bindActionCreators } from 'redux';
+import actions from '../redux/actions';
+
+class App extends Component {
+ render(){
+ return(
+
+
+
Todo List
+
+
+
+ )
+ }
+}
+
+function mapStateToProps(state) {
+ return state
+}
+
+function mapDispatchToProps(dispatch) {
+ return {
+ actions: bindActionCreators(actions, dispatch)
+ }
+}
+
+
+export default connect(mapStateToProps, mapDispatchToProps)(App);
diff --git a/components/TodoInput.js b/components/TodoInput.js
new file mode 100644
index 0000000..8bdc86f
--- /dev/null
+++ b/components/TodoInput.js
@@ -0,0 +1,37 @@
+import React, {Component} from 'react';
+
+class TodoInput extends Component {
+ constructor(props){
+ super(props)
+ this.state = {
+ inputText: ''
+ }
+ }
+
+ handleChange(event){
+ this.setState({inputText: event.target.value})
+ }
+
+handleSubmit(event) {
+ event.preventDefault()
+ this.props.addTodo(this.state.inputText)
+}
+
+
+ render(){
+ return (
+
+
+
+ )
+ }
+}
+
+export default TodoInput;
diff --git a/components/TodoItem.js b/components/TodoItem.js
new file mode 100644
index 0000000..4dc6c02
--- /dev/null
+++ b/components/TodoItem.js
@@ -0,0 +1,27 @@
+import React, {Component} from 'react';
+
+class TodoItem extends Component {
+
+ handleComplete () {
+ this.props.actions.completeTodo(this.props.todo.id)
+ }
+
+ handleDelete(){
+ this.props.actions.deleteTodo(this.props.todo.id)
+
+ }
+
+
+
+ render(){
+ return (
+
+ {this.props.todo.text}
+
+
+
+
+ )
+ }
+}
+export default TodoItem;
diff --git a/components/TodoList.js b/components/TodoList.js
new file mode 100644
index 0000000..f184f06
--- /dev/null
+++ b/components/TodoList.js
@@ -0,0 +1,20 @@
+import React, {Component} from 'react';
+import TodoItem from './TodoItem';
+
+class TodoList extends Component {
+
+ render(){
+ return (
+
+
+ {
+ this.props.todos.map((todo) => {
+ return
+ })
+ }
+
+
+ )
+ }
+}
+export default TodoList;
diff --git a/package.json b/package.json
index 034be19..22e9495 100644
--- a/package.json
+++ b/package.json
@@ -17,9 +17,15 @@
"babel-loader": "^6.2.2",
"babel-preset-es2015": "^6.3.13",
"babel-preset-react": "^6.3.13",
+ "babel-preset-react-hmre": "^1.1.1",
"express": "^4.13.4",
"react": "^0.14.7",
"react-dom": "^0.14.7",
- "webpack": "^1.12.13"
+ "react-redux": "^5.0.4",
+ "redux": "^3.6.0",
+ "redux-logger": "^3.0.1",
+ "webpack": "^1.12.13",
+ "webpack-dev-middleware": "^1.10.2",
+ "webpack-hot-middleware": "^2.18.0"
}
}
diff --git a/redux/actions.js b/redux/actions.js
new file mode 100644
index 0000000..d8baf24
--- /dev/null
+++ b/redux/actions.js
@@ -0,0 +1,24 @@
+let actions = {
+ addTodo: function(text) {
+ return {
+ type: 'ADD_TODO',
+ text: text
+ }
+ },
+
+ completeTodo: function (id){
+ return {
+ type: 'COMPLETE_TODO',
+ id: id
+ }
+ },
+
+ deleteTodo: function (id) {
+ return {
+ type: 'DELETE_TODO',
+ id:id
+ }
+ }
+}
+
+export default actions;
diff --git a/redux/reducer.js b/redux/reducer.js
new file mode 100644
index 0000000..d2ce8fd
--- /dev/null
+++ b/redux/reducer.js
@@ -0,0 +1,39 @@
+function getId(state){
+ return state.todos.reduce((maxId, todo) => {
+ return Math.max(todo.id, maxId)
+ },-1) + 1
+}
+
+
+let reducer = function (state, action) {
+ switch (action.type) {
+ case 'ADD_TODO':
+ console.log('got to correct add todo');
+ return Object.assign({}, state, {
+ todos: [{
+ text: action.text,
+ completed: false,
+ id: getId(state)
+ }, ...state.todos]
+ })
+ case 'COMPLETE_TODO':
+ console.log('COMPLETE_TODO');
+ return Object.assign({}, state, {
+ todos: state.todos.map((todo) => {
+ return todo.id === action.id ?
+ Object.assign({}, todo, {completed: !todo.completed}) : todo
+ })
+ })
+ case 'DELETE_TODO':
+ console.log('DELETE_TODO');
+ return Object.assign({}, state, {
+ todos: state.todos.filter((todo) => {
+ return todo.id !== action.id
+ })
+ })
+ default:
+ return state;
+ }
+}
+
+export default reducer;
diff --git a/redux/store.js b/redux/store.js
new file mode 100644
index 0000000..9d9e79b
--- /dev/null
+++ b/redux/store.js
@@ -0,0 +1,12 @@
+import { applyMiddleware, compose, createStore } from 'redux';
+import reducer from './reducer';
+import { createLogger } from 'redux-logger';
+
+let finalCreateStore = compose (
+ applyMiddleware(createLogger())
+)(createStore)
+
+
+export default function configureStore (initialState = { todos: [] }) {
+ return createStore(reducer, initialState)
+}
diff --git a/server/server.js b/server/server.js
index 51a4946..c6d2160 100644
--- a/server/server.js
+++ b/server/server.js
@@ -1,8 +1,16 @@
var express = require('express');
var path = require('path');
+var config = require('../webpack.config.js');
+var webpack = require('webpack');
+var webpackDevMiddleware = require('webpack-dev-middleware');
+var webpackHotMiddleware = require('webpack-hot-middleware');
var app = express();
+var compiler = webpack(config);
+app.use(webpackDevMiddleware(compiler, {noInfo: true, publicPath: config.output.publicPath}));
+app.use(webpackHotMiddleware(compiler));
+
app.use(express.static('./dist'));
app.use('/', function (req, res) {
diff --git a/webpack.config.js b/webpack.config.js
index 8b13789..ae5bfd8 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -1 +1,31 @@
+const webpack = require('webpack');
+module.exports = {
+ devtool:'inline-source-map',
+ entry: [
+ 'webpack-hot-middleware/client',
+ './client/client.js'
+ ],
+ output: {
+ path: require('path').resolve('./dist'),
+ filename: 'bundle.js',
+ publicPath: '/',
+ hot: true
+ },
+ plugins:[
+ new webpack.HotModuleReplacementPlugin(),
+ new webpack.NoErrorsPlugin()
+ ],
+ module: {
+ loaders: [
+ {
+ test: /\.js$/,
+ loader: 'babel-loader',
+ exclude: /node_modules/,
+ query: {
+ presets: ['react', 'es2015', 'react-hmre']
+ }
+ }
+ ]
+ }
+}