From ebeb7d692b1e754955cf56cc6f6792f8daf54e48 Mon Sep 17 00:00:00 2001 From: Sriram Hariharan Date: Mon, 6 Mar 2023 22:45:34 -0600 Subject: [PATCH] created reusable button component, created course info header component, created utility type for Colors, removed typescript-css-modules plugin, and added a threshold to the infinite scroll hook --- .vscode/extensions.json | 5 + @types/css-imports.d.ts | 18 +- package-lock.json | 552 ------------------ package.json | 1 - src/shared/types/CourseSchedule.ts | 12 +- src/views/components/CourseCatalogMain.tsx | 4 +- .../common/Button/Button.module.scss | 126 ++++ src/views/components/common/Button/Button.tsx | 27 +- .../components/common/Link/Link.module.scss | 6 + src/views/components/common/Link/Link.tsx | 14 +- .../components/common/Spinner/Spinner.tsx | 4 +- src/views/components/common/Text/Text.tsx | 4 +- .../CourseInfoHeader.module.scss | 23 + .../CourseInfoHeader/CourseInfoHeader.tsx | 75 +++ .../CourseInfoPopup.module.scss | 11 + .../CourseInfoPopup/CourseInfoPopup.tsx | 27 + .../CoursePopup/CoursePopup.module.scss | 34 -- .../injected/CoursePopup/CoursePopup.tsx | 68 --- .../components/injected/TableRow/TableRow.tsx | 10 +- src/views/hooks/useInfiniteScroll.ts | 2 +- src/views/styles/colors.module.scss | 4 + src/views/styles/colors.module.scss.d.ts | 6 + tsconfig.json | 5 - 23 files changed, 351 insertions(+), 687 deletions(-) create mode 100644 .vscode/extensions.json create mode 100644 src/views/components/injected/CourseInfoPopup/CourseInfoHeader/CourseInfoHeader.module.scss create mode 100644 src/views/components/injected/CourseInfoPopup/CourseInfoHeader/CourseInfoHeader.tsx create mode 100644 src/views/components/injected/CourseInfoPopup/CourseInfoPopup.module.scss create mode 100644 src/views/components/injected/CourseInfoPopup/CourseInfoPopup.tsx delete mode 100644 src/views/components/injected/CoursePopup/CoursePopup.module.scss delete mode 100644 src/views/components/injected/CoursePopup/CoursePopup.tsx diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 00000000..66779fde --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "clinyong.vscode-css-modules" + ] +} \ No newline at end of file diff --git a/@types/css-imports.d.ts b/@types/css-imports.d.ts index 6a4bc457..60c46e85 100644 --- a/@types/css-imports.d.ts +++ b/@types/css-imports.d.ts @@ -1,13 +1,13 @@ -declare module "*.module.css" { - const classes: { [key: string]: string }; - export default classes; +declare module '*.module.css' { + const classes: { [key: string]: string }; + export default classes; } -declare module "*.module.scss" { - const classes: { [key: string]: string }; - export default classes; +declare module '*.module.scss' { + const classes: { [key: string]: string }; + export default classes; } -declare module "*.mp3" { - const src: string; - export default src; +declare module '*.mp3' { + const src: string; + export default src; } diff --git a/package-lock.json b/package-lock.json index 9117270d..ee6f6042 100644 --- a/package-lock.json +++ b/package-lock.json @@ -67,19 +67,12 @@ "tsconfig-paths-webpack-plugin": "^4.0.0", "tsx": "^3.12.1", "typescript": "^4.9.5", - "typescript-plugin-css-modules": "^4.2.2", "url-loader": "^4.1.1", "webpack": "^5.75.0", "webpack-build-notifier": "^2.3.0", "webpack-dev-server": "^4.11.1" } }, - "node_modules/@adobe/css-tools": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.2.0.tgz", - "integrity": "sha512-E09FiIft46CmH5Qnjb0wsW54/YQd69LsxeKUOWawmws1XWvyFGURnAChH0mlr7YPFR1ofwvUQfcL0J3lMxXqPA==", - "dev": true - }, "node_modules/@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", @@ -3187,24 +3180,6 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, - "node_modules/@types/postcss-modules-local-by-default": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", - "integrity": "sha512-0VLab/pcLTLcfbxi6THSIMVYcw9hEUBGvjwwaGpW77mMgRXfGF+a76t7BxTGyLh1y68tBvrffp8UWnqvm76+yg==", - "dev": true, - "dependencies": { - "postcss": "^8.0.0" - } - }, - "node_modules/@types/postcss-modules-scope": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/postcss-modules-scope/-/postcss-modules-scope-3.0.1.tgz", - "integrity": "sha512-LNkp3c4ML9EQj2dgslp4i80Jxj72YK3HjYzrTn6ftUVylW1zaKFGqrMlNIyqBmPWmIhZ/Y5r0Y4T49Hk1IuDUg==", - "dev": true, - "dependencies": { - "postcss": "^8.0.0" - } - }, "node_modules/@types/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/@types/prompts/-/prompts-2.4.2.tgz", @@ -5330,18 +5305,6 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "dev": true }, - "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/copy-webpack-plugin": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", @@ -6283,19 +6246,6 @@ "node": ">=6" } }, - "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", @@ -8583,19 +8533,6 @@ "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.16", "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.16.tgz", @@ -9135,12 +9072,6 @@ "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", @@ -9450,32 +9381,6 @@ "safe-buffer": "~5.1.0" } }, - "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/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -9489,15 +9394,6 @@ "node": ">= 0.8.0" } }, - "node_modules/lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -9575,12 +9471,6 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "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.capitalize": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz", @@ -9691,40 +9581,6 @@ "yallist": "^3.0.2" } }, - "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/make-dir/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/make-dir/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/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -10084,47 +9940,6 @@ "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", "dev": true }, - "node_modules/needle": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/needle/-/needle-3.2.0.tgz", - "integrity": "sha512-oUvzXnyLiVyVGoianLijF9O/RecZUf7TkBfimjGrLM4eQhXyeJwM6GeAWccwfQ9aa4gMCZKqhAOuLaMIcQxajQ==", - "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/needle/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "optional": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -13297,15 +13112,6 @@ "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/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -13614,35 +13420,6 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/postcss-load-config": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", - "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", - "dev": true, - "dependencies": { - "lilconfig": "^2.0.5", - "yaml": "^1.10.2" - }, - "engines": { - "node": ">= 10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": ">=8.0.9", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "postcss": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, "node_modules/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", @@ -13859,13 +13636,6 @@ "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/pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", @@ -14674,12 +14444,6 @@ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", "dev": true }, - "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", @@ -14883,12 +14647,6 @@ } } }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true - }, "node_modules/scheduler": { "version": "0.23.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", @@ -15860,37 +15618,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/stylus": { - "version": "0.59.0", - "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.59.0.tgz", - "integrity": "sha512-lQ9w/XIOH5ZHVNuNbWW8D822r+/wBSO/d6XvtyHLF7LW4KaCIDeVbvn5DF8fGCJAUCwVhVi/h6J0NUcnylUEjg==", - "dev": true, - "dependencies": { - "@adobe/css-tools": "^4.0.1", - "debug": "^4.3.2", - "glob": "^7.1.6", - "sax": "~1.2.4", - "source-map": "^0.7.3" - }, - "bin": { - "stylus": "bin/stylus" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://opencollective.com/stylus" - } - }, - "node_modules/stylus/node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, "node_modules/sumchecker": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", @@ -16652,46 +16379,6 @@ "node": ">=4.2.0" } }, - "node_modules/typescript-plugin-css-modules": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/typescript-plugin-css-modules/-/typescript-plugin-css-modules-4.2.2.tgz", - "integrity": "sha512-X5OYGkX96ENq2c7xFJO4tgtiMTlBkOMoRmVHQXH2H4CGFcVODKGieDqPU2B0IV0I+AyvKYDFdKh4ZKtKxAcAww==", - "dev": true, - "dependencies": { - "@types/postcss-modules-local-by-default": "^4.0.0", - "@types/postcss-modules-scope": "^3.0.1", - "dotenv": "^16.0.3", - "icss-utils": "^5.1.0", - "less": "^4.1.3", - "lodash.camelcase": "^4.3.0", - "postcss": "^8.4.21", - "postcss-load-config": "^3.1.4", - "postcss-modules-local-by-default": "^4.0.0", - "postcss-modules-scope": "^3.0.0", - "reserved-words": "^0.1.2", - "sass": "^1.58.3", - "source-map-js": "^1.0.2", - "stylus": "^0.59.0", - "tsconfig-paths": "^4.1.2" - }, - "peerDependencies": { - "typescript": ">=3.9.0" - } - }, - "node_modules/typescript-plugin-css-modules/node_modules/tsconfig-paths": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.1.2.tgz", - "integrity": "sha512-uhxiMgnXQp1IR622dUXI+9Ehnws7i/y6xvpZB9IbUVOPy0muvdvgXeZOn88UcGPiT98Vp3rJPTa8bFoalZ3Qhw==", - "dev": true, - "dependencies": { - "json5": "^2.2.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/uglify-js": { "version": "3.17.4", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", @@ -17596,12 +17283,6 @@ } }, "dependencies": { - "@adobe/css-tools": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.2.0.tgz", - "integrity": "sha512-E09FiIft46CmH5Qnjb0wsW54/YQd69LsxeKUOWawmws1XWvyFGURnAChH0mlr7YPFR1ofwvUQfcL0J3lMxXqPA==", - "dev": true - }, "@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", @@ -19856,24 +19537,6 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, - "@types/postcss-modules-local-by-default": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", - "integrity": "sha512-0VLab/pcLTLcfbxi6THSIMVYcw9hEUBGvjwwaGpW77mMgRXfGF+a76t7BxTGyLh1y68tBvrffp8UWnqvm76+yg==", - "dev": true, - "requires": { - "postcss": "^8.0.0" - } - }, - "@types/postcss-modules-scope": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/postcss-modules-scope/-/postcss-modules-scope-3.0.1.tgz", - "integrity": "sha512-LNkp3c4ML9EQj2dgslp4i80Jxj72YK3HjYzrTn6ftUVylW1zaKFGqrMlNIyqBmPWmIhZ/Y5r0Y4T49Hk1IuDUg==", - "dev": true, - "requires": { - "postcss": "^8.0.0" - } - }, "@types/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/@types/prompts/-/prompts-2.4.2.tgz", @@ -21535,15 +21198,6 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "dev": true }, - "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" - } - }, "copy-webpack-plugin": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", @@ -22246,16 +21900,6 @@ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "dev": true }, - "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", @@ -23984,13 +23628,6 @@ "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true }, - "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.16", "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.16.tgz", @@ -24361,12 +23998,6 @@ "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", @@ -24615,24 +24246,6 @@ } } }, - "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" - } - }, "levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -24643,12 +24256,6 @@ "type-check": "~0.4.0" } }, - "lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "dev": true - }, "lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -24710,12 +24317,6 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "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.capitalize": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz", @@ -24820,33 +24421,6 @@ "yallist": "^3.0.2" } }, - "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" - }, - "dependencies": { - "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 - } - } - }, "make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -25104,40 +24678,6 @@ "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", "dev": true }, - "needle": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/needle/-/needle-3.2.0.tgz", - "integrity": "sha512-oUvzXnyLiVyVGoianLijF9O/RecZUf7TkBfimjGrLM4eQhXyeJwM6GeAWccwfQ9aa4gMCZKqhAOuLaMIcQxajQ==", - "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" - } - }, - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - } - } - }, "negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -27373,12 +26913,6 @@ "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 - }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -27606,16 +27140,6 @@ "source-map-js": "^1.0.2" } }, - "postcss-load-config": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", - "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", - "dev": true, - "requires": { - "lilconfig": "^2.0.5", - "yaml": "^1.10.2" - } - }, "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", @@ -27777,13 +27301,6 @@ } } }, - "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 - }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", @@ -28415,12 +27932,6 @@ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", "dev": true }, - "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", @@ -28534,12 +28045,6 @@ "neo-async": "^2.6.2" } }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true - }, "scheduler": { "version": "0.23.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", @@ -29347,27 +28852,6 @@ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, - "stylus": { - "version": "0.59.0", - "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.59.0.tgz", - "integrity": "sha512-lQ9w/XIOH5ZHVNuNbWW8D822r+/wBSO/d6XvtyHLF7LW4KaCIDeVbvn5DF8fGCJAUCwVhVi/h6J0NUcnylUEjg==", - "dev": true, - "requires": { - "@adobe/css-tools": "^4.0.1", - "debug": "^4.3.2", - "glob": "^7.1.6", - "sax": "~1.2.4", - "source-map": "^0.7.3" - }, - "dependencies": { - "source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true - } - } - }, "sumchecker": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", @@ -29924,42 +29408,6 @@ "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true }, - "typescript-plugin-css-modules": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/typescript-plugin-css-modules/-/typescript-plugin-css-modules-4.2.2.tgz", - "integrity": "sha512-X5OYGkX96ENq2c7xFJO4tgtiMTlBkOMoRmVHQXH2H4CGFcVODKGieDqPU2B0IV0I+AyvKYDFdKh4ZKtKxAcAww==", - "dev": true, - "requires": { - "@types/postcss-modules-local-by-default": "^4.0.0", - "@types/postcss-modules-scope": "^3.0.1", - "dotenv": "^16.0.3", - "icss-utils": "^5.1.0", - "less": "^4.1.3", - "lodash.camelcase": "^4.3.0", - "postcss": "^8.4.21", - "postcss-load-config": "^3.1.4", - "postcss-modules-local-by-default": "^4.0.0", - "postcss-modules-scope": "^3.0.0", - "reserved-words": "^0.1.2", - "sass": "^1.58.3", - "source-map-js": "^1.0.2", - "stylus": "^0.59.0", - "tsconfig-paths": "^4.1.2" - }, - "dependencies": { - "tsconfig-paths": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.1.2.tgz", - "integrity": "sha512-uhxiMgnXQp1IR622dUXI+9Ehnws7i/y6xvpZB9IbUVOPy0muvdvgXeZOn88UcGPiT98Vp3rJPTa8bFoalZ3Qhw==", - "dev": true, - "requires": { - "json5": "^2.2.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - } - } - }, "uglify-js": { "version": "3.17.4", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", diff --git a/package.json b/package.json index 7790414f..f9909f11 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,6 @@ "tsconfig-paths-webpack-plugin": "^4.0.0", "tsx": "^3.12.1", "typescript": "^4.9.5", - "typescript-plugin-css-modules": "^4.2.2", "url-loader": "^4.1.1", "webpack": "^5.75.0", "webpack-build-notifier": "^2.3.0", diff --git a/src/shared/types/CourseSchedule.ts b/src/shared/types/CourseSchedule.ts index 45e6867a..670df761 100644 --- a/src/shared/types/CourseSchedule.ts +++ b/src/shared/types/CourseSchedule.ts @@ -51,16 +51,18 @@ export class CourseSchedule { return Number(hour) * 60 + Number(minute); }); - const [building, room] = locLine.split(' '); + const location = locLine.split(' ').filter(Boolean); return new CourseMeeting({ days, startTime, endTime, - location: { - building, - room, - }, + location: location.length + ? { + building: location[0], + room: location[1], + } + : undefined, }); } catch (e) { throw new Error(`Failed to parse schedule: ${dayLine} ${timeLine} ${locLine}`); diff --git a/src/views/components/CourseCatalogMain.tsx b/src/views/components/CourseCatalogMain.tsx index 0db7d739..15c1e708 100644 --- a/src/views/components/CourseCatalogMain.tsx +++ b/src/views/components/CourseCatalogMain.tsx @@ -9,7 +9,7 @@ import ExtensionRoot from './common/ExtensionRoot/ExtensionRoot'; import Icon from './common/Icon/Icon'; import Text from './common/Text/Text'; import AutoLoad from './injected/AutoLoad/AutoLoad'; -import CoursePopup from './injected/CoursePopup/CoursePopup'; +import CourseInfoPopup from './injected/CourseInfoPopup/CourseInfoPopup'; import TableHead from './injected/TableHead'; import TableRow from './injected/TableRow/TableRow'; @@ -74,7 +74,7 @@ export default function CourseCatalogMain({ support }: Props) { /> ); })} - {selectedCourse && } + {selectedCourse && } ); diff --git a/src/views/components/common/Button/Button.module.scss b/src/views/components/common/Button/Button.module.scss index dcd74cb0..74a07c75 100644 --- a/src/views/components/common/Button/Button.module.scss +++ b/src/views/components/common/Button/Button.module.scss @@ -12,8 +12,134 @@ transition: all 0.3s ease; font-family: 'Inter'; + display: flex; + align-items: center; + justify-content: center; + + &:active { + animation: ripple 1s ease-out; + } + + $primary: $burnt_orange; + $secondary: $charcoal; + $tertiary: $bluebonnet; + $danger: $speedway_brick; + $warning: $tangerine; + $success: $turtle_pond; + $info: $turquoise; + &:hover { background-color: #fff; color: #000; } + + &.primary { + background-color: $primary; + color: #fff; + + &:hover { + background-color: lighten($primary, 10%); + } + + &:active, + &:active { + background-color: darken($primary, 10%); + } + } + + &.secondary { + background-color: $secondary; + color: #fff; + + &:hover { + background-color: lighten($secondary, 10%); + } + + &:active, + &:active { + background-color: darken($secondary, 10%); + } + } + + &.tertiary { + background-color: $tertiary; + color: #fff; + + &:hover { + background-color: lighten($tertiary, 10%); + } + + &:focus, + &:active { + background-color: darken($tertiary, 10%); + } + } + + &.danger { + background-color: $danger; + color: #fff; + + &:hover { + background-color: lighten($danger, 10%); + } + + &:focus, + &:active { + background-color: darken($danger, 10%); + } + } + + &.warning { + background-color: $warning; + color: #fff; + + &:hover { + background-color: lighten($warning, 10%); + } + + &:focus, + &:active { + background-color: darken($warning, 10%); + } + } + + &.success { + background-color: $success; + color: #fff; + + &:hover { + background-color: lighten($success, 10%); + } + + &:focus, + &:active { + background-color: darken($success, 10%); + } + } + + &.info { + background-color: $info; + color: #fff; + + &:hover { + background-color: lighten($info, 10%); + } + + &:focus, + &:active { + background-color: darken($info, 10%); + } + } +} + +@keyframes ripple { + 0% { + transform: scale(1); + } + 50% { + transform: scale(0.9); + } + 100% { + transform: scale(1); + } } diff --git a/src/views/components/common/Button/Button.tsx b/src/views/components/common/Button/Button.tsx index b3aa96d4..270f0f8a 100644 --- a/src/views/components/common/Button/Button.tsx +++ b/src/views/components/common/Button/Button.tsx @@ -1,14 +1,35 @@ +import classNames from 'classnames'; import React from 'react'; import styles from './Button.module.scss'; interface Props { + className?: string; + style?: React.CSSProperties; onClick?: () => void; + type?: 'primary' | 'secondary' | 'tertiary' | 'danger' | 'warning' | 'success' | 'info'; + testId?: string; } -export function Button(props: React.PropsWithChildren): JSX.Element { +/** + * A reusable button component that follows the design system of the extension. + * @returns + */ +export function Button({ + style, + className, + type, + testId, + children, + onClick, +}: React.PropsWithChildren): JSX.Element { return ( - ); } diff --git a/src/views/components/common/Link/Link.module.scss b/src/views/components/common/Link/Link.module.scss index 5cc8a0c3..f9770c18 100644 --- a/src/views/components/common/Link/Link.module.scss +++ b/src/views/components/common/Link/Link.module.scss @@ -3,3 +3,9 @@ text-decoration: underline; cursor: pointer; } + +.disabled { + cursor: not-allowed !important; + text-decoration: none !important; + color: #999999 !important; +} diff --git a/src/views/components/common/Link/Link.tsx b/src/views/components/common/Link/Link.tsx index 9b4ccd83..8f592233 100644 --- a/src/views/components/common/Link/Link.tsx +++ b/src/views/components/common/Link/Link.tsx @@ -6,6 +6,7 @@ import styles from './Link.module.scss'; type Props = TextProps & { url?: string; + disabled?: boolean; }; /** @@ -21,5 +22,16 @@ export default function Link(props: PropsWithChildren) { passedProps.onClick = () => bMessenger.openNewTab({ url }); } - return ; + return ( + + ); } diff --git a/src/views/components/common/Spinner/Spinner.tsx b/src/views/components/common/Spinner/Spinner.tsx index 4ef5fa2c..758a64d7 100644 --- a/src/views/components/common/Spinner/Spinner.tsx +++ b/src/views/components/common/Spinner/Spinner.tsx @@ -1,9 +1,9 @@ import React from 'react'; -import { ISassColors } from 'src/views/styles/colors.module.scss'; +import { Color } from 'src/views/styles/colors.module.scss'; import styles from './Spinner.module.scss'; type Props = { - color?: keyof ISassColors; + color?: Color; }; /** diff --git a/src/views/components/common/Text/Text.tsx b/src/views/components/common/Text/Text.tsx index b4e2880d..ceb0b18d 100644 --- a/src/views/components/common/Text/Text.tsx +++ b/src/views/components/common/Text/Text.tsx @@ -1,11 +1,11 @@ import classNames from 'classnames'; import React, { PropsWithChildren } from 'react'; -import colors, { ISassColors } from 'src/views/styles/colors.module.scss'; +import colors, { Color } from 'src/views/styles/colors.module.scss'; import fonts, { Size, Weight } from 'src/views/styles/fonts.module.scss'; import styles from './Text.module.scss'; export type TextProps = { - color?: keyof ISassColors; + color?: Color; weight?: Weight; size: Size; span?: boolean; diff --git a/src/views/components/injected/CourseInfoPopup/CourseInfoHeader/CourseInfoHeader.module.scss b/src/views/components/injected/CourseInfoPopup/CourseInfoHeader/CourseInfoHeader.module.scss new file mode 100644 index 00000000..2ac181d0 --- /dev/null +++ b/src/views/components/injected/CourseInfoPopup/CourseInfoHeader/CourseInfoHeader.module.scss @@ -0,0 +1,23 @@ +@import 'src/views/styles/base.module.scss'; +.header { + height: auto; + color: white; + padding: 12px; + margin: 50px 20px; + align-items: center; + justify-content: center; + + .title { + display: flex; + align-items: center; + justify-content: center; + + .uniqueId { + margin-left: 8px; + } + } + + .instructors { + margin-top: 8px; + } +} diff --git a/src/views/components/injected/CourseInfoPopup/CourseInfoHeader/CourseInfoHeader.tsx b/src/views/components/injected/CourseInfoPopup/CourseInfoHeader/CourseInfoHeader.tsx new file mode 100644 index 00000000..dc332d8d --- /dev/null +++ b/src/views/components/injected/CourseInfoPopup/CourseInfoHeader/CourseInfoHeader.tsx @@ -0,0 +1,75 @@ +import React from 'react'; +import { bMessenger } from 'src/shared/messages'; +import { Course } from 'src/shared/types/Course'; +import Card from 'src/views/components/common/Card/Card'; +import Link from 'src/views/components/common/Link/Link'; +import Text from 'src/views/components/common/Text/Text'; +import styles from './CourseInfoHeader.module.scss'; + +type Props = { + course: Course; +}; + +/** + * This component displays the header of the course info popup. + * It displays the course name, unique id, instructors, and schedule, all formatted nicely. + */ +export default function CourseInfoHeader({ course }: Props) { + const getBuildingUrl = (building?: string): string | undefined => { + if (!building) return undefined; + return `https://utdirect.utexas.edu/apps/campus/buildings/nlogon/maps/UTM/${building}/`; + }; + + return ( + + + {course.courseName} ({course.department} {course.number}) + + #{course.uniqueId} + + + + {course.getInstructorString({ + prefix: 'with ', + format: 'first_last', + })} + + + {course.schedule.meetings.map(meeting => ( + + + {meeting.getDaysString({ + format: 'long', + separator: 'short', + })} + + {' at '} + + {meeting.getTimeString({ + separator: 'to', + capitalize: true, + })} + + {' in '} + + {meeting.location?.building ?? 'TBA'} + + + ))} + + ); +} diff --git a/src/views/components/injected/CourseInfoPopup/CourseInfoPopup.module.scss b/src/views/components/injected/CourseInfoPopup/CourseInfoPopup.module.scss new file mode 100644 index 00000000..03c61052 --- /dev/null +++ b/src/views/components/injected/CourseInfoPopup/CourseInfoPopup.module.scss @@ -0,0 +1,11 @@ +.popup { + border-radius: 12px; + position: relative; + + .close { + position: absolute; + top: 12px; + right: 12px; + cursor: pointer; + } +} diff --git a/src/views/components/injected/CourseInfoPopup/CourseInfoPopup.tsx b/src/views/components/injected/CourseInfoPopup/CourseInfoPopup.tsx new file mode 100644 index 00000000..2540c4d2 --- /dev/null +++ b/src/views/components/injected/CourseInfoPopup/CourseInfoPopup.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import { Course } from 'src/shared/types/Course'; +import Card from '../../common/Card/Card'; +import Icon from '../../common/Icon/Icon'; +import Link from '../../common/Link/Link'; +import Popup from '../../common/Popup/Popup'; +import Text from '../../common/Text/Text'; +import CourseInfoHeader from './CourseInfoHeader/CourseInfoHeader'; +import styles from './CourseInfoPopup.module.scss'; + +interface Props { + course: Course; + onClose: () => void; +} + +/** + * The popup that appears when the user clicks on a course for more details. + */ +export default function CourseInfoPopup({ course, onClose }: Props) { + console.log(course); + return ( + + + + + ); +} diff --git a/src/views/components/injected/CoursePopup/CoursePopup.module.scss b/src/views/components/injected/CoursePopup/CoursePopup.module.scss deleted file mode 100644 index 72cf2d27..00000000 --- a/src/views/components/injected/CoursePopup/CoursePopup.module.scss +++ /dev/null @@ -1,34 +0,0 @@ -.popup { - border-radius: 12px; - position: relative; - - .close { - position: absolute; - top: 12px; - right: 12px; - cursor: pointer; - } - - .body { - height: auto; - color: white; - padding: 12px; - margin: 50px 20px; - align-items: center; - justify-content: center; - - .title { - display: flex; - align-items: center; - justify-content: center; - - .uniqueId { - margin-left: 8px; - } - } - - .instructors { - margin-top: 8px; - } - } -} diff --git a/src/views/components/injected/CoursePopup/CoursePopup.tsx b/src/views/components/injected/CoursePopup/CoursePopup.tsx deleted file mode 100644 index b3177254..00000000 --- a/src/views/components/injected/CoursePopup/CoursePopup.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import React from 'react'; -import { Course } from 'src/shared/types/Course'; -import Card from '../../common/Card/Card'; -import Icon from '../../common/Icon/Icon'; -import Link from '../../common/Link/Link'; -import Popup from '../../common/Popup/Popup'; -import Text from '../../common/Text/Text'; -import styles from './CoursePopup.module.scss'; - -interface Props { - course: Course; - onClose: () => void; -} - -/** - * The popup that appears when the user clicks on a course for more details. - */ -export default function CoursePopup({ course, onClose }: Props) { - console.log(course); - return ( - - - - - {course.courseName} ({course.department} {course.number}) - - #{course.uniqueId} - - - - {course.getInstructorString({ - prefix: 'with ', - format: 'first_last', - })} - - - {course.schedule.meetings.map(meeting => ( - - - {meeting.getDaysString({ - format: 'long', - separator: 'short', - })} - - {' at '} - - {meeting.getTimeString({ - separator: 'to', - capitalize: true, - })} - - {' in '} - - {meeting.location?.building} - - - ))} - - - ); -} diff --git a/src/views/components/injected/TableRow/TableRow.tsx b/src/views/components/injected/TableRow/TableRow.tsx index 34f3af99..722d91ac 100644 --- a/src/views/components/injected/TableRow/TableRow.tsx +++ b/src/views/components/injected/TableRow/TableRow.tsx @@ -3,6 +3,7 @@ import ReactDOM from 'react-dom'; import { Course, ScrapedRow } from 'src/shared/types/Course'; import { SiteSupport } from 'src/views/lib/getSiteSupport'; import { Button } from '../../common/Button/Button'; +import Icon from '../../common/Icon/Icon'; import styles from './TableRow.module.scss'; interface Props { @@ -29,11 +30,16 @@ export default function TableRow({ support, course, element, isSelected, onClick useEffect(() => { element.classList[isSelected ? 'add' : 'remove'](styles.selectedRow); - }, [course, isSelected]); + }, [course, isSelected, element.classList]); if (!container) { return null; } - return ReactDOM.createPortal(, container); + return ReactDOM.createPortal( + , + container + ); } diff --git a/src/views/hooks/useInfiniteScroll.ts b/src/views/hooks/useInfiniteScroll.ts index 2c31017e..b54d9ccd 100644 --- a/src/views/hooks/useInfiniteScroll.ts +++ b/src/views/hooks/useInfiniteScroll.ts @@ -13,7 +13,7 @@ export default function useInfiniteScroll( const isScrolling = () => { const { innerHeight } = window; const { scrollTop, offsetHeight } = document.documentElement; - if (innerHeight + scrollTop >= offsetHeight) { + if (innerHeight + scrollTop >= offsetHeight - 100) { callback(); } }; diff --git a/src/views/styles/colors.module.scss b/src/views/styles/colors.module.scss index ea9a238a..45e74adf 100644 --- a/src/views/styles/colors.module.scss +++ b/src/views/styles/colors.module.scss @@ -10,6 +10,9 @@ $turquoise: #00a9b7; $bluebonnet: #005f86; $shade: #9cadb7; $limestone: #d6d2c4; +$speedway_brick: #af2e2d; + +//scss hover active focus color calculation :export { burnt_orange: $burnt_orange; @@ -24,4 +27,5 @@ $limestone: #d6d2c4; bluebonnet: $bluebonnet; shade: $shade; limestone: $limestone; + speedway_brick: $speedway_brick; } diff --git a/src/views/styles/colors.module.scss.d.ts b/src/views/styles/colors.module.scss.d.ts index 65cd47bd..c11c80c5 100644 --- a/src/views/styles/colors.module.scss.d.ts +++ b/src/views/styles/colors.module.scss.d.ts @@ -15,7 +15,13 @@ export interface ISassColors { bluebonnet: string; shade: string; limestone: string; + speedway_brick: string; } +/** + * A type that represents all the colors that we have in our sass files + */ +export type Color = keyof ISassColors; + declare const colors: ISassColors; export default colors; diff --git a/tsconfig.json b/tsconfig.json index 206b424e..cef01079 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -47,11 +47,6 @@ "./release.config.js", "webpack/plugins/custom/.ts" ], - "plugins": [ - { - "name": "typescript-plugin-css-modules" - } - ], "exclude": [ "node_modules", "**/.*/",