Skip to content

Commit

Permalink
fix tests and errors
Browse files Browse the repository at this point in the history
  • Loading branch information
yzhyhaliuk committed Feb 4, 2025
1 parent a433fd7 commit 1eda377
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 61 deletions.
19 changes: 14 additions & 5 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,40 +12,49 @@ import { Todo } from './types/Todo';

export const App: React.FC = () => {
const [allTodos, setAllTodos] = useState<Todo[]>([]);
const [filteredTodos, setFilteredTodos] = useState<Todo[]>([]);
const [todos, setTodos] = useState<Todo[]>([]);
const [loading, setLoading] = useState(false);
const [selectedId, setSelectedId] = useState(0);
const [selectedId, setSelectedId] = useState<number | null>(null);

useEffect(() => {
setLoading(true);
getTodos().then(todosFromServer => {
setAllTodos(todosFromServer);
setFilteredTodos(todosFromServer);
setTodos(todosFromServer);
setLoading(false);
});
}, []);

const handleFilterAll = useCallback(() => {
setTodos(allTodos);
setFilteredTodos(allTodos);
}, [allTodos]);

const handleFilterActive = useCallback(() => {
setTodos(allTodos.filter(todo => !todo.completed));
const activeTodos = allTodos.filter(todo => !todo.completed);

setFilteredTodos(activeTodos);
setTodos(activeTodos);
}, [allTodos]);

const handleFilterComplete = useCallback(() => {
setTodos(allTodos.filter(todo => todo.completed));
const completedTodos = allTodos.filter(todo => todo.completed);

setFilteredTodos(completedTodos);
setTodos(completedTodos);
}, [allTodos]);

const filterByTitle = useCallback(
(query: string) => {
setTodos(
todos.filter(todo =>
filteredTodos.filter(todo =>
todo.title.toLowerCase().includes(query.toLowerCase()),
),
);
},
[todos],
[filteredTodos],
);

return (
Expand Down
67 changes: 21 additions & 46 deletions src/components/TodoFilter/TodoFilter.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { ChangeEvent, useEffect, useState } from 'react';
import React, { useEffect, useState } from 'react';

type Props = {
onFilterAll: () => void;
Expand All @@ -13,64 +13,39 @@ export const TodoFilter: React.FC<Props> = ({
onFilterCompleted,
onFilterByTitle,
}) => {
const [isQuery, setIsQuery] = useState(false);
const [query, setQuery] = useState('');
const [filterStatus, setFilterStatus] = useState('all');

function handleChange(event: ChangeEvent<HTMLSelectElement>) {
const status = event.target.value;

setFilterStatus(status);

switch (status) {
case 'all':
onFilterAll();
break;

case 'active':
onFilterActive();
break;

case 'completed':
onFilterCompleted();
break;

default:
break;
}
}

function handleTitleChange(event: React.ChangeEvent<HTMLInputElement>) {
const newQuery = event.target.value;

setQuery(newQuery);
onFilterByTitle(newQuery.toLowerCase());
setIsQuery(newQuery.length > 0);
}

function clearInput() {
setQuery('');
setIsQuery(false);
onFilterByTitle('');
}

useEffect(() => {
if (!query) {
switch (filterStatus) {
case 'all':
onFilterAll();
break;
case 'active':
onFilterActive();
break;
case 'completed':
onFilterCompleted();
break;
default:
break;
}
if (filterStatus === 'all') {
onFilterAll();
} else if (filterStatus === 'active') {
onFilterActive();
} else if (filterStatus === 'completed') {
onFilterCompleted();
}

if (query !== '') {
onFilterByTitle(query);
}
}, [query, filterStatus, onFilterActive, onFilterAll, onFilterCompleted]);
}, [
query,
filterStatus,
onFilterAll,
onFilterActive,
onFilterCompleted,
onFilterByTitle,
]);

return (
<form className="field has-addons">
Expand All @@ -79,7 +54,7 @@ export const TodoFilter: React.FC<Props> = ({
<select
data-cy="statusSelect"
value={filterStatus}
onChange={handleChange}
onChange={event => setFilterStatus(event.target.value)}
>
<option value="all">All</option>
<option value="active">Active</option>
Expand All @@ -103,7 +78,7 @@ export const TodoFilter: React.FC<Props> = ({

<span className="icon is-right" style={{ pointerEvents: 'all' }}>
{/* eslint-disable-next-line jsx-a11y/control-has-associated-label */}
{isQuery && (
{query.length > 0 && (
<button
data-cy="clearSearchButton"
type="button"
Expand Down
16 changes: 9 additions & 7 deletions src/components/TodoList/TodoList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,10 @@ import classNames from 'classnames';
type Props = {
todos: Todo[];
onSelect: (userId: number) => void;
selectedId: number;
selectedId: number | null;
};

export const TodoList: React.FC<Props> = ({ todos, onSelect, selectedId }) => {
function handleSelect(id: number) {
onSelect(id);
}

return (
<table className="table is-narrow is-fullwidth">
<thead>
Expand All @@ -30,7 +26,13 @@ export const TodoList: React.FC<Props> = ({ todos, onSelect, selectedId }) => {

<tbody>
{todos.map(todo => (
<tr data-cy="todo" key={todo.id} className="">
<tr
data-cy="todo"
key={todo.id}
className={classNames({
'has-background-info-light': selectedId === todo.id,
})}
>
<td className="is-vcentered">{todo.id}</td>
<td className="is-vcentered">
{todo.completed && (
Expand All @@ -54,7 +56,7 @@ export const TodoList: React.FC<Props> = ({ todos, onSelect, selectedId }) => {
data-cy="selectButton"
className="button"
type="button"
onClick={() => handleSelect(todo.id)}
onClick={() => onSelect(todo.id)}
>
<span className="icon">
<i
Expand Down
8 changes: 5 additions & 3 deletions src/components/TodoModal/TodoModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Todo } from '../../types/Todo';
type Props = {
id: number;
todos: Todo[];
onClose: (id: number) => void;
onClose: (id: number | null) => void;
};

export const TodoModal: React.FC<Props> = ({ id, todos, onClose }) => {
Expand Down Expand Up @@ -47,7 +47,7 @@ export const TodoModal: React.FC<Props> = ({ id, todos, onClose }) => {
type="button"
className="delete"
data-cy="modal-close"
onClick={() => onClose(0)}
onClick={() => onClose(null)}
/>
</header>

Expand All @@ -66,7 +66,9 @@ export const TodoModal: React.FC<Props> = ({ id, todos, onClose }) => {

{' by '}

<a href={`mailto: ${data?.email}`}>{data?.name}</a>
{data?.email && data.name && (
<a href={`mailto: ${data.email}`}>{data.name}</a>
)}
</p>
</div>
</div>
Expand Down

0 comments on commit 1eda377

Please sign in to comment.