diff --git a/3-flux/package.json b/3-flux/package.json
index d04fdd7a..61aab93e 100644
--- a/3-flux/package.json
+++ b/3-flux/package.json
@@ -4,6 +4,7 @@
"description": "",
"main": "webpack.config.js",
"dependencies": {
+ "babel-core": "^6.18.2",
"babel-loader": "^6.2.0",
"babel-plugin-add-module-exports": "^0.1.2",
"babel-plugin-react-html-attrs": "^2.0.0",
diff --git a/3-flux/src/js/pages/Todos.js b/3-flux/src/js/pages/Todos.js
index ff248c83..5e145b9a 100644
--- a/3-flux/src/js/pages/Todos.js
+++ b/3-flux/src/js/pages/Todos.js
@@ -5,7 +5,7 @@ import * as TodoActions from "../actions/TodoActions";
import TodoStore from "../stores/TodoStore";
-export default class Featured extends React.Component {
+export default class Todos extends React.Component {
constructor() {
super();
this.getTodos = this.getTodos.bind(this);
diff --git a/4-redux/package.json b/4-redux/package.json
index 5606144d..47461630 100644
--- a/4-redux/package.json
+++ b/4-redux/package.json
@@ -5,6 +5,7 @@
"main": "webpack.config.js",
"dependencies": {
"axios": "^0.12.0",
+ "babel-core": "^6.17.0",
"babel-loader": "^6.2.0",
"babel-plugin-add-module-exports": "^0.1.2",
"babel-plugin-react-html-attrs": "^2.0.0",
diff --git a/4-redux/src/js/4-async-middleware.js b/4-redux/src/js/4-async-middleware.js
index 777caa1e..235eea33 100644
--- a/4-redux/src/js/4-async-middleware.js
+++ b/4-redux/src/js/4-async-middleware.js
@@ -21,7 +21,7 @@ const reducer = (state=initialState, action) => {
return {...state, fetching: false, error: action.payload}
break;
}
- case "FETCH_USERS_ FULFILLED": {
+ case "FETCH_USERS_FULFILLED": {
return {
...state,
fetching: false,
diff --git a/5-redux-react/package.json b/5-redux-react/package.json
index 141fb42d..bf4c684e 100644
--- a/5-redux-react/package.json
+++ b/5-redux-react/package.json
@@ -5,6 +5,7 @@
"main": "webpack.config.js",
"dependencies": {
"axios": "^0.12.0",
+ "babel-core": "^6.18.2",
"babel-loader": "^6.2.0",
"babel-plugin-add-module-exports": "^0.1.2",
"babel-plugin-react-html-attrs": "^2.0.0",
diff --git a/5-redux-react/src/js/actions/tweetsActions.js b/5-redux-react/src/js/actions/tweetsActions.js
index cba31e31..87926d0f 100644
--- a/5-redux-react/src/js/actions/tweetsActions.js
+++ b/5-redux-react/src/js/actions/tweetsActions.js
@@ -2,7 +2,15 @@ import axios from "axios";
export function fetchTweets() {
return function(dispatch) {
- axios.get("http://rest.learncode.academy/api/test123/tweets")
+ dispatch({type: "FETCH_TWEETS"});
+
+ /*
+ http://rest.learncode.academy is a public test server, so another user's experimentation can break your tests
+ If you get console errors due to bad data:
+ - change "reacttest" below to any other username
+ - post some tweets to http://rest.learncode.academy/api/yourusername/tweets
+ */
+ axios.get("http://rest.learncode.academy/api/reacttest/tweets")
.then((response) => {
dispatch({type: "FETCH_TWEETS_FULFILLED", payload: response.data})
})
diff --git a/5-redux-react/src/js/components/Layout.js b/5-redux-react/src/js/components/Layout.js
index 41517fb3..8d416cd7 100644
--- a/5-redux-react/src/js/components/Layout.js
+++ b/5-redux-react/src/js/components/Layout.js
@@ -27,7 +27,7 @@ export default class Layout extends React.Component {
return
{user.name}
diff --git a/6-mobx-react/.babelrc b/6-mobx-react/.babelrc
new file mode 100644
index 00000000..1957865a
--- /dev/null
+++ b/6-mobx-react/.babelrc
@@ -0,0 +1,4 @@
+{
+ "presets": ['react', 'es2015'],
+ "plugins": ['transform-decorators-legacy', 'transform-class-properties']
+}
diff --git a/6-mobx-react/.gitignore b/6-mobx-react/.gitignore
new file mode 100644
index 00000000..fd4f2b06
--- /dev/null
+++ b/6-mobx-react/.gitignore
@@ -0,0 +1,2 @@
+node_modules
+.DS_Store
diff --git a/6-mobx-react/.nvmrc b/6-mobx-react/.nvmrc
new file mode 100644
index 00000000..dffc266d
--- /dev/null
+++ b/6-mobx-react/.nvmrc
@@ -0,0 +1 @@
+v6.3.0
diff --git a/6-mobx-react/package.json b/6-mobx-react/package.json
new file mode 100644
index 00000000..2bafc21d
--- /dev/null
+++ b/6-mobx-react/package.json
@@ -0,0 +1,31 @@
+{
+ "name": "react-mobx-todos",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "start": "webpack-dev-server --content-base src --inline --hot"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "mobx": "^2.3.7",
+ "mobx-react": "^3.5.1",
+ "react": "^15.2.1",
+ "react-dom": "^15.3.0"
+ },
+ "devDependencies": {
+ "babel-core": "^6.17.0",
+ "babel-loader": "^6.2.4",
+ "babel-plugin-transform-class-properties": "^6.10.2",
+ "babel-plugin-transform-decorators-legacy": "^1.3.4",
+ "babel-preset-es2015": "^6.9.0",
+ "babel-preset-react": "^6.11.1",
+ "css-loader": "^0.23.1",
+ "react-addons-test-utils": "^15.3.0",
+ "style-loader": "^0.13.1",
+ "webpack": "^1.13.1",
+ "webpack-dev-server": "^1.14.1"
+ }
+}
diff --git a/6-mobx-react/src/css/main.css b/6-mobx-react/src/css/main.css
new file mode 100644
index 00000000..8d6ed00c
--- /dev/null
+++ b/6-mobx-react/src/css/main.css
@@ -0,0 +1,50 @@
+html,
+body {
+ margin: 0;
+ padding: 0;
+}
+
+body {
+ font-family: 'Slabo 27px', serif;
+ background: #f5f5f5;
+ color: #4d4d4d;
+ min-width: 230px;
+ max-width: 550px;
+ margin: 0 auto;
+ -webkit-font-smoothing: antialiased;
+ -moz-font-smoothing: antialiased;
+ font-smoothing: antialiased;
+ font-weight: 300;
+}
+
+input {
+ border-radius: 5px;
+ padding: 5px;
+ border: 1px solid rgba(0,0,0,0.3);
+ margin-right: 10px
+}
+
+input::-webkit-input-placeholder {
+ font-style: italic;
+ font-weight: 300;
+ color: rgba(0,0,0,0.3);
+}
+
+input::-moz-placeholder {
+ font-style: italic;
+ font-weight: 300;
+ color: rgba(0,0,0,0.3);
+}
+
+input::input-placeholder {
+ font-style: italic;
+ font-weight: 300;
+ color: rgba(0,0,0,0.3);
+}
+
+h1 {
+ font-weight: 100;
+ font-size: 100px;
+ padding:0;
+ margin: 0;
+}
diff --git a/6-mobx-react/src/index.html b/6-mobx-react/src/index.html
new file mode 100644
index 00000000..a9e74ecd
--- /dev/null
+++ b/6-mobx-react/src/index.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/6-mobx-react/src/js/TodoList.js b/6-mobx-react/src/js/TodoList.js
new file mode 100644
index 00000000..b54204a8
--- /dev/null
+++ b/6-mobx-react/src/js/TodoList.js
@@ -0,0 +1,39 @@
+import React from "react"
+import { observer } from "mobx-react"
+
+
+@observer
+export default class TodoList extends React.Component {
+ createNew(e) {
+ if (e.which === 13) {
+ this.props.store.createTodo(e.target.value)
+ e.target.value = ""
+ }
+ }
+
+ filter(e) {
+ this.props.store.filter = e.target.value
+ }
+
+ toggleComplete(todo) {
+ todo.complete = !todo.complete
+ }
+
+ render() {
+ const { clearComplete, filter, filteredTodos, todos } = this.props.store
+
+ const todoLis = filteredTodos.map(todo => (
+
+
+ {todo.value}
+
+ ))
+ return
+ }
+}
diff --git a/6-mobx-react/src/js/TodoStore.js b/6-mobx-react/src/js/TodoStore.js
new file mode 100644
index 00000000..7a40b5cd
--- /dev/null
+++ b/6-mobx-react/src/js/TodoStore.js
@@ -0,0 +1,34 @@
+import { computed, observable } from "mobx"
+
+class Todo {
+ @observable value
+ @observable id
+ @observable complete
+
+ constructor(value) {
+ this.value = value
+ this.id = Date.now()
+ this.complete = false
+ }
+}
+
+export class TodoStore {
+ @observable todos = []
+ @observable filter = ""
+ @computed get filteredTodos() {
+ var matchesFilter = new RegExp(this.filter, "i")
+ return this.todos.filter(todo => !this.filter || matchesFilter.test(todo.value))
+ }
+
+ createTodo(value) {
+ this.todos.push(new Todo(value))
+ }
+
+ clearComplete = () => {
+ const incompleteTodos = this.todos.filter(todo => !todo.complete)
+ this.todos.replace(incompleteTodos)
+ }
+}
+
+export default new TodoStore
+
diff --git a/6-mobx-react/src/js/main.js b/6-mobx-react/src/js/main.js
new file mode 100644
index 00000000..6672df8a
--- /dev/null
+++ b/6-mobx-react/src/js/main.js
@@ -0,0 +1,10 @@
+import "../css/main.css"
+import React from "react"
+import ReactDOM from "react-dom"
+import TodoStore from "./TodoStore"
+import TodoList from "./TodoList"
+
+const app = document.getElementById("app")
+
+ReactDOM.render(
, app)
+
diff --git a/6-mobx-react/webpack.config.js b/6-mobx-react/webpack.config.js
new file mode 100644
index 00000000..de21163e
--- /dev/null
+++ b/6-mobx-react/webpack.config.js
@@ -0,0 +1,29 @@
+var debug = process.env.NODE_ENV !== "production";
+var webpack = require('webpack');
+var path = require('path');
+
+module.exports = {
+ context: path.join(__dirname, "src"),
+ devtool: debug ? "inline-sourcemap" : null,
+ entry: "./js/main.js",
+ module: {
+ loaders: [
+ {
+ test: /\.js$/,
+ exclude: /(node_modules|bower_components)/,
+ loader: 'babel-loader',
+ query: { presets: ['es2015', 'react'], plugins: ["transform-decorators-legacy", "transform-class-properties"] }
+ },
+ { test: /\.css$/, loader: "style-loader!css-loader" },
+ ]
+ },
+ output: {
+ path: path.join(__dirname, "src"),
+ filename: "main.min.js"
+ },
+ plugins: debug ? [] : [
+ new webpack.optimize.DedupePlugin(),
+ new webpack.optimize.OccurenceOrderPlugin(),
+ new webpack.optimize.UglifyJsPlugin({ mangle: false, sourcemap: false }),
+ ],
+};