Skip to content

Commit

Permalink
fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
PieCyberPie committed Dec 27, 2024
1 parent fc98b1a commit 37bce69
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 143 deletions.
40 changes: 22 additions & 18 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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<Todo[]>([]);
const [visibleTodos, setVisibleTodos] = useState<Todo[]>([]);
const [loading, setLoading] = useState<boolean>(true);
const [query, setQuery] = useState<string>('');
const [filter, setFilter] = useState<string>('');
const [filter, setFilter] = useState<Filter>(Filter.All);
const [modalVisible, setModalVisible] = useState<boolean>(false);
const [selectedTodo, setSelectedTodo] = useState<Todo | null>(null);

Expand All @@ -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;
});
}

Expand All @@ -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 (
<>
<div className="section">
Expand All @@ -75,22 +84,17 @@ export const App: React.FC = () => {
) : (
<TodoList
todos={visibleTodos}
modalVisible={modalVisible}
setModalVisible={setModalVisible}
onSelectTodo={handleSelectTodo}
selectedTodo={selectedTodo}
setSelectedTodo={setSelectedTodo}
/>
)}
</div>
</div>
</div>
</div>

{modalVisible && (
<TodoModal
selectedTodo={selectedTodo}
setModalVisible={setModalVisible}
/>
{modalVisible && selectedTodo && (
<TodoModal todo={selectedTodo} onClose={handleCloseModal} />
)}
</>
);
Expand Down
13 changes: 7 additions & 6 deletions src/components/TodoFilter/TodoFilter.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
interface Props {
query: string;
setQuery: React.Dispatch<React.SetStateAction<string>>;
filter: string;
setFilter: React.Dispatch<React.SetStateAction<string>>;
filter: Filter;
setFilter: React.Dispatch<React.SetStateAction<Filter>>;
}
import { Filter } from '../../types/Filter';

export const TodoFilter: React.FC<Props> = ({
query,
Expand All @@ -17,11 +18,11 @@ export const TodoFilter: React.FC<Props> = ({
<select
data-cy="statusSelect"
value={filter}
onChange={e => setFilter(e.target.value)}
onChange={e => setFilter(e.target.value as Filter)}
>
<option value="all">All</option>
<option value="active">Active</option>
<option value="completed">Completed</option>
<option value={Filter.All}>All</option>
<option value={Filter.Active}>Active</option>
<option value={Filter.Completed}>Completed</option>
</select>
</span>
</p>
Expand Down
60 changes: 60 additions & 0 deletions src/components/TodoItem/TodoItem.tsx
Original file line number Diff line number Diff line change
@@ -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<Props> = ({
todo,
onSelectTodo,
selectedTodo,
}) => {
const { id, title, completed } = todo;

return (
<tr data-cy="todo" key={todo.id}>
<td className="is-vcentered">{todo.id}</td>
{completed ? (
<>
<td className="is-vcentered">
<span className="icon" data-cy="iconCompleted">
<i className="fas fa-check" />
</span>
</td>
<td className="is-vcentered is-expanded">
<p className="has-text-success">{title}</p>
</td>
</>
) : (
<>
<td className="is-vcentered"></td>
<td className="is-vcentered is-expanded">
<p className="has-text-danger">{title}</p>
</td>
</>
)}

<td className="has-text-right is-vcentered">
<button
data-cy="selectButton"
className="button"
type="button"
onClick={() => onSelectTodo(todo)}
>
{selectedTodo?.id === id ? (
<span className="icon">
<i className="far fa-eye-slash" />
</span>
) : (
<span className="icon">
<i className="far fa-eye" />
</span>
)}
</button>
</td>
</tr>
);
};
1 change: 1 addition & 0 deletions src/components/TodoItem/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './TodoItem';
73 changes: 10 additions & 63 deletions src/components/TodoList/TodoList.tsx
Original file line number Diff line number Diff line change
@@ -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<React.SetStateAction<boolean>>;
onSelectTodo: (todo: Todo) => void;
selectedTodo: Todo | null;
setSelectedTodo: React.Dispatch<React.SetStateAction<Todo | null>>;
}

export const TodoList: React.FC<Props> = ({
todos,
modalVisible,
setModalVisible,
onSelectTodo,
selectedTodo,
setSelectedTodo,
}) => (
<table className="table is-narrow is-fullwidth">
<thead>
Expand All @@ -31,64 +29,13 @@ export const TodoList: React.FC<Props> = ({

<tbody>
{todos.map(todo => (
<tr data-cy="todo" className="" key={todo.id}>
<td className="is-vcentered">{todo.id}</td>
{todo.completed ? (
<>
<td className="is-vcentered">
<span className="icon" data-cy="iconCompleted">
<i className="fas fa-check" />
</span>
</td>
<td className="is-vcentered is-expanded">
<p className="has-text-success">{todo.title}</p>
</td>
</>
) : (
<>
<td className="is-vcentered"></td>
<td className="is-vcentered is-expanded">
<p className="has-text-danger">{todo.title}</p>
</td>
</>
)}

<td className="has-text-right is-vcentered">
<button
data-cy="selectButton"
className="button"
type="button"
onClick={() => {
setModalVisible(true);
setSelectedTodo(todo);
}}
>
{modalVisible && selectedTodo?.id === todo.id ? (
<span className="icon">
<i className="far fa-eye-slash" />
</span>
) : (
<span className="icon">
<i className="far fa-eye" />
</span>
)}
</button>
</td>
</tr>
<TodoItem
todo={todo}
onSelectTodo={onSelectTodo}
selectedTodo={selectedTodo}
key={todo.id}
/>
))}
</tbody>
</table>
);

// <td className="is-vcentered">
// <span className="icon" data-cy="iconCompleted">
// <i className="fas fa-check" />
// </span>
// </td>
// <td className="is-vcentered is-expanded">
// {todo.completed ? (
// <p className="has-text-success">{todo.title}</p>
// ) : (
// <p className="has-text-danger">{todo.title}</p>
// )}
// </td>
69 changes: 13 additions & 56 deletions src/components/TodoModal/TodoModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,24 @@ import { getUser } from '../../api';
import { Todo } from '../../types/Todo';

interface Props {
selectedTodo: Todo | null;
setModalVisible: React.Dispatch<React.SetStateAction<boolean>>;
todo: Todo;
onClose: () => void;
}

export const TodoModal: React.FC<Props> = ({
selectedTodo,
setModalVisible,
}) => {
export const TodoModal: React.FC<Props> = ({ todo, onClose }) => {
const [loading, setLoading] = useState<boolean>(true);
const [user, setUser] = useState<User | null>(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 (
<div className="modal is-active" data-cy="modal">
<div className="modal-background" />
<div className="modal-background" onClick={onClose} />
{loading ? (
<Loader />
) : (
Expand All @@ -37,21 +32,20 @@ export const TodoModal: React.FC<Props> = ({
className="modal-card-title has-text-weight-medium"
data-cy="modal-header"
>
{`Todo #${selectedTodo?.id}`}
{`Todo #${todo.id}`}
</div>
{/* eslint-disable-next-line jsx-a11y/control-has-associated-label */}
<button
type="button"
className="delete"
data-cy="modal-close"
onClick={() => setModalVisible(false)}
onClick={onClose}
/>
</header>
<div className="modal-card-body">
<p className="block" data-cy="modal-title">
{selectedTodo?.title}
{todo.title}
</p>
{selectedTodo?.completed ? (
{todo.completed ? (
<p className="block" data-cy="modal-user">
<strong className="has-text-success">Done</strong>
{' by '}
Expand All @@ -70,40 +64,3 @@ export const TodoModal: React.FC<Props> = ({
</div>
);
};

// <div className="modal is-active" data-cy="modal">
// <div className="modal-background" />
//
// {true ? (
// <Loader />
// ) : (
// <div className="modal-card">
// <header className="modal-card-head">
// <div
// className="modal-card-title has-text-weight-medium"
// data-cy="modal-header"
// >
// Todo #2
// </div>
//
// {/* eslint-disable-next-line jsx-a11y/control-has-associated-label */}
// <button type="button" className="delete" data-cy="modal-close" />
// </header>
//
// <div className="modal-card-body">
// <p className="block" data-cy="modal-title">
// quis ut nam facilis et officia qui
// </p>
//
// <p className="block" data-cy="modal-user">
// {/* <strong className="has-text-success">Done</strong> */}
// <strong className="has-text-danger">Planned</strong>
//
// {' by '}
//
// <a href="mailto:[email protected]">Leanne Graham</a>
// </p>
// </div>
// </div>
// )}
// </div>;
5 changes: 5 additions & 0 deletions src/types/Filter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export enum Filter {
All = 'all',
Active = 'active',
Completed = 'completed',
}

0 comments on commit 37bce69

Please sign in to comment.