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.completed ? ( - <> - - - - ) : ( - <> - - - - )} - - - + ))}
{todo.id} - - - - -

{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 */}
-// )} -//
; diff --git a/src/types/Filter.ts b/src/types/Filter.ts new file mode 100644 index 0000000000..174408fd69 --- /dev/null +++ b/src/types/Filter.ts @@ -0,0 +1,5 @@ +export enum Filter { + All = 'all', + Active = 'active', + Completed = 'completed', +}