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

Solution #1569

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open

Solution #1569

wants to merge 4 commits into from

Conversation

LiliiaVol
Copy link

Copy link

@AnderZerfall AnderZerfall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good job! I left some comments below. Maybe that will be useful.
Also, I couldn't open App.tsx in review mode, so I've written some notes here:

  • You can drop finally {} in try\catch block. The thing is, that everything after catch{} block will execute automatically regardless the result.

  • Your statements in if(...) (I guess, I saw that in handleUpdate func and all sorts of it) look a bit too complicated - I guess, that's the result of having too many states and variables. Try to reduce anything that seems useless. You can even reuse your own code here. That will definitely clean it up a bit and make statements easier.

Anyway, that's just small suggestions. The todo app works as indented and that's the point! Good job!

import { Todo } from '../../types/Todo';

type Props = {
onDoubleClickTodo: (todo: Todo) => void;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have many props here. Some could be created within associated components, so your component won't rely on all of them from the outside.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have many props here. Some could be created within associated components, so your component won't rely on all of them from the outside.

Good point

data-cy="TodoLoader"
className={classNames('modal overlay', {
'is-active':
idDeletedTodo === id ||

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this statement, you could create some variable, which combines all possible scenarios. For example: isLoading =todo.id === 0 || isDeleting === todo.id || isUpdating === todo.id || loadingTodos.includes(todo.id) .... Something like that. You can create this variable in your component, outside the render.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this statement, you could create some variable, which combines all possible scenarios. For example: isLoading =todo.id === 0 || isDeleting === todo.id || isUpdating === todo.id || loadingTodos.includes(todo.id) .... Something like that. You can create this variable in your component, outside the render.

I think it should be simplified, just one condition is enough for example store loading todo ids and as AnderZerfall said loadingTodoIds.includes(todo.id)

Copy link

@BudnikOleksii BudnikOleksii left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good work 👍
Let's improve your solution. Also, I don't see any loaders when I click Clear completed button, check the working example

Comment on lines 26 to 31
{errorState[ErrorType.Input] && `Title should not be empty`}
{errorState[ErrorType.Add] && `Unable to add a todo`}
{(errorState[ErrorType.Delete] ||
errorState[ErrorType.CompletedDelete]) &&
`Unable to delete a todo`}
{errorState[ErrorType.Update] && `Unable to update a todo`}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can just store a message in an error state. As it's a bad idea to do like you, you have to add more and more conditions here for each case

Comment on lines 30 to 51
<a
href="#/"
className={classNames('filter__link', {
selected: filterType === FilterType.All,
})}
data-cy="FilterLinkAll"
onClick={() => {
setFilterType(FilterType.All);
}}
>
All
</a>

<a
href="#/active"
className={classNames('filter__link', {
selected: filterType === FilterType.Active,
})}
data-cy="FilterLinkActive"
onClick={() => {
setFilterType(FilterType.Active);
}}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The links look almost the same. You can transform FilterType into an array with Object.values/keys/entries and map through them to generate links


return (
<header className="todoapp__header">
{!todos.length || (

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
{!todos.length || (
{!!todos.length && (

import { Todo } from '../../types/Todo';

type Props = {
onDoubleClickTodo: (todo: Todo) => void;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have many props here. Some could be created within associated components, so your component won't rely on all of them from the outside.

Good point

data-cy="TodoLoader"
className={classNames('modal overlay', {
'is-active':
idDeletedTodo === id ||

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this statement, you could create some variable, which combines all possible scenarios. For example: isLoading =todo.id === 0 || isDeleting === todo.id || isUpdating === todo.id || loadingTodos.includes(todo.id) .... Something like that. You can create this variable in your component, outside the render.

I think it should be simplified, just one condition is enough for example store loading todo ids and as AnderZerfall said loadingTodoIds.includes(todo.id)

inputEditRef.current.removeEventListener('keydown', handleKeyDown);
}
};
}, [todoChangedTitle, inputEditRef]);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix linter errors. And it's better to avoid DOM manipulations in react

Copy link

@StasSokolov1 StasSokolov1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good, let's improve your solution a bit more!

src/App.tsx Outdated
Comment on lines 35 to 37
setTimeout(() => {
setErrorState(ErrorType.Default);
}, 3000);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please don't forget to clear setTimeout

src/App.tsx Outdated
event.preventDefault();
setIsAllCompleted(false);

if (!title.trim().length) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please move title.trim() to const and reuse

src/api/todos.ts Outdated
export const USER_ID = 2179;

export const getTodos = () => {
return client.get<Todo[]>(`/todos?userId=${USER_ID}`);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's move /todos to const and reuse

Input = 'Title should not be empty',
Add = 'Unable to add a todo',
Delete = 'Unable to delete a todo',
// CompletedDelete = 'Unable to delete a completed todo',

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please remove redundant comment

Copy link

@StasSokolov1 StasSokolov1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, I'm approving it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants