From cfe7700f650d58edc70090f489c0876140754141 Mon Sep 17 00:00:00 2001 From: hirwaaldo1 Date: Wed, 3 May 2023 16:13:34 +0300 Subject: [PATCH 1/5] feat: adding typscript --- package-lock.json | 345 ++++-------------- package.json | 5 + src/{App.test.js => App.test.tsx} | 6 +- src/{App.jsx => App.tsx} | 0 .../layout/{Header.jsx => Header.tsx} | 0 .../articlespage/{Blog.jsx => Blog.tsx} | 0 .../sections/homepage/{Blog.jsx => Blog.tsx} | 3 +- .../sections/homepage/NavSkeleton.jsx | 7 - .../sections/homepage/NavSkeleton.tsx | 13 + .../{Navigation.jsx => Navigation.tsx} | 2 +- src/components/ui/Card/Skeleton.jsx | 18 - src/components/ui/Card/Skeleton.tsx | 22 ++ .../ui/Card/{index.jsx => index.tsx} | 0 .../ui/{ErrorFound.jsx => ErrorFound.tsx} | 0 .../ui/{NotFound.jsx => NotFound.tsx} | 0 .../ui/{SearchInput.jsx => SearchInput.tsx} | 0 .../{PageWrapper.jsx => PageWrapper.tsx} | 0 ...ctSlickSetting.js => reactSlickSetting.ts} | 0 src/features/{articles.js => articles.ts} | 0 src/{index.js => index.tsx} | 12 +- src/interfaces/articles.ts | 18 + src/pages/{Article.jsx => Article.tsx} | 10 +- src/pages/{Articles.jsx => Articles.tsx} | 0 src/pages/{Home.jsx => Home.tsx} | 0 ...{reportWebVitals.js => reportWebVitals.ts} | 0 .../{articlesApi.js => articlesApi.ts} | 5 +- .../{publishersApi.js => publishersApi.ts} | 0 src/{setupTests.js => setupTests.ts} | 0 src/store/{index.js => index.ts} | 0 src/utils/{getDateTime.js => getDateTime.ts} | 0 tailwind.config.js | 2 +- tsconfig.json | 9 + 32 files changed, 162 insertions(+), 315 deletions(-) rename src/{App.test.js => App.test.tsx} (50%) rename src/{App.jsx => App.tsx} (100%) rename src/components/layout/{Header.jsx => Header.tsx} (100%) rename src/components/sections/articlespage/{Blog.jsx => Blog.tsx} (100%) rename src/components/sections/homepage/{Blog.jsx => Blog.tsx} (90%) delete mode 100644 src/components/sections/homepage/NavSkeleton.jsx create mode 100644 src/components/sections/homepage/NavSkeleton.tsx rename src/components/sections/homepage/{Navigation.jsx => Navigation.tsx} (95%) delete mode 100644 src/components/ui/Card/Skeleton.jsx create mode 100644 src/components/ui/Card/Skeleton.tsx rename src/components/ui/Card/{index.jsx => index.tsx} (100%) rename src/components/ui/{ErrorFound.jsx => ErrorFound.tsx} (100%) rename src/components/ui/{NotFound.jsx => NotFound.tsx} (100%) rename src/components/ui/{SearchInput.jsx => SearchInput.tsx} (100%) rename src/components/wrappers/{PageWrapper.jsx => PageWrapper.tsx} (100%) rename src/config/{reactSlickSetting.js => reactSlickSetting.ts} (100%) rename src/features/{articles.js => articles.ts} (100%) rename src/{index.js => index.tsx} (74%) create mode 100644 src/interfaces/articles.ts rename src/pages/{Article.jsx => Article.tsx} (87%) rename src/pages/{Articles.jsx => Articles.tsx} (100%) rename src/pages/{Home.jsx => Home.tsx} (100%) rename src/{reportWebVitals.js => reportWebVitals.ts} (100%) rename src/services/{articlesApi.js => articlesApi.ts} (82%) rename src/services/{publishersApi.js => publishersApi.ts} (100%) rename src/{setupTests.js => setupTests.ts} (100%) rename src/store/{index.js => index.ts} (100%) rename src/utils/{getDateTime.js => getDateTime.ts} (100%) create mode 100644 tsconfig.json diff --git a/package-lock.json b/package-lock.json index 5976c38..1c30ed8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,8 @@ "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", + "@types/jest": "^29.5.1", + "@types/node": "^18.16.3", "react": "^18.2.0", "react-dom": "^18.2.0", "react-feather": "^2.0.10", @@ -23,9 +25,12 @@ "react-slick": "^0.29.0", "redux": "^4.2.1", "slick-carousel": "^1.8.1", + "typescript": "^5.0.4", "web-vitals": "^2.1.4" }, "devDependencies": { + "@types/react": "^18.2.0", + "@types/react-dom": "^18.2.1", "tailwindcss": "^3.2.7" } }, @@ -3482,95 +3487,6 @@ "tailwindcss": ">=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1" } }, - "node_modules/@testing-library/dom": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.0.1.tgz", - "integrity": "sha512-fTOVsMY9QLFCCXRHG3Ese6cMH5qIWwSbgxZsgeF5TNsy81HKaZ4kgehnSF8FsR3OF+numlIV2YcU79MzbnhSig==", - "peer": true, - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^5.0.1", - "aria-query": "^5.0.0", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.5.0", - "pretty-format": "^27.0.2" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@testing-library/dom/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "peer": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@testing-library/dom/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "peer": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@testing-library/dom/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "peer": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@testing-library/dom/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "peer": true - }, - "node_modules/@testing-library/dom/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/dom/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "peer": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@testing-library/jest-dom": { "version": "5.16.5", "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.5.tgz", @@ -3955,9 +3871,9 @@ } }, "node_modules/@types/jest": { - "version": "29.4.0", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.4.0.tgz", - "integrity": "sha512-VaywcGQ9tPorCX/Jkkni7RWGFfI11whqzs8dvxF41P17Z+z872thvEvlIbznjPJ02kl1HMX3LmLOonsj2n7HeQ==", + "version": "29.5.1", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.1.tgz", + "integrity": "sha512-tEuVcHrpaixS36w7hpsfLBLpjtMRJUE09/MHXn923LOVojDwyC14cWcfc0rDs0VEfUyYmt/+iX1kxxp+gZMcaQ==", "dependencies": { "expect": "^29.0.0", "pretty-format": "^29.0.0" @@ -4206,9 +4122,9 @@ "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==" }, "node_modules/@types/node": { - "version": "18.15.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.1.tgz", - "integrity": "sha512-U2TWca8AeHSmbpi314QBESRk7oPjSZjDsR+c+H4ECC1l+kFgpZf8Ydhv3SJpPy51VyZHHqxlb6mTTqYNNRVAIw==" + "version": "18.16.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.3.tgz", + "integrity": "sha512-OPs5WnnT1xkCBiuQrZA4+YAV4HEJejmHneyraIaxsbev5yCEr6KMwINNFP9wQeFIw8FWcoTqF3vQsa5CDaI+8Q==" }, "node_modules/@types/parse-json": { "version": "4.0.0", @@ -4241,9 +4157,9 @@ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, "node_modules/@types/react": { - "version": "18.0.28", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.28.tgz", - "integrity": "sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==", + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.0.tgz", + "integrity": "sha512-0FLj93y5USLHdnhIhABk83rm8XEGA7kH3cr+YUlvxoUGp1xNt/DINUMvqPxLyOQMzLmZe8i4RTHbvb8MC7NmrA==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -4251,9 +4167,9 @@ } }, "node_modules/@types/react-dom": { - "version": "18.0.11", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.11.tgz", - "integrity": "sha512-O38bPbI2CWtgw/OoQoY+BRelw7uysmXbWvw3nLWO21H1HSh+GOlqPuXshJfjmpNlKiiSDG9cc1JZAaMmVdcTlw==", + "version": "18.2.1", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.1.tgz", + "integrity": "sha512-8QZEV9+Kwy7tXFmjJrp3XUKQSs9LTnE0KnoUb0YCguWBiNW0Yfb2iBMYZ08WPg35IR6P3Z0s00B15SwZnO26+w==", "dependencies": { "@types/react": "*" } @@ -11626,12 +11542,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/jquery": { - "version": "3.6.4", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.4.tgz", - "integrity": "sha512-v28EW9DWDFpzcD9O5iyJXg3R3+q+mET5JhnjJzQUZMHOv67bpSIHq81GEYpPNZHG+XXHsfSme3nxp/hndKEcsQ==", - "peer": true - }, "node_modules/js-sdsl": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", @@ -16303,16 +16213,15 @@ } }, "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "peer": true, + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", + "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=12.20" } }, "node_modules/unbox-primitive": { @@ -18831,14 +18740,12 @@ "@csstools/postcss-unset-value": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.2.tgz", - "integrity": "sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g==", - "requires": {} + "integrity": "sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g==" }, "@csstools/selector-specificity": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.1.1.tgz", - "integrity": "sha512-jwx+WCqszn53YHOfvFMJJRd/B2GqkCBt+1MJSG6o5/s8+ytHMvDZXsJgUEWLk12UnLd7HYKac4BYU5i/Ron1Cw==", - "requires": {} + "integrity": "sha512-jwx+WCqszn53YHOfvFMJJRd/B2GqkCBt+1MJSG6o5/s8+ytHMvDZXsJgUEWLk12UnLd7HYKac4BYU5i/Ron1Cw==" }, "@eslint-community/eslint-utils": { "version": "4.2.0", @@ -19759,75 +19666,7 @@ "@tailwindcss/line-clamp": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/@tailwindcss/line-clamp/-/line-clamp-0.4.2.tgz", - "integrity": "sha512-HFzAQuqYCjyy/SX9sLGB1lroPzmcnWv1FHkIpmypte10hptf4oPUfucryMKovZh2u0uiS9U5Ty3GghWfEJGwVw==", - "requires": {} - }, - "@testing-library/dom": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.0.1.tgz", - "integrity": "sha512-fTOVsMY9QLFCCXRHG3Ese6cMH5qIWwSbgxZsgeF5TNsy81HKaZ4kgehnSF8FsR3OF+numlIV2YcU79MzbnhSig==", - "peer": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^5.0.1", - "aria-query": "^5.0.0", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.5.0", - "pretty-format": "^27.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "peer": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "peer": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "peer": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "peer": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "peer": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "peer": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } + "integrity": "sha512-HFzAQuqYCjyy/SX9sLGB1lroPzmcnWv1FHkIpmypte10hptf4oPUfucryMKovZh2u0uiS9U5Ty3GghWfEJGwVw==" }, "@testing-library/jest-dom": { "version": "5.16.5", @@ -20150,9 +19989,9 @@ } }, "@types/jest": { - "version": "29.4.0", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.4.0.tgz", - "integrity": "sha512-VaywcGQ9tPorCX/Jkkni7RWGFfI11whqzs8dvxF41P17Z+z872thvEvlIbznjPJ02kl1HMX3LmLOonsj2n7HeQ==", + "version": "29.5.1", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.1.tgz", + "integrity": "sha512-tEuVcHrpaixS36w7hpsfLBLpjtMRJUE09/MHXn923LOVojDwyC14cWcfc0rDs0VEfUyYmt/+iX1kxxp+gZMcaQ==", "requires": { "expect": "^29.0.0", "pretty-format": "^29.0.0" @@ -20348,9 +20187,9 @@ "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==" }, "@types/node": { - "version": "18.15.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.1.tgz", - "integrity": "sha512-U2TWca8AeHSmbpi314QBESRk7oPjSZjDsR+c+H4ECC1l+kFgpZf8Ydhv3SJpPy51VyZHHqxlb6mTTqYNNRVAIw==" + "version": "18.16.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.3.tgz", + "integrity": "sha512-OPs5WnnT1xkCBiuQrZA4+YAV4HEJejmHneyraIaxsbev5yCEr6KMwINNFP9wQeFIw8FWcoTqF3vQsa5CDaI+8Q==" }, "@types/parse-json": { "version": "4.0.0", @@ -20383,9 +20222,9 @@ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, "@types/react": { - "version": "18.0.28", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.28.tgz", - "integrity": "sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==", + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.0.tgz", + "integrity": "sha512-0FLj93y5USLHdnhIhABk83rm8XEGA7kH3cr+YUlvxoUGp1xNt/DINUMvqPxLyOQMzLmZe8i4RTHbvb8MC7NmrA==", "requires": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -20393,9 +20232,9 @@ } }, "@types/react-dom": { - "version": "18.0.11", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.11.tgz", - "integrity": "sha512-O38bPbI2CWtgw/OoQoY+BRelw7uysmXbWvw3nLWO21H1HSh+GOlqPuXshJfjmpNlKiiSDG9cc1JZAaMmVdcTlw==", + "version": "18.2.1", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.1.tgz", + "integrity": "sha512-8QZEV9+Kwy7tXFmjJrp3XUKQSs9LTnE0KnoUb0YCguWBiNW0Yfb2iBMYZ08WPg35IR6P3Z0s00B15SwZnO26+w==", "requires": { "@types/react": "*" } @@ -20786,14 +20625,12 @@ "acorn-import-assertions": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", - "requires": {} + "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==" }, "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "requires": {} + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==" }, "acorn-node": { "version": "1.8.2", @@ -20879,8 +20716,7 @@ "ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "requires": {} + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" }, "ansi-escapes": { "version": "4.3.2", @@ -21190,8 +21026,7 @@ "babel-plugin-named-asset-import": { "version": "0.3.8", "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz", - "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==", - "requires": {} + "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==" }, "babel-plugin-polyfill-corejs2": { "version": "0.3.3", @@ -21799,8 +21634,7 @@ "css-declaration-sorter": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz", - "integrity": "sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==", - "requires": {} + "integrity": "sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==" }, "css-has-pseudo": { "version": "3.0.4", @@ -21883,8 +21717,7 @@ "css-prefers-color-scheme": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz", - "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==", - "requires": {} + "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==" }, "css-select": { "version": "4.3.0", @@ -21988,8 +21821,7 @@ "cssnano-utils": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", - "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", - "requires": {} + "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==" }, "csso": { "version": "4.2.0", @@ -22889,8 +22721,7 @@ "eslint-plugin-react-hooks": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", - "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", - "requires": {} + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==" }, "eslint-plugin-testing-library": { "version": "5.10.2", @@ -23912,8 +23743,7 @@ "icss-utils": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "requires": {} + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==" }, "idb": { "version": "7.1.1", @@ -25005,8 +24835,7 @@ "jest-pnp-resolver": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "requires": {} + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==" }, "jest-regex-util": { "version": "27.5.1", @@ -25765,12 +25594,6 @@ } } }, - "jquery": { - "version": "3.6.4", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.4.tgz", - "integrity": "sha512-v28EW9DWDFpzcD9O5iyJXg3R3+q+mET5JhnjJzQUZMHOv67bpSIHq81GEYpPNZHG+XXHsfSme3nxp/hndKEcsQ==", - "peer": true - }, "js-sdsl": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", @@ -26686,8 +26509,7 @@ "postcss-browser-comments": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-4.0.0.tgz", - "integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==", - "requires": {} + "integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==" }, "postcss-calc": { "version": "8.2.4", @@ -26785,26 +26607,22 @@ "postcss-discard-comments": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", - "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", - "requires": {} + "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==" }, "postcss-discard-duplicates": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", - "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", - "requires": {} + "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==" }, "postcss-discard-empty": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", - "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", - "requires": {} + "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==" }, "postcss-discard-overridden": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", - "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", - "requires": {} + "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==" }, "postcss-double-position-gradients": { "version": "3.1.2", @@ -26826,8 +26644,7 @@ "postcss-flexbugs-fixes": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz", - "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==", - "requires": {} + "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==" }, "postcss-focus-visible": { "version": "6.0.4", @@ -26848,14 +26665,12 @@ "postcss-font-variant": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", - "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", - "requires": {} + "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==" }, "postcss-gap-properties": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz", - "integrity": "sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==", - "requires": {} + "integrity": "sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==" }, "postcss-image-set-function": { "version": "4.0.7", @@ -26878,8 +26693,7 @@ "postcss-initial": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz", - "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==", - "requires": {} + "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==" }, "postcss-js": { "version": "4.0.1", @@ -26920,14 +26734,12 @@ "postcss-logical": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz", - "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==", - "requires": {} + "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==" }, "postcss-media-minmax": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz", - "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==", - "requires": {} + "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==" }, "postcss-merge-longhand": { "version": "5.1.7", @@ -26988,8 +26800,7 @@ "postcss-modules-extract-imports": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "requires": {} + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==" }, "postcss-modules-local-by-default": { "version": "4.0.0", @@ -27047,8 +26858,7 @@ "postcss-normalize-charset": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", - "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", - "requires": {} + "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==" }, "postcss-normalize-display-values": { "version": "5.1.0", @@ -27119,8 +26929,7 @@ "postcss-opacity-percentage": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.3.tgz", - "integrity": "sha512-An6Ba4pHBiDtyVpSLymUUERMo2cU7s+Obz6BTrS+gxkbnSBNKSuD0AVUc+CpBMrpVPKKfoVz0WQCX+Tnst0i4A==", - "requires": {} + "integrity": "sha512-An6Ba4pHBiDtyVpSLymUUERMo2cU7s+Obz6BTrS+gxkbnSBNKSuD0AVUc+CpBMrpVPKKfoVz0WQCX+Tnst0i4A==" }, "postcss-ordered-values": { "version": "5.1.3", @@ -27142,8 +26951,7 @@ "postcss-page-break": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", - "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", - "requires": {} + "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==" }, "postcss-place": { "version": "7.0.5", @@ -27237,8 +27045,7 @@ "postcss-replace-overflow-wrap": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", - "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", - "requires": {} + "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==" }, "postcss-selector-not": { "version": "6.0.1", @@ -27632,8 +27439,7 @@ "react-loading-skeleton": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/react-loading-skeleton/-/react-loading-skeleton-3.2.0.tgz", - "integrity": "sha512-kN12x4Ud69jbksr2EdhYywAFeW4bPdvFQ9p3ID1OM/QeFjgwFSmSUY2a6P6uOb5ACzWp3ozY8C+7+04KR6+PHA==", - "requires": {} + "integrity": "sha512-kN12x4Ud69jbksr2EdhYywAFeW4bPdvFQ9p3ID1OM/QeFjgwFSmSUY2a6P6uOb5ACzWp3ozY8C+7+04KR6+PHA==" }, "react-redux": { "version": "8.0.5", @@ -27798,8 +27604,7 @@ "redux-thunk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz", - "integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==", - "requires": {} + "integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==" }, "regenerate": { "version": "1.4.2", @@ -28324,8 +28129,7 @@ "slick-carousel": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/slick-carousel/-/slick-carousel-1.8.1.tgz", - "integrity": "sha512-XB9Ftrf2EEKfzoQXt3Nitrt/IPbT+f1fgqBdoxO3W/+JYvtEOW6EgxnWfr9GH6nmULv7Y2tPmEX3koxThVmebA==", - "requires": {} + "integrity": "sha512-XB9Ftrf2EEKfzoQXt3Nitrt/IPbT+f1fgqBdoxO3W/+JYvtEOW6EgxnWfr9GH6nmULv7Y2tPmEX3koxThVmebA==" }, "sockjs": { "version": "0.3.24", @@ -28589,8 +28393,7 @@ "style-loader": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz", - "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==", - "requires": {} + "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==" }, "stylehacks": { "version": "5.1.1", @@ -28994,10 +28797,9 @@ } }, "typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "peer": true + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", + "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==" }, "unbox-primitive": { "version": "1.0.2", @@ -29091,8 +28893,7 @@ "use-sync-external-store": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", - "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", - "requires": {} + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==" }, "util-deprecate": { "version": "1.0.2", @@ -29366,8 +29167,7 @@ "ws": { "version": "8.13.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", - "requires": {} + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==" } } }, @@ -29825,8 +29625,7 @@ "ws": { "version": "7.5.9", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "requires": {} + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==" }, "xml-name-validator": { "version": "3.0.0", diff --git a/package.json b/package.json index a88423d..7b3cf72 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,8 @@ "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", + "@types/jest": "^29.5.1", + "@types/node": "^18.16.3", "react": "^18.2.0", "react-dom": "^18.2.0", "react-feather": "^2.0.10", @@ -18,6 +20,7 @@ "react-slick": "^0.29.0", "redux": "^4.2.1", "slick-carousel": "^1.8.1", + "typescript": "^5.0.4", "web-vitals": "^2.1.4" }, "scripts": { @@ -45,6 +48,8 @@ ] }, "devDependencies": { + "@types/react": "^18.2.0", + "@types/react-dom": "^18.2.1", "tailwindcss": "^3.2.7" } } diff --git a/src/App.test.js b/src/App.test.tsx similarity index 50% rename from src/App.test.js rename to src/App.test.tsx index 1f03afe..9382b9a 100644 --- a/src/App.test.js +++ b/src/App.test.tsx @@ -1,7 +1,7 @@ -import { render, screen } from '@testing-library/react'; -import App from './App'; +import { render, screen } from "@testing-library/react"; +import App from "./App"; -test('renders learn react link', () => { +test("renders learn react link", () => { render(); const linkElement = screen.getByText(/learn react/i); expect(linkElement).toBeInTheDocument(); diff --git a/src/App.jsx b/src/App.tsx similarity index 100% rename from src/App.jsx rename to src/App.tsx diff --git a/src/components/layout/Header.jsx b/src/components/layout/Header.tsx similarity index 100% rename from src/components/layout/Header.jsx rename to src/components/layout/Header.tsx diff --git a/src/components/sections/articlespage/Blog.jsx b/src/components/sections/articlespage/Blog.tsx similarity index 100% rename from src/components/sections/articlespage/Blog.jsx rename to src/components/sections/articlespage/Blog.tsx diff --git a/src/components/sections/homepage/Blog.jsx b/src/components/sections/homepage/Blog.tsx similarity index 90% rename from src/components/sections/homepage/Blog.jsx rename to src/components/sections/homepage/Blog.tsx index 57e0938..610cba3 100644 --- a/src/components/sections/homepage/Blog.jsx +++ b/src/components/sections/homepage/Blog.tsx @@ -6,6 +6,7 @@ import Card from "../../ui/Card"; import CardSkeleton from "../../ui/Card/Skeleton"; import ErrorFound from "../../ui/ErrorFound"; import NotFound from "../../ui/NotFound"; +import { ApiResponse } from "interfaces/articles"; export default function Blog() { const { @@ -14,7 +15,7 @@ export default function Blog() { isError, } = useGetArticlesQuery("headlines"); const dispatch = useDispatch(); - const data = useSelector((state) => state.articles); + const data = useSelector((state: ApiResponse) => state.articles); useEffect(() => { if (headlines) { dispatch(setArticles(headlines)); diff --git a/src/components/sections/homepage/NavSkeleton.jsx b/src/components/sections/homepage/NavSkeleton.jsx deleted file mode 100644 index 2878670..0000000 --- a/src/components/sections/homepage/NavSkeleton.jsx +++ /dev/null @@ -1,7 +0,0 @@ -import Skeleton from "react-loading-skeleton"; - -export default function NavSkeleton({ count }) { - return Array(count) - .fill() - .map((_, index) => ); -} diff --git a/src/components/sections/homepage/NavSkeleton.tsx b/src/components/sections/homepage/NavSkeleton.tsx new file mode 100644 index 0000000..5e63ec9 --- /dev/null +++ b/src/components/sections/homepage/NavSkeleton.tsx @@ -0,0 +1,13 @@ +import Skeleton from "react-loading-skeleton"; + +export default function NavSkeleton({ count }) { + return ( + <> + {Array(count) + .fill("") + .map((_, index) => ( + + ))} + + ); +} diff --git a/src/components/sections/homepage/Navigation.jsx b/src/components/sections/homepage/Navigation.tsx similarity index 95% rename from src/components/sections/homepage/Navigation.jsx rename to src/components/sections/homepage/Navigation.tsx index cc5313b..2279d26 100644 --- a/src/components/sections/homepage/Navigation.jsx +++ b/src/components/sections/homepage/Navigation.tsx @@ -7,7 +7,7 @@ import { Link } from "react-router-dom"; import NavSkeleton from "./NavSkeleton"; export default function Navigation() { - const { data: publishers, isLoading } = useGetPublisherQuery(); + const { data: publishers, isLoading } = useGetPublisherQuery(undefined); const [whichTab, setWhichTab] = useState(""); return ( diff --git a/src/components/ui/Card/Skeleton.jsx b/src/components/ui/Card/Skeleton.jsx deleted file mode 100644 index cbfbc81..0000000 --- a/src/components/ui/Card/Skeleton.jsx +++ /dev/null @@ -1,18 +0,0 @@ -import Skeleton from "react-loading-skeleton"; - -export default function CardSkeleton({ count }) { - return Array(count) - .fill() - .map((_, index) => { - return ( -
- -
- - -
- -
- ); - }); -} diff --git a/src/components/ui/Card/Skeleton.tsx b/src/components/ui/Card/Skeleton.tsx new file mode 100644 index 0000000..15e9c51 --- /dev/null +++ b/src/components/ui/Card/Skeleton.tsx @@ -0,0 +1,22 @@ +import Skeleton from "react-loading-skeleton"; + +export default function CardSkeleton({ count }) { + return ( + <> + {Array(count) + .fill("") + .map((_, index) => { + return ( +
+ +
+ + +
+ +
+ ); + })} + + ); +} diff --git a/src/components/ui/Card/index.jsx b/src/components/ui/Card/index.tsx similarity index 100% rename from src/components/ui/Card/index.jsx rename to src/components/ui/Card/index.tsx diff --git a/src/components/ui/ErrorFound.jsx b/src/components/ui/ErrorFound.tsx similarity index 100% rename from src/components/ui/ErrorFound.jsx rename to src/components/ui/ErrorFound.tsx diff --git a/src/components/ui/NotFound.jsx b/src/components/ui/NotFound.tsx similarity index 100% rename from src/components/ui/NotFound.jsx rename to src/components/ui/NotFound.tsx diff --git a/src/components/ui/SearchInput.jsx b/src/components/ui/SearchInput.tsx similarity index 100% rename from src/components/ui/SearchInput.jsx rename to src/components/ui/SearchInput.tsx diff --git a/src/components/wrappers/PageWrapper.jsx b/src/components/wrappers/PageWrapper.tsx similarity index 100% rename from src/components/wrappers/PageWrapper.jsx rename to src/components/wrappers/PageWrapper.tsx diff --git a/src/config/reactSlickSetting.js b/src/config/reactSlickSetting.ts similarity index 100% rename from src/config/reactSlickSetting.js rename to src/config/reactSlickSetting.ts diff --git a/src/features/articles.js b/src/features/articles.ts similarity index 100% rename from src/features/articles.js rename to src/features/articles.ts diff --git a/src/index.js b/src/index.tsx similarity index 74% rename from src/index.js rename to src/index.tsx index 510a87d..6de022e 100644 --- a/src/index.js +++ b/src/index.tsx @@ -1,5 +1,4 @@ -import React from "react"; -import ReactDOM from "react-dom/client"; +import { createRoot } from "react-dom/client"; import "react-loading-skeleton/dist/skeleton.css"; import App from "./App"; import reportWebVitals from "./reportWebVitals"; @@ -10,9 +9,10 @@ import "./index.css"; import "slick-carousel/slick/slick.css"; import "slick-carousel/slick/slick-theme.css"; import { BrowserRouter } from "react-router-dom"; -const root = ReactDOM.createRoot(document.getElementById("root")); +import { StrictMode } from "react"; +const root = createRoot(document.getElementById("root")); root.render( - + @@ -20,6 +20,6 @@ root.render( - + ); -reportWebVitals(); +reportWebVitals(undefined); diff --git a/src/interfaces/articles.ts b/src/interfaces/articles.ts new file mode 100644 index 0000000..4bae31a --- /dev/null +++ b/src/interfaces/articles.ts @@ -0,0 +1,18 @@ +export interface Article { + source: Source; + author: string; + title: string; + description: string; + url: string; + urlToImage: string; + publishedAt: string; + content: string; +} +export interface Source { + id: any; + name: string; +} + +export interface ApiResponse { + articles: Article[]; +} diff --git a/src/pages/Article.jsx b/src/pages/Article.tsx similarity index 87% rename from src/pages/Article.jsx rename to src/pages/Article.tsx index 96d5ca3..183f5cf 100644 --- a/src/pages/Article.jsx +++ b/src/pages/Article.tsx @@ -1,16 +1,20 @@ -import { Link, useLocation } from "react-router-dom"; +import { useNavigate, useLocation } from "react-router-dom"; import getDateTime from "../utils/getDateTime"; import { ArrowLeft } from "react-feather"; export default function Article() { const { state } = useLocation(); + const navigate = useNavigate(); const date = new Date(state.publishedAt); return (
- +
navigate(-1)} + className="mt-3 flex items-center gap-5" + > Back - +

{state.title}

diff --git a/src/pages/Articles.jsx b/src/pages/Articles.tsx similarity index 100% rename from src/pages/Articles.jsx rename to src/pages/Articles.tsx diff --git a/src/pages/Home.jsx b/src/pages/Home.tsx similarity index 100% rename from src/pages/Home.jsx rename to src/pages/Home.tsx diff --git a/src/reportWebVitals.js b/src/reportWebVitals.ts similarity index 100% rename from src/reportWebVitals.js rename to src/reportWebVitals.ts diff --git a/src/services/articlesApi.js b/src/services/articlesApi.ts similarity index 82% rename from src/services/articlesApi.js rename to src/services/articlesApi.ts index e45fec5..f274274 100644 --- a/src/services/articlesApi.js +++ b/src/services/articlesApi.ts @@ -1,4 +1,5 @@ import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; +import { ApiResponse } from "interfaces/articles"; const { REACT_APP_API_KEY, REACT_APP_API_URL } = process.env; export const articlesApi = createApi({ reducerPath: "articlesApi", @@ -15,13 +16,13 @@ export const articlesApi = createApi({ : `top-headlines?sources=${publisher}&pageSize=10&apiKey=${REACT_APP_API_KEY}`; } }, - transformResponse: (response) => response.articles, + transformResponse: (response: ApiResponse) => response.articles, }), searchArticles: builder.query({ query: (keyword) => { return `everything?q=${keyword}&pageSize=10&apiKey=${REACT_APP_API_KEY}`; }, - transformResponse: (response) => response.articles, + transformResponse: (response: ApiResponse) => response.articles, }), }), }); diff --git a/src/services/publishersApi.js b/src/services/publishersApi.ts similarity index 100% rename from src/services/publishersApi.js rename to src/services/publishersApi.ts diff --git a/src/setupTests.js b/src/setupTests.ts similarity index 100% rename from src/setupTests.js rename to src/setupTests.ts diff --git a/src/store/index.js b/src/store/index.ts similarity index 100% rename from src/store/index.js rename to src/store/index.ts diff --git a/src/utils/getDateTime.js b/src/utils/getDateTime.ts similarity index 100% rename from src/utils/getDateTime.js rename to src/utils/getDateTime.ts diff --git a/tailwind.config.js b/tailwind.config.js index a3d33e0..61408d3 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,6 +1,6 @@ /** @type {import('tailwindcss').Config} */ module.exports = { - content: ["./src/**/*.{js,jsx}"], + content: ["./src/**/*.{js,jsx,tsx,ts}"], theme: { extend: {}, }, diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..10c205a --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "baseUrl": "src", + "jsx": "preserve", + "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "module": "commonjs", /* Specify what module code is generated. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +} From fcf969e4a8ca08501bb5640e807fd539f8908574 Mon Sep 17 00:00:00 2001 From: hirwaaldo1 Date: Wed, 3 May 2023 16:23:55 +0300 Subject: [PATCH 2/5] build: add force flag on netifly --- src/index.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/index.tsx b/src/index.tsx index 6de022e..e2c0ba6 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -10,7 +10,9 @@ import "slick-carousel/slick/slick.css"; import "slick-carousel/slick/slick-theme.css"; import { BrowserRouter } from "react-router-dom"; import { StrictMode } from "react"; + const root = createRoot(document.getElementById("root")); + root.render( From adaf0598326a1d0e7aab1aa7208f43a26b01477c Mon Sep 17 00:00:00 2001 From: hirwaaldo1 Date: Mon, 8 May 2023 14:07:39 +0300 Subject: [PATCH 3/5] feat: add more typescript --- src/components/layout/Header.tsx | 3 +- src/components/sections/articlespage/Blog.tsx | 6 +++- src/components/sections/homepage/Blog.tsx | 11 +++--- .../sections/homepage/NavSkeleton.tsx | 2 +- .../sections/homepage/Navigation.tsx | 7 ++-- src/components/ui/Card/Skeleton.tsx | 2 +- src/components/ui/Card/index.tsx | 6 ++-- src/components/ui/ErrorFound.tsx | 2 +- src/components/ui/NotFound.tsx | 2 +- src/components/ui/SearchInput.tsx | 10 +++--- src/components/wrappers/PageWrapper.tsx | 12 +++++-- src/features/articles.ts | 5 +-- src/index.tsx | 6 ++-- src/interfaces/articles.ts | 2 +- src/interfaces/publisher.ts | 9 +++++ src/services/articlesApi.ts | 34 +++++++++++++++---- src/services/publishersApi.ts | 24 +++++++++++-- src/utils/getDateTime.ts | 4 +-- 18 files changed, 107 insertions(+), 40 deletions(-) create mode 100644 src/interfaces/publisher.ts diff --git a/src/components/layout/Header.tsx b/src/components/layout/Header.tsx index f937e70..4f5f767 100644 --- a/src/components/layout/Header.tsx +++ b/src/components/layout/Header.tsx @@ -1,6 +1,7 @@ +import { ReactElement } from "react"; import { Link } from "react-router-dom"; -export default function Header() { +export default function Header(): ReactElement { return (
diff --git a/src/components/sections/articlespage/Blog.tsx b/src/components/sections/articlespage/Blog.tsx index d925c29..3b2210a 100644 --- a/src/components/sections/articlespage/Blog.tsx +++ b/src/components/sections/articlespage/Blog.tsx @@ -4,7 +4,11 @@ import CardSkeleton from "../../ui/Card/Skeleton"; import ErrorFound from "../../ui/ErrorFound"; import NotFound from "../../ui/NotFound"; -export default function Blog({ whichTab }) { +export default function Blog({ + whichTab, +}: { + whichTab: string; +}): React.ReactElement { const { data, isError, isLoading } = useGetArticlesQuery(whichTab); return ( diff --git a/src/components/sections/homepage/Blog.tsx b/src/components/sections/homepage/Blog.tsx index 610cba3..f50e35c 100644 --- a/src/components/sections/homepage/Blog.tsx +++ b/src/components/sections/homepage/Blog.tsx @@ -1,4 +1,4 @@ -import { useEffect } from "react"; +import { Dispatch, useEffect } from "react"; import { useDispatch, useSelector } from "react-redux"; import { setArticles } from "../../../features/articles"; import { useGetArticlesQuery } from "../../../services/articlesApi"; @@ -6,16 +6,17 @@ import Card from "../../ui/Card"; import CardSkeleton from "../../ui/Card/Skeleton"; import ErrorFound from "../../ui/ErrorFound"; import NotFound from "../../ui/NotFound"; -import { ApiResponse } from "interfaces/articles"; +import { Articles } from "interfaces/articles"; +import { AnyAction } from "redux"; -export default function Blog() { +export default function Blog(): React.ReactElement { const { data: headlines, isLoading, isError, } = useGetArticlesQuery("headlines"); - const dispatch = useDispatch(); - const data = useSelector((state: ApiResponse) => state.articles); + const dispatch: Dispatch = useDispatch(); + const data = useSelector((state: Articles) => state.articles); useEffect(() => { if (headlines) { dispatch(setArticles(headlines)); diff --git a/src/components/sections/homepage/NavSkeleton.tsx b/src/components/sections/homepage/NavSkeleton.tsx index 5e63ec9..f5c6566 100644 --- a/src/components/sections/homepage/NavSkeleton.tsx +++ b/src/components/sections/homepage/NavSkeleton.tsx @@ -1,6 +1,6 @@ import Skeleton from "react-loading-skeleton"; -export default function NavSkeleton({ count }) { +export default function NavSkeleton({ count }: { count: number }) { return ( <> {Array(count) diff --git a/src/components/sections/homepage/Navigation.tsx b/src/components/sections/homepage/Navigation.tsx index 2279d26..a9783b3 100644 --- a/src/components/sections/homepage/Navigation.tsx +++ b/src/components/sections/homepage/Navigation.tsx @@ -5,10 +5,11 @@ import Slider from "react-slick"; import settings from "../../../config/reactSlickSetting"; import { Link } from "react-router-dom"; import NavSkeleton from "./NavSkeleton"; +import { Publisher } from "interfaces/publisher"; -export default function Navigation() { +export default function Navigation(): React.ReactElement { const { data: publishers, isLoading } = useGetPublisherQuery(undefined); - const [whichTab, setWhichTab] = useState(""); + const [whichTab, setWhichTab] = useState(""); return (
@@ -17,7 +18,7 @@ export default function Navigation() { ) : ( - {publishers?.sources.map((item) => ( + {publishers?.sources.map((item: Publisher) => ( {Array(count) diff --git a/src/components/ui/Card/index.tsx b/src/components/ui/Card/index.tsx index 04a7034..3521737 100644 --- a/src/components/ui/Card/index.tsx +++ b/src/components/ui/Card/index.tsx @@ -1,9 +1,11 @@ import { Link } from "react-router-dom"; import getDateTime from "../../../utils/getDateTime"; +import { Article } from "interfaces/articles"; -export default function Card({ article }) { +export default function Card({ article }: { article: Article }) { const { title, urlToImage, publishedAt } = article; const date = new Date(publishedAt); + return (
@@ -13,7 +15,7 @@ export default function Card({ article }) { alt={title} />
- {getDateTime(date.getMonth(), date.getDay())} + {getDateTime(date.getMonth(), date.getDate())} {date.getMinutes()} min
diff --git a/src/components/ui/ErrorFound.tsx b/src/components/ui/ErrorFound.tsx index 494bab4..56ca81a 100644 --- a/src/components/ui/ErrorFound.tsx +++ b/src/components/ui/ErrorFound.tsx @@ -1,4 +1,4 @@ -export default function ErrorFound() { +export default function ErrorFound(): React.ReactElement { return (
diff --git a/src/components/ui/NotFound.tsx b/src/components/ui/NotFound.tsx index c8992c1..601dc3c 100644 --- a/src/components/ui/NotFound.tsx +++ b/src/components/ui/NotFound.tsx @@ -1,4 +1,4 @@ -export default function NotFound() { +export default function NotFound(): React.ReactElement { return (
diff --git a/src/components/ui/SearchInput.tsx b/src/components/ui/SearchInput.tsx index 99f259d..b6b2349 100644 --- a/src/components/ui/SearchInput.tsx +++ b/src/components/ui/SearchInput.tsx @@ -1,10 +1,10 @@ -import { useState } from "react"; +import { ChangeEvent, useState } from "react"; import { Search, X } from "react-feather"; import { useDispatch } from "react-redux"; import { setArticles } from "../../features/articles"; import { useSearchArticlesQuery } from "../../services/articlesApi"; -export default function SearchInput() { +export default function SearchInput(): React.ReactElement { const [search, setSearch] = useState(""); const { data: article } = useSearchArticlesQuery(search); const dispatch = useDispatch(); @@ -19,7 +19,9 @@ export default function SearchInput() { setSearch(event.target.value)} + onChange={(event: ChangeEvent) => + setSearch(event.target.value) + } value={search} className="outline-none placeholder:text-black" placeholder="Search..." @@ -32,7 +34,7 @@ export default function SearchInput() { setSearch("")} + onClick={(): void => setSearch("")} />
)} diff --git a/src/components/wrappers/PageWrapper.tsx b/src/components/wrappers/PageWrapper.tsx index fa45839..1e4ad73 100644 --- a/src/components/wrappers/PageWrapper.tsx +++ b/src/components/wrappers/PageWrapper.tsx @@ -1,11 +1,17 @@ import Header from "../layout/Header"; +type Props = React.PropsWithChildren<{ + as: "div" | "section" | "aside"; +}>; -const PageWrapper = ({ children }) => { +const PageWrapper = ({ + as: Component = "section", + children, +}: Props): React.ReactElement => { return ( -
+
{children} -
+ ); }; diff --git a/src/features/articles.ts b/src/features/articles.ts index 30e24bc..d99439d 100644 --- a/src/features/articles.ts +++ b/src/features/articles.ts @@ -1,9 +1,10 @@ -import { createSlice } from "@reduxjs/toolkit"; +import { PayloadAction, createSlice } from "@reduxjs/toolkit"; +import { Article } from "interfaces/articles"; const articlesSlice = createSlice({ name: "articles", initialState: [], reducers: { - setArticles: (state, action) => { + setArticles: (state: Array
, action: PayloadAction) => { return (state = action.payload); }, }, diff --git a/src/index.tsx b/src/index.tsx index e2c0ba6..7e21238 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -4,7 +4,7 @@ import App from "./App"; import reportWebVitals from "./reportWebVitals"; import { Provider } from "react-redux"; import store from "./store"; -import PageWrapper from "./components/wrappers/PageWrapper"; +import Wrapper from "./components/wrappers/PageWrapper"; import "./index.css"; import "slick-carousel/slick/slick.css"; import "slick-carousel/slick/slick-theme.css"; @@ -17,9 +17,9 @@ root.render( - + - + diff --git a/src/interfaces/articles.ts b/src/interfaces/articles.ts index 4bae31a..54df7ff 100644 --- a/src/interfaces/articles.ts +++ b/src/interfaces/articles.ts @@ -13,6 +13,6 @@ export interface Source { name: string; } -export interface ApiResponse { +export interface Articles { articles: Article[]; } diff --git a/src/interfaces/publisher.ts b/src/interfaces/publisher.ts new file mode 100644 index 0000000..8917e7a --- /dev/null +++ b/src/interfaces/publisher.ts @@ -0,0 +1,9 @@ +export interface Publisher { + id: string; + name: string; + description: string; + url: URL; + category: string; + language: string; + country: string; +} diff --git a/src/services/articlesApi.ts b/src/services/articlesApi.ts index f274274..7c0852b 100644 --- a/src/services/articlesApi.ts +++ b/src/services/articlesApi.ts @@ -1,5 +1,13 @@ -import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; -import { ApiResponse } from "interfaces/articles"; +import { EndpointBuilder } from "@reduxjs/toolkit/dist/query/endpointDefinitions"; +import { + BaseQueryFn, + FetchArgs, + FetchBaseQueryError, + FetchBaseQueryMeta, + createApi, + fetchBaseQuery, +} from "@reduxjs/toolkit/query/react"; +import { Articles } from "interfaces/articles"; const { REACT_APP_API_KEY, REACT_APP_API_URL } = process.env; export const articlesApi = createApi({ reducerPath: "articlesApi", @@ -7,22 +15,34 @@ export const articlesApi = createApi({ baseUrl: REACT_APP_API_URL, }), - endpoints: (builder) => ({ + endpoints: ( + builder: EndpointBuilder< + BaseQueryFn< + string | FetchArgs, + unknown, + FetchBaseQueryError, + {}, + FetchBaseQueryMeta + >, + never, + "articlesApi" + > + ) => ({ getArticles: builder.query({ - query: (publisher) => { + query: (publisher: string) => { if (publisher) { return publisher === "headlines" ? `top-headlines?country=us&pageSize=10&apiKey=${REACT_APP_API_KEY}` : `top-headlines?sources=${publisher}&pageSize=10&apiKey=${REACT_APP_API_KEY}`; } }, - transformResponse: (response: ApiResponse) => response.articles, + transformResponse: (response: Articles) => response.articles, }), searchArticles: builder.query({ - query: (keyword) => { + query: (keyword: string) => { return `everything?q=${keyword}&pageSize=10&apiKey=${REACT_APP_API_KEY}`; }, - transformResponse: (response: ApiResponse) => response.articles, + transformResponse: (response: Articles) => response.articles, }), }), }); diff --git a/src/services/publishersApi.ts b/src/services/publishersApi.ts index c510be0..cb31023 100644 --- a/src/services/publishersApi.ts +++ b/src/services/publishersApi.ts @@ -1,11 +1,31 @@ -import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; +import { EndpointBuilder } from "@reduxjs/toolkit/dist/query/endpointDefinitions"; +import { + BaseQueryFn, + FetchArgs, + FetchBaseQueryError, + FetchBaseQueryMeta, + createApi, + fetchBaseQuery, +} from "@reduxjs/toolkit/query/react"; const { REACT_APP_API_KEY, REACT_APP_API_URL } = process.env; export const publishersApi = createApi({ reducerPath: "publishersApi", baseQuery: fetchBaseQuery({ baseUrl: REACT_APP_API_URL, }), - endpoints: (builder) => ({ + endpoints: ( + builder: EndpointBuilder< + BaseQueryFn< + string | FetchArgs, + unknown, + FetchBaseQueryError, + {}, + FetchBaseQueryMeta + >, + never, + "publishersApi" + > + ) => ({ getPublisher: builder.query({ query: () => `top-headlines/sources?country=us&apiKey=${REACT_APP_API_KEY}`, diff --git a/src/utils/getDateTime.ts b/src/utils/getDateTime.ts index 951dc50..c621af5 100644 --- a/src/utils/getDateTime.ts +++ b/src/utils/getDateTime.ts @@ -12,6 +12,6 @@ const monthNames = [ "Nov", "Dec", ]; -export default function getDateTime(month, day) { - return monthNames[month] + " " + day; +export default function getDateTime(month: number, day: number) { + return monthNames[month] + " " + (day + 1); } From 0fd75321112933ece5d64e74555a57f87c1b014d Mon Sep 17 00:00:00 2001 From: hirwaaldo1 Date: Mon, 8 May 2023 20:19:57 +0300 Subject: [PATCH 4/5] feat: add debounce in search --- src/components/sections/homepage/Blog.tsx | 6 +- src/components/ui/NotFound.tsx | 2 +- src/components/ui/SearchInput.tsx | 68 ++++++++++++++++------- src/services/articlesApi.ts | 3 +- 4 files changed, 55 insertions(+), 24 deletions(-) diff --git a/src/components/sections/homepage/Blog.tsx b/src/components/sections/homepage/Blog.tsx index f50e35c..cf3fa83 100644 --- a/src/components/sections/homepage/Blog.tsx +++ b/src/components/sections/homepage/Blog.tsx @@ -26,11 +26,13 @@ export default function Blog(): React.ReactElement { return ( <> {isError && } -
+
{isLoading ? ( ) : data?.length === 0 ? ( - +
+ +
) : ( data.map((article, index) => { return ; diff --git a/src/components/ui/NotFound.tsx b/src/components/ui/NotFound.tsx index 601dc3c..34a8d1e 100644 --- a/src/components/ui/NotFound.tsx +++ b/src/components/ui/NotFound.tsx @@ -1,6 +1,6 @@ export default function NotFound(): React.ReactElement { return ( -
+
(""); + const [keyword, setKeyword] = useState(); + const { data: article } = useSearchArticlesQuery(keyword); + const { data: headlines } = useGetArticlesQuery("headlines"); + const [loading, setLoading] = useState(false); const dispatch = useDispatch(); - function searchArticle(event) { - event.preventDefault(); - dispatch(setArticles(article)); + useEffect(() => { + if (keyword) { + dispatch(setArticles(article)); + } + }, [article, dispatch, keyword]); + + const debounce = (cb: Function) => { + let timeout; + if (timeout) clearTimeout(timeout); + timeout = setTimeout(() => { + cb(); + }, 1000); + }; + function onChangleText(event: ChangeEvent): void { + setLoading(true); + setSearch(event.target.value); + debounce(() => { + if (event.target.value.length > 0) { + setLoading(false); + setKeyword(event.target.value); + } + }); } return ( -
+ ) => - setSearch(event.target.value) - } + onChange={onChangleText} value={search} className="outline-none placeholder:text-black" placeholder="Search..." /> {search.length > 0 && (
- - setSearch("")} - /> + {loading ? ( + + ) : ( + { + setSearch(""); + setKeyword(undefined); + dispatch(setArticles(headlines)); + }} + /> + )}
)} diff --git a/src/services/articlesApi.ts b/src/services/articlesApi.ts index 7c0852b..efa05d2 100644 --- a/src/services/articlesApi.ts +++ b/src/services/articlesApi.ts @@ -40,7 +40,8 @@ export const articlesApi = createApi({ }), searchArticles: builder.query({ query: (keyword: string) => { - return `everything?q=${keyword}&pageSize=10&apiKey=${REACT_APP_API_KEY}`; + if (keyword) + return `everything?q=${keyword}&pageSize=10&apiKey=${REACT_APP_API_KEY}`; }, transformResponse: (response: Articles) => response.articles, }), From e060849c27db80be822d1db836042e3e20b401c0 Mon Sep 17 00:00:00 2001 From: hirwaaldo1 Date: Mon, 8 May 2023 20:26:59 +0300 Subject: [PATCH 5/5] build: fix api key --- src/services/articlesApi.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/services/articlesApi.ts b/src/services/articlesApi.ts index efa05d2..6eceab0 100644 --- a/src/services/articlesApi.ts +++ b/src/services/articlesApi.ts @@ -47,4 +47,5 @@ export const articlesApi = createApi({ }), }), }); + export const { useGetArticlesQuery, useSearchArticlesQuery } = articlesApi;