From e747ece0258fd1a15515a10fb90a290933b291e4 Mon Sep 17 00:00:00 2001 From: AlenaLoik Date: Sun, 10 May 2020 16:31:53 +0300 Subject: [PATCH 1/2] edit input + esc was add --- src/App.js | 33 +++++++- src/components/TodoList/TodoList.js | 121 +++++++++++++++++++++------- 2 files changed, 124 insertions(+), 30 deletions(-) diff --git a/src/App.js b/src/App.js index 4017274b7..5b5e37d3e 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,5 @@ import React, { Component } from 'react'; -import { TodoList } from './components/TodoList/TodoList'; +import TodoList from './components/TodoList/TodoList'; import NewTodo from './components/NewTodo/NewTodo'; import { TodosFilter } from './components/TodosFilter/TodosFilter'; @@ -27,6 +27,35 @@ class App extends Component { })); } + 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 + )), + })); + } + } + handleRemuveCompleted = () => { this.setState(prevState => ({ todos: prevState.todos.filter(todo => ( @@ -107,6 +136,8 @@ class App extends Component { todos={todoView} remuve={this.handleRemuve} toggleComplete={this.toggleComplete} + handleDobleClick={this.handleDobleClick} + editTodo={this.editTodo} /> diff --git a/src/components/TodoList/TodoList.js b/src/components/TodoList/TodoList.js index e00392016..e7e16d01c 100644 --- a/src/components/TodoList/TodoList.js +++ b/src/components/TodoList/TodoList.js @@ -1,34 +1,95 @@ -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, + }); + } + + render() { + return ( + + ); + } +} + +export default TodoList; TodoList.propTypes = { todos: PropTypes.arrayOf( @@ -40,4 +101,6 @@ TodoList.propTypes = { ).isRequired, remuve: PropTypes.func.isRequired, toggleComplete: PropTypes.func.isRequired, + handleDobleClick: PropTypes.func.isRequired, + editTodo: PropTypes.func.isRequired, }; From 93fd528ce070854fdb799a791e12e1d660105457 Mon Sep 17 00:00:00 2001 From: AlenaLoik Date: Tue, 12 May 2020 16:38:17 +0300 Subject: [PATCH 2/2] fixed --- src/App.js | 67 ++++++++++------------- src/components/Footer/Footer.css | 0 src/components/Footer/Footer.js | 46 ++++++++++++++++ src/components/Header/Header.css | 0 src/components/Header/Header.js | 15 +++++ src/components/NewTodo/NewTodo.js | 13 +++-- src/components/TodoList/TodoList.js | 28 +++++----- src/components/TodosFilter/TodosFilter.js | 46 ++++++---------- 8 files changed, 129 insertions(+), 86 deletions(-) create mode 100644 src/components/Footer/Footer.css create mode 100644 src/components/Footer/Footer.js create mode 100644 src/components/Header/Header.css create mode 100644 src/components/Header/Header.js diff --git a/src/App.js b/src/App.js index 5b5e37d3e..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 { 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 @@ -56,7 +56,7 @@ class App extends Component { } } - handleRemuveCompleted = () => { + handleRemoveCompleted = () => { this.setState(prevState => ({ todos: prevState.todos.filter(todo => ( !todo.completed @@ -97,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, +}) => ( +
+ + {itemLeft} + {' '} + item left + + + { + (todos.filter(todo => (todo.completed)).length) + ? ( + + ) + : ('') + } +
+); + +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 e7e16d01c..2f00ac632 100644 --- a/src/components/TodoList/TodoList.js +++ b/src/components/TodoList/TodoList.js @@ -21,6 +21,14 @@ class TodoList extends Component { }); } + handleEdit = (todo) => { + this.props.handleDobleClick(todo); + this.setState(() => ({ + content: todo.content, + submitEditing: true, + })); + } + render() { return (