From e0d52ec8e7437b4dea25ac07f9c5395379288f01 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 30 Sep 2022 15:30:23 +0400 Subject: [PATCH 1/8] init project, changed tsconfig, installed MUI icons, UI for champions table --- .gitignore | 1 + package-lock.json | 1026 ++++++++++++++++- package.json | 4 +- {src => public}/img/Mortal-Kombat-Logo.png | Bin src/App.tsx | 13 +- .../CharactersSearch.module.css | 41 + .../CharactersSearch/CharactersSearch.tsx | 81 ++ src/components/Header/Header.module.css | 14 + src/components/Header/Header.tsx | 15 + tsconfig.json | 11 +- 10 files changed, 1188 insertions(+), 18 deletions(-) rename {src => public}/img/Mortal-Kombat-Logo.png (100%) create mode 100644 src/components/CharactersSearch/CharactersSearch.module.css create mode 100644 src/components/CharactersSearch/CharactersSearch.tsx create mode 100644 src/components/Header/Header.module.css create mode 100644 src/components/Header/Header.tsx diff --git a/.gitignore b/.gitignore index 4d29575..f3b9212 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ # misc .DS_Store +.idea .env.local .env.development.local .env.test.local diff --git a/package-lock.json b/package-lock.json index 0b833a1..f17f2d1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@emotion/react": "^11.9.3", "@emotion/styled": "^11.9.3", + "@mui/icons-material": "^5.10.6", "@mui/material": "^5.8.4", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^13.3.0", @@ -25,7 +26,8 @@ "@types/node": "^18.0.0", "@types/react": "^18.0.14", "@types/react-dom": "^18.0.5", - "typescript": "^4.7.4" + "typescript": "^4.7.4", + "typescript-plugin-css-modules": "^3.4.0" } }, "node_modules/@ampproject/remapping": { @@ -1806,9 +1808,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.3.tgz", - "integrity": "sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.0.tgz", + "integrity": "sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==", "dependencies": { "regenerator-runtime": "^0.13.4" }, @@ -3122,6 +3124,31 @@ } } }, + "node_modules/@mui/icons-material": { + "version": "5.10.6", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.10.6.tgz", + "integrity": "sha512-QwxdRmLA46S94B0hExPDx0td+A2unF+33bQ6Cs+lNpJKVsm1YeHwNdYXYcnpWeHeQQ07055OXl7IB2GKDd0MfA==", + "dependencies": { + "@babel/runtime": "^7.19.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@mui/material": "^5.0.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@mui/material": { "version": "5.8.4", "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.8.4.tgz", @@ -6094,6 +6121,18 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, + "node_modules/copy-anything": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", + "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", + "dev": true, + "dependencies": { + "is-what": "^3.14.1" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, "node_modules/core-js": { "version": "3.23.1", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.23.1.tgz", @@ -6350,6 +6389,50 @@ "node": ">=0.10.0" } }, + "node_modules/css-parse": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-2.0.0.tgz", + "integrity": "sha512-UNIFik2RgSbiTwIW1IsFwXWn6vs+bYdq83LKTSOsx7NJR7WII9dxewkHLltfTLVppoUApHV0118a4RZRI9FLwA==", + "dev": true, + "dependencies": { + "css": "^2.0.0" + } + }, + "node_modules/css-parse/node_modules/css": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", + "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "source-map": "^0.6.1", + "source-map-resolve": "^0.5.2", + "urix": "^0.1.0" + } + }, + "node_modules/css-parse/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-parse/node_modules/source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", + "dev": true, + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, "node_modules/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", @@ -6384,6 +6467,16 @@ "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" }, + "node_modules/css-selector-tokenizer": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.3.tgz", + "integrity": "sha512-jWQv3oCEL5kMErj4wRnK/OPoBi0D+P1FR2cDCKYPaMeD2eW3/mttav8HT4hT1CKopiJI/psEULjkClhvJo4Lvg==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "fastparse": "^1.1.2" + } + }, "node_modules/css-tree": { "version": "1.0.0-alpha.37", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", @@ -7021,6 +7114,19 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "optional": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -8020,6 +8126,12 @@ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" }, + "node_modules/fastparse": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", + "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", + "dev": true + }, "node_modules/fastq": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", @@ -8493,6 +8605,54 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/generic-names": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/generic-names/-/generic-names-1.0.3.tgz", + "integrity": "sha512-b6OHfQuKasIKM9b6YPkX+KUj/TLBTx3B/1aT1T5F12FEuEqyFMdr59OMS53aoaSw8eVtapdqieX6lbg5opaOhA==", + "dev": true, + "dependencies": { + "loader-utils": "^0.2.16" + } + }, + "node_modules/generic-names/node_modules/big.js": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/generic-names/node_modules/emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha512-knHEZMgs8BB+MInokmNTg/OyPlAddghe1YBgNwJBc5zsJi/uyIcXoSDsL/W9ymOsBoBGdPIHXYJ9+qKFwRwDng==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/generic-names/node_modules/json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/generic-names/node_modules/loader-utils": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", + "integrity": "sha512-tiv66G0SmiOx+pLWMtGEkfSEejxvb6N6uRrQjfWJIT79W9GMpgKeCAmm9aVBKtd4WEgntciI8CsGqjpDoCWJug==", + "dev": true, + "dependencies": { + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0", + "object-assign": "^4.0.1" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -9033,6 +9193,19 @@ "node": ">= 4" } }, + "node_modules/image-size": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", + "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", + "dev": true, + "optional": true, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/immer": { "version": "9.0.15", "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.15.tgz", @@ -9042,6 +9215,12 @@ "url": "https://opencollective.com/immer" } }, + "node_modules/immutable": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", + "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", + "devOptional": true + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -9425,6 +9604,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-what": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", + "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", + "dev": true + }, "node_modules/is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -11672,6 +11857,76 @@ "language-subtag-registry": "~0.3.2" } }, + "node_modules/less": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/less/-/less-4.1.3.tgz", + "integrity": "sha512-w16Xk/Ta9Hhyei0Gpz9m7VS8F28nieJaL/VyShID7cYvP6IL5oHeL6p4TXSDJqZE/lNv0oJ2pGVjJsRkfwm5FA==", + "dev": true, + "dependencies": { + "copy-anything": "^2.0.1", + "parse-node-version": "^1.0.1", + "tslib": "^2.3.0" + }, + "bin": { + "lessc": "bin/lessc" + }, + "engines": { + "node": ">=6" + }, + "optionalDependencies": { + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "make-dir": "^2.1.0", + "mime": "^1.4.1", + "needle": "^3.1.0", + "source-map": "~0.6.0" + } + }, + "node_modules/less/node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "optional": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/less/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/less/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/less/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -11745,6 +12000,12 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -12086,6 +12347,34 @@ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" }, + "node_modules/needle": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.1.0.tgz", + "integrity": "sha512-gCE9weDhjVGCRqS8dwDR/D3GTAeyXLXuqp7I8EzH6DllZGXSUyxuqqLh+YX9rMAWaaTFyVAg6rHGL25dqvczKw==", + "dev": true, + "optional": true, + "dependencies": { + "debug": "^3.2.6", + "iconv-lite": "^0.6.3", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/needle/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "optional": true, + "dependencies": { + "ms": "^2.1.1" + } + }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -12471,6 +12760,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", @@ -13004,6 +13302,38 @@ "postcss": "^8.4" } }, + "node_modules/postcss-filter-plugins": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/postcss-filter-plugins/-/postcss-filter-plugins-3.0.1.tgz", + "integrity": "sha512-tRKbW4wWBEkSSFuJtamV2wkiV9rj6Yy7P3Y13+zaynlPEEZt8EgYKn3y/RBpMeIhNmHXFlSdzofml65hD5OafA==", + "dev": true, + "dependencies": { + "postcss": "^6.0.14" + } + }, + "node_modules/postcss-filter-plugins/node_modules/postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/postcss-filter-plugins/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/postcss-flexbugs-fixes": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz", @@ -13059,6 +13389,100 @@ "postcss": "^8.4" } }, + "node_modules/postcss-icss-keyframes": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/postcss-icss-keyframes/-/postcss-icss-keyframes-0.2.1.tgz", + "integrity": "sha512-4m+hLY5TVqoTM198KKnzdNudyu1OvtqwD+8kVZ9PNiEO4+IfHYoyVvEXsOHjV8nZ1k6xowf+nY4HlUfZhOFvvw==", + "dev": true, + "dependencies": { + "icss-utils": "^3.0.1", + "postcss": "^6.0.2", + "postcss-value-parser": "^3.3.0" + } + }, + "node_modules/postcss-icss-keyframes/node_modules/icss-utils": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-3.0.1.tgz", + "integrity": "sha512-ANhVLoEfe0KoC9+z4yiTaXOneB49K6JIXdS+yAgH0NERELpdIT7kkj2XxUPuHafeHnn8umXnECSpsfk1RTaUew==", + "dev": true, + "dependencies": { + "postcss": "^6.0.2" + } + }, + "node_modules/postcss-icss-keyframes/node_modules/postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/postcss-icss-keyframes/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-icss-keyframes/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-icss-selectors": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/postcss-icss-selectors/-/postcss-icss-selectors-2.0.3.tgz", + "integrity": "sha512-dxFtq+wscbU9faJaH8kIi98vvCPDbt+qg1g9GoG0os1PY3UvgY1Y2G06iZrZb1iVC9cyFfafwSY1IS+IQpRQ4w==", + "dev": true, + "dependencies": { + "css-selector-tokenizer": "^0.7.0", + "generic-names": "^1.0.2", + "icss-utils": "^3.0.1", + "lodash": "^4.17.4", + "postcss": "^6.0.2" + } + }, + "node_modules/postcss-icss-selectors/node_modules/icss-utils": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-3.0.1.tgz", + "integrity": "sha512-ANhVLoEfe0KoC9+z4yiTaXOneB49K6JIXdS+yAgH0NERELpdIT7kkj2XxUPuHafeHnn8umXnECSpsfk1RTaUew==", + "dev": true, + "dependencies": { + "postcss": "^6.0.2" + } + }, + "node_modules/postcss-icss-selectors/node_modules/postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/postcss-icss-selectors/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/postcss-image-set-function": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.6.tgz", @@ -13945,6 +14369,13 @@ "node": ">= 0.10" } }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", + "dev": true, + "optional": true + }, "node_modules/psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -14537,6 +14968,12 @@ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, + "node_modules/reserved-words": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/reserved-words/-/reserved-words-0.1.2.tgz", + "integrity": "sha512-0S5SrIUJ9LfpbVl4Yzij6VipUdafHrOTzvmfazSw/jeZrZtQK303OPZW+obtkaw7jQlTQppy0UvZWm9872PbRw==", + "dev": true + }, "node_modules/resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -14572,6 +15009,13 @@ "node": ">=8" } }, + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", + "deprecated": "https://github.com/lydell/resolve-url#deprecated", + "dev": true + }, "node_modules/resolve-url-loader": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz", @@ -14772,6 +15216,23 @@ "resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-13.0.0.tgz", "integrity": "sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA==" }, + "node_modules/sass": { + "version": "1.55.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.55.0.tgz", + "integrity": "sha512-Pk+PMy7OGLs9WaxZGJMn7S96dvlyVBwwtToX895WmCpAOr5YiJYEUJfiJidMuKb613z2xNWcXCHEuOvjZbqC6A==", + "devOptional": true, + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/sass-loader": { "version": "12.6.0", "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.6.0.tgz", @@ -15151,6 +15612,13 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", + "deprecated": "See https://github.com/lydell/source-map-url#deprecated", + "dev": true + }, "node_modules/sourcemap-codec": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", @@ -15437,6 +15905,64 @@ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz", "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==" }, + "node_modules/stylus": { + "version": "0.54.8", + "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.8.tgz", + "integrity": "sha512-vr54Or4BZ7pJafo2mpf0ZcwA74rpuYCZbxrHBsH8kbcXOwSfvBFwsRfpGO5OD5fhG5HDCFW737PKaawI7OqEAg==", + "dev": true, + "dependencies": { + "css-parse": "~2.0.0", + "debug": "~3.1.0", + "glob": "^7.1.6", + "mkdirp": "~1.0.4", + "safer-buffer": "^2.1.2", + "sax": "~1.2.4", + "semver": "^6.3.0", + "source-map": "^0.7.3" + }, + "bin": { + "stylus": "bin/stylus" + }, + "engines": { + "node": "*" + } + }, + "node_modules/stylus/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/stylus/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stylus/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/stylus/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -15951,6 +16477,30 @@ "node": ">=4.2.0" } }, + "node_modules/typescript-plugin-css-modules": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/typescript-plugin-css-modules/-/typescript-plugin-css-modules-3.4.0.tgz", + "integrity": "sha512-2MdjfSg4MGex1csCWRUwKD+MpgnvcvLLr9bSAMemU/QYGqBsXdez0cc06H/fFhLtRoKJjXg6PSTur3Gy1Umhpw==", + "dev": true, + "dependencies": { + "dotenv": "^10.0.0", + "icss-utils": "^5.1.0", + "less": "^4.1.1", + "lodash.camelcase": "^4.3.0", + "postcss": "^8.3.0", + "postcss-filter-plugins": "^3.0.1", + "postcss-icss-keyframes": "^0.2.1", + "postcss-icss-selectors": "^2.0.3", + "postcss-load-config": "^3.0.1", + "reserved-words": "^0.1.2", + "sass": "^1.32.13", + "stylus": "^0.54.8", + "tsconfig-paths": "^3.9.0" + }, + "peerDependencies": { + "typescript": ">=3.0.0" + } + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -16050,6 +16600,13 @@ "punycode": "^2.1.0" } }, + "node_modules/urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", + "deprecated": "Please see https://github.com/lydell/urix#deprecated", + "dev": true + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -18218,9 +18775,9 @@ } }, "@babel/runtime": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.3.tgz", - "integrity": "sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.0.tgz", + "integrity": "sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==", "requires": { "regenerator-runtime": "^0.13.4" } @@ -19146,6 +19703,14 @@ "react-is": "^17.0.2" } }, + "@mui/icons-material": { + "version": "5.10.6", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.10.6.tgz", + "integrity": "sha512-QwxdRmLA46S94B0hExPDx0td+A2unF+33bQ6Cs+lNpJKVsm1YeHwNdYXYcnpWeHeQQ07055OXl7IB2GKDd0MfA==", + "requires": { + "@babel/runtime": "^7.19.0" + } + }, "@mui/material": { "version": "5.8.4", "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.8.4.tgz", @@ -21289,6 +21854,15 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, + "copy-anything": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", + "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", + "dev": true, + "requires": { + "is-what": "^3.14.1" + } + }, "core-js": { "version": "3.23.1", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.23.1.tgz", @@ -21456,6 +22030,48 @@ } } }, + "css-parse": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-2.0.0.tgz", + "integrity": "sha512-UNIFik2RgSbiTwIW1IsFwXWn6vs+bYdq83LKTSOsx7NJR7WII9dxewkHLltfTLVppoUApHV0118a4RZRI9FLwA==", + "dev": true, + "requires": { + "css": "^2.0.0" + }, + "dependencies": { + "css": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", + "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "source-map": "^0.6.1", + "source-map-resolve": "^0.5.2", + "urix": "^0.1.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + } + } + }, "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", @@ -21479,6 +22095,16 @@ "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" }, + "css-selector-tokenizer": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.3.tgz", + "integrity": "sha512-jWQv3oCEL5kMErj4wRnK/OPoBi0D+P1FR2cDCKYPaMeD2eW3/mttav8HT4hT1CKopiJI/psEULjkClhvJo4Lvg==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "fastparse": "^1.1.2" + } + }, "css-tree": { "version": "1.0.0-alpha.37", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", @@ -21945,6 +22571,16 @@ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" }, + "errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "optional": true, + "requires": { + "prr": "~1.0.1" + } + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -22682,6 +23318,12 @@ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" }, + "fastparse": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", + "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", + "dev": true + }, "fastq": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", @@ -23014,6 +23656,47 @@ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==" }, + "generic-names": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/generic-names/-/generic-names-1.0.3.tgz", + "integrity": "sha512-b6OHfQuKasIKM9b6YPkX+KUj/TLBTx3B/1aT1T5F12FEuEqyFMdr59OMS53aoaSw8eVtapdqieX6lbg5opaOhA==", + "dev": true, + "requires": { + "loader-utils": "^0.2.16" + }, + "dependencies": { + "big.js": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", + "dev": true + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha512-knHEZMgs8BB+MInokmNTg/OyPlAddghe1YBgNwJBc5zsJi/uyIcXoSDsL/W9ymOsBoBGdPIHXYJ9+qKFwRwDng==", + "dev": true + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==", + "dev": true + }, + "loader-utils": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", + "integrity": "sha512-tiv66G0SmiOx+pLWMtGEkfSEejxvb6N6uRrQjfWJIT79W9GMpgKeCAmm9aVBKtd4WEgntciI8CsGqjpDoCWJug==", + "dev": true, + "requires": { + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0", + "object-assign": "^4.0.1" + } + } + } + }, "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -23407,11 +24090,24 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==" }, + "image-size": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", + "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", + "dev": true, + "optional": true + }, "immer": { "version": "9.0.15", "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.15.tgz", "integrity": "sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ==" }, + "immutable": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", + "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", + "devOptional": true + }, "import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -23659,6 +24355,12 @@ "call-bind": "^1.0.2" } }, + "is-what": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", + "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", + "dev": true + }, "is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -25308,6 +26010,58 @@ "language-subtag-registry": "~0.3.2" } }, + "less": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/less/-/less-4.1.3.tgz", + "integrity": "sha512-w16Xk/Ta9Hhyei0Gpz9m7VS8F28nieJaL/VyShID7cYvP6IL5oHeL6p4TXSDJqZE/lNv0oJ2pGVjJsRkfwm5FA==", + "dev": true, + "requires": { + "copy-anything": "^2.0.1", + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "make-dir": "^2.1.0", + "mime": "^1.4.1", + "needle": "^3.1.0", + "parse-node-version": "^1.0.1", + "source-map": "~0.6.0", + "tslib": "^2.3.0" + }, + "dependencies": { + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "optional": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "optional": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true + } + } + }, "leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -25360,6 +26114,12 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true + }, "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -25615,6 +26375,30 @@ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" }, + "needle": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.1.0.tgz", + "integrity": "sha512-gCE9weDhjVGCRqS8dwDR/D3GTAeyXLXuqp7I8EzH6DllZGXSUyxuqqLh+YX9rMAWaaTFyVAg6rHGL25dqvczKw==", + "dev": true, + "optional": true, + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.6.3", + "sax": "^1.2.4" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, "negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -25886,6 +26670,12 @@ "lines-and-columns": "^1.1.6" } }, + "parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "dev": true + }, "parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", @@ -26209,6 +26999,34 @@ "postcss-value-parser": "^4.2.0" } }, + "postcss-filter-plugins": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/postcss-filter-plugins/-/postcss-filter-plugins-3.0.1.tgz", + "integrity": "sha512-tRKbW4wWBEkSSFuJtamV2wkiV9rj6Yy7P3Y13+zaynlPEEZt8EgYKn3y/RBpMeIhNmHXFlSdzofml65hD5OafA==", + "dev": true, + "requires": { + "postcss": "^6.0.14" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, "postcss-flexbugs-fixes": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz", @@ -26243,6 +27061,92 @@ "integrity": "sha512-rPPZRLPmEKgLk/KlXMqRaNkYTUpE7YC+bOIQFN5xcu1Vp11Y4faIXv6/Jpft6FMnl6YRxZqDZG0qQOW80stzxQ==", "requires": {} }, + "postcss-icss-keyframes": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/postcss-icss-keyframes/-/postcss-icss-keyframes-0.2.1.tgz", + "integrity": "sha512-4m+hLY5TVqoTM198KKnzdNudyu1OvtqwD+8kVZ9PNiEO4+IfHYoyVvEXsOHjV8nZ1k6xowf+nY4HlUfZhOFvvw==", + "dev": true, + "requires": { + "icss-utils": "^3.0.1", + "postcss": "^6.0.2", + "postcss-value-parser": "^3.3.0" + }, + "dependencies": { + "icss-utils": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-3.0.1.tgz", + "integrity": "sha512-ANhVLoEfe0KoC9+z4yiTaXOneB49K6JIXdS+yAgH0NERELpdIT7kkj2XxUPuHafeHnn8umXnECSpsfk1RTaUew==", + "dev": true, + "requires": { + "postcss": "^6.0.2" + } + }, + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "postcss-icss-selectors": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/postcss-icss-selectors/-/postcss-icss-selectors-2.0.3.tgz", + "integrity": "sha512-dxFtq+wscbU9faJaH8kIi98vvCPDbt+qg1g9GoG0os1PY3UvgY1Y2G06iZrZb1iVC9cyFfafwSY1IS+IQpRQ4w==", + "dev": true, + "requires": { + "css-selector-tokenizer": "^0.7.0", + "generic-names": "^1.0.2", + "icss-utils": "^3.0.1", + "lodash": "^4.17.4", + "postcss": "^6.0.2" + }, + "dependencies": { + "icss-utils": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-3.0.1.tgz", + "integrity": "sha512-ANhVLoEfe0KoC9+z4yiTaXOneB49K6JIXdS+yAgH0NERELpdIT7kkj2XxUPuHafeHnn8umXnECSpsfk1RTaUew==", + "dev": true, + "requires": { + "postcss": "^6.0.2" + } + }, + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, "postcss-image-set-function": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.6.tgz", @@ -26791,6 +27695,13 @@ } } }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", + "dev": true, + "optional": true + }, "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -27232,6 +28143,12 @@ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, + "reserved-words": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/reserved-words/-/reserved-words-0.1.2.tgz", + "integrity": "sha512-0S5SrIUJ9LfpbVl4Yzij6VipUdafHrOTzvmfazSw/jeZrZtQK303OPZW+obtkaw7jQlTQppy0UvZWm9872PbRw==", + "dev": true + }, "resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -27255,6 +28172,12 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", + "dev": true + }, "resolve-url-loader": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz", @@ -27386,6 +28309,17 @@ "resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-13.0.0.tgz", "integrity": "sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA==" }, + "sass": { + "version": "1.55.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.55.0.tgz", + "integrity": "sha512-Pk+PMy7OGLs9WaxZGJMn7S96dvlyVBwwtToX895WmCpAOr5YiJYEUJfiJidMuKb613z2xNWcXCHEuOvjZbqC6A==", + "devOptional": true, + "requires": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + } + }, "sass-loader": { "version": "12.6.0", "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.6.0.tgz", @@ -27676,6 +28610,12 @@ } } }, + "source-map-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", + "dev": true + }, "sourcemap-codec": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", @@ -27888,6 +28828,51 @@ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz", "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==" }, + "stylus": { + "version": "0.54.8", + "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.8.tgz", + "integrity": "sha512-vr54Or4BZ7pJafo2mpf0ZcwA74rpuYCZbxrHBsH8kbcXOwSfvBFwsRfpGO5OD5fhG5HDCFW737PKaawI7OqEAg==", + "dev": true, + "requires": { + "css-parse": "~2.0.0", + "debug": "~3.1.0", + "glob": "^7.1.6", + "mkdirp": "~1.0.4", + "safer-buffer": "^2.1.2", + "sax": "~1.2.4", + "semver": "^6.3.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -28273,6 +29258,27 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==" }, + "typescript-plugin-css-modules": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/typescript-plugin-css-modules/-/typescript-plugin-css-modules-3.4.0.tgz", + "integrity": "sha512-2MdjfSg4MGex1csCWRUwKD+MpgnvcvLLr9bSAMemU/QYGqBsXdez0cc06H/fFhLtRoKJjXg6PSTur3Gy1Umhpw==", + "dev": true, + "requires": { + "dotenv": "^10.0.0", + "icss-utils": "^5.1.0", + "less": "^4.1.1", + "lodash.camelcase": "^4.3.0", + "postcss": "^8.3.0", + "postcss-filter-plugins": "^3.0.1", + "postcss-icss-keyframes": "^0.2.1", + "postcss-icss-selectors": "^2.0.3", + "postcss-load-config": "^3.0.1", + "reserved-words": "^0.1.2", + "sass": "^1.32.13", + "stylus": "^0.54.8", + "tsconfig-paths": "^3.9.0" + } + }, "unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -28344,6 +29350,12 @@ "punycode": "^2.1.0" } }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", + "dev": true + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/package.json b/package.json index 51155a2..58debea 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "dependencies": { "@emotion/react": "^11.9.3", "@emotion/styled": "^11.9.3", + "@mui/icons-material": "^5.10.6", "@mui/material": "^5.8.4", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^13.3.0", @@ -45,6 +46,7 @@ "@types/node": "^18.0.0", "@types/react": "^18.0.14", "@types/react-dom": "^18.0.5", - "typescript": "^4.7.4" + "typescript": "^4.7.4", + "typescript-plugin-css-modules": "^3.4.0" } } diff --git a/src/img/Mortal-Kombat-Logo.png b/public/img/Mortal-Kombat-Logo.png similarity index 100% rename from src/img/Mortal-Kombat-Logo.png rename to public/img/Mortal-Kombat-Logo.png diff --git a/src/App.tsx b/src/App.tsx index f8006cd..2aa3ad6 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,20 +2,15 @@ import logo from './logo.svg' import './App.css' import jsonData from './data/characters.json' import type { Character } from './types' +import Header from './components/Header/Header' +import CharactersSearch from './components/CharactersSearch/CharactersSearch' const data: Character[] = jsonData as Character[] function App() { return (
-
- logo -

- Edit src/App.js and save to reload. -

- - Learn React - -
+
+
) } diff --git a/src/components/CharactersSearch/CharactersSearch.module.css b/src/components/CharactersSearch/CharactersSearch.module.css new file mode 100644 index 0000000..e797943 --- /dev/null +++ b/src/components/CharactersSearch/CharactersSearch.module.css @@ -0,0 +1,41 @@ +.charListContainer { + padding: 40px 150px; +} + +.charList { + box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.25); + border-radius: 10px; +} + +.row { + display: flex; + padding: 22px; + border-bottom: 1px solid #EEEEEE; + gap: 24px; +} + +.character, .tags, .abilities { + display: flex; + gap: 24px; + flex: 1; + align-items: center; +} + +.tags { + gap: 15px; +} + +.abilities { + flex: 2; +} + +.score { + flex: 1; +} + +.allTags { + display: flex; + flex-direction: row; + flex-wrap: wrap; + gap: 8px; +} diff --git a/src/components/CharactersSearch/CharactersSearch.tsx b/src/components/CharactersSearch/CharactersSearch.tsx new file mode 100644 index 0000000..4986aa3 --- /dev/null +++ b/src/components/CharactersSearch/CharactersSearch.tsx @@ -0,0 +1,81 @@ +import React, {useState} from 'react' +import type { Character } from '../../types' +import {TextField, InputAdornment, Checkbox, Avatar, Chip, Pagination} from '@mui/material' +import SearchIcon from '@mui/icons-material/Search' +import jsonData from '../../data/characters.json' +import charStyles from './CharactersSearch.module.css' + +const data: Character[] = jsonData as Character[] +const ALL_TAGS = ['Monster', 'Melee', 'Human', 'Ninja', 'Agile', 'God', 'Aerial', 'Strong', 'Grappling', 'Defend', 'Attack', 'Block', 'Mercenary', 'Demon', 'Robot', 'Magic', 'Ranged', 'Alien', 'Ghost', 'Grapple', 'Animal', 'My Team'] + + + +const CharactersSearch = () => { + + const [searchQuery, setSearchQuery] = useState('') + const [searchResults, setSearchResults] = useState(data) + + + const handleInput = (ev) => { + const searchString = ev.target.value.trim().toLowerCase() + const filteredData = data.filter((char) => { + let tag + if(char.tags){ + tag = char.tags.find((tag)=> tag.tag_name.toLowerCase().includes(searchString)) + return tag || char.name.toLowerCase().includes(searchString) + } + return char.name.toLowerCase().includes(searchString) + }) + console.log(filteredData) + setSearchQuery(ev.target.value) + setSearchResults(filteredData) + } + + const renderRows = () => ( + searchResults?.map((char: Character)=> ( +
+
+ + + {char.name} +
+ +
+ {char.tags?.map((tag, index)=>( + + ))} +
+
+ {char.abilities?.map((ability, index )=>( + {ability.abilityScore} + ))} +
+
+ )) + ) + console.log(searchResults) + return ( +
+ handleInput(ev)} placeholder='Search Characters...' InputProps={{ + startAdornment: ( + + + + ), + }}/> +
+
+ {searchResults.length ? renderRows() : null} +
+
+ + + + +
+ ) +} + +export default CharactersSearch \ No newline at end of file diff --git a/src/components/Header/Header.module.css b/src/components/Header/Header.module.css new file mode 100644 index 0000000..6d030d3 --- /dev/null +++ b/src/components/Header/Header.module.css @@ -0,0 +1,14 @@ +.header { + background: black; + height: 76px; +} + +.logo { + height: 90px; + width: 160px; + background-image: url('/public/img/Mortal-Kombat-Logo.png'); + background-size: contain; + background-repeat: no-repeat; + margin-left: auto; + margin-right: auto; +} \ No newline at end of file diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx new file mode 100644 index 0000000..80b852b --- /dev/null +++ b/src/components/Header/Header.tsx @@ -0,0 +1,15 @@ +import React from 'react' +import headerStyles from './Header.module.css' + +const Header = () => { + + return ( +
+
+
+ +
+ ) +} + +export default Header \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 8b64872..7bb48d7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "plugins": [{ "name": "typescript-plugin-css-modules" }], "target": "es5", "lib": [ "dom", @@ -19,7 +20,15 @@ "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", - "defaultSeverity": "warning" + "defaultSeverity": "warning", + "noImplicitAny": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "strictNullChecks": true, + "downlevelIteration": true, + "experimentalDecorators": true, + "noUnusedLocals": true, + "sourceMap": true }, "include": [ "src" From 023b9fb62d372a3dc314170c6181572b775e311f Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 30 Sep 2022 15:31:11 +0400 Subject: [PATCH 2/8] added tag selection --- .../CharactersSearch/CharactersSearch.tsx | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/components/CharactersSearch/CharactersSearch.tsx b/src/components/CharactersSearch/CharactersSearch.tsx index 4986aa3..b9d3ba5 100644 --- a/src/components/CharactersSearch/CharactersSearch.tsx +++ b/src/components/CharactersSearch/CharactersSearch.tsx @@ -4,6 +4,7 @@ import {TextField, InputAdornment, Checkbox, Avatar, Chip, Pagination} from '@mu import SearchIcon from '@mui/icons-material/Search' import jsonData from '../../data/characters.json' import charStyles from './CharactersSearch.module.css' +import CheckIcon from '@mui/icons-material/Check'; const data: Character[] = jsonData as Character[] const ALL_TAGS = ['Monster', 'Melee', 'Human', 'Ninja', 'Agile', 'God', 'Aerial', 'Strong', 'Grappling', 'Defend', 'Attack', 'Block', 'Mercenary', 'Demon', 'Robot', 'Magic', 'Ranged', 'Alien', 'Ghost', 'Grapple', 'Animal', 'My Team'] @@ -14,6 +15,7 @@ const CharactersSearch = () => { const [searchQuery, setSearchQuery] = useState('') const [searchResults, setSearchResults] = useState(data) + const [selectedTags, setSelectedTags] = useState([]) const handleInput = (ev) => { @@ -29,8 +31,39 @@ const CharactersSearch = () => { console.log(filteredData) setSearchQuery(ev.target.value) setSearchResults(filteredData) + + } + + const handleTagSelect = (tag) => { + let updatedSelection = [] + if (selectedTags.includes(tag)){ + updatedSelection = selectedTags.filter(t => t !== tag) + } + else { + updatedSelection = [...selectedTags, tag] + } + setSelectedTags(updatedSelection) } + const renderTags = () => ( + ALL_TAGS.map((tag, index) => { + if (selectedTags.includes(tag.toLowerCase())){ + return ( +
+ } onClick={() => handleTagSelect(tag.toLowerCase())} clickable label={tag} color="primary"/> +
+ ) + } + else{ + return ( +
+ handleTagSelect(tag.toLowerCase())} clickable label={tag} color="primary" variant="outlined"/> +
+ ) + } + }) + ) + const renderRows = () => ( searchResults?.map((char: Character)=> (
@@ -65,6 +98,9 @@ const CharactersSearch = () => { ), }}/> +
+ {renderTags()} +
{searchResults.length ? renderRows() : null} From d740bcb7a4647242b568db88fa7e7c2d83f46926 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 30 Sep 2022 15:31:29 +0400 Subject: [PATCH 3/8] added pagination --- .../CharactersSearch/CharactersSearch.tsx | 50 +++++++++++-------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/src/components/CharactersSearch/CharactersSearch.tsx b/src/components/CharactersSearch/CharactersSearch.tsx index b9d3ba5..2c45460 100644 --- a/src/components/CharactersSearch/CharactersSearch.tsx +++ b/src/components/CharactersSearch/CharactersSearch.tsx @@ -16,7 +16,11 @@ const CharactersSearch = () => { const [searchQuery, setSearchQuery] = useState('') const [searchResults, setSearchResults] = useState(data) const [selectedTags, setSelectedTags] = useState([]) + const [page, setPage] = React.useState(1); + const handleChangePage = (event: React.ChangeEvent, value: number) => { + setPage(value); + }; const handleInput = (ev) => { const searchString = ev.target.value.trim().toLowerCase() @@ -31,7 +35,7 @@ const CharactersSearch = () => { console.log(filteredData) setSearchQuery(ev.target.value) setSearchResults(filteredData) - + setPage(1) } const handleTagSelect = (tag) => { @@ -65,27 +69,27 @@ const CharactersSearch = () => { ) const renderRows = () => ( - searchResults?.map((char: Character)=> ( -
-
- - - {char.name} -
+ searchResults?.slice((page - 1) * 10, (page - 1) * 10 + 10).map((char: Character)=> ( +
+
+ + + {char.name} +
-
- {char.tags?.map((tag, index)=>( - - ))} -
-
- {char.abilities?.map((ability, index )=>( - {ability.abilityScore} - ))} -
+
+ {char.tags?.map((tag, index)=>( + + ))}
+
+ {char.abilities?.map((ability, index )=>( + {ability.abilityScore} + ))} +
+
)) ) console.log(searchResults) @@ -107,7 +111,11 @@ const CharactersSearch = () => {
- + { + searchResults.length ? + + : null + }
From 4995489a901cf57b71752b045705ea3dac0bafbe Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 30 Sep 2022 16:39:35 +0400 Subject: [PATCH 4/8] refactored filters to account tags --- .../CharactersSearch/CharactersSearch.tsx | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/components/CharactersSearch/CharactersSearch.tsx b/src/components/CharactersSearch/CharactersSearch.tsx index 2c45460..e6108ae 100644 --- a/src/components/CharactersSearch/CharactersSearch.tsx +++ b/src/components/CharactersSearch/CharactersSearch.tsx @@ -22,22 +22,27 @@ const CharactersSearch = () => { setPage(value); }; - const handleInput = (ev) => { - const searchString = ev.target.value.trim().toLowerCase() + const filterData = (searchString : string, tags) => { const filteredData = data.filter((char) => { - let tag - if(char.tags){ - tag = char.tags.find((tag)=> tag.tag_name.toLowerCase().includes(searchString)) - return tag || char.name.toLowerCase().includes(searchString) + if(tags.length){ + if(char.tags?.find((tag)=> tags.includes(tag.tag_name.toLowerCase()))){ + return char.name.toLowerCase().includes(searchString) + } + else return false } - return char.name.toLowerCase().includes(searchString) + else return char.name.toLowerCase().includes(searchString) }) console.log(filteredData) - setSearchQuery(ev.target.value) setSearchResults(filteredData) setPage(1) } + const handleInput = (ev) => { + const searchString = ev.target.value.trim().toLowerCase() + filterData(searchString, selectedTags) + setSearchQuery(ev.target.value) + } + const handleTagSelect = (tag) => { let updatedSelection = [] if (selectedTags.includes(tag)){ @@ -46,6 +51,7 @@ const CharactersSearch = () => { else { updatedSelection = [...selectedTags, tag] } + filterData(searchQuery, updatedSelection) setSelectedTags(updatedSelection) } @@ -81,7 +87,7 @@ const CharactersSearch = () => {
{char.tags?.map((tag, index)=>( - + ))}
From ca6308ee7216ad727acc7e51581376bdfe0f3af4 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 30 Sep 2022 17:59:05 +0400 Subject: [PATCH 5/8] added champion selection logic --- .../CharactersSearch/CharactersSearch.tsx | 28 +++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/components/CharactersSearch/CharactersSearch.tsx b/src/components/CharactersSearch/CharactersSearch.tsx index e6108ae..2efd586 100644 --- a/src/components/CharactersSearch/CharactersSearch.tsx +++ b/src/components/CharactersSearch/CharactersSearch.tsx @@ -4,7 +4,7 @@ import {TextField, InputAdornment, Checkbox, Avatar, Chip, Pagination} from '@mu import SearchIcon from '@mui/icons-material/Search' import jsonData from '../../data/characters.json' import charStyles from './CharactersSearch.module.css' -import CheckIcon from '@mui/icons-material/Check'; +import CheckIcon from '@mui/icons-material/Check' const data: Character[] = jsonData as Character[] const ALL_TAGS = ['Monster', 'Melee', 'Human', 'Ninja', 'Agile', 'God', 'Aerial', 'Strong', 'Grappling', 'Defend', 'Attack', 'Block', 'Mercenary', 'Demon', 'Robot', 'Magic', 'Ranged', 'Alien', 'Ghost', 'Grapple', 'Animal', 'My Team'] @@ -16,11 +16,20 @@ const CharactersSearch = () => { const [searchQuery, setSearchQuery] = useState('') const [searchResults, setSearchResults] = useState(data) const [selectedTags, setSelectedTags] = useState([]) - const [page, setPage] = React.useState(1); + const [page, setPage] = useState(1) + const [selectedChampions, setSelectedChampions] = useState([]) const handleChangePage = (event: React.ChangeEvent, value: number) => { - setPage(value); - }; + setPage(value) + } + + const handleChampionSelect = (ev, char) => { + ev.target.checked ? + setSelectedChampions([...selectedChampions, char]) : + setSelectedChampions(selectedChampions.filter((selectedChar) => selectedChar.id !== char.id)) + } + + console.log(selectedChampions) const filterData = (searchString : string, tags) => { const filteredData = data.filter((char) => { @@ -55,6 +64,13 @@ const CharactersSearch = () => { setSelectedTags(updatedSelection) } + const handleCheckboxDisable = (char: Character) => { + if(selectedChampions.length === 6){ + return !selectedChampions.find(({id}) => id === char.id); + } + return false + } + const renderTags = () => ( ALL_TAGS.map((tag, index) => { if (selectedTags.includes(tag.toLowerCase())){ @@ -78,7 +94,8 @@ const CharactersSearch = () => { searchResults?.slice((page - 1) * 10, (page - 1) * 10 + 10).map((char: Character)=> (
- + handleChampionSelect(ev, char)} sx={{color: '#227aff'}} color='primary'/> @@ -110,6 +127,7 @@ const CharactersSearch = () => { }}/>
{renderTags()} + Clear all
From f5db1f2e6a3e62b232593f6f0b48981c89bd1845 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 30 Sep 2022 18:17:11 +0400 Subject: [PATCH 6/8] added squad section, refactored squad selection logic placement --- src/App.tsx | 13 ++++++++++++- .../CharactersSearch/CharactersSearch.tsx | 13 +++---------- src/components/Squad/Squad.module.css | 5 +++++ src/components/Squad/Squad.tsx | 19 +++++++++++++++++++ 4 files changed, 39 insertions(+), 11 deletions(-) create mode 100644 src/components/Squad/Squad.module.css create mode 100644 src/components/Squad/Squad.tsx diff --git a/src/App.tsx b/src/App.tsx index 2aa3ad6..57693ef 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,13 +4,24 @@ import jsonData from './data/characters.json' import type { Character } from './types' import Header from './components/Header/Header' import CharactersSearch from './components/CharactersSearch/CharactersSearch' +import Squad from './components/Squad/Squad' +import {useState} from 'react' const data: Character[] = jsonData as Character[] function App() { + const [selectedChampions, setSelectedChampions] = useState([]) + + const handleChampionSelect = (ev, char) => { + ev.target.checked ? + setSelectedChampions([...selectedChampions, char]) : + setSelectedChampions(selectedChampions.filter((selectedChar) => selectedChar.id !== char.id)) + } + return (
- + +
) } diff --git a/src/components/CharactersSearch/CharactersSearch.tsx b/src/components/CharactersSearch/CharactersSearch.tsx index 2efd586..534be48 100644 --- a/src/components/CharactersSearch/CharactersSearch.tsx +++ b/src/components/CharactersSearch/CharactersSearch.tsx @@ -11,24 +11,17 @@ const ALL_TAGS = ['Monster', 'Melee', 'Human', 'Ninja', 'Agile', 'God', 'Aerial' -const CharactersSearch = () => { +const CharactersSearch = ({handleChampionSelect, selectedChampions}) => { const [searchQuery, setSearchQuery] = useState('') const [searchResults, setSearchResults] = useState(data) const [selectedTags, setSelectedTags] = useState([]) const [page, setPage] = useState(1) - const [selectedChampions, setSelectedChampions] = useState([]) const handleChangePage = (event: React.ChangeEvent, value: number) => { setPage(value) } - const handleChampionSelect = (ev, char) => { - ev.target.checked ? - setSelectedChampions([...selectedChampions, char]) : - setSelectedChampions(selectedChampions.filter((selectedChar) => selectedChar.id !== char.id)) - } - console.log(selectedChampions) const filterData = (searchString : string, tags) => { @@ -43,6 +36,7 @@ const CharactersSearch = () => { }) console.log(filteredData) setSearchResults(filteredData) + setSelectedTags(tags) setPage(1) } @@ -61,7 +55,6 @@ const CharactersSearch = () => { updatedSelection = [...selectedTags, tag] } filterData(searchQuery, updatedSelection) - setSelectedTags(updatedSelection) } const handleCheckboxDisable = (char: Character) => { @@ -127,7 +120,7 @@ const CharactersSearch = () => { }}/>
{renderTags()} - Clear all + filterData(searchQuery, [])}>Clear all
diff --git a/src/components/Squad/Squad.module.css b/src/components/Squad/Squad.module.css new file mode 100644 index 0000000..eb49438 --- /dev/null +++ b/src/components/Squad/Squad.module.css @@ -0,0 +1,5 @@ +.squad { + display: flex; + justify-content: center; + gap: 10px; +} \ No newline at end of file diff --git a/src/components/Squad/Squad.tsx b/src/components/Squad/Squad.tsx new file mode 100644 index 0000000..9978d77 --- /dev/null +++ b/src/components/Squad/Squad.tsx @@ -0,0 +1,19 @@ +import React, {useState} from 'react' +import type { Character } from '../../types' +import {Avatar} from '@mui/material' +import squadStyles from './Squad.module.css' + +const Squad = ({selectedChampions}) => { + + return ( +
+ {selectedChampions.map((char)=> ( + + ))} +
+ ) +} + +export default Squad \ No newline at end of file From b79c6396dbcb6c980cf5264d9cfd3e4cd5c942ad Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 30 Sep 2022 21:00:44 +0400 Subject: [PATCH 7/8] added styles, resolved ts conflicts --- src/App.css | 1 + src/App.tsx | 11 +-- .../CharactersSearch.module.css | 78 +++++++++++++++++++ .../CharactersSearch/CharactersSearch.tsx | 50 +++++++----- src/components/Header/Header.module.css | 9 +++ src/components/Header/Header.tsx | 4 +- src/components/Squad/Squad.module.css | 53 ++++++++++++- src/components/Squad/Squad.tsx | 46 ++++++++--- src/constants/common.tsx | 9 +++ tsconfig.json | 2 +- 10 files changed, 225 insertions(+), 38 deletions(-) create mode 100644 src/constants/common.tsx diff --git a/src/App.css b/src/App.css index 74b5e05..e852b65 100644 --- a/src/App.css +++ b/src/App.css @@ -1,5 +1,6 @@ .App { text-align: center; + background-color: #F5FDFF; } .App-logo { diff --git a/src/App.tsx b/src/App.tsx index 57693ef..ebe3ded 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,17 +1,14 @@ -import logo from './logo.svg' -import './App.css' -import jsonData from './data/characters.json' -import type { Character } from './types' +import React, {useState} from 'react' import Header from './components/Header/Header' import CharactersSearch from './components/CharactersSearch/CharactersSearch' import Squad from './components/Squad/Squad' -import {useState} from 'react' -const data: Character[] = jsonData as Character[] +import type { Character } from './types' +import './App.css' function App() { const [selectedChampions, setSelectedChampions] = useState([]) - const handleChampionSelect = (ev, char) => { + const handleChampionSelect = (ev : React.ChangeEvent, char : Character) => { ev.target.checked ? setSelectedChampions([...selectedChampions, char]) : setSelectedChampions(selectedChampions.filter((selectedChar) => selectedChar.id !== char.id)) diff --git a/src/components/CharactersSearch/CharactersSearch.module.css b/src/components/CharactersSearch/CharactersSearch.module.css index e797943..908252e 100644 --- a/src/components/CharactersSearch/CharactersSearch.module.css +++ b/src/components/CharactersSearch/CharactersSearch.module.css @@ -5,6 +5,9 @@ .charList { box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.25); border-radius: 10px; + background-color: #ffffff; + font-weight: 700; + font-size: 20px; } .row { @@ -35,7 +38,82 @@ .allTags { display: flex; + justify-content: center; + align-items: center; flex-direction: row; flex-wrap: wrap; gap: 8px; + padding: 0 45px; +} + +.searchContainer { + position: relative; +} + +.searchBar { + width: 500px; + margin-bottom: 40px !important; +} + +.searchBar >div { + height: 40px; + z-index: 1; + background-color: #ffffff; +} + +.line { + position: absolute; + top: 25%; + left: 0; + right: 0; + display: block; + border: none; + color: #ffffff; + height: 1px; + background: #000000; + background: -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 500, from(#000), to(transparent)); +} + +.clearButton { + color: #999999; + text-decoration: underline; + cursor: pointer; +} + +.pagination { + display: flex; + justify-content: center; + padding-bottom: 20px; +} + +.pagination >ul { + gap: 10px; +} + +.charTitles { + display: flex; + padding-bottom: 10px; + padding-right: 22px; + gap: 24px; + font-weight: 700; + font-size: 20px; +} + +.charTitles >span { + flex: 1; + text-align: start; +} + +.tagsTitle { + padding-left: 22px; +} + +.titleList { + flex: 2; + display: flex; + gap: 24px; +} + +.titleList >span { + flex: 1; } diff --git a/src/components/CharactersSearch/CharactersSearch.tsx b/src/components/CharactersSearch/CharactersSearch.tsx index 534be48..58fe04c 100644 --- a/src/components/CharactersSearch/CharactersSearch.tsx +++ b/src/components/CharactersSearch/CharactersSearch.tsx @@ -1,21 +1,24 @@ -import React, {useState} from 'react' +import React, {FC, useState} from 'react' import type { Character } from '../../types' import {TextField, InputAdornment, Checkbox, Avatar, Chip, Pagination} from '@mui/material' import SearchIcon from '@mui/icons-material/Search' import jsonData from '../../data/characters.json' import charStyles from './CharactersSearch.module.css' import CheckIcon from '@mui/icons-material/Check' +import { CHAR_TITLES, ALL_TAGS } from '../../constants/common' const data: Character[] = jsonData as Character[] -const ALL_TAGS = ['Monster', 'Melee', 'Human', 'Ninja', 'Agile', 'God', 'Aerial', 'Strong', 'Grappling', 'Defend', 'Attack', 'Block', 'Mercenary', 'Demon', 'Robot', 'Magic', 'Ranged', 'Alien', 'Ghost', 'Grapple', 'Animal', 'My Team'] - +interface ICharactersSearch { + selectedChampions: Character[] + handleChampionSelect: (ev: React.ChangeEvent, char: Character) => void +} -const CharactersSearch = ({handleChampionSelect, selectedChampions}) => { +const CharactersSearch : FC = ({handleChampionSelect, selectedChampions}) => { const [searchQuery, setSearchQuery] = useState('') const [searchResults, setSearchResults] = useState(data) - const [selectedTags, setSelectedTags] = useState([]) + const [selectedTags, setSelectedTags] = useState([]) const [page, setPage] = useState(1) const handleChangePage = (event: React.ChangeEvent, value: number) => { @@ -24,7 +27,7 @@ const CharactersSearch = ({handleChampionSelect, selectedChampions}) => { console.log(selectedChampions) - const filterData = (searchString : string, tags) => { + const filterData = (searchString : string, tags: string[]) => { const filteredData = data.filter((char) => { if(tags.length){ if(char.tags?.find((tag)=> tags.includes(tag.tag_name.toLowerCase()))){ @@ -40,13 +43,13 @@ const CharactersSearch = ({handleChampionSelect, selectedChampions}) => { setPage(1) } - const handleInput = (ev) => { + const handleInput = (ev : React.ChangeEvent) => { const searchString = ev.target.value.trim().toLowerCase() filterData(searchString, selectedTags) setSearchQuery(ev.target.value) } - const handleTagSelect = (tag) => { + const handleTagSelect = (tag: string) => { let updatedSelection = [] if (selectedTags.includes(tag)){ updatedSelection = selectedTags.filter(t => t !== tag) @@ -59,7 +62,7 @@ const CharactersSearch = ({handleChampionSelect, selectedChampions}) => { const handleCheckboxDisable = (char: Character) => { if(selectedChampions.length === 6){ - return !selectedChampions.find(({id}) => id === char.id); + return !selectedChampions.find(({id} : {id: number}) => id === char.id); } return false } @@ -109,20 +112,31 @@ const CharactersSearch = ({handleChampionSelect, selectedChampions}) => { )) ) console.log(searchResults) + return (
- handleInput(ev)} placeholder='Search Characters...' InputProps={{ - startAdornment: ( - - - - ), - }}/> +
+ ) => handleInput(ev)} placeholder='Search Characters...' InputProps={{ + startAdornment: ( + + + + ), + }}/> +
+
{renderTags()} - filterData(searchQuery, [])}>Clear all + filterData(searchQuery, [])}>Clear all
+
+ Characters + Tags +
{CHAR_TITLES.map((title) => { + return {title} + })}
+
{searchResults.length ? renderRows() : null}
@@ -130,7 +144,7 @@ const CharactersSearch = ({handleChampionSelect, selectedChampions}) => { { searchResults.length ? - + : null } diff --git a/src/components/Header/Header.module.css b/src/components/Header/Header.module.css index 6d030d3..cea2d21 100644 --- a/src/components/Header/Header.module.css +++ b/src/components/Header/Header.module.css @@ -1,9 +1,18 @@ .header { + position: relative; + margin-bottom: 50px; +} + +.background { background: black; height: 76px; } .logo { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, 0); height: 90px; width: 160px; background-image: url('/public/img/Mortal-Kombat-Logo.png'); diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx index 80b852b..e2aee1b 100644 --- a/src/components/Header/Header.tsx +++ b/src/components/Header/Header.tsx @@ -4,8 +4,8 @@ import headerStyles from './Header.module.css' const Header = () => { return ( -
-
+
+
diff --git a/src/components/Squad/Squad.module.css b/src/components/Squad/Squad.module.css index eb49438..b11a68d 100644 --- a/src/components/Squad/Squad.module.css +++ b/src/components/Squad/Squad.module.css @@ -1,5 +1,56 @@ .squad { display: flex; justify-content: center; - gap: 10px; + gap: 15px; + padding: 30px 0; +} + +.title { + padding-top: 25px; + font-weight: 700; + font-size: 24px; +} + +.list, .numbers { + display: flex; + justify-content: center; + padding-top: 20px; + max-width: 500px; + margin: auto; +} + +.numbers { + font-weight: 700; + font-size: 20px; +} + +.list >span, .numbers >span { + flex: 1; +} + +.abilities { + position: relative; + padding-bottom: 40px; +} + +.leftLign, .rightLign { + position: absolute; + right: 0; + display: block; + border: none; + color: #ffffff; + height: 1px; + background: #000000; + background: -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 50, from(#000), to(transparent)); + transform: rotate(90deg); +} + +.leftLign { + left: -20%; + top: 50%; +} + +.rightLign { + left: 20%; + top: 50%; } \ No newline at end of file diff --git a/src/components/Squad/Squad.tsx b/src/components/Squad/Squad.tsx index 9978d77..33717c0 100644 --- a/src/components/Squad/Squad.tsx +++ b/src/components/Squad/Squad.tsx @@ -1,17 +1,45 @@ -import React, {useState} from 'react' -import type { Character } from '../../types' +import React, {FC} from 'react' import {Avatar} from '@mui/material' import squadStyles from './Squad.module.css' +import { CHAR_TITLES } from '../../constants/common' +import {Character} from '../../types' -const Squad = ({selectedChampions}) => { +interface ISquad { + selectedChampions: Character[] +} + +const Squad : FC = ({selectedChampions}) => { + + const numbers = [ + 65, + 70, + 44, + 4, + 10 + ] return ( -
- {selectedChampions.map((char)=> ( - - ))} +
+
Your champions!
+
+ {selectedChampions.map((char)=> ( + + ))} +
+
+
{CHAR_TITLES.map((title) => { + return {title} + })}
+
{numbers.map((title) => { + return {title} + })}
+
+
+
) } diff --git a/src/constants/common.tsx b/src/constants/common.tsx new file mode 100644 index 0000000..0c3a9d0 --- /dev/null +++ b/src/constants/common.tsx @@ -0,0 +1,9 @@ +export const CHAR_TITLES = [ + 'Power', + 'Mobility', + 'Technique', + 'Survivability', + 'Energy' +] + +export const ALL_TAGS = ['Monster', 'Melee', 'Human', 'Ninja', 'Agile', 'God', 'Aerial', 'Strong', 'Grappling', 'Defend', 'Attack', 'Block', 'Mercenary', 'Demon', 'Robot', 'Magic', 'Ranged', 'Alien', 'Ghost', 'Grapple', 'Animal', 'My Team'] diff --git a/tsconfig.json b/tsconfig.json index 7bb48d7..f0f16e9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,7 +19,7 @@ "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, - "jsx": "react-jsx", + "jsx": "preserve", "defaultSeverity": "warning", "noImplicitAny": true, "noImplicitReturns": true, From 18d02d4ca45796a4cefa4a45e5dacf7c0b76852c Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 1 Oct 2022 02:33:05 +0400 Subject: [PATCH 8/8] added squad removing functionality, my team filter, resolved ts errors, added averages --- src/App.css | 1 + src/App.tsx | 19 +++-- .../CharactersSearch.module.css | 17 ++++- .../CharactersSearch/CharactersSearch.tsx | 62 +++++++++------- src/components/Header/Header.tsx | 1 - src/components/Squad/Squad.module.css | 49 +++++++++++-- src/components/Squad/Squad.tsx | 70 ++++++++++++------- src/constants/common.tsx | 14 +++- src/index.css | 4 ++ src/types.ts | 4 ++ 10 files changed, 179 insertions(+), 62 deletions(-) diff --git a/src/App.css b/src/App.css index e852b65..3ba5842 100644 --- a/src/App.css +++ b/src/App.css @@ -1,6 +1,7 @@ .App { text-align: center; background-color: #F5FDFF; + height: 100%; } .App-logo { diff --git a/src/App.tsx b/src/App.tsx index ebe3ded..466ae8d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -7,18 +7,29 @@ import './App.css' function App() { const [selectedChampions, setSelectedChampions] = useState([]) + const [selectedChampionIds, setSelectedChampionIds] = useState([]) + + const handleChampionRemove = (id : number) => { + setSelectedChampions(selectedChampions.filter((selectedChar) => selectedChar.id !== id)) + setSelectedChampionIds(selectedChampionIds.filter((selectedCharId) => selectedCharId !== id)) + } const handleChampionSelect = (ev : React.ChangeEvent, char : Character) => { - ev.target.checked ? - setSelectedChampions([...selectedChampions, char]) : + if(ev.target.checked){ + setSelectedChampions([...selectedChampions, char]) + setSelectedChampionIds([...selectedChampionIds, char.id]) + } + else { setSelectedChampions(selectedChampions.filter((selectedChar) => selectedChar.id !== char.id)) + setSelectedChampionIds(selectedChampionIds.filter((selectedCharId) => selectedCharId !== char.id)) + } } return (
- - + +
) } diff --git a/src/components/CharactersSearch/CharactersSearch.module.css b/src/components/CharactersSearch/CharactersSearch.module.css index 908252e..8b634b8 100644 --- a/src/components/CharactersSearch/CharactersSearch.module.css +++ b/src/components/CharactersSearch/CharactersSearch.module.css @@ -10,13 +10,17 @@ font-size: 20px; } -.row { +.row, .selectedRow { display: flex; padding: 22px; border-bottom: 1px solid #EEEEEE; gap: 24px; } +.selectedRow { + background-color: #EDF5FF; +} + .character, .tags, .abilities { display: flex; gap: 24px; @@ -36,6 +40,11 @@ flex: 1; } +.score10 { + flex: 1; + color: #FF0000; +} + .allTags { display: flex; justify-content: center; @@ -117,3 +126,9 @@ .titleList >span { flex: 1; } + +.noResults { + font-weight: 700; + font-size: 22px; + padding: 50px; +} diff --git a/src/components/CharactersSearch/CharactersSearch.tsx b/src/components/CharactersSearch/CharactersSearch.tsx index 58fe04c..d3b3c34 100644 --- a/src/components/CharactersSearch/CharactersSearch.tsx +++ b/src/components/CharactersSearch/CharactersSearch.tsx @@ -5,16 +5,18 @@ import SearchIcon from '@mui/icons-material/Search' import jsonData from '../../data/characters.json' import charStyles from './CharactersSearch.module.css' import CheckIcon from '@mui/icons-material/Check' -import { CHAR_TITLES, ALL_TAGS } from '../../constants/common' +import { CHAR_ABILITIES, ALL_TAGS } from '../../constants/common' +import {AbilityName} from '../../types' const data: Character[] = jsonData as Character[] interface ICharactersSearch { selectedChampions: Character[] + selectedChampionIds: number[] handleChampionSelect: (ev: React.ChangeEvent, char: Character) => void } -const CharactersSearch : FC = ({handleChampionSelect, selectedChampions}) => { +const CharactersSearch : FC = ({handleChampionSelect, selectedChampions, selectedChampionIds}) => { const [searchQuery, setSearchQuery] = useState('') const [searchResults, setSearchResults] = useState(data) @@ -25,11 +27,15 @@ const CharactersSearch : FC = ({handleChampionSelect, selecte setPage(value) } - console.log(selectedChampions) - const filterData = (searchString : string, tags: string[]) => { - const filteredData = data.filter((char) => { - if(tags.length){ + let dataToBeFiltered = data + let filterableTags = [...tags] + if(tags.includes('my team')){ + filterableTags = filterableTags.filter(t => t !== 'my team') + dataToBeFiltered = selectedChampions + } + const filteredData = dataToBeFiltered.filter((char) => { + if(filterableTags.length){ if(char.tags?.find((tag)=> tags.includes(tag.tag_name.toLowerCase()))){ return char.name.toLowerCase().includes(searchString) } @@ -37,7 +43,6 @@ const CharactersSearch : FC = ({handleChampionSelect, selecte } else return char.name.toLowerCase().includes(searchString) }) - console.log(filteredData) setSearchResults(filteredData) setSelectedTags(tags) setPage(1) @@ -49,6 +54,8 @@ const CharactersSearch : FC = ({handleChampionSelect, selecte setSearchQuery(ev.target.value) } + const abilityScore = (char : Character, abilityName : AbilityName) => char.abilities.find((charAb)=>(charAb.abilityName === abilityName))?.abilityScore + const handleTagSelect = (tag: string) => { let updatedSelection = [] if (selectedTags.includes(tag)){ @@ -68,7 +75,7 @@ const CharactersSearch : FC = ({handleChampionSelect, selecte } const renderTags = () => ( - ALL_TAGS.map((tag, index) => { + [...ALL_TAGS, 'My Team'].map((tag, index) => { if (selectedTags.includes(tag.toLowerCase())){ return (
@@ -88,9 +95,10 @@ const CharactersSearch : FC = ({handleChampionSelect, selecte const renderRows = () => ( searchResults?.slice((page - 1) * 10, (page - 1) * 10 + 10).map((char: Character)=> ( -
+
handleChampionSelect(ev, char)} sx={{color: '#227aff'}} color='primary'/> = ({handleChampionSelect, selecte ))}
- {char.abilities?.map((ability, index )=>( - {ability.abilityScore} + {CHAR_ABILITIES.map((abilityName: AbilityName, index )=>( + + {abilityScore(char, abilityName)} + ))}
)) ) - console.log(searchResults) return (
@@ -129,18 +138,23 @@ const CharactersSearch : FC = ({handleChampionSelect, selecte {renderTags()} filterData(searchQuery, [])}>Clear all
-
-
- Characters - Tags -
{CHAR_TITLES.map((title) => { - return {title} - })}
-
-
- {searchResults.length ? renderRows() : null} -
-
+ { + searchResults.length ? +
+
+ Characters + Tags +
{CHAR_ABILITIES.map((title, index) => ( + {title} + ))}
+
+
+ {searchResults.length ? renderRows() : null} +
+
: +
No Results
+ } + { searchResults.length ? diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx index e2aee1b..fc07c20 100644 --- a/src/components/Header/Header.tsx +++ b/src/components/Header/Header.tsx @@ -7,7 +7,6 @@ const Header = () => {
-
) } diff --git a/src/components/Squad/Squad.module.css b/src/components/Squad/Squad.module.css index b11a68d..9dd36f2 100644 --- a/src/components/Squad/Squad.module.css +++ b/src/components/Squad/Squad.module.css @@ -11,12 +11,11 @@ font-size: 24px; } -.list, .numbers { +.list { display: flex; justify-content: center; padding-top: 20px; - max-width: 500px; - margin: auto; + width: 100%; } .numbers { @@ -24,13 +23,21 @@ font-size: 20px; } -.list >span, .numbers >span { +.results { + display: flex; + flex-direction: column; flex: 1; } +.results >span { + padding-bottom: 20px; +} + .abilities { position: relative; padding-bottom: 40px; + max-width: 500px; + margin: auto; } .leftLign, .rightLign { @@ -47,10 +54,40 @@ .leftLign { left: -20%; - top: 50%; + top: 35%; } .rightLign { left: 20%; - top: 50%; + top: 35%; +} + +.avatar { + position: relative; +} + +.avatar:hover .remove { + display: flex; + z-index: 1; +} + +.remove { + display: none; + top: 0; + bottom: 0; + left: 0; + right: 0; + border-radius: 50%; + position: absolute; + background-color: #217AFF; + opacity: 60%; + cursor: pointer; + justify-content: center; + align-items: center; +} + +.remove >span { + font-weight: 700; + font-size: 10px; + color: #ffffff; } \ No newline at end of file diff --git a/src/components/Squad/Squad.tsx b/src/components/Squad/Squad.tsx index 33717c0..228627c 100644 --- a/src/components/Squad/Squad.tsx +++ b/src/components/Squad/Squad.tsx @@ -1,42 +1,64 @@ -import React, {FC} from 'react' +import React, {FC, useEffect, useState} from 'react' import {Avatar} from '@mui/material' import squadStyles from './Squad.module.css' -import { CHAR_TITLES } from '../../constants/common' -import {Character} from '../../types' +import {ABILITY_AVERAGES} from '../../constants/common' +import {AbilityName, AverageAbility, Character, CharacterAbility} from '../../types' interface ISquad { selectedChampions: Character[] + handleChampionRemove: (id: number) => void } -const Squad : FC = ({selectedChampions}) => { +const Squad: FC = ({selectedChampions, handleChampionRemove}) => { + const [abilityAverages, setAbilityAverages] = useState(ABILITY_AVERAGES) - const numbers = [ - 65, - 70, - 44, - 4, - 10 - ] + useEffect(() => { + const updateAbilitiesAverage = {...ABILITY_AVERAGES} + if(selectedChampions.length > 0){ + selectedChampions.forEach((char: Character) => { + char.abilities.forEach((ability: CharacterAbility) => { + updateAbilitiesAverage[ability.abilityName] = updateAbilitiesAverage[ability.abilityName] ? + updateAbilitiesAverage[ability.abilityName] + ability.abilityScore : + ability.abilityScore + }) + }) + Object.entries(updateAbilitiesAverage).forEach(([key, value] ) => { + updateAbilitiesAverage[key as AbilityName] = Math.round(value / selectedChampions.length * 10) / 10 + }); + setAbilityAverages(updateAbilitiesAverage) + } + else { + setAbilityAverages(ABILITY_AVERAGES) + } + }, [selectedChampions]) return (
-
Your champions!
+
+ {selectedChampions.length ? 'Your champions!' : 'Select your squad to defend earthrealm'} +
- {selectedChampions.map((char)=> ( - + {selectedChampions.map((char) => ( +
handleChampionRemove(char.id)} className={squadStyles.avatar}> + +
Remove
+
))}
-
{CHAR_TITLES.map((title) => { - return {title} - })}
-
{numbers.map((title) => { - return {title} - })}
+
+ {Object.entries(abilityAverages).map(([key, value], index)=> ( +
+ {key} + {selectedChampions.length ? value : '-' } +
+ + ))} +
diff --git a/src/constants/common.tsx b/src/constants/common.tsx index 0c3a9d0..be9edec 100644 --- a/src/constants/common.tsx +++ b/src/constants/common.tsx @@ -1,4 +1,6 @@ -export const CHAR_TITLES = [ +import {AbilityName, AverageAbility} from '../types' + +export const CHAR_ABILITIES : AbilityName[] = [ 'Power', 'Mobility', 'Technique', @@ -6,4 +8,12 @@ export const CHAR_TITLES = [ 'Energy' ] -export const ALL_TAGS = ['Monster', 'Melee', 'Human', 'Ninja', 'Agile', 'God', 'Aerial', 'Strong', 'Grappling', 'Defend', 'Attack', 'Block', 'Mercenary', 'Demon', 'Robot', 'Magic', 'Ranged', 'Alien', 'Ghost', 'Grapple', 'Animal', 'My Team'] +export const ALL_TAGS = ['Monster', 'Melee', 'Human', 'Ninja', 'Agile', 'God', 'Aerial', 'Strong', 'Grappling', 'Defend', 'Attack', 'Block', 'Mercenary', 'Demon', 'Robot', 'Magic', 'Ranged', 'Alien', 'Ghost', 'Grapple', 'Animal'] + +export const ABILITY_AVERAGES : AverageAbility = { + Power : 0, + Mobility : 0, + Technique : 0, + Survivability : 0, + Energy : 0 +} \ No newline at end of file diff --git a/src/index.css b/src/index.css index ec2585e..d686899 100644 --- a/src/index.css +++ b/src/index.css @@ -1,3 +1,7 @@ +body, #root { + height: 100%; +} + body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', diff --git a/src/types.ts b/src/types.ts index b03f892..e7b6a4a 100644 --- a/src/types.ts +++ b/src/types.ts @@ -5,6 +5,10 @@ export interface CharacterAbility { abilityScore: number } +export type AverageAbility = { + [key in AbilityName]: number +} + export interface CharacterTag { slot: number tag_name: string