Skip to content

Commit

Permalink
add task solution
Browse files Browse the repository at this point in the history
  • Loading branch information
Marina Rohozhynska committed Nov 26, 2023
1 parent 1085a28 commit 9657b38
Show file tree
Hide file tree
Showing 10 changed files with 347 additions and 396 deletions.
225 changes: 219 additions & 6 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,224 @@
import React from 'react';
import { TodosProvider } from './Utils/TodosContext';
import { TodoApp } from './Components/TodoApp/TodoApp';
import React, { useState, useMemo } from 'react';
import { Todo } from './types/Todo';
import { TodoList } from './сomponents/TodoList/TodoList';
import { TodosFilter } from './сomponents/TodoFilter/TodoFilter';

enum Status {
all = '#/',
active = '#/active',
completed = '#/completed',
}

function filterTodos(todos: Todo[], status: string):Todo[] {
return todos.filter(todo => {
if (status === Status.active) {
return !todo.completed;
}

if (status === Status.completed) {
return todo.completed;
}

return true;
});
}

const storedTodos = localStorage.getItem('todos');
const todos = storedTodos ? JSON.parse(storedTodos) : [];

export const App: React.FC = () => {
const [todo, setTodo] = useState('');
const [todoList, setTodoList] = useState<Todo[]>(todos);
const [statusButton, setStatusButton] = useState('#/');
const [isEdited, setIsEdited] = useState('');

const visibleTodos = useMemo(() => filterTodos(todoList, statusButton),
[todoList, statusButton]);

const changeNameAction
= (
event: React.KeyboardEvent<HTMLInputElement>,
currTodo: Todo,
currValue: string,
) => {
if (event.key === 'Enter') {
if (currValue.trim() !== '') {
const changeable = [...todoList]
.map(changeableTodo => {
if (currTodo.id === changeableTodo.id) {
return {
...changeableTodo,
title: currValue,
};
}

return changeableTodo;
});

setTodoList(changeable);
setIsEdited('');
}

if (currValue.trim() === '') {
const changeable = [...todoList]
.filter(changeableTodo => currTodo.id !== changeableTodo.id);

setTodoList(changeable);
setIsEdited('');
}
}

if (event.key === 'Escape') {
setIsEdited('');
}
};

const handleSetTodo = (event: React.ChangeEvent<HTMLInputElement>) => {
setTodo(event.target.value);
};

const todoLeftCount = () => {
let count = 0;

todoList.forEach(currentTodo => {
if (!currentTodo.completed) {
count += 1;
}
});

return count;
};

const addTodo = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();

const newTodo: Todo = {
id: +new Date(),
title: todo,
completed: false,
};

setTodoList((prevTodoList) => [...prevTodoList, newTodo]);
setTodo('');
};

const handleDeleteTodo = (todoId: number) => {
setTodoList(currentTodoList => {
return currentTodoList.filter(todoItem => todoId !== todoItem.id);
});
};

const handleChangeCheckbox = (todoId: number) => {
setTodoList(currentTodoList => {
return currentTodoList
.map(todoItem => {
return (todoId === todoItem.id)
? {
...todoItem,
completed: !todoItem.completed,
}
: todoItem;
});
});
};

const handleClearCompleted = () => {
setTodoList(currentTodoList => {
return currentTodoList.filter(currTodo => !currTodo.completed);
});
};

const statusChange = (newStatus: string) => {
setStatusButton(newStatus);
};

const isAnyCompleted = todoList.some(currTodo => currTodo.completed === true);

const toggleAllAction
= () => {
const isAllCompleted = todoList
.every(currTodo => currTodo.completed === true);

if (isAllCompleted) {
setTodoList(todoList.map(currentTodo => ({
...currentTodo,
completed: false,
})));
}

if (!isAllCompleted) {
setTodoList(todoList.map(currentTodo => ({
...currentTodo,
completed: true,
})));
}
};

const handleChangeTodoTitle = (event: string) => {
setIsEdited(event);
};

return (
<TodosProvider>
<TodoApp />
</TodosProvider>
<div className="todoapp">
<header className="header">
<h1>todos</h1>

<form
onSubmit={addTodo}
>
<input
type="text"
data-cy="createTodo"
className="new-todo"
placeholder="What needs to be done?"
value={todo}
onChange={handleSetTodo}
/>
</form>
</header>
<section className="main">
<input
type="checkbox"
id="toggle-all"
className="toggle-all"
data-cy="toggleAll"
onChange={toggleAllAction}
/>
<label htmlFor="toggle-all">Mark all as complete</label>

{todoList.length > 0 && (
<TodoList
todos={visibleTodos}
onChange={handleChangeCheckbox}
onDelete={handleDeleteTodo}
edit={isEdited}
onEdit={handleChangeTodoTitle}
onChangeName={changeNameAction}
/>
)}
</section>

{todoList.length > 0 && (
<footer className="footer">
<span className="todo-count" data-cy="todosCounter">
{`${todoLeftCount()} items left`}
</span>

<TodosFilter
status={statusButton}
onChangeStatus={statusChange}
/>
{isAnyCompleted && (
<button
type="button"
className="clear-completed"
onClick={handleClearCompleted}
>
Clear completed
</button>
)}
</footer>
)}
</div>
);
};
142 changes: 0 additions & 142 deletions src/Components/TodoApp/TodoApp.tsx

This file was deleted.

Loading

0 comments on commit 9657b38

Please sign in to comment.