diff --git a/src/App.tsx b/src/App.tsx
index 64bfc088c0..bba23e4320 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable max-len */
import React, { useEffect, useState } from 'react';
import 'bulma/css/bulma.css';
import '@fortawesome/fontawesome-free/css/all.css';
@@ -9,13 +8,14 @@ import { TodoModal } from './components/TodoModal';
import { Loader } from './components/Loader';
import { getTodos } from './api';
import { Todo } from './types/Todo';
+import { Filter } from './types/Filter';
export const App: React.FC = () => {
const [allTodos, setAllTodos] = useState([]);
const [visibleTodos, setVisibleTodos] = useState([]);
const [loading, setLoading] = useState(true);
const [query, setQuery] = useState('');
- const [filter, setFilter] = useState('');
+ const [filter, setFilter] = useState(Filter.All);
const [modalVisible, setModalVisible] = useState(false);
const [selectedTodo, setSelectedTodo] = useState(null);
@@ -32,15 +32,14 @@ export const App: React.FC = () => {
if (filter) {
newTodos = newTodos.filter(todo => {
- if (filter === 'completed') {
- return todo.completed;
+ switch (filter) {
+ case Filter.Completed:
+ return todo.completed;
+ case Filter.Active:
+ return !todo.completed;
+ default:
+ return true;
}
-
- if (filter === 'active') {
- return !todo.completed;
- }
-
- return true;
});
}
@@ -53,6 +52,16 @@ export const App: React.FC = () => {
setVisibleTodos(newTodos);
}, [filter, query, allTodos]);
+ const handleSelectTodo = (todo: Todo) => {
+ setSelectedTodo(todo);
+ setModalVisible(true);
+ };
+
+ const handleCloseModal = () => {
+ setModalVisible(false);
+ setSelectedTodo(null);
+ };
+
return (
<>
@@ -75,10 +84,8 @@ export const App: React.FC = () => {
) : (
)}
@@ -86,11 +93,8 @@ export const App: React.FC = () => {
- {modalVisible && (
-
+ {modalVisible && selectedTodo && (
+
)}
>
);
diff --git a/src/components/TodoFilter/TodoFilter.tsx b/src/components/TodoFilter/TodoFilter.tsx
index 2577fd1b34..337844789e 100644
--- a/src/components/TodoFilter/TodoFilter.tsx
+++ b/src/components/TodoFilter/TodoFilter.tsx
@@ -1,9 +1,10 @@
interface Props {
query: string;
setQuery: React.Dispatch>;
- filter: string;
- setFilter: React.Dispatch>;
+ filter: Filter;
+ setFilter: React.Dispatch>;
}
+import { Filter } from '../../types/Filter';
export const TodoFilter: React.FC = ({
query,
@@ -17,11 +18,11 @@ export const TodoFilter: React.FC = ({
diff --git a/src/components/TodoItem/TodoItem.tsx b/src/components/TodoItem/TodoItem.tsx
new file mode 100644
index 0000000000..587af0f132
--- /dev/null
+++ b/src/components/TodoItem/TodoItem.tsx
@@ -0,0 +1,60 @@
+import React from 'react';
+import { Todo } from '../../types/Todo';
+
+interface Props {
+ todo: Todo;
+ onSelectTodo: (todo: Todo) => void;
+ selectedTodo: Todo | null;
+}
+
+export const TodoItem: React.FC = ({
+ todo,
+ onSelectTodo,
+ selectedTodo,
+}) => {
+ const { id, title, completed } = todo;
+
+ return (
+
+ {todo.id} |
+ {completed ? (
+ <>
+
+
+
+
+ |
+
+ {title}
+ |
+ >
+ ) : (
+ <>
+ |
+
+ {title}
+ |
+ >
+ )}
+
+
+
+ |
+
+ );
+};
diff --git a/src/components/TodoItem/index.ts b/src/components/TodoItem/index.ts
new file mode 100644
index 0000000000..21f4abac39
--- /dev/null
+++ b/src/components/TodoItem/index.ts
@@ -0,0 +1 @@
+export * from './TodoItem';
diff --git a/src/components/TodoList/TodoList.tsx b/src/components/TodoList/TodoList.tsx
index ba17910129..391eefbb55 100644
--- a/src/components/TodoList/TodoList.tsx
+++ b/src/components/TodoList/TodoList.tsx
@@ -1,19 +1,17 @@
import React from 'react';
import { Todo } from '../../types/Todo';
+import { TodoItem } from '../TodoItem';
+
interface Props {
todos: Todo[];
- modalVisible: boolean;
- setModalVisible: React.Dispatch>;
+ onSelectTodo: (todo: Todo) => void;
selectedTodo: Todo | null;
- setSelectedTodo: React.Dispatch>;
}
export const TodoList: React.FC = ({
todos,
- modalVisible,
- setModalVisible,
+ onSelectTodo,
selectedTodo,
- setSelectedTodo,
}) => (
@@ -31,64 +29,13 @@ export const TodoList: React.FC = ({
{todos.map(todo => (
-
- {todo.id} |
- {todo.completed ? (
- <>
-
-
-
-
- |
-
- {todo.title}
- |
- >
- ) : (
- <>
- |
-
- {todo.title}
- |
- >
- )}
-
-
-
- |
-
+
))}
);
-
-//
-//
-//
-//
-// |
-//
-// {todo.completed ? (
-// {todo.title}
-// ) : (
-// {todo.title}
-// )}
-// |
diff --git a/src/components/TodoModal/TodoModal.tsx b/src/components/TodoModal/TodoModal.tsx
index 41e5157e09..84c136d0f5 100644
--- a/src/components/TodoModal/TodoModal.tsx
+++ b/src/components/TodoModal/TodoModal.tsx
@@ -5,29 +5,24 @@ import { getUser } from '../../api';
import { Todo } from '../../types/Todo';
interface Props {
- selectedTodo: Todo | null;
- setModalVisible: React.Dispatch>;
+ todo: Todo;
+ onClose: () => void;
}
-export const TodoModal: React.FC = ({
- selectedTodo,
- setModalVisible,
-}) => {
+export const TodoModal: React.FC = ({ todo, onClose }) => {
const [loading, setLoading] = useState(true);
const [user, setUser] = useState(null);
useEffect(() => {
- if (selectedTodo) {
- getUser(selectedTodo.userId).then(selectedUser => {
- setUser(selectedUser);
- setLoading(false);
- });
- }
- }, [selectedTodo]);
+ getUser(todo.userId).then(selectedUser => {
+ setUser(selectedUser);
+ setLoading(false);
+ });
+ }, [todo.userId]);
return (
-
+
{loading ? (
) : (
@@ -37,21 +32,20 @@ export const TodoModal: React.FC
= ({
className="modal-card-title has-text-weight-medium"
data-cy="modal-header"
>
- {`Todo #${selectedTodo?.id}`}
+ {`Todo #${todo.id}`}
- {/* eslint-disable-next-line jsx-a11y/control-has-associated-label */}