Skip to content

Commit

Permalink
Ass solution
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitruz committed Sep 25, 2024
1 parent 71932b1 commit 6ed177e
Show file tree
Hide file tree
Showing 11 changed files with 334 additions and 289 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ components (no need to write them in the store file)

## Instructions
- Install Prettier Extention and use this [VSCode settings](https://mate-academy.github.io/fe-program/tools/vscode/settings.json) to enable format on save.
- Replace `<your_account>` with your Github username in the [DEMO LINK](https://<your_account>.github.io/react_redux-list-of-todos/)
- Replace `<your_account>` with your Github username in the [DEMO LINK](https://dmitruz.github.io/react_redux-list-of-todos/)
- Follow the [React task guideline](https://github.com/mate-academy/react_task-guideline#react-tasks-guideline)
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
},
"devDependencies": {
"@cypress/react18": "^2.0.1",
"@mate-academy/scripts": "^1.8.5",
"@mate-academy/scripts": "^1.9.12",
"@mate-academy/students-ts-config": "*",
"@mate-academy/stylelint-config": "*",
"@types/node": "^20.14.10",
Expand Down
65 changes: 49 additions & 16 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,59 @@
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 { setTodos } from './features/todos';
import { useDispatch, useSelector } from 'react-redux';
import { RootState } from './app/store';

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

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

useEffect(() => {
const fetchTodos = async () => {
setIsLoading(true);
try {
const response = await getTodos();

dispatch(setTodos(response));
} catch (error) {
// eslint-disable-next-line no-console
console.error('Error fetching todos:', error);
} finally {
setIsLoading(false);
}
};

fetchTodos();
}, [dispatch]);

const noTodos = !todos.length;
const modalIsVisible = !!currentTodo;

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

<div className="block">
<TodoFilter />
</div>

<div className="block">
<Loader />
<TodoList />
<div className="block">
{isLoading ? <Loader /> : !noTodos ? <TodoList /> : null}
</div>
</div>
</div>
</div>
</div>

<TodoModal />
</>
);
{modalIsVisible && <TodoModal />}
</>
);
};
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 { todosSlice } from '../features/todos';
import { filterSlice } from '../features/filter';

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

export const store = configureStore({
reducer: rootReducer,
Expand Down
47 changes: 34 additions & 13 deletions src/components/TodoFilter/TodoFilter.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,30 @@
import React from 'react';

import { FilterStatus, setQuery, setStatus } from '../../features/filter';
import { useDispatch, useSelector } from 'react-redux';
import { RootState } from '../../app/store';

export const TodoFilter: React.FC = () => {
const dispatch = useDispatch();
const query = useSelector((state: RootState) => state.filter.query);

const handleStatusChange = (value: React.ChangeEvent<HTMLSelectElement>) => {
dispatch(setStatus(value.target.value as FilterStatus));
};

const handleQueryChange = (value: React.ChangeEvent<HTMLInputElement>) => {
dispatch(setQuery(value.target.value));
};

const resetQuery = () => {
dispatch(setQuery(''));
};

return (
<form
className="field has-addons"
onSubmit={event => event.preventDefault()}
>
<form className="field has-addons">
<p className="control">
<span className="select">
<select data-cy="statusSelect">
<select data-cy="statusSelect" onChange={handleStatusChange}>
<option value="all">All</option>
<option value="active">Active</option>
<option value="completed">Completed</option>
Expand All @@ -22,19 +38,24 @@ export const TodoFilter: React.FC = () => {
type="text"
className="input"
placeholder="Search..."
value={query}
onChange={handleQueryChange}
/>
<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"
/>
</span>
{query && (
<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"
onClick={resetQuery}
/>
</span>
)}
</p>
</form>
);
Expand Down
Loading

0 comments on commit 6ed177e

Please sign in to comment.