diff --git a/package.json b/package.json
index bc825e78a..1d8b43708 100755
--- a/package.json
+++ b/package.json
@@ -7,6 +7,7 @@
"author": "Mate Academy",
"license": "GPL-3.0",
"dependencies": {
+ "classnames": "^2.2.6",
"prop-types": "^15.7.2",
"react": "^16.8.6",
"react-dom": "^16.8.6",
diff --git a/src/App.js b/src/App.js
index 33f1939ef..4f6124e94 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,75 +1,147 @@
import React from 'react';
+import getTodos from './api/todos';
+import TodoApp from './TodoApp';
+import TodoList from './TodoList';
+import TodosFilter from './TodosFilter';
-function App() {
- return (
-
-
-
-
+ componentDidMount() {
+ this.setState({
+ visibleTodos: getTodos,
+ });
+ }
+
+ addTodo = (title) => {
+ this.setState(prevState => ({
+ visibleTodos: [
+ ...prevState.visibleTodos,
+ {
+ title,
+ id: Math.ceil(Math.random() * 1000 + prevState.visibleTodos.length),
+ completed: false,
+ },
+ ],
+ }));
+ };
+
+ handlerChangeCompleted = (id) => {
+ this.setState(prevState => ({
+ visibleTodos: prevState.visibleTodos.map((todo) => {
+ if (todo.id === id) {
+ return {
+ ...todo,
+ completed: !todo.completed,
+ };
+ }
+
+ return todo;
+ }),
+ }));
+ };
+
+ handleChangeCompletedAll = () => {
+ this.setState(prevState => {
+ if (prevState.visibleTodos.every(todo => !todo.completed)
+ || prevState.visibleTodos.every(todo => todo.completed)) {
+ return {
+ visibleTodos: prevState.visibleTodos.map(todo => ({
+ ...todo,
+ completed: !todo.completed,
+ })),
+ };
+ } else {
+ return {
+ visibleTodos: prevState.visibleTodos.map(todo => ({
+ ...todo,
+ completed: true,
+ })),
+ };
+ }
+ });
+ };
+
+ handleRemoveTodo = (id) => {
+ this.setState(prevState => ({
+ visibleTodos: prevState.visibleTodos.filter(todo => (
+ todo.id !== id
+ )),
+ }
+ ));
+ };
+
+ handlerFilter = () => {
+ const { currentFilter, visibleTodos } = this.state;
+
+ switch (currentFilter) {
+ case 'all':
+ return visibleTodos;
+ case 'active':
+ return visibleTodos.filter(todo => (
+ !todo.completed));
+ case 'completed':
+ return visibleTodos.filter(todo => (
+ todo.completed));
+ }
+ };
-
-
- );
+
+
+
+ );
+ }
}
export default App;
diff --git a/src/Todo.js b/src/Todo.js
new file mode 100644
index 000000000..4836f5e28
--- /dev/null
+++ b/src/Todo.js
@@ -0,0 +1,33 @@
+import React from 'react';
+
+class Todo extends React.Component {
+ render() {
+ const { todo, changeCompleted, removeTodo} = this.props;
+
+ return (
+
+ changeCompleted(todo.id)}
+ />
+
+
+ );
+ }
+
+}
+
+export default Todo;
diff --git a/src/TodoApp.js b/src/TodoApp.js
new file mode 100644
index 000000000..1186760c9
--- /dev/null
+++ b/src/TodoApp.js
@@ -0,0 +1,50 @@
+import React from 'react';
+import propTypes from 'prop-types';
+
+class TodoApp extends React.Component {
+ state = {
+ title: '',
+ };
+
+ onChangeInput = (event) => {
+ const { value } = event.target;
+
+ this.setState({ title: value });
+ };
+
+ onCLickEnter = (event) => {
+ const { title } = this.state;
+ if (event.keyCode === 13) {
+ event.preventDefault();
+
+ if (!title || title === ' ') {
+ return;
+ }
+
+ this.props.addTodo(title);
+ this.setState({ title: '' });
+ }
+ };
+
+ render() {
+ const { title } = this.state;
+
+ return (
+
+ );
+ }
+}
+
+TodoApp.propTypes = {
+ addTodo: propTypes.func.isRequired,
+};
+
+export default TodoApp;
diff --git a/src/TodoList.js b/src/TodoList.js
new file mode 100644
index 000000000..590c271eb
--- /dev/null
+++ b/src/TodoList.js
@@ -0,0 +1,50 @@
+import React from 'react';
+import propTypes from 'prop-types';
+import classnames from 'classnames';
+import './styles/todoList.css';
+import Todo from './Todo';
+
+const TodoList = ({ todos, changeCompleted, changeCompletedAll, removeTodo}) => (
+
+);
+
+TodoList.propTypes = {
+ todos: propTypes.arrayOf().isRequired,
+ changeCompleted: propTypes.func,
+ changeCompletedAll: propTypes.func,
+};
+
+export default TodoList;
diff --git a/src/TodosFilter.js b/src/TodosFilter.js
new file mode 100644
index 000000000..96a3e5097
--- /dev/null
+++ b/src/TodosFilter.js
@@ -0,0 +1,35 @@
+import React from 'react';
+import propTypes from 'prop-types';
+
+const TodosFilter = ({ handlerFilter }) => {
+
+ return (
+
+ );
+};
+
+TodosFilter.propTypes = {
+ filterAll: propTypes.func,
+ filterCompleted: propTypes.func,
+ filterActive: propTypes.func,
+};
+
+export default TodosFilter;
diff --git a/src/api/todos.js b/src/api/todos.js
new file mode 100644
index 000000000..3e5897268
--- /dev/null
+++ b/src/api/todos.js
@@ -0,0 +1,19 @@
+const todos = [
+ {
+ id: 1,
+ title: 'Learn HTML',
+ completed: false,
+ },
+ {
+ id: 2,
+ title: 'Learn CSS',
+ completed: false,
+ },
+ {
+ id: 3,
+ title: 'Learn JS',
+ completed: false,
+ },
+];
+
+export default todos;
diff --git a/src/index.js b/src/index.js
index ebde5cecc..e31e42b12 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,7 +1,7 @@
import React from 'react';
import ReactDOM from 'react-dom';
-import './base.css';
-import './index.css';
+import './styles/base.css';
+import './styles/index.css';
import App from './App';
ReactDOM.render(
diff --git a/src/base.css b/src/styles/base.css
similarity index 100%
rename from src/base.css
rename to src/styles/base.css
diff --git a/src/index.css b/src/styles/index.css
similarity index 100%
rename from src/index.css
rename to src/styles/index.css
diff --git a/src/styles/todoList.css b/src/styles/todoList.css
new file mode 100644
index 000000000..ca972a794
--- /dev/null
+++ b/src/styles/todoList.css
@@ -0,0 +1,11 @@
+main {
+ display: block;
+}
+
+.todo-completed {
+ text-decoration: line-through;
+}
+
+.filters--active:focus {
+ border-color: rgba(175, 47, 47, 0.2);
+}