diff --git a/.eslintrc.js b/.eslintrc.js index cfae62de7..aeb79e7e2 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,19 +1,12 @@ module.exports = { - extends: ['@mate-academy/eslint-config-react', 'plugin:cypress/recommended'], + extends: ['@mate-academy/eslint-config-react-typescript', 'plugin:cypress/recommended'], rules: { - 'import/no-extraneous-dependencies': ['error', { - devDependencies: true, - optionalDependencies: false, - peerDependencies: false, - }], - 'react/prop-types': 0, 'max-len': ['error', { ignoreTemplateLiterals: true, ignoreComments: true, }], - 'jsx-a11y/label-has-associated-control': ['error', { - assert: 'either', + 'jsx-a11y/label-has-associated-control': ["error", { + assert: "either", }], - 'jsx-a11y/control-has-associated-label': 'off', }, }; diff --git a/node_modules/.cache/.eslintcache b/node_modules/.cache/.eslintcache index 4ac4a9631..b665127b5 100644 --- a/node_modules/.cache/.eslintcache +++ b/node_modules/.cache/.eslintcache @@ -1 +1 @@ -[{"/Users/alexandraprotyanova/Desktop/node/fe_aug23_product-categories-practice/src/index.jsx":"1","/Users/alexandraprotyanova/Desktop/node/fe_aug23_product-categories-practice/src/App.jsx":"2","/Users/alexandraprotyanova/Desktop/node/fe_aug23_product-categories-practice/src/api/products.js":"3","/Users/alexandraprotyanova/Desktop/node/fe_aug23_product-categories-practice/src/api/users.js":"4","/Users/alexandraprotyanova/Desktop/node/fe_aug23_product-categories-practice/src/api/categories.js":"5"},{"size":241,"mtime":1697387370538,"results":"6","hashOfConfig":"7"},{"size":9528,"mtime":1697447666398,"results":"8","hashOfConfig":"7"},{"size":542,"mtime":1697387370538,"results":"9","hashOfConfig":"7"},{"size":167,"mtime":1697387370538,"results":"10","hashOfConfig":"7"},{"size":402,"mtime":1697387370538,"results":"11","hashOfConfig":"7"},{"filePath":"12","messages":"13","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"5bxbhg",{"filePath":"14","messages":"15","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"16","messages":"17","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"18"},{"filePath":"19","messages":"20","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"18"},{"filePath":"21","messages":"22","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"18"},"/Users/alexandraprotyanova/Desktop/node/fe_aug23_product-categories-practice/src/index.jsx",[],"/Users/alexandraprotyanova/Desktop/node/fe_aug23_product-categories-practice/src/App.jsx",[],"/Users/alexandraprotyanova/Desktop/node/fe_aug23_product-categories-practice/src/api/products.js",[],["23","24","25","26","27","28","29","30","31","32"],"/Users/alexandraprotyanova/Desktop/node/fe_aug23_product-categories-practice/src/api/users.js",[],"/Users/alexandraprotyanova/Desktop/node/fe_aug23_product-categories-practice/src/api/categories.js",[],{"ruleId":"33","replacedBy":"34"},{"ruleId":"35","replacedBy":"36"},{"ruleId":"37","replacedBy":"38"},{"ruleId":"39","replacedBy":"40"},{"ruleId":"41","replacedBy":"42"},{"ruleId":"43","replacedBy":"44"},{"ruleId":"45","replacedBy":"46"},{"ruleId":"47","replacedBy":"48"},{"ruleId":"49","replacedBy":"50"},{"ruleId":"51","replacedBy":"52"},"jsx-a11y/label-has-for",[],"handle-callback-err",[],"no-negated-in-lhs",["53"],"no-new-require",[],"no-path-concat",[],"jsx-a11y/accessible-emoji",[],"lines-around-directive",["54"],"no-spaced-func",["55"],"global-require",[],"no-buffer-constructor",[],"no-unsafe-negation","padding-line-between-statements","func-call-spacing"] \ No newline at end of file +[{"/Users/alexandraprotyanova/Desktop/node/fe_aug23_product-categories-practice/src/index.tsx":"1","/Users/alexandraprotyanova/Desktop/node/fe_aug23_product-categories-practice/src/App.tsx":"2","/Users/alexandraprotyanova/Desktop/node/fe_aug23_product-categories-practice/src/api/products.ts":"3","/Users/alexandraprotyanova/Desktop/node/fe_aug23_product-categories-practice/src/api/categories.ts":"4","/Users/alexandraprotyanova/Desktop/node/fe_aug23_product-categories-practice/src/api/users.ts":"5","/Users/alexandraprotyanova/Desktop/node/fe_aug23_product-categories-practice/src/components/PeopleTable.tsx":"6","/Users/alexandraprotyanova/Desktop/node/fe_aug23_product-categories-practice/src/types/ColumnNames.ts":"7","/Users/alexandraprotyanova/Desktop/node/fe_aug23_product-categories-practice/src/components/Filters.tsx":"8"},{"size":214,"mtime":1697699454625,"results":"9","hashOfConfig":"10"},{"size":3816,"mtime":1697704011624,"results":"11","hashOfConfig":"10"},{"size":561,"mtime":1697700584558,"results":"12","hashOfConfig":"10"},{"size":472,"mtime":1697700440357,"results":"13","hashOfConfig":"10"},{"size":220,"mtime":1697700325393,"results":"14","hashOfConfig":"10"},{"size":2767,"mtime":1697704214187,"results":"15","hashOfConfig":"10"},{"size":107,"mtime":1697702919848,"results":"16","hashOfConfig":"10"},{"size":3986,"mtime":1697703873198,"results":"17","hashOfConfig":"10"},{"filePath":"18","messages":"19","errorCount":1,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":1,"fixableWarningCount":0,"source":"20","usedDeprecatedRules":"21"},"1ayjumf",{"filePath":"22","messages":"23","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"24","messages":"25","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"21"},{"filePath":"26","messages":"27","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"21"},{"filePath":"28","messages":"29","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"21"},{"filePath":"30","messages":"31","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"32","messages":"33","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"21"},{"filePath":"34","messages":"35","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"21"},"/Users/alexandraprotyanova/Desktop/node/fe_aug23_product-categories-practice/src/index.tsx",["36"],"import ReactDOM from 'react-dom';\n\nimport 'bulma/css/bulma.css';\nimport '@fortawesome/fontawesome-free/css/all.css';\n\nimport { App } from './App';\n\nReactDOM.render(\n ,\n document.getElementById('root'),\n);\n",["37","38","39","40","41","42","43"],"/Users/alexandraprotyanova/Desktop/node/fe_aug23_product-categories-practice/src/App.tsx",[],"/Users/alexandraprotyanova/Desktop/node/fe_aug23_product-categories-practice/src/api/products.ts",[],"/Users/alexandraprotyanova/Desktop/node/fe_aug23_product-categories-practice/src/api/categories.ts",[],"/Users/alexandraprotyanova/Desktop/node/fe_aug23_product-categories-practice/src/api/users.ts",[],"/Users/alexandraprotyanova/Desktop/node/fe_aug23_product-categories-practice/src/components/PeopleTable.tsx",[],"/Users/alexandraprotyanova/Desktop/node/fe_aug23_product-categories-practice/src/types/ColumnNames.ts",[],"/Users/alexandraprotyanova/Desktop/node/fe_aug23_product-categories-practice/src/components/Filters.tsx",[],{"ruleId":"44","severity":2,"message":"45","line":1,"column":1,"nodeType":"46","messageId":"47","endLine":2,"endColumn":1,"fix":"48"},{"ruleId":"49","replacedBy":"50"},{"ruleId":"51","replacedBy":"52"},{"ruleId":"53","replacedBy":"54"},{"ruleId":"55","replacedBy":"56"},{"ruleId":"57","replacedBy":"58"},{"ruleId":"59","replacedBy":"60"},{"ruleId":"61","replacedBy":"62"},"no-multiple-empty-lines","Too many blank lines at the beginning of file. Max of 0 allowed.","Program","blankBeginningOfFile",{"range":"63","text":"64"},"jsx-a11y/label-has-for",[],"lines-around-directive",["65"],"no-spaced-func",["66"],"global-require",[],"no-buffer-constructor",[],"no-new-require",[],"no-path-concat",[],[0,1],"","padding-line-between-statements","func-call-spacing"] \ No newline at end of file diff --git a/package.json b/package.json index 54cbfb148..58f4f8769 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ }, "mateAcademy": { "_comment": "Replace 'reactTypescript' with 'react' if you want use React without Typescript", - "projectType": "react", + "projectType": "reactTypescript", "tests": { "_comment": "Add `cypressComponents: true` to enable component tests", "cypress": true diff --git a/src/App.jsx b/src/App.jsx deleted file mode 100644 index 99d0c9ad1..000000000 --- a/src/App.jsx +++ /dev/null @@ -1,341 +0,0 @@ -/* eslint-disable jsx-a11y/accessible-emoji */ -import React, { useState } from 'react'; -import './App.scss'; - -import cn from 'classnames'; -import usersFromServer from './api/users'; -import categoriesFromServer from './api/categories'; -import productsFromServer from './api/products'; - -const products = productsFromServer.map((product) => { - const category = categoriesFromServer.find(c => c.id === product.categoryId) - || null; - const user = usersFromServer.find(u => u.id === category.ownerId) - || null; - - return { - ...product, - category, - user, - }; -}); - -const columns = [ - 'ID', - 'Product', - 'Category', - 'User', -]; - -const getVisibleProducts = ({ - goods, - selectedUserId, - query, - selectedCategoriesIds, - sortBy, - isReversed, -}) => { - let visibleProducts = [...goods]; - - if (selectedUserId) { - visibleProducts = visibleProducts.filter(product => ( - product.user.id === selectedUserId - )); - } - - if (query) { - const normalizedQuery = query.trim().toLowerCase(); - - visibleProducts = visibleProducts.filter(product => ( - product.name.toLowerCase().includes(normalizedQuery) - )); - } - - if (selectedCategoriesIds.length > 0) { - visibleProducts = visibleProducts.filter(product => ( - selectedCategoriesIds.includes(product.categoryId) - )); - } - - if (sortBy) { - visibleProducts.sort((a, b) => { - switch (sortBy) { - case 'ID': - return a.id - b.id; - - case 'Product': - return a.name.localeCompare(b.name); - - case 'Category': - return a.category.title.localeCompare(b.category.title); - - case 'User': - return a.user.name.localeCompare(b.user.name); - - default: - return 0; - } - }); - - if (isReversed) { - visibleProducts.reverse(); - } - } - - return visibleProducts; -}; - -export const App = () => { - const [selectedUserId, setSelectedUserId] = useState(0); - const [query, setQuery] = useState(''); - const [selectedCategoriesIds, setSelectedCategoriesIds] = useState([]); - const [sortBy, setSortBy] = useState(''); - const [isReversed, setIsReversed] = useState(false); - - function toggleCategories(categoryId) { - if (selectedCategoriesIds.includes(categoryId)) { - setSelectedCategoriesIds(selectedCategoriesIds.filter(id => ( - id !== categoryId - ))); - } else { - setSelectedCategoriesIds([...selectedCategoriesIds, categoryId]); - } - } - - function resetAll() { - if (selectedUserId) { - setSelectedUserId(0); - } - - if (query) { - setQuery(''); - } - - if (selectedCategoriesIds.length) { - setSelectedCategoriesIds([]); - } - } - - function toggleSortBy(newColumnName) { - const firstClick = sortBy !== newColumnName; - const secondClick = sortBy === newColumnName && isReversed === false; - const thirdClick = sortBy === newColumnName && isReversed === true; - - if (firstClick) { - setSortBy(newColumnName); - setIsReversed(false); - } - - if (secondClick) { - setIsReversed(true); - } - - if (thirdClick) { - setSortBy(''); - setIsReversed(false); - } - } - - const visibleProducts = getVisibleProducts({ - goods: products, - selectedUserId, - query, - selectedCategoriesIds, - sortBy, - isReversed, - }); - - return ( -
-
-

Product Categories

- -
-