Skip to content

Commit

Permalink
solution 0.01 still mistake single delete
Browse files Browse the repository at this point in the history
  • Loading branch information
StanislavKapytsia committed Dec 13, 2024
1 parent ddea68f commit 56d0477
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 48 deletions.
81 changes: 42 additions & 39 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import React, { useEffect, useMemo, useRef, useState } from 'react';
import React, {
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react';
import { addTodo, delTodo, get, updTodo } from './api/todos';
import { TodoInterface } from './types/Todo';
import { Filter } from './types/filter';
import { TodoList } from './components/todoList/todoList';
import { FilteredTodoList } from './components/footer/filteredTodoList';
import { TodoList } from './components/todoList/TodoList';
import { FilteredTodoList } from './components/footer/FilteredTodoList';
import classNames from 'classnames';

export const App: React.FC = () => {
Expand All @@ -12,17 +18,16 @@ export const App: React.FC = () => {
const [value, setValue] = useState('');
const [tempTodo, setTempTodo] = useState<TodoInterface | null>(null);
const [errorMessage, setErrorMessage] = useState('');
const [active, setActive] = useState(false);
const [todosForModify, setTodosForModify] = useState<TodoInterface[]>([]);

const inputForFocusRef = useRef<HTMLInputElement>(null);
const notificationRef = useRef<HTMLDivElement>(null);

const hideNotification = () => {
const hideNotification = useCallback(() => {
if (notificationRef.current) {
notificationRef.current.classList.add('hidden');
}
};
}, []);

const errorHandling = (error: Error) => {
if (notificationRef.current) {
Expand Down Expand Up @@ -75,19 +80,17 @@ export const App: React.FC = () => {
};

fetchTodos();
}, []);
}, [hideNotification]);

const allTodosComplited = useMemo(() => {
return todos.every(item => item.completed);
}, [todos]);

const [active, setActive] = useState(allTodosComplited);

useEffect(() => {
if (allTodosComplited) {
setActive(true);
} else {
setActive(false);
}
}, [allTodosComplited, active]);
setActive(allTodosComplited);
}, [allTodosComplited]);

useEffect(() => {
if (inputForFocusRef.current && !tempTodo) {
Expand Down Expand Up @@ -165,26 +168,13 @@ export const App: React.FC = () => {
setTodosForModify([]);
};

const onSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();

if (value.trim()) {
addTodos(value);
} else {
const empty = new Error('Title should not be empty');

errorHandling(empty);
setValue('');
}
};

const handleClose = () => {
if (notificationRef.current) {
notificationRef.current.classList.add('hidden');
}
};

const filteredTodos = (): TodoInterface[] => {
const filteredTodos = useMemo(() => {
return todos.filter(todo => {
switch (filter) {
case Filter.All:
Expand All @@ -197,7 +187,7 @@ export const App: React.FC = () => {
return true;
}
});
};
}, [todos, filter]);

const handleChangeValue = (e: React.ChangeEvent<HTMLInputElement>) => {
if (notificationRef.current) {
Expand All @@ -207,24 +197,37 @@ export const App: React.FC = () => {
setValue(e.target.value);
};

const handleUpdateStatus = () => {
const copyTodos = [...todos];
const onSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();

if (active) {
const content = copyTodos.map(item => ({ ...item, completed: false }));
if (value.trim()) {
addTodos(value);
} else {
const empty = new Error('Title should not be empty');

errorHandling(empty);
setValue('');
}
};

const handleUpdateStatus = async () => {
const copyTodos = [...todos];

setTodosForModify(content);
let content;

updateTodos(content);
if (active) {
content = copyTodos.map(item => ({ ...item, completed: false }));
} else {
const content = copyTodos
content = copyTodos
.filter(todo => !todo.completed)
.map(item => ({ ...item, completed: true }));
}

setTodosForModify(content);
setTodosForModify(content);

updateTodos(content);
}
await Promise.allSettled(content.map(todo => updateTodos([todo])));

setTodosForModify([]);
};

return (
Expand Down Expand Up @@ -258,7 +261,7 @@ export const App: React.FC = () => {

{todos.length > 0 && (
<TodoList
filteredTodos={filteredTodos()}
filteredTodos={filteredTodos}
deleteTodos={deleteTodos}
tempTodo={tempTodo}
setTodosForModify={setTodosForModify}
Expand Down
12 changes: 5 additions & 7 deletions src/components/footer/FilteredTodoList.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useCallback } from 'react';
import { TodoInterface } from '../../types/todo';
import { useMemo } from 'react';
import { TodoInterface } from '../../types/Todo';
import cn from 'classnames';
import { Filter } from '../../types/filter';

Expand All @@ -21,14 +21,12 @@ export const FilteredTodoList: React.FC<Props> = ({

setTodosForModify,
}) => {
const countNotCompletedItem = useCallback(() => {
const countNotCompletedItem = useMemo(() => {
const filtered = todos.filter(todo => !todo.completed);

return filtered.length;
}, [todos]);

const notCompletedItem = countNotCompletedItem();

const handledeleteTodos = () => {
setTodosForModify(() => {
return todos.filter(todo => todo.completed);
Expand All @@ -42,7 +40,7 @@ export const FilteredTodoList: React.FC<Props> = ({
return (
<footer className="todoapp__footer" data-cy="Footer">
<span className="todo-count" data-cy="TodosCounter">
{`${notCompletedItem} items left`}
{`${countNotCompletedItem} items left`}
</span>

<nav className="filter" data-cy="Filter">
Expand All @@ -66,7 +64,7 @@ export const FilteredTodoList: React.FC<Props> = ({
className="todoapp__clear-completed"
data-cy="ClearCompletedButton"
onClick={handledeleteTodos}
disabled={todos.length - notCompletedItem === 0}
disabled={todos.length - countNotCompletedItem === 0}
>
Clear completed
</button>
Expand Down
4 changes: 2 additions & 2 deletions src/components/todoList/TodoList.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable jsx-a11y/control-has-associated-label */
/* eslint-disable jsx-a11y/label-has-associated-control */
import { TodoInterface } from '../../types/todo';
import { Todo } from '../todo/todo';
import { TodoInterface } from '../../types/Todo';
import { Todo } from '../todo/Todo';

interface Props {
filteredTodos: TodoInterface[];
Expand Down

0 comments on commit 56d0477

Please sign in to comment.