Skip to content

Commit

Permalink
add task solution
Browse files Browse the repository at this point in the history
  • Loading branch information
ivankovbohdan committed Sep 23, 2024
1 parent 71932b1 commit 252f04e
Show file tree
Hide file tree
Showing 10 changed files with 346 additions and 276 deletions.
82 changes: 66 additions & 16 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,76 @@
import 'bulma/css/bulma.css';
import '@fortawesome/fontawesome-free/css/all.css';
import { Loader, TodoFilter, TodoList, TodoModal } from './components';
import { useEffect, useState } from 'react';
import { getTodos } from './api';
import { prepareTodos } from './tools/prepareTodos';
import { useDispatch, useSelector } from 'react-redux';
import { RootState } from './app/store';
import { todosActions } from './features/todos';
import { filterActions } from './features/filter';
import { currentTodoActions } from './features/currentTodo';

export const App = () => (
<>
<div className="section">
<div className="container">
<div className="box">
<h1 className="title">Todos:</h1>
export const App = () => {
const dispatch = useDispatch();
const todos = useSelector((state: RootState) => state.todos);
const { query, status } = useSelector((state: RootState) => state.filter);
const selectedTodo = useSelector((state: RootState) => state.currentTodo);

<div className="block">
<TodoFilter />
</div>
const [isLoading, setIsLoading] = useState(false);

useEffect(() => {
setIsLoading(true);
getTodos()
.then(readyTodos => dispatch(todosActions.setTodos(readyTodos)))
.finally(() => setIsLoading(false));
}, [dispatch]);

const readyTodos = prepareTodos(todos, query, status);

return (
<>
<div className="section">
<div className="container">
<div className="box">
<h1 className="title">Todos:</h1>

<div className="block">
<TodoFilter
query={query}
setTitle={newQuery =>
dispatch(filterActions.setQuery(newQuery))
}
setStatus={newStatus =>
dispatch(filterActions.setStatus(newStatus))
}
/>
</div>

<div className="block">
{isLoading && <Loader />}

<div className="block">
<Loader />
<TodoList />
{!isLoading && todos.length > 0 && (
<TodoList
todos={readyTodos}
selectedTodo={selectedTodo}
setSelectedTodo={newSelectedTodo =>
dispatch(currentTodoActions.setCurrentTodo(newSelectedTodo))
}
/>
)}
</div>
</div>
</div>
</div>
</div>

<TodoModal />
</>
);
{selectedTodo && (
<TodoModal
selectedTodo={selectedTodo}
setSelectedTodo={newSelectedTodo =>
dispatch(currentTodoActions.setCurrentTodo(newSelectedTodo))
}
/>
)}
</>
);
};
5 changes: 4 additions & 1 deletion src/app/store.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { combineSlices, configureStore } from '@reduxjs/toolkit';
import { currentTodoSlice } from '../features/currentTodo';
import { filterSlice } from '../features/filter';
import { todosSlice } from '../features/todos';

const rootReducer = combineSlices();
const rootReducer = combineSlices(todosSlice, filterSlice, currentTodoSlice);

export const store = configureStore({
reducer: rootReducer,
Expand Down
42 changes: 31 additions & 11 deletions src/components/TodoFilter/TodoFilter.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,33 @@
import React from 'react';
import { Status } from '../../tools/constants';

export const TodoFilter: React.FC = () => {
type Props = {
query: string;
setStatus: (filterField: string) => void;
setTitle: (title: string) => void;
};

export const TodoFilter: React.FC<Props> = ({
query,
setStatus: setFilterField,
setTitle,
}) => {
return (
<form
className="field has-addons"
onSubmit={event => event.preventDefault()}
>
<p className="control">
<span className="select">
<select data-cy="statusSelect">
<option value="all">All</option>
<option value="active">Active</option>
<option value="completed">Completed</option>
<select
data-cy="statusSelect"
onChange={event => setFilterField(event.target.value)}
>
{Object.values(Status).map((field: Status) => (
<option key={field} value={field}>
{field[0].toUpperCase() + field.slice(1).toLowerCase()}
</option>
))}
</select>
</span>
</p>
Expand All @@ -22,18 +38,22 @@ export const TodoFilter: React.FC = () => {
type="text"
className="input"
placeholder="Search..."
value={query}
onChange={event => setTitle(event.target.value)}
/>
<span className="icon is-left">
<i className="fas fa-magnifying-glass" />
</span>

<span className="icon is-right" style={{ pointerEvents: 'all' }}>
{/* eslint-disable-next-line jsx-a11y/control-has-associated-label */}
<button
data-cy="clearSearchButton"
type="button"
className="delete"
/>
{query !== '' && (
<button
data-cy="clearSearchButton"
type="button"
className="delete"
onClick={() => setTitle('')}
/>
)}
</span>
</p>
</form>
Expand Down
Loading

0 comments on commit 252f04e

Please sign in to comment.