Skip to content

Commit

Permalink
add some changes
Browse files Browse the repository at this point in the history
  • Loading branch information
BohdanDymydiuk committed Dec 11, 2024
1 parent 0c7835a commit 42ba2cc
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 145 deletions.
54 changes: 14 additions & 40 deletions src/components/TodoFooter/TodoFooter.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
import React, { useContext } from 'react';
import { TodosContext } from '../../context';
import { Filter } from '../../enums/Filter';
import { Filter } from '../../enums/Enums';
import classNames from 'classnames';

export const TodoFooter: React.FC = () => {
// #regions vars from contexts

const { todos, activeTodos, filter, setFilter, deleteHandler } =
useContext(TodosContext);

// #endregion
// #region handlers

const deleteCompleted = () => {
const idsToDelete: number[] = [];

Expand All @@ -26,47 +21,26 @@ export const TodoFooter: React.FC = () => {
deleteHandler(idsToDelete);
};

// #endregion

return (
<footer className="todoapp__footer" data-cy="Footer">
<span className="todo-count" data-cy="TodosCounter">
{activeTodos} items left
</span>

<nav className="filter" data-cy="Filter">
<a
href="#/"
className={classNames('filter__link', {
selected: filter === Filter.all,
})}
data-cy="FilterLinkAll"
onClick={() => setFilter(Filter.all)}
>
{Filter.all}
</a>

<a
href="#/active"
className={classNames('filter__link', {
selected: filter === Filter.active,
})}
data-cy="FilterLinkActive"
onClick={() => setFilter(Filter.active)}
>
{Filter.active}
</a>

<a
href="#/completed"
className={classNames('filter__link', {
selected: filter === Filter.completed,
})}
data-cy="FilterLinkCompleted"
onClick={() => setFilter(Filter.completed)}
>
{Filter.completed}
</a>
{Object.values(Filter).map((value, i) => (
<a
href="#/"
key={value + i}
className={classNames('filter__link', {
selected: filter === value,
})}
data-cy={`FilterLink${value}`}
onClick={() => setFilter(value)}
>
{value}
</a>
))}
</nav>

<button
Expand Down
9 changes: 1 addition & 8 deletions src/components/TodoHeader/TodoHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@ import React, { useContext } from 'react';
import { TodosContext } from '../../context';
import classNames from 'classnames';
import { myLocalStorage } from '../../localStorage';
import { Names } from '../../enums/Filter';
import { Names } from '../../enums/Enums';

export const TodoHeader: React.FC = () => {
// #region vars from contexts

const {
todos,
activeTodos,
Expand All @@ -17,9 +15,6 @@ export const TodoHeader: React.FC = () => {
onSubmit,
} = useContext(TodosContext);

// #endregion
// #region handlers

const toogleAll = () => {
const updatedTodos = todos.map(todo => {
const { completed } = todo;
Expand All @@ -35,8 +30,6 @@ export const TodoHeader: React.FC = () => {
myLocalStorage.setItem(Names.todos, JSON.stringify(updatedTodos));
};

// #endregion

return (
<header className="todoapp__header">
{todos.length > 0 && (
Expand Down
86 changes: 86 additions & 0 deletions src/components/TodoItem/TodoItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/* eslint-disable jsx-a11y/label-has-associated-control */
import classNames from 'classnames';
import React from 'react';

interface Props {
id: number;
title: string;
editableTitle: string;
isTodoChecked: boolean;
editableTodoById: number;
todoInputRef: React.MutableRefObject<HTMLInputElement | null>;
setEditableTitle: (value: string) => void;
editHandler: (id: number, title: string) => void;
deleteHandler: (ids: number[]) => void;
toogleHandler: (id: number) => void;
onSubmit: (event: React.FormEvent, id: number) => void;
}

export const TodoItem: React.FC<Props> = React.memo(
({
id,
title,
editableTitle,
editableTodoById,
isTodoChecked,
todoInputRef,
setEditableTitle,
editHandler,
deleteHandler,
toogleHandler,
onSubmit,
}) => {
return (
<div
data-cy="Todo"
className={classNames('todo', { completed: isTodoChecked })}
>
<label className="todo__status-label">
<input
data-cy="TodoStatus"
type="checkbox"
className="todo__status"
onChange={() => toogleHandler(id)}
checked={isTodoChecked}
/>
</label>

{editableTodoById === id ? (
<form onSubmit={event => onSubmit(event, id)}>
<input
ref={todoInputRef}
onBlur={event => onSubmit(event, id)}
data-cy="TodoTitleField"
type="text"
className="todo__title-field"
placeholder="Empty todo will be deleted"
value={editableTitle}
onChange={event => setEditableTitle(event.target.value)}
/>
</form>
) : (
<span
data-cy="TodoTitle"
className="todo__title"
onDoubleClick={() => editHandler(id, title)}
>
{title || 'Todo is being saved now'}
</span>
)}

{editableTodoById !== id && (
<button
type="button"
className="todo__remove"
data-cy="TodoDelete"
onClick={() => deleteHandler([id])}
>
×
</button>
)}
</div>
);
},
);

TodoItem.displayName = 'TodoItem';
Empty file.
85 changes: 15 additions & 70 deletions src/components/TodoList/TodoList.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,18 @@
/* eslint-disable jsx-a11y/label-has-associated-control */
import React, { useContext, useEffect, useRef, useState } from 'react';
import { TodosContext } from '../../context';
import classNames from 'classnames';
import { Filter, Names } from '../../enums/Filter';
import { Filter, Names } from '../../enums/Enums';
import { myLocalStorage } from '../../localStorage';
import { TodoItem } from '../TodoItem/TodoItem';

export const TodoList: React.FC = () => {
// #regions vars from contexts

const { todos, filter, setTodos, toogleHandler, deleteHandler } =
useContext(TodosContext);

// #endregion
// #region states

const [editableTodoById, setEditableTodoById] = useState(0);
const [editableTitle, setEditableTitle] = useState('');

// #endregion
// #region refs

const todoInputRef = useRef<HTMLInputElement | null>(null);

// #endregion
// #region variables

const filteredTodos = todos.filter(todo => {
switch (filter) {
case Filter.active:
Expand All @@ -36,9 +24,6 @@ export const TodoList: React.FC = () => {
}
});

// #endregion
// #region handlers

const editHandler = (id: number, value: string) => {
setEditableTodoById(id);
setEditableTitle(value);
Expand Down Expand Up @@ -74,15 +59,10 @@ export const TodoList: React.FC = () => {
}
};

// #endregion
// #region useEffects

useEffect(() => {
todoInputRef.current?.focus();
}, [editableTodoById]);

// #endregion

return (
<section
className="todoapp__main"
Expand All @@ -94,55 +74,20 @@ export const TodoList: React.FC = () => {
const isTodoChecked = todo.completed;

return (
<div
<TodoItem
key={id}
data-cy="Todo"
className={classNames('todo', { completed: isTodoChecked })}
>
<label className="todo__status-label">
<input
data-cy="TodoStatus"
type="checkbox"
className="todo__status"
onChange={() => toogleHandler(id)}
checked={isTodoChecked}
/>
</label>

{editableTodoById === id ? (
<form onSubmit={event => onSubmit(event, id)}>
<input
ref={todoInputRef}
onBlur={event => onSubmit(event, id)}
data-cy="TodoTitleField"
type="text"
className="todo__title-field"
placeholder="Empty todo will be deleted"
value={editableTitle}
onChange={event => setEditableTitle(event.target.value)}
/>
</form>
) : (
<span
data-cy="TodoTitle"
className="todo__title"
onDoubleClick={() => editHandler(id, title)}
>
{title || 'Todo is being saved now'}
</span>
)}

{editableTodoById !== id && (
<button
type="button"
className="todo__remove"
data-cy="TodoDelete"
onClick={() => deleteHandler([id])}
>
×
</button>
)}
</div>
id={id}
title={title}
isTodoChecked={isTodoChecked}
editableTitle={editableTitle}
editableTodoById={editableTodoById}
todoInputRef={todoInputRef}
setEditableTitle={setEditableTitle}
editHandler={editHandler}
deleteHandler={deleteHandler}
toogleHandler={toogleHandler}
onSubmit={onSubmit}
/>
);
})}
</section>
Expand Down
Loading

0 comments on commit 42ba2cc

Please sign in to comment.