diff --git a/src/App.js b/src/App.js index 4017274b7..aa472ca50 100644 --- a/src/App.js +++ b/src/App.js @@ -1,7 +1,7 @@ import React, { Component } from 'react'; -import { TodoList } from './components/TodoList/TodoList'; -import NewTodo from './components/NewTodo/NewTodo'; -import { TodosFilter } from './components/TodosFilter/TodosFilter'; +import TodoList from './components/TodoList/TodoList'; +import { Footer } from './components/Footer/Footer'; +import { Header } from './components/Header/Header'; class App extends Component { state = { @@ -19,7 +19,7 @@ class App extends Component { this.setState({ showParam: todoToShow }); } - handleRemuve = (id) => { + handleRemove = (id) => { this.setState(prevState => ({ todos: prevState.todos.filter(todo => ( todo.id !== id @@ -27,7 +27,36 @@ class App extends Component { })); } - handleRemuveCompleted = () => { + handleDobleClick = ({ id }) => { + this.setState(prevState => ({ + todos: prevState.todos.map(todo => ( + (todo.id !== id) ? ({ + ...todo, editing: false, + }) : ({ + ...todo, editing: true, + }) + )), + })); + } + + editTodo = (content) => { + if (content) { + this.setState(prevState => ({ + todos: prevState.todos.map(todo => ( + (todo.editing) ? ({ + ...todo, content, + }) : todo)), + })); + } else { + this.setState(prevState => ({ + todos: prevState.todos.filter(todo => ( + !todo.editing + )), + })); + } + } + + handleRemoveCompleted = () => { this.setState(prevState => ({ todos: prevState.todos.filter(todo => ( !todo.completed @@ -68,36 +97,44 @@ class App extends Component { } } - render() { + getTodos = (status) => { let todoView = []; + const { todos } = this.state; - switch (this.state.showParam) { + switch (status) { case 'active': - todoView = [...this.state.todos].filter(todo => ( + todoView = todos.filter(todo => ( !todo.completed )); break; case 'completed': - todoView = [...this.state.todos].filter(todo => ( + todoView = todos.filter(todo => ( todo.completed )); break; default: - todoView = [...this.state.todos]; + todoView = todos; } + return todoView; + } + + render() { + const { todos, showParam } = this.state; + const todoView = this.getTodos(showParam); + const itemLeft = todos.filter(todo => ( + !todo.completed)).length; + return (
-
-

todos

- -
- {(this.state.todos.length) +
+ {(todos.length) ? ( <>
Mark all as complete
- -
- - {this.state.todos.filter(todo => ( - !todo.completed)).length} - item left - - - { - (this.state.todos.filter(todo => ( - todo.completed)).length) - ? ( - - ) - : ('') - } -
+
diff --git a/src/components/Footer/Footer.css b/src/components/Footer/Footer.css new file mode 100644 index 000000000..e69de29bb diff --git a/src/components/Footer/Footer.js b/src/components/Footer/Footer.js new file mode 100644 index 000000000..fba79705b --- /dev/null +++ b/src/components/Footer/Footer.js @@ -0,0 +1,46 @@ +import React from 'react'; +import './Footer.css'; +import PropTypes from 'prop-types'; +import { TodosFilter } from '../TodosFilter/TodosFilter'; + +export const Footer = ({ + todos, + updateTodosToShow, + handleRemoveCompleted, + itemLeft, +}) => ( + +); + +Footer.propTypes = { + todos: PropTypes.arrayOf( + PropTypes.shape({ + content: PropTypes.string.isRequired, + id: PropTypes.number.isRequired, + completed: PropTypes.bool.isRequired, + }), + ).isRequired, + updateTodosToShow: PropTypes.func.isRequired, + handleRemoveCompleted: PropTypes.func.isRequired, + itemLeft: PropTypes.number.isRequired, +}; diff --git a/src/components/Header/Header.css b/src/components/Header/Header.css new file mode 100644 index 000000000..e69de29bb diff --git a/src/components/Header/Header.js b/src/components/Header/Header.js new file mode 100644 index 000000000..1a79fa25a --- /dev/null +++ b/src/components/Header/Header.js @@ -0,0 +1,15 @@ +import React from 'react'; +import './Header.css'; +import PropTypes from 'prop-types'; +import NewTodo from '../NewTodo/NewTodo'; + +export const Header = ({ addTodo }) => ( +
+

todos

+ +
+); + +Header.propTypes = { + addTodo: PropTypes.func.isRequired, +}; diff --git a/src/components/NewTodo/NewTodo.js b/src/components/NewTodo/NewTodo.js index 32777a399..4cc7dd0ba 100644 --- a/src/components/NewTodo/NewTodo.js +++ b/src/components/NewTodo/NewTodo.js @@ -5,8 +5,6 @@ import PropTypes from 'prop-types'; class NewTodo extends Component { state = { content: '', - id: 1, - completed: false, } handleChange = (event) => { @@ -17,13 +15,18 @@ class NewTodo extends Component { handleSubmit = (e) => { e.preventDefault(); + const { content } = this.state; + const id = +Date.now(); + const completed = false; + const todo = { + content, id, completed, + }; - if (this.state.content) { - this.props.addTodo(this.state); + if (content) { + this.props.addTodo(todo); this.setState(prevState => ({ content: '', - id: prevState.id + 1, })); } } diff --git a/src/components/TodoList/TodoList.js b/src/components/TodoList/TodoList.js index e00392016..2f00ac632 100644 --- a/src/components/TodoList/TodoList.js +++ b/src/components/TodoList/TodoList.js @@ -1,34 +1,93 @@ -import React from 'react'; +import React, { Component } from 'react'; import PropTypes from 'prop-types'; -export const TodoList = ({ todos, remuve, toggleComplete }) => ( - -); +class TodoList extends Component { + state = { + content: '', + submitEditing: true, + } + + handleChange = (event) => { + this.setState({ + content: event.target.value.trim(), + }); + } + + handleSubmit = (e) => { + e.preventDefault(); + this.props.editTodo(this.state.content); + this.setState({ + submitEditing: false, + }); + } + + handleEdit = (todo) => { + this.props.handleDobleClick(todo); + this.setState(() => ({ + content: todo.content, + submitEditing: true, + })); + } + + render() { + return ( + + ); + } +} + +export default TodoList; TodoList.propTypes = { todos: PropTypes.arrayOf( @@ -38,6 +97,8 @@ TodoList.propTypes = { completed: PropTypes.bool.isRequired, }), ).isRequired, - remuve: PropTypes.func.isRequired, + remove: PropTypes.func.isRequired, toggleComplete: PropTypes.func.isRequired, + handleDobleClick: PropTypes.func.isRequired, + editTodo: PropTypes.func.isRequired, }; diff --git a/src/components/TodosFilter/TodosFilter.js b/src/components/TodosFilter/TodosFilter.js index a75393d27..d6038f946 100644 --- a/src/components/TodosFilter/TodosFilter.js +++ b/src/components/TodosFilter/TodosFilter.js @@ -2,34 +2,24 @@ import React from 'react'; import './TodosFilter.css'; import PropTypes from 'prop-types'; -export const TodosFilter = ({ updateTodosToShow }) => ( - -); +export const TodosFilter = ({ updateTodosToShow }) => { + const statuses = ['all', 'active', 'completed']; + + return ( + + ); +}; TodosFilter.propTypes = { updateTodosToShow: PropTypes.func.isRequired,