diff --git a/index.html b/index.html
index 793036f..960cfca 100644
--- a/index.html
+++ b/index.html
@@ -1,5 +1,13 @@
diff --git a/step03/index.html b/step03/index.html
new file mode 100644
index 0000000..321247d
--- /dev/null
+++ b/step03/index.html
@@ -0,0 +1,91 @@
+
+
+
+
+
todos
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/step03/index.js b/step03/index.js
new file mode 100644
index 0000000..e69de29
diff --git a/step03/style.css b/step03/style.css
new file mode 100644
index 0000000..c897b4c
--- /dev/null
+++ b/step03/style.css
@@ -0,0 +1,50 @@
+body {
+ font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
+ width: 400px;
+ margin: 20px auto;
+}
+h1 {
+ text-align: center;
+}
+
+.textfield {
+ width: 80%;
+}
+
+.add {
+ margin-left: 5%;
+}
+
+.button {
+ border: none;
+ padding: 5px 10px;
+}
+
+.filter {
+ margin: 10px 0 0;
+}
+
+.filter button {
+ background: transparent;
+ border: none;
+}
+.filter .active {
+ border-bottom: 2px solid blue;
+}
+
+.todos {
+ list-style: none;
+ padding: 0;
+}
+
+footer {
+ display: flex;
+}
+
+footer span {
+ flex-grow: 1;
+}
+
+.hidden {
+ display: none;
+}
\ No newline at end of file
diff --git a/step04/index.html b/step04/index.html
new file mode 100644
index 0000000..a5fad94
--- /dev/null
+++ b/step04/index.html
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/step04/src/App.tsx b/step04/src/App.tsx
new file mode 100644
index 0000000..23cb3da
--- /dev/null
+++ b/step04/src/App.tsx
@@ -0,0 +1,13 @@
+import React from 'react';
+
+
+export class App extends React.Component {
+ render() {
+
+ return (
+
+
+
+ );
+ }
+}
diff --git a/step04/src/index.tsx b/step04/src/index.tsx
new file mode 100644
index 0000000..1d9694f
--- /dev/null
+++ b/step04/src/index.tsx
@@ -0,0 +1,4 @@
+import React from "react";
+import ReactDOM from "react-dom";
+import { App } from "./App";
+ReactDOM.render(
, document.getElementById("app"));
diff --git a/step05/index.html b/step05/index.html
new file mode 100644
index 0000000..de2c99d
--- /dev/null
+++ b/step05/index.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/step05/src/App.tsx b/step05/src/App.tsx
new file mode 100644
index 0000000..5726b54
--- /dev/null
+++ b/step05/src/App.tsx
@@ -0,0 +1,18 @@
+import React from 'react';
+import { TodoFooter } from './components/TodoFooter';
+import { TodoHeader } from './components/TodoHeader';
+import { TodoList } from './components/TodoList';
+
+
+export class TodoApp extends React.Component {
+ render() {
+
+ return (
+
+
+
+
+
+ );
+ }
+}
diff --git a/step05/src/components/TodoFooter.tsx b/step05/src/components/TodoFooter.tsx
new file mode 100644
index 0000000..ff294ec
--- /dev/null
+++ b/step05/src/components/TodoFooter.tsx
@@ -0,0 +1,13 @@
+import React from "react";
+
+export const TodoFooter = (props: any) => {
+
+ return (
+
+ );
+};
diff --git a/step05/src/components/TodoHeader.tsx b/step05/src/components/TodoHeader.tsx
new file mode 100644
index 0000000..2b2da8b
--- /dev/null
+++ b/step05/src/components/TodoHeader.tsx
@@ -0,0 +1,23 @@
+import React from 'react';
+
+export class TodoHeader extends React.Component {
+
+ render() {
+ return (
+
+
todos
+
+
+
+
+
+
+
+
+ );
+ }
+}
diff --git a/step05/src/components/TodoList.tsx b/step05/src/components/TodoList.tsx
new file mode 100644
index 0000000..93dbc04
--- /dev/null
+++ b/step05/src/components/TodoList.tsx
@@ -0,0 +1,40 @@
+import React from 'react';
+import { TodoListItem } from './TodoListItem';
+
+export class TodoList extends React.Component
{
+ render() {
+ const { filter, todos } = this.props;
+ let filteredTodos: typeof todos = {};
+
+ switch (filter) {
+ case 'completed':
+ Object.keys(todos).forEach(id => {
+ if (todos[id].completed) {
+ filteredTodos[id] = todos[id];
+ }
+ });
+ break;
+
+ case 'active':
+ Object.keys(todos).forEach(id => {
+ if (!todos[id].completed) {
+ filteredTodos[id] = todos[id];
+ }
+ });
+ break;
+
+ default:
+ filteredTodos = todos;
+ break;
+ }
+
+ return (
+
+ );
+ }
+}
diff --git a/step05/src/components/TodoListItem.tsx b/step05/src/components/TodoListItem.tsx
new file mode 100644
index 0000000..1bff0f7
--- /dev/null
+++ b/step05/src/components/TodoListItem.tsx
@@ -0,0 +1,13 @@
+import React from "react";
+
+export class TodoListItem extends React.Component {
+ render() {
+ return (
+
+
+
+ );
+ }
+}
diff --git a/step05/src/index.tsx b/step05/src/index.tsx
new file mode 100644
index 0000000..3289ec8
--- /dev/null
+++ b/step05/src/index.tsx
@@ -0,0 +1,4 @@
+import React from "react";
+import ReactDOM from "react-dom";
+import { TodoApp } from "./App";
+ReactDOM.render(, document.getElementById("app"));
diff --git a/step05/src/style.css b/step05/src/style.css
new file mode 100644
index 0000000..c897b4c
--- /dev/null
+++ b/step05/src/style.css
@@ -0,0 +1,50 @@
+body {
+ font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
+ width: 400px;
+ margin: 20px auto;
+}
+h1 {
+ text-align: center;
+}
+
+.textfield {
+ width: 80%;
+}
+
+.add {
+ margin-left: 5%;
+}
+
+.button {
+ border: none;
+ padding: 5px 10px;
+}
+
+.filter {
+ margin: 10px 0 0;
+}
+
+.filter button {
+ background: transparent;
+ border: none;
+}
+.filter .active {
+ border-bottom: 2px solid blue;
+}
+
+.todos {
+ list-style: none;
+ padding: 0;
+}
+
+footer {
+ display: flex;
+}
+
+footer span {
+ flex-grow: 1;
+}
+
+.hidden {
+ display: none;
+}
\ No newline at end of file
diff --git a/step06/index.html b/step06/index.html
new file mode 100644
index 0000000..de2c99d
--- /dev/null
+++ b/step06/index.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/step06/src/App.tsx b/step06/src/App.tsx
new file mode 100644
index 0000000..d6265ff
--- /dev/null
+++ b/step06/src/App.tsx
@@ -0,0 +1,27 @@
+import React from 'react';
+import { TodoFooter } from './components/TodoFooter';
+import { TodoHeader } from './components/TodoHeader';
+import { TodoList } from './components/TodoList';
+
+
+export class TodoApp extends React.Component {
+ render() {
+
+ const todos = [
+ {key: 1, text: 'Todo 1', completed: true},
+ {key: 2, text: 'Todo 2'},
+ {key: 3, text: 'Todo 3'},
+ {key: 4, text: 'Todo 4'},
+ ];
+
+ const filter = 'all';
+
+ return (
+
+
+
+
+
+ );
+ }
+}
diff --git a/step06/src/components/TodoFooter.tsx b/step06/src/components/TodoFooter.tsx
new file mode 100644
index 0000000..53417df
--- /dev/null
+++ b/step06/src/components/TodoFooter.tsx
@@ -0,0 +1,11 @@
+import React from "react";
+
+export const TodoFooter = (props: any) => {
+ const items = props.todos.filter(todo => !todo.completed)
+ return (
+
+ );
+};
diff --git a/step06/src/components/TodoHeader.tsx b/step06/src/components/TodoHeader.tsx
new file mode 100644
index 0000000..11787c5
--- /dev/null
+++ b/step06/src/components/TodoHeader.tsx
@@ -0,0 +1,21 @@
+import React from "react";
+
+export class TodoHeader extends React.Component {
+ render() {
+ const { filter } = this.props;
+ return (
+
+
todos
+
+
+
+
+
+
+
+
+ );
+ }
+}
diff --git a/step06/src/components/TodoList.tsx b/step06/src/components/TodoList.tsx
new file mode 100644
index 0000000..8fb047a
--- /dev/null
+++ b/step06/src/components/TodoList.tsx
@@ -0,0 +1,28 @@
+import React from 'react';
+import { TodoListItem } from './TodoListItem';
+
+export class TodoList extends React.Component {
+ render() {
+ const { filter, todos } = this.props;
+ let filteredTodos: typeof todos = {};
+
+ filteredTodos = todos.filter(todo => {
+ const matchesActive = filter == 'active' && !todo.completed;
+ const matchesCompleted = filter == 'completed' && todo.completed;
+
+ return filter == 'all' || matchesActive || matchesCompleted;
+ })
+
+ const TodoListItems = filteredTodos.map(todo => {
+ return (
+
+ );
+ })
+
+ return (
+
+ );
+ }
+}
diff --git a/step06/src/components/TodoListItem.tsx b/step06/src/components/TodoListItem.tsx
new file mode 100644
index 0000000..29db423
--- /dev/null
+++ b/step06/src/components/TodoListItem.tsx
@@ -0,0 +1,15 @@
+import React from "react";
+
+export class TodoListItem extends React.Component {
+
+ render() {
+ const {text, completed} = this.props;
+ return (
+
+
+
+ );
+ }
+}
diff --git a/step06/src/index.tsx b/step06/src/index.tsx
new file mode 100644
index 0000000..3289ec8
--- /dev/null
+++ b/step06/src/index.tsx
@@ -0,0 +1,4 @@
+import React from "react";
+import ReactDOM from "react-dom";
+import { TodoApp } from "./App";
+ReactDOM.render(, document.getElementById("app"));
diff --git a/step06/src/style.css b/step06/src/style.css
new file mode 100644
index 0000000..c897b4c
--- /dev/null
+++ b/step06/src/style.css
@@ -0,0 +1,50 @@
+body {
+ font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
+ width: 400px;
+ margin: 20px auto;
+}
+h1 {
+ text-align: center;
+}
+
+.textfield {
+ width: 80%;
+}
+
+.add {
+ margin-left: 5%;
+}
+
+.button {
+ border: none;
+ padding: 5px 10px;
+}
+
+.filter {
+ margin: 10px 0 0;
+}
+
+.filter button {
+ background: transparent;
+ border: none;
+}
+.filter .active {
+ border-bottom: 2px solid blue;
+}
+
+.todos {
+ list-style: none;
+ padding: 0;
+}
+
+footer {
+ display: flex;
+}
+
+footer span {
+ flex-grow: 1;
+}
+
+.hidden {
+ display: none;
+}
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
index 91a0625..a0963f8 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"outDir": "./dist/",
- "noImplicitAny": true,
+ "noImplicitAny": false,
"module": "esnext",
"moduleResolution": "node",
"esModuleInterop": true,
diff --git a/webpack.config.js b/webpack.config.js
index 48e8663..a27dc12 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -2,8 +2,9 @@ const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const entries = {
- step01: './step01/index',
- step02: './step02/index',
+ step04: './step04/src/index',
+ step05: './step05/src/index',
+ step06: './step06/src/index',
playground: './playground/src/index'
};