From 2a6dd8a31ddd30324916137cc767331d53ed72eb Mon Sep 17 00:00:00 2001 From: Yuriy Bilskiy Date: Fri, 1 Nov 2024 14:57:17 +0200 Subject: [PATCH] solution --- README.md | 2 +- package-lock.json | 20 ++- package.json | 4 +- src/App.tsx | 65 ++++++++- src/components/TodoFilter/TodoFilter.tsx | 125 +++++++++++++---- src/components/TodoList/TodoList.tsx | 171 +++++++++++------------ src/components/TodoModal/TodoModal.tsx | 64 +++++++-- src/functions/filteredTodos.ts | 29 ++++ src/hooks/useLoading.ts | 10 ++ src/types/Filter.ts | 1 + 10 files changed, 348 insertions(+), 143 deletions(-) create mode 100644 src/functions/filteredTodos.ts create mode 100644 src/hooks/useLoading.ts create mode 100644 src/types/Filter.ts diff --git a/README.md b/README.md index 5ec1e6f104..77f487fc9d 100644 --- a/README.md +++ b/README.md @@ -29,4 +29,4 @@ loaded and show them using `TodoList` (check the code in the `api.ts`); - Implement a solution following the [React task guideline](https://github.com/mate-academy/react_task-guideline#react-tasks-guideline). - Use the [React TypeScript cheat sheet](https://mate-academy.github.io/fe-program/js/extra/react-typescript). - Open one more terminal and run tests with `npm test` to ensure your solution is correct. -- Replace `` with your Github username in the [DEMO LINK](https://.github.io/react_dynamic-list-of-todos/) and add it to the PR description. +- Replace `` with your Github username in the [DEMO LINK](https://yuriybilskiy.github.io/react_dynamic-list-of-todos/) and add it to the PR description. diff --git a/package-lock.json b/package-lock.json index 76d22cf660..a5382c24fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,14 +13,16 @@ "@fortawesome/fontawesome-free": "^6.5.2", "bulma": "^1.0.1", "classnames": "^2.5.1", + "lodash": "^4.17.21", "react": "^18.3.1", "react-dom": "^18.3.1" }, "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/lodash": "^4.17.13", "@types/node": "^20.14.10", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", @@ -1170,10 +1172,11 @@ } }, "node_modules/@mate-academy/scripts": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@mate-academy/scripts/-/scripts-1.8.5.tgz", - "integrity": "sha512-mHRY2FkuoYCf5U0ahIukkaRo5LSZsxrTSgMJheFoyf3VXsTvfM9OfWcZIDIDB521kdPrScHHnRp+JRNjCfUO5A==", + "version": "1.9.12", + "resolved": "https://registry.npmjs.org/@mate-academy/scripts/-/scripts-1.9.12.tgz", + "integrity": "sha512-/OcmxMa34lYLFlGx7Ig926W1U1qjrnXbjFJ2TzUcDaLmED+A5se652NcWwGOidXRuMAOYLPU2jNYBEkKyXrFJA==", "dev": true, + "license": "MIT", "dependencies": { "@octokit/rest": "^17.11.2", "@types/get-port": "^4.2.0", @@ -2167,6 +2170,13 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "node_modules/@types/lodash": { + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.13.tgz", + "integrity": "sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", @@ -6761,7 +6771,7 @@ "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "license": "MIT" }, "node_modules/lodash.get": { "version": "4.4.2", diff --git a/package.json b/package.json index e1661aa8bd..2beb6aa854 100644 --- a/package.json +++ b/package.json @@ -9,14 +9,16 @@ "@fortawesome/fontawesome-free": "^6.5.2", "bulma": "^1.0.1", "classnames": "^2.5.1", + "lodash": "^4.17.21", "react": "^18.3.1", "react-dom": "^18.3.1" }, "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/lodash": "^4.17.13", "@types/node": "^20.14.10", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", diff --git a/src/App.tsx b/src/App.tsx index d46111e825..4b6bc53e87 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,5 +1,5 @@ /* eslint-disable max-len */ -import React from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import 'bulma/css/bulma.css'; import '@fortawesome/fontawesome-free/css/all.css'; @@ -7,8 +7,44 @@ import { TodoList } from './components/TodoList'; import { TodoFilter } from './components/TodoFilter'; import { TodoModal } from './components/TodoModal'; import { Loader } from './components/Loader'; +import { Todo } from './types/Todo'; +import { getTodos } from './api'; +import { FilterType } from './types/Filter'; +import { filteredTodos } from './functions/filteredTodos'; +import { useLoading } from './hooks/useLoading'; export const App: React.FC = () => { + const [todos, setTodos] = useState([]); + const [filter, setFilter] = useState('all'); + const [query, setQuery] = useState(''); + const [selectedTodo, setSelectedTodo] = useState(null); + const { isLoading, startLoading, finishLoading } = useLoading(); + + const visibleTodos = filteredTodos(todos, filter, query); + + const handleClickOfPost = useCallback(() => { + setSelectedTodo(null); + }, []); + + const handleChangeSelect = useCallback((newValue: FilterType) => { + setFilter(newValue); + }, []); + + useEffect(() => { + startLoading(); + const fetchData = async () => { + try { + const repsonse = await getTodos(); + + setTodos(repsonse); + } finally { + finishLoading(); + } + }; + + fetchData(); + }, []); + return ( <>
@@ -17,18 +53,35 @@ export const App: React.FC = () => {

Todos:

- +
- - + {isLoading ? ( + + ) : ( + + )}
- - + {selectedTodo && ( + + )} ); }; diff --git a/src/components/TodoFilter/TodoFilter.tsx b/src/components/TodoFilter/TodoFilter.tsx index 193f1cd2b2..bb5fb98327 100644 --- a/src/components/TodoFilter/TodoFilter.tsx +++ b/src/components/TodoFilter/TodoFilter.tsx @@ -1,30 +1,95 @@ -export const TodoFilter = () => ( -
-

- - - -

- -

- - - - - - - {/* eslint-disable-next-line jsx-a11y/control-has-associated-label */} -