Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First implementation #23

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#airbnb
root = true

[*]
indent_style = space
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
end_of_line = lf
#airbnb
root = true
[*]
indent_style = space
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
end_of_line = lf
4 changes: 2 additions & 2 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
/build
/node_modules
/build
/node_modules
6 changes: 3 additions & 3 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module.exports = {
extends: '@mate-academy/eslint-config-react',
};
module.exports = {
extends: '@mate-academy/eslint-config-react',
};
20 changes: 10 additions & 10 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
.idea
node_modules
.DS_Store
yarn.lock
package-lock.json

npm-debug.log*
yarn-debug.log*
yarn-error.log*
build
.idea
node_modules
.DS_Store
yarn.lock
package-lock.json
npm-debug.log*
yarn-debug.log*
yarn-error.log*
build
2 changes: 1 addition & 1 deletion .stylelintignore
Original file line number Diff line number Diff line change
@@ -1 +1 @@
/build
/build
8 changes: 4 additions & 4 deletions .stylelintrc.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module.exports = {
extends: "@mate-academy/stylelint-config",
rules: {}
};
module.exports = {
extends: "@mate-academy/stylelint-config",
rules: {}
};
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Resources:
```jsx harmony
<TodoList items={todos} />
```
1. Implement `TodoItem` component with ability to toggle the `complete` status.
1. Implement `TodoApp` component with ability to toggle the `complete` status.
1. Add ability to toggle the completed status of all the todos.
1. Create `TodosFilter` component to switch between `all`/`active`/`comleted` todos
1. Add ability to remove an item.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"homepage": "http://mate-academy.github.io/react_todo-app",
"homepage": "http://artem-meleshko.github.io/react_todo-app",
"name": "react-todo-app",
"version": "0.1.0",
"private": true,
Expand Down
160 changes: 91 additions & 69 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,75 +1,97 @@
import React from 'react';
import TodoList from './TodoList';
import TodoApp from './TodoApp';
import TodosFilter from './TodosFilter';

function App() {
return (
<section className="todoapp">
<header className="header">
<h1>todos</h1>

<input
className="new-todo"
placeholder="What needs to be done?"
/>
</header>

<section className="main" style={{ display: 'block' }}>
<input type="checkbox" id="toggle-all" className="toggle-all" />
<label htmlFor="toggle-all">Mark all as complete</label>

<ul className="todo-list">
<li className="">
<div className="view">
<input type="checkbox" className="toggle" id="todo-1" />
<label htmlFor="todo-1">sdfsdfsdf</label>
<button type="button" className="destroy" />
</div>
</li>

<li className="">
<div className="view">
<input type="checkbox" className="toggle" id="todo-2" />
<label htmlFor="todo-2">sakgjdfgkhjasgdhjfhs</label>
<button type="button" className="destroy" />
</div>
</li>

<li className="">
<div className="view">
<input type="checkbox" className="toggle" id="todo-3" />
<label htmlFor="todo-3">sddfgdfgdf</label>
<button type="button" className="destroy" />
</div>
</li>
</ul>
</section>
class App extends React.Component {
state = {
todos: [],
filter: 0, // 0 - all, 1 - Active, 2- Completed
};

handleChangeFilter = newFilterValue => () => {
this.setState({
filter: newFilterValue,
});
};

addTodo = (todo) => {
this.setState(prevState => ({
todos: [...prevState.todos, todo],
}));
};

destroyItem = (id) => {
this.setState(prevState => ({
todos: prevState.todos.filter(todo => id !== todo.id),
}));
};

handleOnchange = (id, completed) => {
const { todos } = this.state;

const newTodos = todos.map(todo => ((todo.id === id)
? { ...todo, completed }
: todo));

this.setState({
todos: newTodos,
});
};

render() {
const { todos, filter } = this.state;
const notCompletedCount = todos.filter(todo => !todo.completed).length;
let filteredList;

<footer className="footer" style={{ display: 'block' }}>
<span className="todo-count">
3 items left
</span>

<ul className="filters">
<li>
<a href="#/" className="selected">All</a>
</li>

<li>
<a href="#/active">Active</a>
</li>

<li>
<a href="#/completed">Completed</a>
</li>
</ul>

<button
type="button"
className="clear-completed"
style={{ display: 'block' }}
/>
</footer>
</section>
);
switch (filter) {
case 0:
filteredList = todos;
break;
case 1:
filteredList = todos.filter(todo => !todo.completed);
break;
case 2:
filteredList = todos.filter(todo => todo.completed);
break;
default:
// do nothing
}

return (
<section className="todoapp">
<header className="header">
<h1>todos</h1>

<TodoApp addNewTodo={this.addTodo} />
</header>

<section className="main" style={{ display: 'block' }}>
<input type="checkbox" id="toggle-all" className="toggle-all" />
<label htmlFor="toggle-all">Mark all as complete</label>

<TodoList
todos={filteredList}
handleChange={this.handleOnchange}
destroyItem={this.destroyItem}
/>
</section>

<footer className="footer" style={{ display: 'block' }}>
<span className="todo-count">
{`${notCompletedCount} items left`}
</span>

<TodosFilter changeFilter={this.handleChangeFilter} filter={filter} />
<button
type="button"
className="clear-completed"
style={{ display: 'block' }}
/>
</footer>
</section>
);
}
}

export default App;
45 changes: 45 additions & 0 deletions src/TodoApp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from 'react';

class TodoApp extends React.Component {
state = {
title: '',
id: (new Date()).valueOf(),
};

handleChange = (event) => {
this.setState({
title: event.target.value,
});
};

handleKeyUp = (event) => {
const { addNewTodo } = this.props;
const { id, title } = this.state;

if (title !== '' && event.keyCode === 13) {
addNewTodo({
id,
title,
completed: false,
});
this.setState({
title: '',
id: id + 1,
});
}
};

render() {
return (
<input
className="new-todo"
placeholder="What needs to be done?"
value={this.state.title}
onChange={this.handleChange}
onKeyUp={this.handleKeyUp}
/>
);
}
}

export default TodoApp;
44 changes: 44 additions & 0 deletions src/TodoItem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React from 'react';

class TodoItem extends React.Component {
state = {
isEditing: false,
currentTitle: this.props.todo.title,
};

handleChange = () => {
const { todo, handleChangeItem } = this.props;

handleChangeItem(todo.id, !todo.completed);
};

handleDestroy = () => {
const { todo, handleDestroyItem } = this.props;

handleDestroyItem(todo.id);
};

render() {
const { todo } = this.props;

return (
<div className="view">
<input
type="checkbox"
className="toggle"
id={`todo-${todo.id}`}
onChange={this.handleChange}
/>
{/* eslint-disable-next-line jsx-a11y/label-has-for */}
<label htmlFor={`todo-${todo.id}`}>{todo.title}</label>
<button
type="button"
className="destroy"
onClick={this.handleDestroy}
/>
</div>
);
}
}

export default TodoItem;
27 changes: 27 additions & 0 deletions src/TodoList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';
import TodoItem from './TodoItem';

class TodoList extends React.Component {
render() {
const { todos, handleChange, destroyItem } = this.props;

return (
<ul className="todo-list">
{todos.map(todo => (
<li
className={todo.completed === true ? 'completed' : ''}
key={todo.id}
>
<TodoItem
todo={todo}
handleChangeItem={handleChange}
handleDestroyItem={destroyItem}
/>
</li>
))}
</ul>
);
}
}

export default TodoList;
Loading