diff --git a/index.html b/index.html index 6b8a2cd..75579a1 100644 --- a/index.html +++ b/index.html @@ -7,28 +7,22 @@ Brock Visual TimeTable diff --git a/package-lock.json b/package-lock.json index 66d6483..9ce765b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,15 +8,11 @@ "name": "brockvisualtimetable", "version": "0.0.0", "dependencies": { - "@emotion/react": "^11.11.4", - "@emotion/styled": "^11.11.5", "@fullcalendar/core": "^6.1.14", "@fullcalendar/daygrid": "^6.1.14", "@fullcalendar/interaction": "^6.1.14", "@fullcalendar/react": "^6.1.14", "@fullcalendar/timegrid": "^6.1.14", - "@mui/icons-material": "^5.15.20", - "@mui/material": "^5.15.20", "@radix-ui/react-collapsible": "^1.1.12", "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-dropdown-menu": "^2.1.16", @@ -141,6 +137,7 @@ "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", + "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.28.5", @@ -174,6 +171,7 @@ "version": "7.28.0", "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -183,6 +181,7 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "dev": true, "license": "MIT", "dependencies": { "@babel/traverse": "^7.27.1", @@ -224,6 +223,7 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -266,6 +266,7 @@ "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.28.5" @@ -322,6 +323,7 @@ "version": "7.27.2", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", @@ -336,6 +338,7 @@ "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", @@ -354,6 +357,7 @@ "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", @@ -363,152 +367,6 @@ "node": ">=6.9.0" } }, - "node_modules/@emotion/babel-plugin": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz", - "integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.16.7", - "@babel/runtime": "^7.18.3", - "@emotion/hash": "^0.9.2", - "@emotion/memoize": "^0.9.0", - "@emotion/serialize": "^1.2.0", - "babel-plugin-macros": "^3.1.0", - "convert-source-map": "^1.5.0", - "escape-string-regexp": "^4.0.0", - "find-root": "^1.1.0", - "source-map": "^0.5.7", - "stylis": "4.2.0" - } - }, - "node_modules/@emotion/cache": { - "version": "11.13.0", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.0.tgz", - "integrity": "sha512-hPV345J/tH0Cwk2wnU/3PBzORQ9HeX+kQSbwI+jslzpRCHE6fSGTohswksA/Ensr8znPzwfzKZCmAM9Lmlhp7g==", - "license": "MIT", - "dependencies": { - "@emotion/memoize": "^0.9.0", - "@emotion/sheet": "^1.4.0", - "@emotion/utils": "^1.4.0", - "@emotion/weak-memoize": "^0.4.0", - "stylis": "4.2.0" - } - }, - "node_modules/@emotion/hash": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", - "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", - "license": "MIT" - }, - "node_modules/@emotion/is-prop-valid": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.0.tgz", - "integrity": "sha512-SHetuSLvJDzuNbOdtPVbq6yMMMlLoW5Q94uDqJZqy50gcmAjxFkVqmzqSGEFq9gT2iMuIeKV1PXVWmvUhuZLlQ==", - "license": "MIT", - "dependencies": { - "@emotion/memoize": "^0.9.0" - } - }, - "node_modules/@emotion/memoize": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", - "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", - "license": "MIT" - }, - "node_modules/@emotion/react": { - "version": "11.13.0", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.13.0.tgz", - "integrity": "sha512-WkL+bw1REC2VNV1goQyfxjx1GYJkcc23CRQkXX+vZNLINyfI7o+uUn/rTGPt/xJ3bJHd5GcljgnxHf4wRw5VWQ==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.12.0", - "@emotion/cache": "^11.13.0", - "@emotion/serialize": "^1.3.0", - "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", - "@emotion/utils": "^1.4.0", - "@emotion/weak-memoize": "^0.4.0", - "hoist-non-react-statics": "^3.3.1" - }, - "peerDependencies": { - "react": ">=16.8.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@emotion/serialize": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.0.tgz", - "integrity": "sha512-jACuBa9SlYajnpIVXB+XOXnfJHyckDfe6fOpORIM6yhBDlqGuExvDdZYHDQGoDf3bZXGv7tNr+LpLjJqiEQ6EA==", - "license": "MIT", - "dependencies": { - "@emotion/hash": "^0.9.2", - "@emotion/memoize": "^0.9.0", - "@emotion/unitless": "^0.9.0", - "@emotion/utils": "^1.4.0", - "csstype": "^3.0.2" - } - }, - "node_modules/@emotion/sheet": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", - "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", - "license": "MIT" - }, - "node_modules/@emotion/styled": { - "version": "11.13.0", - "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.13.0.tgz", - "integrity": "sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.12.0", - "@emotion/is-prop-valid": "^1.3.0", - "@emotion/serialize": "^1.3.0", - "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", - "@emotion/utils": "^1.4.0" - }, - "peerDependencies": { - "@emotion/react": "^11.0.0-rc.0", - "react": ">=16.8.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@emotion/unitless": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.9.0.tgz", - "integrity": "sha512-TP6GgNZtmtFaFcsOgExdnfxLLpRDla4Q66tnenA9CktvVSdNKDvMVuUah4QvWPIpNjrWsGg3qeGo9a43QooGZQ==", - "license": "MIT" - }, - "node_modules/@emotion/use-insertion-effect-with-fallbacks": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz", - "integrity": "sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==", - "license": "MIT", - "peerDependencies": { - "react": ">=16.8.0" - } - }, - "node_modules/@emotion/utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.0.tgz", - "integrity": "sha512-spEnrA1b6hDR/C68lC2M7m6ALPUHZC0lIY7jAS/B/9DuuO1ZP04eov8SMv/6fwRd8pzmsn2AuJEznRREWlQrlQ==", - "license": "MIT" - }, - "node_modules/@emotion/weak-memoize": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", - "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", - "license": "MIT" - }, "node_modules/@esbuild/aix-ppc64": { "version": "0.27.2", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", @@ -1268,6 +1126,7 @@ "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", @@ -1289,6 +1148,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -1298,241 +1158,20 @@ "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.31", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@mui/core-downloads-tracker": { - "version": "5.16.4", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.4.tgz", - "integrity": "sha512-rNdHXhclwjEZnK+//3SR43YRx0VtjdHnUFhMSGYmAMJve+KiwEja/41EYh8V3pZKqF2geKyfcFUenTfDTYUR4w==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - } - }, - "node_modules/@mui/icons-material": { - "version": "5.16.4", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.16.4.tgz", - "integrity": "sha512-j9/CWctv6TH6Dou2uR2EH7UOgu79CW/YcozxCYVLJ7l03pCsiOlJ5sBArnWJxJ+nGkFwyL/1d1k8JEPMDR125A==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.23.9" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "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.16.4", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.4.tgz", - "integrity": "sha512-dBnh3/zRYgEVIS3OE4oTbujse3gifA0qLMmuUk13ywsDCbngJsdgwW5LuYeiT5pfA8PGPGSqM7mxNytYXgiMCw==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.23.9", - "@mui/core-downloads-tracker": "^5.16.4", - "@mui/system": "^5.16.4", - "@mui/types": "^7.2.15", - "@mui/utils": "^5.16.4", - "@popperjs/core": "^2.11.8", - "@types/react-transition-group": "^4.4.10", - "clsx": "^2.1.0", - "csstype": "^3.1.3", - "prop-types": "^15.8.1", - "react-is": "^18.3.1", - "react-transition-group": "^4.4.5" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@emotion/react": "^11.5.0", - "@emotion/styled": "^11.3.0", - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - }, - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/private-theming": { - "version": "5.16.4", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.16.4.tgz", - "integrity": "sha512-ZsAm8cq31SJ37SVWLRlu02v9SRthxnfQofaiv14L5Bht51B0dz6yQEoVU/V8UduZDCCIrWkBHuReVfKhE/UuXA==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.23.9", - "@mui/utils": "^5.16.4", - "prop-types": "^15.8.1" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/styled-engine": { - "version": "5.16.4", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.16.4.tgz", - "integrity": "sha512-0+mnkf+UiAmTVB8PZFqOhqf729Yh0Cxq29/5cA3VAyDVTRIUUQ8FXQhiAhUIbijFmM72rY80ahFPXIm4WDbzcA==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.23.9", - "@emotion/cache": "^11.11.0", - "csstype": "^3.1.3", - "prop-types": "^15.8.1" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@emotion/react": "^11.4.1", - "@emotion/styled": "^11.3.0", - "react": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - } - } - }, - "node_modules/@mui/system": { - "version": "5.16.4", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.16.4.tgz", - "integrity": "sha512-ET1Ujl2/8hbsD611/mqUuNArMCGv/fIWO/f8B3ZqF5iyPHM2aS74vhTNyjytncc4i6dYwGxNk+tLa7GwjNS0/w==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.23.9", - "@mui/private-theming": "^5.16.4", - "@mui/styled-engine": "^5.16.4", - "@mui/types": "^7.2.15", - "@mui/utils": "^5.16.4", - "clsx": "^2.1.0", - "csstype": "^3.1.3", - "prop-types": "^15.8.1" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@emotion/react": "^11.5.0", - "@emotion/styled": "^11.3.0", - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - }, - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/types": { - "version": "7.2.15", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.15.tgz", - "integrity": "sha512-nbo7yPhtKJkdf9kcVOF8JZHPZTmqXjJ/tI0bdWgHg5tp9AnIN4Y7f7wm9T+0SyGYJk76+GYZ8Q5XaTYAsUHN0Q==", - "license": "MIT", - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/utils": { - "version": "5.16.4", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.4.tgz", - "integrity": "sha512-nlppYwq10TBIFqp7qxY0SvbACOXeOjeVL3pOcDsK0FT8XjrEXh9/+lkg8AEIzD16z7YfiJDQjaJG2OLkE7BxNg==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.23.9", - "@types/prop-types": "^15.7.12", - "clsx": "^2.1.1", - "prop-types": "^15.8.1", - "react-is": "^18.3.1" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1571,16 +1210,6 @@ "node": ">= 8" } }, - "node_modules/@popperjs/core": { - "version": "2.11.8", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", - "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/popperjs" - } - }, "node_modules/@radix-ui/number": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", @@ -3250,12 +2879,6 @@ "undici-types": "~7.16.0" } }, - "node_modules/@types/parse-json": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", - "license": "MIT" - }, "node_modules/@types/prop-types": { "version": "15.7.12", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", @@ -3281,15 +2904,6 @@ "@types/react": "*" } }, - "node_modules/@types/react-transition-group": { - "version": "4.4.10", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", - "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", - "license": "MIT", - "dependencies": { - "@types/react": "*" - } - }, "node_modules/@types/stack-utils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", @@ -3783,21 +3397,6 @@ "proxy-from-env": "^1.1.0" } }, - "node_modules/babel-plugin-macros": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", - "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.12.5", - "cosmiconfig": "^7.0.0", - "resolve": "^1.19.0" - }, - "engines": { - "node": ">=10", - "npm": ">=6" - } - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -3931,6 +3530,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -4113,37 +3713,6 @@ "dev": true, "license": "MIT" }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "license": "MIT" - }, - "node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "license": "MIT", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cosmiconfig/node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "license": "ISC", - "engines": { - "node": ">= 6" - } - }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -4242,6 +3811,7 @@ "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -4416,16 +3986,6 @@ "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", "license": "MIT" }, - "node_modules/dom-helpers": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", - "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.8.7", - "csstype": "^3.0.2" - } - }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -4447,15 +4007,6 @@ "dev": true, "license": "ISC" }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, "node_modules/es-abstract": { "version": "1.23.3", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", @@ -4699,6 +4250,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -5158,12 +4710,6 @@ "node": ">=8" } }, - "node_modules/find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", - "license": "MIT" - }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -5553,21 +5099,6 @@ "node": ">= 0.4" } }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "license": "BSD-3-Clause", - "dependencies": { - "react-is": "^16.7.0" - } - }, - "node_modules/hoist-non-react-statics/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "license": "MIT" - }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", @@ -5582,6 +5113,7 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, "license": "MIT", "dependencies": { "parent-module": "^1.0.0", @@ -5678,12 +5210,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "license": "MIT" - }, "node_modules/is-async-function": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", @@ -5757,6 +5283,7 @@ "version": "2.15.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", + "dev": true, "license": "MIT", "dependencies": { "hasown": "^2.0.2" @@ -6536,6 +6063,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -6551,12 +6079,6 @@ "dev": true, "license": "MIT" }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "license": "MIT" - }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -6915,6 +6437,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, "license": "MIT" }, "node_modules/locate-path": { @@ -7082,6 +6605,7 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, "license": "MIT" }, "node_modules/mz": { @@ -7172,6 +6696,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -7358,6 +6883,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, "license": "MIT", "dependencies": { "callsites": "^3.0.0" @@ -7366,24 +6892,6 @@ "node": ">=6" } }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -7418,17 +6926,9 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, "license": "MIT" }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/pathe": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", @@ -7705,6 +7205,7 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.4.0", @@ -7716,6 +7217,7 @@ "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true, "license": "MIT" }, "node_modules/proxy-from-env": { @@ -7902,22 +7404,6 @@ } } }, - "node_modules/react-transition-group": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", - "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", - "license": "BSD-3-Clause", - "dependencies": { - "@babel/runtime": "^7.5.5", - "dom-helpers": "^5.0.1", - "loose-envify": "^1.4.0", - "prop-types": "^15.6.2" - }, - "peerDependencies": { - "react": ">=16.6.0", - "react-dom": ">=16.6.0" - } - }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -7998,6 +7484,7 @@ "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", @@ -8015,6 +7502,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -8259,15 +7747,6 @@ "node": ">=8" } }, - "node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -8473,12 +7952,6 @@ "dev": true, "license": "MIT" }, - "node_modules/stylis": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", - "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", - "license": "MIT" - }, "node_modules/sucrase": { "version": "3.35.1", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz", @@ -8506,6 +7979,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" diff --git a/package.json b/package.json index b790851..6cb08c2 100644 --- a/package.json +++ b/package.json @@ -11,15 +11,11 @@ "test": "vitest" }, "dependencies": { - "@emotion/react": "^11.11.4", - "@emotion/styled": "^11.11.5", "@fullcalendar/core": "^6.1.14", "@fullcalendar/daygrid": "^6.1.14", "@fullcalendar/interaction": "^6.1.14", "@fullcalendar/react": "^6.1.14", "@fullcalendar/timegrid": "^6.1.14", - "@mui/icons-material": "^5.15.20", - "@mui/material": "^5.15.20", "@radix-ui/react-collapsible": "^1.1.12", "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-dropdown-menu": "^2.1.16", diff --git a/src/components/generator/Calendar/CalendarComponent.jsx b/src/components/generator/Calendar/CalendarComponent.jsx index beabdb4..9aac6a0 100644 --- a/src/components/generator/Calendar/CalendarComponent.jsx +++ b/src/components/generator/Calendar/CalendarComponent.jsx @@ -63,7 +63,7 @@ export default function CalendarComponent({ useContext(CourseColorsContext); const [isTruncated, setIsTruncated] = useState(false); const [noTimetablesGenerated, setNoTimetablesGenerated] = useState(false); - const [noCourses, setNoCourses] = useState(true); + const [, setNoCourses] = useState(true); const [timeslotsOverridden, setTimeslotsOverridden] = useState(false); const [showWeekends, setShowWeekends] = useState(false); const [renameDialogOpen, setRenameDialogOpen] = useState(false); @@ -485,7 +485,6 @@ export default function CalendarComponent({ selectedDuration={selectedDuration} setSelectedDuration={setSelectedDuration} durations={durations} - noCourses={noCourses} sortByBracketContent={sortByBracketContent} /> diff --git a/src/components/generator/Calendar/CalendarNavBar.jsx b/src/components/generator/Calendar/CalendarNavBar.jsx index af1f2ea..fb0ffe7 100644 --- a/src/components/generator/Calendar/CalendarNavBar.jsx +++ b/src/components/generator/Calendar/CalendarNavBar.jsx @@ -1,11 +1,11 @@ -import React from "react"; -import { Box, useTheme } from "@mui/material"; -import NavigateBeforeIcon from "@mui/icons-material/NavigateBefore"; -import NavigateNextIcon from "@mui/icons-material/NavigateNext"; -import NavigateFirstIcon from "@mui/icons-material/FirstPage"; -import NavigateLastIcon from "@mui/icons-material/LastPage"; -import InfoIcon from "@mui/icons-material/Info"; -import CancelIcon from "@mui/icons-material/Cancel"; +import { + ChevronLeft, + ChevronRight, + ChevronsLeft, + ChevronsRight, + CircleX, + Info, +} from "lucide-react"; import { Button } from "@/components/ui/button"; import { Popover, @@ -45,37 +45,21 @@ export default function CalendarNavBar({ selectedDuration, setSelectedDuration, durations, - noCourses, sortByBracketContent, }) { - const theme = useTheme(); const navButtonClassName = "bg-red-600 text-white hover:bg-red-700 disabled:bg-red-600/40 transition-none"; const infoButtonBaseClassName = "transition-colors disabled:opacity-50 focus-visible:ring-0 focus-visible:ring-offset-0 hover:bg-accent/60"; return ( - - {isTruncated && ( @@ -87,7 +71,7 @@ export default function CalendarNavBar({ className={`${infoButtonBaseClassName} text-amber-600 hover:text-amber-600`} aria-label="View truncated results info" > - + @@ -115,7 +99,7 @@ export default function CalendarNavBar({ className={`${infoButtonBaseClassName} text-red-600 hover:text-red-600`} aria-label="View no timetables generated info" > - + @@ -143,7 +127,7 @@ export default function CalendarNavBar({ className={`${infoButtonBaseClassName} text-sky-600 hover:text-sky-600`} aria-label="View time block overlap info" > - + @@ -162,76 +146,61 @@ export default function CalendarNavBar({ )} - - +
- +
- - +
+
- - +
{currentTimetableIndex + 1} of {timetables.length} - - +
+
- - +
+
- - - +
+
- - +
+
); } diff --git a/src/components/generator/Calendar/CourseTimelineComponent.jsx b/src/components/generator/Calendar/CourseTimelineComponent.jsx index 4114447..a0cbf84 100644 --- a/src/components/generator/Calendar/CourseTimelineComponent.jsx +++ b/src/components/generator/Calendar/CourseTimelineComponent.jsx @@ -1,9 +1,4 @@ import React, { useContext, useState } from "react"; -import Box from "@mui/material/Box"; -import Typography from "@mui/material/Typography"; -import Tooltip from "@mui/material/Tooltip"; -import Fade from "@mui/material/Fade"; -import { alpha } from "@mui/material/styles"; import { CourseDetailsContext } from "@/lib/contexts/generator/CourseDetailsContext"; import { CourseColorsContext } from "@/lib/contexts/generator/CourseColorsContext"; @@ -84,15 +79,15 @@ export default function CourseTimelineComponent({ return ( durCode === durationCode && // Allow some flexibility in date matching (within 2 weeks) - Math.abs(parseInt(durStartUnix) - startTimestamp) < 1209600 && - Math.abs(parseInt(durEndUnix) - endTimestamp) < 1209600 + Math.abs(parseInt(durStartUnix, 10) - startTimestamp) < 1209600 && + Math.abs(parseInt(durEndUnix, 10) - endTimestamp) < 1209600 ); }); // If no exact match, try to find by duration code only if (!matchedDuration) { matchedDuration = durations.find((d) => { - const [_, __, durCode] = d.split("-"); + const [, , durCode] = d.split("-"); return durCode === durationCode; }); } @@ -104,8 +99,10 @@ export default function CourseTimelineComponent({ durations.forEach((d) => { const [durStartUnix, durEndUnix] = d.split("-"); - const startDiff = Math.abs(parseInt(durStartUnix) - startTimestamp); - const endDiff = Math.abs(parseInt(durEndUnix) - endTimestamp); + const startDiff = Math.abs( + parseInt(durStartUnix, 10) - startTimestamp, + ); + const endDiff = Math.abs(parseInt(durEndUnix, 10) - endTimestamp); const totalDiff = startDiff + endDiff; if (totalDiff < smallestDiff) { @@ -126,7 +123,7 @@ export default function CourseTimelineComponent({ if (course.startDate && navigateToDate) { const dayOfWeek = course.startDate.getDay(); // 0 = Sunday, 1 = Monday, ..., 6 = Saturday - let navigationDate = new Date(course.startDate); + const navigationDate = new Date(course.startDate); // If classes start on Tuesday-Saturday, navigate to the following week // so we can see the full recurring pattern (Monday-Friday) @@ -175,11 +172,11 @@ export default function CourseTimelineComponent({ const handleTimelineMouseMove = (event) => { try { const rect = event.currentTarget.getBoundingClientRect(); - const clickX = event.clientX - rect.left; - const clickPercent = (clickX / rect.width) * 100; + const hoverX = event.clientX - rect.left; + const hoverPercent = (hoverX / rect.width) * 100; // Calculate the date based on click position - const dayOffset = (clickPercent / 100) * totalDays; + const dayOffset = (hoverPercent / 100) * totalDays; const hoverDate = new Date( earliestDate.getTime() + dayOffset * 24 * 60 * 60 * 1000, ); @@ -189,8 +186,9 @@ export default function CourseTimelineComponent({ if (closestDuration) { const [startUnix] = closestDuration.split("-"); const startDate = parseUnixTimestamp(startUnix); - const dayOffset = (startDate - earliestDate) / (1000 * 60 * 60 * 24); - const position = (dayOffset / totalDays) * 100; + const daysFromStart = + (startDate - earliestDate) / (1000 * 60 * 60 * 24); + const position = (daysFromStart / totalDays) * 100; setMousePosition(position); } } catch (error) { @@ -291,24 +289,9 @@ export default function CourseTimelineComponent({ if (!coursesWithDates.length) { return ( - - - No valid course date information available - - +
+ No valid course date information available +
); } @@ -372,66 +355,23 @@ export default function CourseTimelineComponent({ } } + const timelineHeight = coursesWithDates.length * 24 + 20; + return ( - +
{/* Timeline container */} - alpha(theme.palette.action.hover, 0.04), - }, - }} + className="relative w-full cursor-pointer overflow-hidden rounded-md border border-border transition-colors hover:bg-muted/40" + style={{ height: timelineHeight }} > - {/* Background with subtle grid */} - - {/* Preview line */} {mousePosition !== null && ( - - alpha(theme.palette.primary.main, 0.3), - zIndex: 4, - pointerEvents: "none", - transition: "left 0.1s ease-out", - }} +
)} @@ -439,43 +379,18 @@ export default function CourseTimelineComponent({ {monthMarkers.map((marker, index) => ( {/* Vertical line */} - {/* Month label - only show every other month if there are many months */} {(monthMarkers.length <= 12 || index % 2 === 0) && ( - alpha(theme.palette.text.secondary, 0.9), - fontSize: "0.65rem", - fontWeight: 500, - whiteSpace: "nowrap", - pointerEvents: "none", - textShadow: (theme) => - theme.palette.mode === "dark" - ? "0 1px 2px rgba(0,0,0,0.3)" - : "0 1px 0 rgba(255,255,255,0.8)", - }} +
{marker.label} - +
)}
))} @@ -498,177 +413,69 @@ export default function CourseTimelineComponent({ const position = (dayOffset / totalDays) * 100; return ( - <> - theme.palette.primary.main, - zIndex: 5, - pointerEvents: "none", - animation: "pulse 2s infinite", - "@keyframes pulse": { - "0%": { - opacity: 0.4, - }, - "50%": { - opacity: 1, - }, - "100%": { - opacity: 0.4, - }, - }, - }} - /> - +
); } return null; })()} {/* Course bars with labels */} - {coursesWithDates.map((course, index) => ( - - {/* Course label */} - - { + const tooltipText = `${course.fullName}: ${formatDate( + course.startDate, + )} - ${formatDate(course.endDate)}`; + const isHovered = hoveredCourse === course.id; + const topOffset = 12 + index * 24; + + return ( + + {/* Course label */} +
handleCourseClick(course, event)} onMouseEnter={() => setHoveredCourse(course.id)} onMouseLeave={() => setHoveredCourse(null)} - sx={{ - position: "absolute", + className={`absolute z-40 flex h-3 -translate-y-1/2 items-center whitespace-nowrap rounded-sm px-1 text-[0.65rem] font-semibold text-foreground shadow-sm transition ${ + isHovered ? "bg-background" : "bg-background/90" + }`} + style={{ left: `${course.startPercent}%`, - top: 12 + index * 24, - height: "12px", - transform: "translateY(-50%)", - fontSize: "0.65rem", - fontWeight: 600, - color: (theme) => theme.palette.text.primary, - whiteSpace: "nowrap", - marginLeft: "4px", - zIndex: 4, - display: "flex", - alignItems: "center", - textShadow: (theme) => - theme.palette.mode === "dark" - ? "0 1px 2px rgba(0,0,0,0.5)" - : "0 1px 0 rgba(255,255,255,0.9)", - backgroundColor: (theme) => - alpha(theme.palette.background.paper, 0.85), - padding: "0 4px", - borderRadius: "3px", - cursor: "pointer", - transition: "all 0.15s cubic-bezier(0.4, 0, 0.2, 1)", - boxShadow: - hoveredCourse === course.id - ? (theme) => - `0 2px 4px ${alpha( - course.color, - 0.4, - )}, 0 0 1px ${alpha(theme.palette.common.black, 0.2)}` - : "none", - "&:hover": { - backgroundColor: (theme) => - alpha(theme.palette.background.paper, 0.95), - }, - "&:active": { - transform: "translateY(-45%) scale(0.98)", - }, + top: topOffset, }} > {course.code} - - - - {/* Course bar */} - - + + {/* Course bar */} +
setHoveredCourse(course.id)} onMouseLeave={() => setHoveredCourse(null)} onClick={(event) => handleCourseClick(course, event)} - sx={{ - position: "absolute", + className={`absolute h-3 rounded-md transition ${ + isHovered ? "shadow-md" : "shadow-sm" + }`} + style={{ left: `${course.startPercent}%`, - top: 12 + index * 24, + top: topOffset, width: `${course.widthPercent}%`, - height: "12px", backgroundColor: course.color, - opacity: hoveredCourse === course.id ? 1 : 0.85, - borderRadius: "6px", - cursor: "pointer", - transition: "all 0.15s cubic-bezier(0.4, 0, 0.2, 1)", - transform: - hoveredCourse === course.id ? "translateY(-1px)" : "none", - boxShadow: - hoveredCourse === course.id - ? (theme) => - `0 2px 4px ${alpha( - course.color, - 0.4, - )}, 0 0 1px ${alpha(theme.palette.common.black, 0.2)}` - : "none", - "&:hover": { - opacity: 1, - transform: "translateY(-1px)", - }, - "&:active": { - transform: "translateY(0px) scale(0.98)", - transition: "all 0.1s cubic-bezier(0.4, 0, 0.2, 1)", - }, - zIndex: hoveredCourse === course.id ? 3 : 2, + opacity: isHovered ? 1 : 0.85, }} /> - - - ))} - + + ); + })} +
{/* Date range indicators at the bottom */} - - - {formatDate(earliestDate)} - - - {formatDate(latestDate)} - - -
+
+ {formatDate(earliestDate)} + {formatDate(latestDate)} +
+
); } diff --git a/src/components/generator/Calendar/utils/calendarUtils.jsx b/src/components/generator/Calendar/utils/calendarUtils.jsx index 97301ee..8056698 100644 --- a/src/components/generator/Calendar/utils/calendarUtils.jsx +++ b/src/components/generator/Calendar/utils/calendarUtils.jsx @@ -1,6 +1,4 @@ -import React from "react"; -import BlockIcon from "@mui/icons-material/Block"; -import PinIcon from "@mui/icons-material/PushPin"; +import { Ban, Pin } from "lucide-react"; import { isEventPinned } from "@/lib/generator/createCalendarEvents"; import { getCourseData } from "@/lib/generator/courseData"; @@ -46,7 +44,7 @@ export const renderEventContent = (eventInfo, isMobile = false) => { }} > - +
@@ -84,7 +82,7 @@ export const renderEventContent = (eventInfo, isMobile = false) => { fontSize: "4rem", }} > - +
)}
diff --git a/src/components/generator/Dialogs/RenameBlockedSlotDialog.jsx b/src/components/generator/Dialogs/RenameBlockedSlotDialog.jsx index 88ce805..2864ce1 100644 --- a/src/components/generator/Dialogs/RenameBlockedSlotDialog.jsx +++ b/src/components/generator/Dialogs/RenameBlockedSlotDialog.jsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect, useRef } from "react"; +import { useState, useEffect, useRef } from "react"; import { cn } from "@/lib/utils"; import { Popover, diff --git a/src/components/generator/Export/ExportAsComponent.jsx b/src/components/generator/Export/ExportAsComponent.jsx index 7e2d99e..a7c1a1c 100644 --- a/src/components/generator/Export/ExportAsComponent.jsx +++ b/src/components/generator/Export/ExportAsComponent.jsx @@ -1,8 +1,4 @@ -import * as React from "react"; -import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; -import ImageIcon from "@mui/icons-material/Image"; -import PictureAsPdfIcon from "@mui/icons-material/PictureAsPdf"; -import TableChartIcon from "@mui/icons-material/TableChart"; +import { ChevronDown, FileImage, FileText, Table } from "lucide-react"; import { Button } from "@/components/ui/button"; import { DropdownMenu, @@ -35,20 +31,20 @@ export default function ExportAsComponent() { - + PNG - + PDF - + Excel Sheet diff --git a/src/components/generator/Export/ExportCalendarButton.jsx b/src/components/generator/Export/ExportCalendarButton.jsx index 098c78e..00c91b7 100644 --- a/src/components/generator/Export/ExportCalendarButton.jsx +++ b/src/components/generator/Export/ExportCalendarButton.jsx @@ -1,4 +1,4 @@ -import React, { useMemo, useState } from "react"; +import { useMemo, useState } from "react"; import { Button } from "@/components/ui/button"; import { exportCal } from "@/lib/generator/ExportCal.js"; import { getVisibleTimetables } from "@/components/generator/Calendar/utils/calendarViewUtils.js"; diff --git a/src/components/generator/Forms/CourseList/CourseList.jsx b/src/components/generator/Forms/CourseList/CourseList.jsx index 238f091..ff59a78 100644 --- a/src/components/generator/Forms/CourseList/CourseList.jsx +++ b/src/components/generator/Forms/CourseList/CourseList.jsx @@ -1,4 +1,3 @@ -import React from "react"; import CourseListComponent from "./CourseListComponent"; import BorderBox from "../../UI/BorderBox"; diff --git a/src/components/generator/Forms/CourseList/CourseListComponent.jsx b/src/components/generator/Forms/CourseList/CourseListComponent.jsx index 015eac1..9daa4f0 100644 --- a/src/components/generator/Forms/CourseList/CourseListComponent.jsx +++ b/src/components/generator/Forms/CourseList/CourseListComponent.jsx @@ -1,4 +1,4 @@ -import React, { useContext } from "react"; +import { useContext } from "react"; import CourseListItemComponent from "./CourseListItemComponent"; import { CourseDetailsContext } from "@/lib/contexts/generator/CourseDetailsContext"; diff --git a/src/components/generator/Forms/CourseList/CourseListItemComponent.jsx b/src/components/generator/Forms/CourseList/CourseListItemComponent.jsx index c6312ff..8fd1fa1 100644 --- a/src/components/generator/Forms/CourseList/CourseListItemComponent.jsx +++ b/src/components/generator/Forms/CourseList/CourseListItemComponent.jsx @@ -1,9 +1,6 @@ import React, { useContext, useEffect } from "react"; -import ExpandLess from "@mui/icons-material/ExpandLess"; -import ExpandMore from "@mui/icons-material/ExpandMore"; -import DeleteIcon from "@mui/icons-material/Delete"; +import { ChevronDown, ChevronUp, Palette, Trash2 } from "lucide-react"; import { CourseColorsContext } from "@/lib/contexts/generator/CourseColorsContext"; -import ColorLensIcon from "@mui/icons-material/ColorLens"; import { clearCoursePins } from "@/lib/generator/pinnedComponents"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; @@ -90,7 +87,7 @@ export default function CourseListComponent({ onClick={(e) => e.stopPropagation()} style={{ backgroundColor: currentColor }} > - + - + {open ? ( - + ) : ( - + )} diff --git a/src/components/generator/Forms/InputFormBottomComponent.jsx b/src/components/generator/Forms/InputFormBottomComponent.jsx index 69155d1..da5ca0a 100644 --- a/src/components/generator/Forms/InputFormBottomComponent.jsx +++ b/src/components/generator/Forms/InputFormBottomComponent.jsx @@ -1,9 +1,5 @@ -import React from "react"; -import Box from "@mui/material/Box"; -import Grid from "@mui/material/Grid"; import CourseList from "./CourseList/CourseList"; import PerformanceMetrics from "./Settings/PerformanceMetrics"; -import Tips from "./Settings/Tips"; import ExportOptions from "./Settings/ExportOptions"; import { removeCourseData } from "@/lib/generator/courseData"; import { removePinnedComponent } from "@/lib/generator/pinnedComponents"; @@ -30,28 +26,16 @@ export default function InputFormBottomComponent({ }; return ( - - - - - - {/* - - */} - {process.env.NODE_ENV === "development" && ( - - - - )} - - - - - +
+ + {/* */} + {process.env.NODE_ENV === "development" && } + +
); } diff --git a/src/components/generator/Forms/InputFormTopComponent.jsx b/src/components/generator/Forms/InputFormTopComponent.jsx index 4bfd75d..4f45e91 100644 --- a/src/components/generator/Forms/InputFormTopComponent.jsx +++ b/src/components/generator/Forms/InputFormTopComponent.jsx @@ -1,6 +1,4 @@ -import React, { useState, useEffect, useRef } from "react"; -import Box from "@mui/material/Box"; -import Grid from "@mui/material/Grid"; +import { useState, useEffect, useRef } from "react"; import { useSnackbar } from "notistack"; import ReactGA from "react-ga4"; @@ -213,28 +211,22 @@ export default function InputFormTop({ }; return ( - - - - - - - - - - +
+ + +
); } diff --git a/src/components/generator/Forms/Settings/CourseOptions.jsx b/src/components/generator/Forms/Settings/CourseOptions.jsx index f335d22..9beb46b 100644 --- a/src/components/generator/Forms/Settings/CourseOptions.jsx +++ b/src/components/generator/Forms/Settings/CourseOptions.jsx @@ -1,5 +1,3 @@ -import React from "react"; -import Box from "@mui/material/Box"; import TimeTableSelectComponent from "../CourseSearch/TimeTableSelectComponent"; import TermSelectComponent from "../CourseSearch/TermSelectComponent"; import CourseSearchComponent from "../CourseSearch/CourseSearchComponent"; @@ -18,19 +16,19 @@ export default function CourseOptions({ }) { return ( - - - - - +
+ + + +
); } diff --git a/src/components/generator/Forms/Settings/ExportOptions.jsx b/src/components/generator/Forms/Settings/ExportOptions.jsx index d043505..da765a0 100644 --- a/src/components/generator/Forms/Settings/ExportOptions.jsx +++ b/src/components/generator/Forms/Settings/ExportOptions.jsx @@ -1,4 +1,4 @@ -import React, { useState } from "react"; +import { useState } from "react"; import BorderBox from "../../UI/BorderBox"; import ExportCalendarButton from "../../Export/ExportCalendarButton"; import { Info, ChevronDown, ChevronUp } from "lucide-react"; diff --git a/src/components/generator/Forms/Settings/PerformanceMetrics.jsx b/src/components/generator/Forms/Settings/PerformanceMetrics.jsx index 151bc6b..53a6fe3 100644 --- a/src/components/generator/Forms/Settings/PerformanceMetrics.jsx +++ b/src/components/generator/Forms/Settings/PerformanceMetrics.jsx @@ -1,5 +1,3 @@ -import React from "react"; -import { Typography, Box } from "@mui/material"; import BorderBox from "../../UI/BorderBox"; import { getGenerationPerformance } from "@/lib/generator/timetableGeneration/timetableGeneration"; @@ -34,24 +32,20 @@ export default function PerformanceMetrics() { return ( - - Generation Performance - - - - Generation Time: {formattedTime} - - +
+
+ Generation Performance +
+
Generation Time: {formattedTime}
+
Combinations Processed:{" "} {metrics.totalCombinationsProcessed.toLocaleString()} - - +
+
Valid Timetables: {metrics.validTimetablesFound.toLocaleString()} - - - Combinations/Second: {combinationsPerSecond.toLocaleString()} - - +
+
Combinations/Second: {combinationsPerSecond.toLocaleString()}
+
); } diff --git a/src/components/generator/Forms/Settings/SortDropdown.jsx b/src/components/generator/Forms/Settings/SortDropdown.jsx index bfb5ae4..e867cac 100644 --- a/src/components/generator/Forms/Settings/SortDropdown.jsx +++ b/src/components/generator/Forms/Settings/SortDropdown.jsx @@ -1,5 +1,3 @@ -import React from "react"; -import Box from "@mui/material/Box"; import { Select, SelectContent, @@ -10,17 +8,15 @@ import { export default function SortDropdown({ value, onValueChange }) { return ( - - - + ); } diff --git a/src/components/generator/Forms/Settings/SortOptions.jsx b/src/components/generator/Forms/Settings/SortOptions.jsx index 4f332c8..c58481b 100644 --- a/src/components/generator/Forms/Settings/SortOptions.jsx +++ b/src/components/generator/Forms/Settings/SortOptions.jsx @@ -1,4 +1,3 @@ -import React from "react"; import SortDropdown from "./SortDropdown"; import BorderBox from "../../UI/BorderBox"; diff --git a/src/components/generator/Forms/Settings/Tips.jsx b/src/components/generator/Forms/Settings/Tips.jsx index 3a8cfef..efceda2 100644 --- a/src/components/generator/Forms/Settings/Tips.jsx +++ b/src/components/generator/Forms/Settings/Tips.jsx @@ -1,20 +1,15 @@ -import React from "react"; import BorderBox from "../../UI/BorderBox"; -import List from "@mui/material/List"; -import ListItem from "@mui/material/ListItem"; -import ListItemText from "@mui/material/ListItemText"; export default function Tips() { return ( - - - - - - - - +
    +
  • Pin a course section by clicking on it in the calendar.
  • +
  • + Block out a time slot by clicking and dragging over the desired time + in the calendar. +
  • +
); } diff --git a/src/components/generator/UI/BorderBox.jsx b/src/components/generator/UI/BorderBox.jsx index bb9929e..92e07cf 100644 --- a/src/components/generator/UI/BorderBox.jsx +++ b/src/components/generator/UI/BorderBox.jsx @@ -1,92 +1,81 @@ -import React, { useState } from "react"; -import Box from "@mui/material/Box"; -import IconButton from "@mui/material/IconButton"; -import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; -import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp"; -import Collapse from "@mui/material/Collapse"; +import { useRef, useState } from "react"; +import { ChevronDown } from "lucide-react"; export default function BorderBox({ title, children }) { const [isExpanded, setIsExpanded] = useState(true); + const [contentHeight, setContentHeight] = useState(0); + const [isAnimating, setIsAnimating] = useState(false); + const [maxHeight, setMaxHeight] = useState("none"); + const contentRef = useRef(null); - const toggleExpand = () => { - setIsExpanded(!isExpanded); + const measureContentHeight = () => + contentRef.current ? contentRef.current.scrollHeight : 0; + const transitionDuration = Math.min( + 320, + Math.max(140, Math.round(120 + contentHeight / 4)), + ); + const opacityDuration = Math.max(120, Math.round(transitionDuration * 0.7)); + const transition = isAnimating + ? `max-height ${transitionDuration}ms ease, opacity ${opacityDuration}ms ease` + : "none"; + + const handleToggle = () => { + const measuredHeight = measureContentHeight(); + setContentHeight(measuredHeight); + setIsAnimating(true); + + if (isExpanded) { + setMaxHeight(`${measuredHeight}px`); + requestAnimationFrame(() => { + requestAnimationFrame(() => { + setMaxHeight("0px"); + }); + }); + } else { + setMaxHeight(`${measuredHeight}px`); + } + + setIsExpanded((prev) => !prev); + }; + + const handleTransitionEnd = (event) => { + if (event.propertyName !== "max-height") return; + setIsAnimating(false); + if (isExpanded) { + setMaxHeight("none"); + } }; return ( - ({ - xs: `1px solid ${theme.palette.primary.main}`, - sm: `1px solid ${theme.palette.primary.main}`, - }), - borderTop: (theme) => ({ - xs: `none`, - sm: `1px solid ${theme.palette.primary.main}`, - }), - borderLeft: (theme) => ({ - xs: "none", - sm: `1px solid ${theme.palette.primary.main}`, - }), - borderRight: (theme) => ({ - xs: "none", - sm: `1px solid ${theme.palette.primary.main}`, - }), - borderRadius: { - xs: "0px", - sm: "8px", - }, - width: { - xs: "100vw", - sm: "auto", - }, - marginLeft: { - xs: "calc(-50vw + 50%)", - sm: "0", - }, - marginRight: { - xs: "calc(-50vw + 50%)", - sm: "0", - }, - overflow: "hidden", - transition: "all 0.3s ease", - }} - > - + +
+
+ {children} +
+
+ ); } diff --git a/src/components/sitewide/FooterComponent.jsx b/src/components/sitewide/FooterComponent.jsx index a767dec..0e561b2 100644 --- a/src/components/sitewide/FooterComponent.jsx +++ b/src/components/sitewide/FooterComponent.jsx @@ -1,4 +1,3 @@ -import React from "react"; import { Github } from "lucide-react"; import { Button } from "@/components/ui/button"; diff --git a/src/components/sitewide/MultiLineSnackbar.jsx b/src/components/sitewide/MultiLineSnackbar.jsx index eddad44..6ca5501 100644 --- a/src/components/sitewide/MultiLineSnackbar.jsx +++ b/src/components/sitewide/MultiLineSnackbar.jsx @@ -1,18 +1,16 @@ -import React from "react"; import { SnackbarContent } from "notistack"; -import { Typography } from "@mui/material"; const MultiLineSnackbar = ({ message }) => { return ( - +
{message.split("\n").map((line, index) => ( {line}
))} - +
); }; diff --git a/src/components/sitewide/NavbarComponent.jsx b/src/components/sitewide/NavbarComponent.jsx index 3ceed30..f51703f 100644 --- a/src/components/sitewide/NavbarComponent.jsx +++ b/src/components/sitewide/NavbarComponent.jsx @@ -1,5 +1,4 @@ -import React, { useContext, useState } from "react"; -import { useTheme } from "@mui/material/styles"; +import { useContext, useState } from "react"; import ColorModeContext from "@/lib/contexts/sitewide/ColorModeContext"; import { Link } from "react-router-dom"; import { useIsMobile } from "@/lib/utils/screenSizeUtils"; @@ -23,7 +22,6 @@ import { import { Separator } from "@/components/ui/separator"; const NavbarComponent = () => { - const theme = useTheme(); const colorMode = useContext(ColorModeContext); const isMobile = useIsMobile(); const [drawerOpen, setDrawerOpen] = useState(false); @@ -122,7 +120,7 @@ const NavbarComponent = () => { onClick={colorMode.toggleColorMode} aria-label="Toggle theme" > - {theme.palette.mode === "dark" ? ( + {colorMode.mode === "dark" ? ( ) : ( @@ -161,7 +159,7 @@ const NavbarComponent = () => { onClick={colorMode.toggleColorMode} aria-label="Toggle theme" > - {theme.palette.mode === "dark" ? ( + {colorMode.mode === "dark" ? ( ) : ( diff --git a/src/components/sitewide/SnackbarProvider.jsx b/src/components/sitewide/SnackbarProvider.jsx index 7be0572..a6c0e9c 100644 --- a/src/components/sitewide/SnackbarProvider.jsx +++ b/src/components/sitewide/SnackbarProvider.jsx @@ -1,4 +1,4 @@ -import React, { useEffect } from "react"; +import { useEffect } from "react"; import { SnackbarProvider, useSnackbar } from "notistack"; import eventBus from "@/lib/eventBus"; diff --git a/src/lib/contexts/generator/CourseColorsContext.jsx b/src/lib/contexts/generator/CourseColorsContext.jsx index 5bfd41f..d4771e9 100644 --- a/src/lib/contexts/generator/CourseColorsContext.jsx +++ b/src/lib/contexts/generator/CourseColorsContext.jsx @@ -1,10 +1,4 @@ -import React, { - createContext, - useState, - useRef, - useCallback, - useEffect, -} from "react"; +import { createContext, useState, useRef, useCallback, useEffect } from "react"; // Visually distinguishable colors that work well for both light and dark themes // Colors are ordered to maximize contrast between consecutive colors diff --git a/src/lib/contexts/generator/CourseDetailsContext.jsx b/src/lib/contexts/generator/CourseDetailsContext.jsx index 3fe546d..57e95ce 100644 --- a/src/lib/contexts/generator/CourseDetailsContext.jsx +++ b/src/lib/contexts/generator/CourseDetailsContext.jsx @@ -1,4 +1,4 @@ -import React, { createContext, useState } from "react"; +import { createContext, useState } from "react"; export const CourseDetailsContext = createContext(); diff --git a/src/lib/contexts/sitewide/ColorModeContext.jsx b/src/lib/contexts/sitewide/ColorModeContext.jsx index 285a819..d2096f6 100644 --- a/src/lib/contexts/sitewide/ColorModeContext.jsx +++ b/src/lib/contexts/sitewide/ColorModeContext.jsx @@ -1,5 +1,8 @@ import { createContext } from "react"; -const ColorModeContext = createContext({ toggleColorMode: () => {} }); +const ColorModeContext = createContext({ + mode: "light", + toggleColorMode: () => {}, +}); export default ColorModeContext; diff --git a/src/lib/utils/screenSizeUtils.js b/src/lib/utils/screenSizeUtils.js index bd0327b..3b886c7 100644 --- a/src/lib/utils/screenSizeUtils.js +++ b/src/lib/utils/screenSizeUtils.js @@ -1,11 +1,25 @@ -import { useMediaQuery, useTheme } from "@mui/material"; +import { useEffect, useState } from "react"; -export const useIsMobile = () => { - const theme = useTheme(); - return useMediaQuery(theme.breakpoints.down("sm")); -}; +const useMediaQuery = (query) => { + const getMatch = () => { + if (typeof window === "undefined") return false; + return window.matchMedia(query).matches; + }; + + const [matches, setMatches] = useState(getMatch); + + useEffect(() => { + if (typeof window === "undefined") return undefined; + const mediaQueryList = window.matchMedia(query); + const handleChange = (event) => setMatches(event.matches); + mediaQueryList.addEventListener("change", handleChange); + setMatches(mediaQueryList.matches); + return () => mediaQueryList.removeEventListener("change", handleChange); + }, [query]); -export const useIsBelowMedium = () => { - const theme = useTheme(); - return useMediaQuery(theme.breakpoints.down("md")); + return matches; }; + +export const useIsMobile = () => useMediaQuery("(max-width: 639px)"); + +export const useIsBelowMedium = () => useMediaQuery("(max-width: 767px)"); diff --git a/src/main.jsx b/src/main.jsx index db53e51..ddcf5e1 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -1,10 +1,8 @@ -import React, { useMemo, useState, useEffect } from "react"; +import { useMemo, useState, useEffect } from "react"; import ReactDOM from "react-dom/client"; import { BrowserRouter as Router, Route, Routes } from "react-router-dom"; import GeneratorPage from "@/pages/GeneratorPage"; import GuidePage from "@/pages/GuidePage"; -import { ThemeProvider, createTheme } from "@mui/material/styles"; -import CssBaseline from "@mui/material/CssBaseline"; import ColorModeContext from "@/lib/contexts/sitewide/ColorModeContext"; import CustomSnackbarProvider from "@/components/sitewide/SnackbarProvider"; import ReactGA from "react-ga4"; @@ -33,6 +31,7 @@ const App = () => { const colorMode = useMemo( () => ({ + mode, toggleColorMode: () => { setMode((prevMode) => { const nextMode = prevMode === "light" ? "dark" : "light"; @@ -43,62 +42,6 @@ const App = () => { }); }, }), - [], - ); - - const theme = useMemo( - () => - createTheme({ - palette: { - mode: mode, - primary: { - main: "hsl(0 72% 50%)", - light: "hsl(0 72% 60%)", - dark: "hsl(0 72% 40%)", - contrastText: "#ffffff", - }, - secondary: { - main: "#ffcdd2", - light: "#ffebee", - dark: "#ef9a9a", - contrastText: "#000000", - }, - error: { - main: "#f44336", - light: "#e57373", - dark: "#d32f2f", - contrastText: "#ffffff", - }, - warning: { - main: "#ff9800", - light: "#ffb74d", - dark: "#f57c00", - contrastText: "#000000", - }, - info: { - main: "#2196f3", - light: "#64b5f6", - dark: "#1976d2", - contrastText: "#ffffff", - }, - success: { - main: "#4caf50", - light: "#81c784", - dark: "#388e3c", - contrastText: "#ffffff", - }, - background: { - default: "hsl(var(--background))", - paper: "hsl(var(--card))", - }, - text: { - primary: mode === "light" ? "#000000" : "#ffffff", - secondary: mode === "light" ? "#73767f" : "#b0b3b8", - }, - divider: mode === "light" ? "#e0e0e0" : "#424242", - outline: mode === "light" ? "#b0b0b0" : "#616161", - }, - }), [mode], ); @@ -119,41 +62,17 @@ const App = () => { }, []); useEffect(() => { - document.documentElement.style.setProperty( - "--theme-divider-color", - theme.palette.divider, - ); - document.documentElement.style.setProperty( - "--theme-outline-color", - theme.palette.outline, - ); - // Update background colors when theme changes - document.documentElement.style.backgroundColor = - theme.palette.background.default; - document.body.style.backgroundColor = theme.palette.background.default; - // Update theme classes - document.body.classList.toggle("light-mode", mode === "light"); - document.body.classList.toggle("dark-mode", mode === "dark"); - document.documentElement.classList.toggle("light-mode", mode === "light"); - document.documentElement.classList.toggle("dark-mode", mode === "dark"); document.documentElement.classList.toggle("dark", mode === "dark"); - }, [ - theme.palette.divider, - theme.palette.outline, - theme.palette.background.default, - mode, - ]); + document.documentElement.style.colorScheme = mode; + }, [mode]); return ( - - - - } /> - } /> - - + + } /> + } /> + ); diff --git a/src/pages/GeneratorPage.jsx b/src/pages/GeneratorPage.jsx index 11b29a8..69cd9f1 100644 --- a/src/pages/GeneratorPage.jsx +++ b/src/pages/GeneratorPage.jsx @@ -5,9 +5,6 @@ import { InputFormBottomComponent, InputFormTopComponent, } from "@/components/generator"; -import CssBaseline from "@mui/material/CssBaseline"; -import Grid from "@mui/material/Grid"; -import Box from "@mui/material/Box"; import { useIsBelowMedium } from "@/lib/utils/screenSizeUtils"; import { CourseDetailsProvider } from "@/lib/contexts/generator/CourseDetailsContext"; import { @@ -20,14 +17,8 @@ import { generateTimetables, getValidTimetables, } from "@/lib/generator/timetableGeneration/timetableGeneration"; -import { - removeCourseData, - clearAllCourseData, -} from "@/lib/generator/courseData"; -import { - clearCoursePins, - clearAllPins, -} from "@/lib/generator/pinnedComponents"; +import { clearAllCourseData } from "@/lib/generator/courseData"; +import { clearAllPins } from "@/lib/generator/pinnedComponents"; import FooterComponent from "@/components/sitewide/FooterComponent"; function GeneratorPage() { @@ -59,15 +50,6 @@ function GeneratorPage() { }; }, []); - const removeCourse = (course) => { - const cleanCourseCode = course.split(" ").slice(0, 2).join(""); - setAddedCourses(addedCourses.filter((c) => c !== course)); - removeCourseData(cleanCourseCode); - clearCoursePins(cleanCourseCode); - generateTimetables(sortOption); - setTimetables(getValidTimetables()); - }; - return ( @@ -77,20 +59,12 @@ function GeneratorPage() { setTimetables={setTimetables} sortOption={sortOption} /> - - - +
+
- - - +
+
+
{!isBelowMedium && ( - +
- +
)} -
- - - +
+
+
+
- - +
+
{isBelowMedium && ( - - +
+
- - +
+
)} -
+
-
- +
+
); diff --git a/src/pages/GuidePage.jsx b/src/pages/GuidePage.jsx index e4cb88a..806bfd5 100644 --- a/src/pages/GuidePage.jsx +++ b/src/pages/GuidePage.jsx @@ -1,22 +1,15 @@ -import React, { useEffect, useState } from "react"; -import { NavbarComponent } from "@/components/guide"; -import CssBaseline from "@mui/material/CssBaseline"; -import Grid from "@mui/material/Grid"; -import Box from "@mui/material/Box"; -import { useIsBelowMedium } from "@/lib/utils/screenSizeUtils"; +import { useEffect, useState } from "react"; +import { Link } from "react-router-dom"; import ReactGA from "react-ga4"; -import Typography from "@mui/material/Typography"; -import Link from "@mui/material/Link"; -import List from "@mui/material/List"; -import ListItem from "@mui/material/ListItem"; -import ListItemText from "@mui/material/ListItemText"; -import Collapse from "@mui/material/Collapse"; -import { ListItemButton } from "@mui/material"; -import ExpandLess from "@mui/icons-material/ExpandLess"; -import ExpandMore from "@mui/icons-material/ExpandMore"; -import { useTheme } from "@mui/material/styles"; -import Divider from "@mui/material/Divider"; +import { NavbarComponent } from "@/components/guide"; import FooterComponent from "@/components/sitewide/FooterComponent"; +import { + Collapsible, + CollapsibleContent, + CollapsibleTrigger, +} from "@/components/ui/collapsible"; +import { Separator } from "@/components/ui/separator"; +import { ChevronDown, ChevronUp } from "lucide-react"; function GuidePage() { useEffect(() => { @@ -27,412 +20,355 @@ function GuidePage() { title: "Brock Visual Guide", }); }, []); - const isBelowMedium = useIsBelowMedium(); - const theme = useTheme(); + const [openCourseCode, setOpenCourseCode] = useState(false); const [openAndOr, setOpenAndOr] = useState(false); const [openTermSpecific, setOpenTermSpecific] = useState(false); const [openContextCredits, setOpenContextCredits] = useState(false); const [openElectiveCredits, setOpenElectiveCredits] = useState(false); - const handleCourseCodeClick = () => { - setOpenCourseCode(!openCourseCode); - }; - - const handleAndOrClick = () => { - setOpenAndOr(!openAndOr); - }; + const Disclosure = ({ title, open, onOpenChange, children }) => ( + +
+ + + + +
+ {children} +
+
+
+
+ ); - const handleTermSpecificClick = () => { - setOpenTermSpecific(!openTermSpecific); - }; + return ( +
+
+ +
+
+
+

+ Guide to Course Registration +

+

+ Welcome to the Brock Visual TimeTable! This guide will help you + learn everything you need to know about course planning & + registration at Brock University. This guide is written by + students, for students. We understand the struggles of course + registration and have created this platform to help you make the + process easier. +

+

+ In this guide, you will learn how to find your courses, plan + your schedule, and register for courses. This guide is designed + to be simple and easy to follow. This guide is for all students + at Brock University, including first-year students, upper-year + students, and transfer students. +

+

+ This guide will be running through creating a first-year + computer science co-op student's timetable. The process is + the same for all students, but the courses you need to take will + be different. +

+

+ The Brock Visual TimeTable is not affiliated with Brock + University. We are students who have created this tool to help + other students. We are not responsible for any errors or issues + that may arise from using this tool. Please ensure you + double-check your timetable before registering for courses. +

+
- const handleContextCreditsClick = () => { - setOpenContextCredits(!openContextCredits); - }; +
+

Requirements

+

+ Make sure you've{" "} + + activated + {" "} + your Brock email account at least 24 hours in advance and have + your email and password ready. You will need to log in to your + student portal to register for courses. +

+
- const handleElectiveCreditsClick = () => { - setOpenElectiveCredits(!openElectiveCredits); - }; + - const handleCourseCodeChange = (event) => { - setCourseCode(event.target.value); - }; +
+

+ Step 1: Find Your Courses +

+

+ The first step to course registration is finding the courses you + want to take. Go to the{" "} + + Brock University Course Calendar + {" "} + and select your year, then program from the Table of Contents. + Scroll down to find your specific program and the courses you + need to take. You should see something similar to the image + below. +

+
+ Course Calendar +
+

+ This is a list of all the courses you will need to take for a + given term. Above, you can see the courses required for the + first term of a first-year computer science co-op student. + Let's break down everything you see here: +

- return ( - - - - - - - - - - Guide to Course Registration - - - Welcome to the Brock Visual TimeTable! This guide will help - you learn everything you need to know about course planning & - registration at Brock University. This guide is written by - students, for students. We understand the struggles of course - registration and have created this platform to help you make - the process easier. - - - In this guide, you will learn how to find your courses, plan - your schedule, and register for courses. This guide is - designed to be simple and easy to follow. This guide is for - all students at Brock University, including first-year - students, upper-year students, and transfer students. - - - This guide will be running through creating a first-year - computer science co-op student's timetable. The process is the - same for all students, but the courses you need to take will - be different. - - - The Brock Visual TimeTable is not affiliated with Brock - University. We are students who have created this tool to help - other students. We are not responsible for any errors or - issues that may arise from using this tool. Please ensure you - double-check your timetable before registering for courses. - - - Requirements: - - - Make sure you've{" "} - - activated - {" "} - your Brock email account at least 24 hours in advance and have - your email and password ready. You will need to log in to your - student portal to register for courses. - - - Step 1: Find Your Courses - - - The first step to course registration is finding the courses - you want to take. Go to the{" "} - - Brock University Course Calendar - {" "} - and select your year, then program from the Table of Contents. - Scroll down to find your specific program and the courses you - need to take. You should see something similar to the image - below. - - - Course Calendar - - - This is a list of all the courses you will need to take for a - given term. Above, you can see the courses required for the - first term of a first-year computer science co-op student. - Let's break down everything you see here: - - - - - - {openCourseCode ? : } - - - - - The course code is a unique identifier for each - course. Lets use COSC 1P02 as an - example. It is made up of 4 distinct parts: - - - - - - - - - - - - - - - - - - + +

+ The course code is a unique identifier for each course. + Let's use COSC 1P02 as an example. It + is made up of 4 distinct parts: +

+
    +
  1. + COSC is the department acronym, meaning Computer Science. +
  2. +
  3. 1 shows the year level (1 = first year).
  4. +
  5. + P tells the credit value (P = 0.5 credit, F = 1.0 credit). +
  6. +
  7. 02 is the unique course number in the department.
  8. +
+
+ +

+ Notice how some courses have AND and others + have OR between them. Looking at the image + above, you can see that{" "} + COSC 1P02 AND COSC 1P03 are required. This + means you must take both courses. In the case of these + courses, COSC 1P02 is a prerequisite for COSC 1P03. Assuming + you are a first-year student, you will need to take COSC + 1P02 in your first term and COSC 1P03 in your second term. +

+

+ On the other hand, COSC 1P50 OR COSC 1P71{" "} + are required. This means you only need to take one of the + two courses. You can choose to take COSC 1P50 or COSC 1P71 + in your first term. Both courses are not required. +

+
+ +

+ In the example above, you can see that SCIE 0N90 is a + term-specific course. This means that you can only take this + course in the Winter term. You will need to plan your + schedule accordingly to ensure you can take this course. +

+

+ In the case of SCIE 0N90, this doesn't have much impact + on your schedule, as this is a 0 credit course, that you + normally take on top of your regular course load. +

+
+ +

+ Context credits are courses that are required to give you a + broader understanding of different fields. At Brock, you + need to complete 1.0 context credit in Humanities, Social + Sciences, and Sciences. You can find the list of courses + that fulfill these requirements{" "} + - - {openAndOr ? : } - - - - - Notice how some courses have AND and - others have - OR between them. Looking at the - image above, you can see that - COSC 1P02 AND COSC 1P03 are - required. This means you must take both courses. In - the case of these courses, COSC 1P02 is a prerequisite - for COSC 1P03. Assuming you are a first-year student, - you will need to take COSC 1P02 in your first term and - COSC 1P03 in your second term. - - - On the other hand,{" "} - COSC 1P50 OR COSC 1P71 are required. - This means you only need to take one of the two - courses. You can choose to take COSC 1P50 or COSC 1P71 - in your first term. Both courses are not required. - - - - - - {openTermSpecific ? : } - - - - - In the example above, you can see that SCIE 0N90 is a - term-specific course. This means that you can only - take this course in the Winter term. You will need to - plan your schedule accordingly to ensure you can take - this course. - - - In the case of SCIE 0N90, this doesn't have much - impact on your schedule, as this is a 0 credit course, - that you normally take on top of your regular course - load. - - - - - - {openContextCredits ? : } - - - - - Context credits are courses that are required to give - you a broader understanding of different fields. At - Brock, you need to complete 1.0 context credit in - Humanities, Social Sciences, and Sciences. You can - find the list of courses that fulfill these - requirements{" "} - - here - - . - - - - - - {openElectiveCredits ? : } - - - - - Elective credits are courses that you can choose - freely from any department. These allow you to explore - other areas of interest and can be used to fulfill - additional requirements or personal interests. - - - - - - - Step 2: Create your Timetable - - - Once you have found the courses you need to take, you can - start planning your timetable. You can use the{" "} - - Brock Visual TimeTable - {" "} - to create your timetable. Simply input your courses, and the - generator will create all possible timetables for you. You can - then choose the timetable that works best for you. - - - When adding courses to the generator, ensure that you are - adding the course for the correct term. You can do this by - adding D(number), where number is the term number. For fall - and winter terms: - - - - - - - - - - - - - - The durations used for spring & summer courses are different. - You can find the duration for each course in the{" "} - - timetable - - . - - - Note: This tool is not affiliated with Brock - University. We are students who have created this tool to help - other students. We are not responsible for any errors or - issues that may arise from using this tool. Please ensure you - double-check your timetable before registering for courses. - - - Course Calendar - - - This is an example of a timetable generated using the Brock - Visual TimeTable. You can see I've decided to take COSC 1P02, - COSC 1P50, MATH 1P66, and ECON 1P92 in my first term, and FILM - 1F94 as an 8 month course. FILM 1F94 fills the context credit - for Humanities, and ECON 1P92 fills half of the context credit - for Social Sciences. - - - You can also see that I've blocked out every day from 8:00 AM - to 9:00 AM. This prevents the generator from scheduling any - courses during this time. This is useful if you have other - commitments during this time (e.g. work, volunteering, or - sleeping in!). - - - Step 3: Register for Courses - - - Once you have created your timetable, you can start - registering for courses. Log in to your{" "} - - student portal - {" "} - and navigate to the course registration page (left side, about - half way down the screen). - - - Course Calendar - - - You can then select the term you want to register for and - input the course codes for the courses you want to take. Make - sure you add the correct components (e.g. lecture, tutorial, - lab) for each course. - - - Once you add a course, it will show up in the "List Of - Registered Courses for Current Registration Period" list at - the bottom of the page. The course will be automatically - saved, so once it's added, you're good to go! - - - - - + here + + . +

+
+ +

+ Elective credits are courses that you can choose freely from + any department. These allow you to explore other areas of + interest and can be used to fulfill additional requirements + or personal interests. +

+
+
+
+ + + +
+

+ Step 2: Create your Timetable +

+

+ Once you have found the courses you need to take, you can start + planning your timetable. You can use the{" "} + + Brock Visual TimeTable + {" "} + to create your timetable. Simply input your courses, and the + generator will create all possible timetables for you. You can + then choose the timetable that works best for you. +

+

+ When adding courses to the generator, ensure that you are adding + the course for the correct term. You can do this by adding + D(number), where number is the term number. For fall and winter + terms: +

+
    +
  1. + D1 is for 8 month courses, spanning from September to April. +
  2. +
  3. + D2 is for fall courses, spanning from September to December. +
  4. +
  5. + D3 is for winter courses, spanning from January to April. +
  6. +
+

+ The durations used for spring & summer courses are + different. You can find the duration for each course in the{" "} + + timetable + + . +

+

+ Note: This tool is not affiliated with Brock + University. We are students who have created this tool to help + other students. We are not responsible for any errors or issues + that may arise from using this tool. Please ensure you + double-check your timetable before registering for courses. +

+
+ Example timetable +
+

+ This is an example of a timetable generated using the Brock + Visual TimeTable. You can see I've decided to take COSC + 1P02, COSC 1P50, MATH 1P66, and ECON 1P92 in my first term, and + FILM 1F94 as an 8 month course. FILM 1F94 fills the context + credit for Humanities, and ECON 1P92 fills half of the context + credit for Social Sciences. +

+

+ You can also see that I've blocked out every day from 8:00 + AM to 9:00 AM. This prevents the generator from scheduling any + courses during this time. This is useful if you have other + commitments during this time (e.g. work, volunteering, or + sleeping in!). +

+
+ + + +
+

+ Step 3: Register for Courses +

+

+ Once you have created your timetable, you can start registering + for courses. Log in to your{" "} + + student portal + {" "} + and navigate to the course registration page (left side, about + half way down the screen). +

+
+ Student portal dashboard +
+

+ You can then select the term you want to register for and input + the course codes for the courses you want to take. Make sure you + add the correct components (e.g. lecture, tutorial, lab) for + each course. +

+

+ Once you add a course, it will show up in the "List Of + Registered Courses for Current Registration Period" list at the + bottom of the page. The course will be automatically saved, so + once it's added, you're good to go! +

+
+
+
- - +
+ ); } diff --git a/src/styles/generator/Calendar.css b/src/styles/generator/Calendar.css index 5846cde..2cd2efc 100644 --- a/src/styles/generator/Calendar.css +++ b/src/styles/generator/Calendar.css @@ -39,7 +39,7 @@ max-width: 100%; } -/* Timeline styles moved to inline Material UI styles */ +/* Timeline styles moved to inline styles */ @media (max-width: 1325px) { .fc-event-main { @@ -59,7 +59,7 @@ justify-content: center; } - #calendarNavButtons > Box { + #calendarNavButtons > div { margin: 5px; } @@ -112,7 +112,7 @@ justify-content: center; } - #calendarNavButtons > Box { + #calendarNavButtons > div { margin: 5px; } diff --git a/src/styles/generator/CustomCalendar.css b/src/styles/generator/CustomCalendar.css index e5ea133..9ff4524 100644 --- a/src/styles/generator/CustomCalendar.css +++ b/src/styles/generator/CustomCalendar.css @@ -3,51 +3,51 @@ --calendar-grid-color-dark: var(--theme-outline-color); } -body.light-mode .fc .fc-timegrid-slot, -body.light-mode .fc .fc-col-header-cell, -body.light-mode .fc .fc-daygrid-day, -body.light-mode .fc .fc-daygrid-day-frame, -body.light-mode .fc .fc-timegrid-axis, -body.light-mode .fc .fc-timegrid-divider, -body.light-mode .fc .fc-timegrid-lines, -body.light-mode .fc .fc-timegrid-bg, -body.light-mode .fc .fc-timegrid-slots, -body.light-mode .fc .fc-scrollgrid, -body.light-mode .fc .fc-scrollgrid-sync-inner, -body.light-mode .fc .fc-scrollgrid-liquid, -body.light-mode .fc .fc-scrollgrid-section, -body.light-mode .fc .fc-scrollgrid-section table, -body.light-mode .fc .fc-scrollgrid-section td, -body.light-mode .fc .fc-scrollgrid-section th { +.fc .fc-timegrid-slot, +.fc .fc-col-header-cell, +.fc .fc-daygrid-day, +.fc .fc-daygrid-day-frame, +.fc .fc-timegrid-axis, +.fc .fc-timegrid-divider, +.fc .fc-timegrid-lines, +.fc .fc-timegrid-bg, +.fc .fc-timegrid-slots, +.fc .fc-scrollgrid, +.fc .fc-scrollgrid-sync-inner, +.fc .fc-scrollgrid-liquid, +.fc .fc-scrollgrid-section, +.fc .fc-scrollgrid-section table, +.fc .fc-scrollgrid-section td, +.fc .fc-scrollgrid-section th { border-color: var(--calendar-grid-color-light); } -body.dark-mode .fc .fc-timegrid-slot, -body.dark-mode .fc .fc-col-header-cell, -body.dark-mode .fc .fc-daygrid-day, -body.dark-mode .fc .fc-daygrid-day-frame, -body.dark-mode .fc .fc-timegrid-axis, -body.dark-mode .fc .fc-timegrid-divider, -body.dark-mode .fc .fc-timegrid-lines, -body.dark-mode .fc .fc-timegrid-bg, -body.dark-mode .fc .fc-timegrid-slots, -body.dark-mode .fc .fc-scrollgrid, -body.dark-mode .fc .fc-scrollgrid-sync-inner, -body.dark-mode .fc .fc-scrollgrid-liquid, -body.dark-mode .fc .fc-scrollgrid-section, -body.dark-mode .fc .fc-scrollgrid-section table, -body.dark-mode .fc .fc-scrollgrid-section td, -body.dark-mode .fc .fc-scrollgrid-section th { +.dark .fc .fc-timegrid-slot, +.dark .fc .fc-col-header-cell, +.dark .fc .fc-daygrid-day, +.dark .fc .fc-daygrid-day-frame, +.dark .fc .fc-timegrid-axis, +.dark .fc .fc-timegrid-divider, +.dark .fc .fc-timegrid-lines, +.dark .fc .fc-timegrid-bg, +.dark .fc .fc-timegrid-slots, +.dark .fc .fc-scrollgrid, +.dark .fc .fc-scrollgrid-sync-inner, +.dark .fc .fc-scrollgrid-liquid, +.dark .fc .fc-scrollgrid-section, +.dark .fc .fc-scrollgrid-section table, +.dark .fc .fc-scrollgrid-section td, +.dark .fc .fc-scrollgrid-section th { border-color: var(--calendar-grid-color-dark); } -body.light-mode .fc-event { +.fc-event { border: none; border-radius: 3px; box-shadow: 0 0 1px var(--calendar-grid-color-light); } -body.dark-mode .fc-event { +.dark .fc-event { border: none; border-radius: 3px; box-shadow: 0 0 1px var(--calendar-grid-color-dark); diff --git a/src/styles/index.css b/src/styles/index.css index 9e08812..4f07413 100644 --- a/src/styles/index.css +++ b/src/styles/index.css @@ -24,6 +24,8 @@ --destructive-foreground: 210 40% 98%; --ring: 215 20.2% 65.1%; --radius: 0.5rem; + --theme-divider-color: hsl(var(--border)); + --theme-outline-color: hsl(var(--ring)); } .dark { @@ -46,6 +48,8 @@ --destructive: 0 65% 38%; --destructive-foreground: 0 0% 98%; --ring: 0 0% 45%; + --theme-divider-color: hsl(var(--border)); + --theme-outline-color: hsl(var(--ring)); } }