Compare commits

...

77 Commits

Author SHA1 Message Date
dependabot[bot]
a56a25807b chore(deps): bump the major-updates group with 53 updates
Bumps the major-updates group with 53 updates:

| Package | From | To |
| --- | --- | --- |
| [@octokit/rest](https://github.com/octokit/rest.js) | `21.1.1` | `22.0.1` |
| [@sentry/react](https://github.com/getsentry/sentry-javascript) | `8.55.0` | `10.39.0` |
| [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react) | `4.3.4` | `5.1.4` |
| [conventional-changelog](https://github.com/conventional-changelog/conventional-changelog/tree/HEAD/packages/conventional-changelog) | `6.0.0` | `7.1.1` |
| [highcharts](https://github.com/highcharts/highcharts-dist) | `11.4.8` | `12.5.0` |
| [react](https://github.com/facebook/react/tree/HEAD/packages/react) | `18.3.1` | `19.2.4` |
| [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) | `18.3.18` | `19.2.14` |
| [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) | `18.3.1` | `19.2.4` |
| [@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom) | `18.3.5` | `19.2.3` |
| [react-markdown](https://github.com/remarkjs/react-markdown) | `9.1.0` | `10.1.0` |
| [react-syntax-highlighter](https://github.com/react-syntax-highlighter/react-syntax-highlighter) | `15.6.1` | `16.1.0` |
| [@chromatic-com/storybook](https://github.com/chromaui/addon-visual-tests) | `2.0.2` | `5.0.1` |
| [@commitlint/cli](https://github.com/conventional-changelog/commitlint/tree/HEAD/@commitlint/cli) | `19.7.1` | `20.4.1` |
| [@commitlint/config-conventional](https://github.com/conventional-changelog/commitlint/tree/HEAD/@commitlint/config-conventional) | `19.7.1` | `20.4.1` |
| [@commitlint/types](https://github.com/conventional-changelog/commitlint/tree/HEAD/@commitlint/types) | `19.5.0` | `20.4.0` |
| [@semantic-release/exec](https://github.com/semantic-release/exec) | `6.0.3` | `7.1.0` |
| [@sentry/types](https://github.com/getsentry/sentry-javascript) | `8.55.0` | `10.39.0` |
| [@storybook/addon-designs](https://github.com/storybookjs/addon-designs) | `8.2.0` | `11.1.2` |
| [@storybook/addon-links](https://github.com/storybookjs/storybook/tree/HEAD/code/addons/links) | `8.6.0` | `10.2.8` |
| [@storybook/react](https://github.com/storybookjs/storybook/tree/HEAD/code/renderers/react) | `8.6.0` | `10.2.8` |
| [@storybook/react-vite](https://github.com/storybookjs/storybook/tree/HEAD/code/frameworks/react-vite) | `8.6.0` | `10.2.8` |
| [@types/conventional-changelog](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/conventional-changelog) | `3.1.5` | `6.0.1` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `22.13.5` | `25.2.3` |
| [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) | `7.18.0` | `8.55.0` |
| [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) | `7.18.0` | `8.55.0` |
| [@unocss/eslint-config](https://github.com/unocss/unocss/tree/HEAD/packages-integrations/eslint-config) | `0.63.6` | `66.6.0` |
| [@unocss/postcss](https://github.com/unocss/unocss/tree/HEAD/packages-integrations/postcss) | `0.63.6` | `66.6.0` |
| [@unocss/preset-uno](https://github.com/unocss/unocss/tree/HEAD/packages-deprecated/preset-uno) | `0.63.6` | `66.6.0` |
| [@unocss/preset-web-fonts](https://github.com/unocss/unocss/tree/HEAD/packages-presets/preset-web-fonts) | `0.63.6` | `66.6.0` |
| [@unocss/reset](https://github.com/unocss/unocss/tree/HEAD/packages-presets/reset) | `0.63.6` | `66.6.0` |
| [@unocss/transformer-directives](https://github.com/unocss/unocss/tree/HEAD/packages-presets/transformer-directives) | `0.63.6` | `66.6.0` |
| [@unocss/transformer-variant-group](https://github.com/unocss/unocss/tree/HEAD/packages-presets/transformer-variant-group) | `0.63.6` | `66.6.0` |
| [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react-swc) | `3.8.0` | `4.2.3` |
| [@vitest/coverage-v8](https://github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-v8) | `2.1.9` | `4.0.18` |
| [@vitest/ui](https://github.com/vitest-dev/vitest/tree/HEAD/packages/ui) | `2.1.9` | `4.0.18` |
| [chromatic](https://github.com/chromaui/chromatic-cli) | `11.26.0` | `15.1.0` |
| [dotenv](https://github.com/motdotla/dotenv) | `16.4.7` | `17.3.1` |
| [es-module-lexer](https://github.com/guybedford/es-module-lexer) | `1.7.0` | `2.0.0` |
| [eslint](https://github.com/eslint/eslint) | `8.57.1` | `10.0.0` |
| [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) | `9.1.0` | `10.1.8` |
| [eslint-import-resolver-typescript](https://github.com/import-js/eslint-import-resolver-typescript) | `3.8.3` | `4.4.4` |
| [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) | `50.6.3` | `62.5.5` |
| [eslint-plugin-react-hooks](https://github.com/facebook/react/tree/HEAD/packages/eslint-plugin-react-hooks) | `4.6.2` | `7.0.1` |
| [eslint-plugin-react-prefer-function-component](https://github.com/tatethurston/eslint-plugin-react-prefer-function-component) | `3.4.0` | `5.0.0` |
| [eslint-plugin-storybook](https://github.com/storybookjs/storybook/tree/HEAD/code/lib/eslint-plugin) | `0.9.0` | `10.2.8` |
| [gulp-execa](https://github.com/ehmicky/gulp-execa) | `7.0.1` | `8.0.1` |
| [semantic-release](https://github.com/semantic-release/semantic-release) | `24.2.3` | `25.0.3` |
| [storybook](https://github.com/storybookjs/storybook/tree/HEAD/code/core) | `8.6.0` | `10.2.8` |
| [unocss](https://github.com/unocss/unocss/tree/HEAD/packages-presets/unocss) | `0.63.6` | `66.6.0` |
| [unplugin-icons](https://github.com/unplugin/unplugin-icons) | `0.19.3` | `23.0.1` |
| [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) | `5.4.20` | `7.3.1` |
| [vite-plugin-inspect](https://github.com/antfu/vite-plugin-inspect) | `0.8.9` | `11.3.3` |
| [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) | `2.1.9` | `4.0.18` |


Updates `@octokit/rest` from 21.1.1 to 22.0.1
- [Release notes](https://github.com/octokit/rest.js/releases)
- [Commits](https://github.com/octokit/rest.js/compare/v21.1.1...v22.0.1)

Updates `@sentry/react` from 8.55.0 to 10.39.0
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/8.55.0...10.39.0)

Updates `@vitejs/plugin-react` from 4.3.4 to 5.1.4
- [Release notes](https://github.com/vitejs/vite-plugin-react/releases)
- [Changelog](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite-plugin-react/commits/plugin-react@5.1.4/packages/plugin-react)

Updates `conventional-changelog` from 6.0.0 to 7.1.1
- [Release notes](https://github.com/conventional-changelog/conventional-changelog/releases)
- [Changelog](https://github.com/conventional-changelog/conventional-changelog/blob/master/packages/conventional-changelog/CHANGELOG.md)
- [Commits](https://github.com/conventional-changelog/conventional-changelog/commits/conventional-changelog-v7.1.1/packages/conventional-changelog)

Updates `highcharts` from 11.4.8 to 12.5.0
- [Commits](https://github.com/highcharts/highcharts-dist/compare/v11.4.8...v12.5.0)

Updates `react` from 18.3.1 to 19.2.4
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.4/packages/react)

Updates `@types/react` from 18.3.18 to 19.2.14
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `react-dom` from 18.3.1 to 19.2.4
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.4/packages/react-dom)

Updates `@types/react-dom` from 18.3.5 to 19.2.3
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom)

Updates `react-markdown` from 9.1.0 to 10.1.0
- [Release notes](https://github.com/remarkjs/react-markdown/releases)
- [Changelog](https://github.com/remarkjs/react-markdown/blob/main/changelog.md)
- [Commits](https://github.com/remarkjs/react-markdown/compare/9.1.0...10.1.0)

Updates `react-syntax-highlighter` from 15.6.1 to 16.1.0
- [Release notes](https://github.com/react-syntax-highlighter/react-syntax-highlighter/releases)
- [Changelog](https://github.com/react-syntax-highlighter/react-syntax-highlighter/blob/master/CHANGELOG.MD)
- [Commits](https://github.com/react-syntax-highlighter/react-syntax-highlighter/compare/v15.6.1...v16.1.0)

Updates `@chromatic-com/storybook` from 2.0.2 to 5.0.1
- [Release notes](https://github.com/chromaui/addon-visual-tests/releases)
- [Changelog](https://github.com/chromaui/addon-visual-tests/blob/v5.0.1/CHANGELOG.md)
- [Commits](https://github.com/chromaui/addon-visual-tests/compare/v2.0.2...v5.0.1)

Updates `@commitlint/cli` from 19.7.1 to 20.4.1
- [Release notes](https://github.com/conventional-changelog/commitlint/releases)
- [Changelog](https://github.com/conventional-changelog/commitlint/blob/master/@commitlint/cli/CHANGELOG.md)
- [Commits](https://github.com/conventional-changelog/commitlint/commits/v20.4.1/@commitlint/cli)

Updates `@commitlint/config-conventional` from 19.7.1 to 20.4.1
- [Release notes](https://github.com/conventional-changelog/commitlint/releases)
- [Changelog](https://github.com/conventional-changelog/commitlint/blob/master/@commitlint/config-conventional/CHANGELOG.md)
- [Commits](https://github.com/conventional-changelog/commitlint/commits/v20.4.1/@commitlint/config-conventional)

Updates `@commitlint/types` from 19.5.0 to 20.4.0
- [Release notes](https://github.com/conventional-changelog/commitlint/releases)
- [Changelog](https://github.com/conventional-changelog/commitlint/blob/master/@commitlint/types/CHANGELOG.md)
- [Commits](https://github.com/conventional-changelog/commitlint/commits/v20.4.0/@commitlint/types)

Updates `@semantic-release/exec` from 6.0.3 to 7.1.0
- [Release notes](https://github.com/semantic-release/exec/releases)
- [Commits](https://github.com/semantic-release/exec/compare/v6.0.3...v7.1.0)

Updates `@sentry/types` from 8.55.0 to 10.39.0
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/8.55.0...10.39.0)

Updates `@storybook/addon-designs` from 8.2.0 to 11.1.2
- [Release notes](https://github.com/storybookjs/addon-designs/releases)
- [Changelog](https://github.com/storybookjs/addon-designs/blob/master/CHANGELOG.v1-6.md)
- [Commits](https://github.com/storybookjs/addon-designs/commits)

Updates `@storybook/addon-links` from 8.6.0 to 10.2.8
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v10.2.8/code/addons/links)

Updates `@storybook/react` from 8.6.0 to 10.2.8
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v10.2.8/code/renderers/react)

Updates `@storybook/react-vite` from 8.6.0 to 10.2.8
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v10.2.8/code/frameworks/react-vite)

Updates `@types/conventional-changelog` from 3.1.5 to 6.0.1
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/conventional-changelog)

Updates `@types/node` from 22.13.5 to 25.2.3
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `@types/react` from 18.3.18 to 19.2.14
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `@types/react-dom` from 18.3.5 to 19.2.3
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom)

Updates `@typescript-eslint/eslint-plugin` from 7.18.0 to 8.55.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.55.0/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 7.18.0 to 8.55.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.55.0/packages/parser)

Updates `@unocss/eslint-config` from 0.63.6 to 66.6.0
- [Release notes](https://github.com/unocss/unocss/releases)
- [Commits](https://github.com/unocss/unocss/commits/v66.6.0/packages-integrations/eslint-config)

Updates `@unocss/postcss` from 0.63.6 to 66.6.0
- [Release notes](https://github.com/unocss/unocss/releases)
- [Commits](https://github.com/unocss/unocss/commits/v66.6.0/packages-integrations/postcss)

Updates `@unocss/preset-uno` from 0.63.6 to 66.6.0
- [Release notes](https://github.com/unocss/unocss/releases)
- [Commits](https://github.com/unocss/unocss/commits/v66.6.0/packages-deprecated/preset-uno)

Updates `@unocss/preset-web-fonts` from 0.63.6 to 66.6.0
- [Release notes](https://github.com/unocss/unocss/releases)
- [Commits](https://github.com/unocss/unocss/commits/v66.6.0/packages-presets/preset-web-fonts)

Updates `@unocss/reset` from 0.63.6 to 66.6.0
- [Release notes](https://github.com/unocss/unocss/releases)
- [Commits](https://github.com/unocss/unocss/commits/v66.6.0/packages-presets/reset)

Updates `@unocss/transformer-directives` from 0.63.6 to 66.6.0
- [Release notes](https://github.com/unocss/unocss/releases)
- [Commits](https://github.com/unocss/unocss/commits/v66.6.0/packages-presets/transformer-directives)

Updates `@unocss/transformer-variant-group` from 0.63.6 to 66.6.0
- [Release notes](https://github.com/unocss/unocss/releases)
- [Commits](https://github.com/unocss/unocss/commits/v66.6.0/packages-presets/transformer-variant-group)

Updates `@vitejs/plugin-react-swc` from 3.8.0 to 4.2.3
- [Release notes](https://github.com/vitejs/vite-plugin-react/releases)
- [Changelog](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite-plugin-react/commits/plugin-react-swc@4.2.3/packages/plugin-react-swc)

Updates `@vitest/coverage-v8` from 2.1.9 to 4.0.18
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.18/packages/coverage-v8)

Updates `@vitest/ui` from 2.1.9 to 4.0.18
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.18/packages/ui)

Updates `chromatic` from 11.26.0 to 15.1.0
- [Release notes](https://github.com/chromaui/chromatic-cli/releases)
- [Changelog](https://github.com/chromaui/chromatic-cli/blob/main/CHANGELOG.md)
- [Commits](https://github.com/chromaui/chromatic-cli/compare/v11.26.0...v15.1.0)

Updates `dotenv` from 16.4.7 to 17.3.1
- [Changelog](https://github.com/motdotla/dotenv/blob/master/CHANGELOG.md)
- [Commits](https://github.com/motdotla/dotenv/compare/v16.4.7...v17.3.1)

Updates `es-module-lexer` from 1.7.0 to 2.0.0
- [Release notes](https://github.com/guybedford/es-module-lexer/releases)
- [Commits](https://github.com/guybedford/es-module-lexer/compare/1.7.0...2.0.0)

Updates `eslint` from 8.57.1 to 10.0.0
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/compare/v8.57.1...v10.0.0)

Updates `eslint-config-prettier` from 9.1.0 to 10.1.8
- [Release notes](https://github.com/prettier/eslint-config-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-config-prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-config-prettier/compare/v9.1.0...v10.1.8)

Updates `eslint-import-resolver-typescript` from 3.8.3 to 4.4.4
- [Release notes](https://github.com/import-js/eslint-import-resolver-typescript/releases)
- [Changelog](https://github.com/import-js/eslint-import-resolver-typescript/blob/master/CHANGELOG.md)
- [Commits](https://github.com/import-js/eslint-import-resolver-typescript/compare/v3.8.3...v4.4.4)

Updates `eslint-plugin-jsdoc` from 50.6.3 to 62.5.5
- [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases)
- [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v50.6.3...v62.5.5)

Updates `eslint-plugin-react-hooks` from 4.6.2 to 7.0.1
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/packages/eslint-plugin-react-hooks/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/HEAD/packages/eslint-plugin-react-hooks)

Updates `eslint-plugin-react-prefer-function-component` from 3.4.0 to 5.0.0
- [Release notes](https://github.com/tatethurston/eslint-plugin-react-prefer-function-component/releases)
- [Changelog](https://github.com/tatethurston/eslint-plugin-react-prefer-function-component/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tatethurston/eslint-plugin-react-prefer-function-component/compare/v3.4.0...v5.0.0)

Updates `eslint-plugin-storybook` from 0.9.0 to 10.2.8
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v10.2.8/code/lib/eslint-plugin)

Updates `gulp-execa` from 7.0.1 to 8.0.1
- [Release notes](https://github.com/ehmicky/gulp-execa/releases)
- [Changelog](https://github.com/ehmicky/gulp-execa/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ehmicky/gulp-execa/compare/7.0.1...8.0.1)

Updates `semantic-release` from 24.2.3 to 25.0.3
- [Release notes](https://github.com/semantic-release/semantic-release/releases)
- [Commits](https://github.com/semantic-release/semantic-release/compare/v24.2.3...v25.0.3)

Updates `storybook` from 8.6.0 to 10.2.8
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v10.2.8/code/core)

Updates `unocss` from 0.63.6 to 66.6.0
- [Release notes](https://github.com/unocss/unocss/releases)
- [Commits](https://github.com/unocss/unocss/commits/v66.6.0/packages-presets/unocss)

Updates `unplugin-icons` from 0.19.3 to 23.0.1
- [Release notes](https://github.com/unplugin/unplugin-icons/releases)
- [Commits](https://github.com/unplugin/unplugin-icons/compare/v0.19.3...v23.0.1)

Updates `vite` from 5.4.20 to 7.3.1
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.3.1/packages/vite)

Updates `vite-plugin-inspect` from 0.8.9 to 11.3.3
- [Release notes](https://github.com/antfu/vite-plugin-inspect/releases)
- [Commits](https://github.com/antfu/vite-plugin-inspect/compare/v0.8.9...v11.3.3)

Updates `vitest` from 2.1.9 to 4.0.18
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.18/packages/vitest)

---
updated-dependencies:
- dependency-name: "@octokit/rest"
  dependency-version: 22.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@sentry/react"
  dependency-version: 10.39.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@vitejs/plugin-react"
  dependency-version: 5.1.4
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: conventional-changelog
  dependency-version: 7.1.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: highcharts
  dependency-version: 12.5.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: react
  dependency-version: 19.2.4
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@types/react"
  dependency-version: 19.2.14
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: react-dom
  dependency-version: 19.2.4
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@types/react-dom"
  dependency-version: 19.2.3
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: react-markdown
  dependency-version: 10.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: react-syntax-highlighter
  dependency-version: 16.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@chromatic-com/storybook"
  dependency-version: 5.0.1
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@commitlint/cli"
  dependency-version: 20.4.1
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@commitlint/config-conventional"
  dependency-version: 20.4.1
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@commitlint/types"
  dependency-version: 20.4.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@semantic-release/exec"
  dependency-version: 7.1.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@sentry/types"
  dependency-version: 10.39.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@storybook/addon-designs"
  dependency-version: 11.1.2
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@storybook/addon-links"
  dependency-version: 10.2.8
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@storybook/react"
  dependency-version: 10.2.8
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@storybook/react-vite"
  dependency-version: 10.2.8
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@types/conventional-changelog"
  dependency-version: 6.0.1
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@types/node"
  dependency-version: 25.2.3
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@types/react"
  dependency-version: 19.2.14
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@types/react-dom"
  dependency-version: 19.2.3
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.55.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.55.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@unocss/eslint-config"
  dependency-version: 66.6.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@unocss/postcss"
  dependency-version: 66.6.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@unocss/preset-uno"
  dependency-version: 66.6.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@unocss/preset-web-fonts"
  dependency-version: 66.6.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@unocss/reset"
  dependency-version: 66.6.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@unocss/transformer-directives"
  dependency-version: 66.6.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@unocss/transformer-variant-group"
  dependency-version: 66.6.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@vitejs/plugin-react-swc"
  dependency-version: 4.2.3
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@vitest/coverage-v8"
  dependency-version: 4.0.18
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: "@vitest/ui"
  dependency-version: 4.0.18
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: chromatic
  dependency-version: 15.1.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: dotenv
  dependency-version: 17.3.1
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: es-module-lexer
  dependency-version: 2.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: eslint
  dependency-version: 10.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: eslint-config-prettier
  dependency-version: 10.1.8
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: eslint-import-resolver-typescript
  dependency-version: 4.4.4
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: eslint-plugin-jsdoc
  dependency-version: 62.5.5
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: eslint-plugin-react-hooks
  dependency-version: 7.0.1
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: eslint-plugin-react-prefer-function-component
  dependency-version: 5.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: eslint-plugin-storybook
  dependency-version: 10.2.8
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: gulp-execa
  dependency-version: 8.0.1
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: semantic-release
  dependency-version: 25.0.3
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: storybook
  dependency-version: 10.2.8
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: unocss
  dependency-version: 66.6.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: unplugin-icons
  dependency-version: 23.0.1
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: vite
  dependency-version: 7.3.1
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: vite-plugin-inspect
  dependency-version: 11.3.3
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
- dependency-name: vitest
  dependency-version: 4.0.18
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: major-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-16 16:40:15 +00:00
f8c2788d86 feat: exporting to txt again (#733)
* feat: initial functions for exporting to txt

* feat: add save as text to calendar header new export option

* docs: comment for saveAsText()

* feat: generate text line by line for each course

* docs: jsdoc

* chore: lint

* Apply suggestion from @doprz

---------

Co-authored-by: Diego Perez <52579214+doprz@users.noreply.github.com>
2026-02-12 23:52:00 -06:00
Diego Perez
a537d17a2f feat: inline chrome-extension-toolkit (#744)
* feat(build): inline chrome-extension-toolkit

fix: tsconfig

docs: add chrome-extension-toolkit README.md

chore: update imports

fix: stores

fix: chrome-extension-toolkit ForegroundMessenger

fix: calendarBackgroundHandler

fix: format and lint

fix: path alias

fix: add jsdom env and fix imports

Co-authored-by: Sriram Hariharan <sghsri@gmail.com>

* build: vite storybook config crx toolkit line

---------

Co-authored-by: Sriram Hariharan <sghsri@gmail.com>
Co-authored-by: Derek <derex1987@gmail.com>
2026-02-11 00:50:27 -06:00
zz4zz
d5954410a7 feat: skip the confirmation modal when deleting empty schedules (#716)
Co-authored-by: Derek Chen <derex1987@gmail.com>
2026-02-06 17:18:23 -06:00
ishita778
36e66fd264 feat: UTRP-40: delete active schedule (#631)
* feat: delete active schedule

* fix: lock file

* Update pnpm-lock.yaml

---------

Co-authored-by: Derek <derex1987@gmail.com>
2026-02-06 16:58:25 -06:00
Albert Jiang
7b3fbafa50 feat: add tooltip for Other in grade distribution (#709)
* feat: add tooltip

* refactor: lint happy

* chore: lint

---------

Co-authored-by: Derek Chen <derex1987@gmail.com>
2026-01-30 17:33:40 -06:00
Sebastian Leiman
ea54d926ab fix: settings page lag (#736)
* feat: made a handler for github stats messages same way as the rest

* fix: remove settingsPageLag through incremental rendering and efficient update of local storage

* refactor: passed eslint

* chore: added GitHubStats types

* feat: added contributor card skeletons

* refactor: pass eslint

* feat: removed trickle rendering and added locking to setCachedData

---------

Co-authored-by: Derek <derex1987@gmail.com>
Co-authored-by: Diego Perez <52579214+doprz@users.noreply.github.com>
2026-01-30 16:20:55 -06:00
doprz
4776029cb4 fix: LHD bday 2026-01-21 18:27:51 -06:00
doprz
5e04d46e36 chore: delete empty file 2026-01-21 18:25:36 -06:00
doprz
518a3286fa feat(release): v2.3.0 2026-01-07 13:11:01 -06:00
Diego Perez
2d18553f98 feat: LHD birthday (#717)
* chore: add tsparticles/react

* fix: imports and lint issues

* fix: imports and format

* feat: refactor settings and add LHD birthday celebration

* chore: lint and format
2026-01-07 10:36:45 -06:00
doprz
68e3fe45fa chore(nix): update lock file 2026-01-06 12:47:27 -06:00
Diego Perez
38bb29b20b feat(nix): build UTRP (#714)
* feat(nix): build UTRP

* feat(nix): set fixed rev and sha256 + update lock file

* chore(nix): remove systems input

* chore: format

* chore(nix): add meta attribute

* feat(nix): add doprz as a maintainer
2026-01-06 12:39:34 -06:00
Diego Perez
8ccf7fb37e feat(nix): add prettier-version-match check (#713) 2025-12-26 13:24:22 -06:00
doprz
b406d4dd24 fix: .editorconfig syntax for nix files 2025-12-17 13:50:47 -06:00
doprz
d12c8bd7b7 chore: add treefmt/prettier note 2025-12-13 22:56:38 -06:00
doprz
ea5d1e2b16 chore: format 2025-12-13 22:49:09 -06:00
doprz
c2b43dc949 refactor(nix): use flake-parts (#642)
refactor(nix): split into flake parts module and add shell.nix

chore: add prettier to treefmt and pin version

chore(nix): add prettier exclude

chore(nix): bump pnpm to v10.18.2

feat(nix): add overlay for nodejs

feat(nix): add overlay for nodejs

chore: consolidate .editorconfig
2025-12-13 22:48:23 -06:00
8d2fdfa63c chore: feature request made better for the common student (#702)
I made these a less painful experience for the average non cs major who just wants to make an issue request

Co-authored-by: doprz <52579214+doprz@users.noreply.github.com>
2025-11-22 18:11:20 -06:00
c1ffd89dbe Refine bug report template for clarity and conciseness (#703)
Updated the bug report template to streamline the checklist and clarify sections.

Co-authored-by: doprz <52579214+doprz@users.noreply.github.com>
2025-11-22 18:10:40 -06:00
Aaron Park
dd8187d6da style: UTRP-14: Add a bigger "hitbox" to calendar sidebar buttons (#563)
* fix(sidebar): increase sidebar button hitbox

* chore(ui): change hitbox area for plus button

* chore(ui): update size of hitbox area

* fix: fix pnpm version conflict

* fix: pnpm version conflict

* chore(ui): update size of hitbox area for the social links

* feat: calendar footer story

---------

Co-authored-by: doprz <52579214+doprz@users.noreply.github.com>
Co-authored-by: Samuel Gunter <29130894+Samathingamajig@users.noreply.github.com>
Co-authored-by: Derek <derex1987@gmail.com>
2025-11-20 13:40:17 -06:00
5028d07f0b style: overflow no longer has the scroll because it is meant to be truncated (#704)
oh finally - DerexXD
2025-11-20 12:22:18 -06:00
4f5d8c6d20 fix: toSorted outdated chrome bug (#694)
* fix: polyfill

* fix: polyfill implemented

* chore: lint

* chore: replace polyfill with a single function replacement

* Delete src/polyfills.ts
2025-11-18 22:56:09 -06:00
Vincent Situ
6a67a32e4f feat: allow bypassing the 10-schedule limit (#675)
* feat: allow bypassing the 10-schedule limit

* feat: option to bypass 10 schedules- code done, not tested

* feat(ui): option to bypass 10 schedules

* feat(ui): button to lead to settings after reaching max limit

* Delete manifest.json

* Remove cross-env from build:watch script

* Remove cross-env and update caniuse-lite version

Removed cross-env dependency and updated caniuse-lite version.

* chore: lint

---------

Co-authored-by: Derek <derex1987@gmail.com>
2025-11-10 13:39:36 -06:00
Uthman
549c52a39f feat: add drag-and-drop import for schedules (#661)
* testing

* feat: add drag-and-drop support to FileUpload (#446)

* chore: remove testing comment

* chore: fix lint issues

* chore: format FileUpload.tsx with prettier

---------

Co-authored-by: Uthman Ogungbo <uthmanogungbo@Uthmans-MacBook-Pro.local>
Co-authored-by: Uthman Ogungbo <uthmanogungbo@wireless-10-148-166-229.public.utexas.edu>
Co-authored-by: Derek <derex1987@gmail.com>
2025-11-06 23:03:55 -06:00
doprz
36007b9d1a docs: add CODE_OF_CONDUCT.md (#651)
Added a Code of Conduct document to outline community guidelines and expectations.

Co-authored-by: Derek <derex1987@gmail.com>
2025-11-05 16:58:16 -06:00
cee5f0284f feat: condense resourceLinks course schedule (#676)
* chore: remove summer 2025 schedule list item

* feat: compress course schedules into one link

* Revise ResourceLinks with Spring '26 schedule

Updated course schedule links for Spring '26.
2025-11-05 16:38:00 -06:00
dependabot[bot]
e8a8b8e1ae chore(deps): bump the npm_and_yarn group across 1 directory with 4 updates (#639)
Bumps the npm_and_yarn group with 4 updates in the / directory: [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite), [@babel/helpers](https://github.com/babel/babel/tree/HEAD/packages/babel-helpers), [brace-expansion](https://github.com/juliangruber/brace-expansion) and [undici](https://github.com/nodejs/undici).


Updates `vite` from 5.4.14 to 5.4.20
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v5.4.20/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v5.4.20/packages/vite)

Updates `@babel/helpers` from 7.26.9 to 7.28.4
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.28.4/packages/babel-helpers)

Updates `brace-expansion` from 1.1.11 to 1.1.12
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/1.1.11...v1.1.12)

Updates `undici` from 6.21.1 to 6.22.0
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v6.21.1...v6.22.0)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 5.4.20
  dependency-type: direct:development
  dependency-group: npm_and_yarn
- dependency-name: "@babel/helpers"
  dependency-version: 7.28.4
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: brace-expansion
  dependency-version: 1.1.12
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: undici
  dependency-version: 6.22.0
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-13 11:36:53 -05:00
doprz
c21cbd77f0 feat(release): v2.2.2 2025-10-13 11:20:01 -05:00
99a035e29d chore: remove summer 2025 schedule list item (#637) 2025-10-13 02:25:27 -05:00
doprz
64baa6d290 refactor(nix): dev shells (#634) 2025-10-12 22:47:47 -05:00
Samuel Gunter
46fe591fa7 fix: whitespace wrapping in semester warning (#629) 2025-10-07 18:28:41 -05:00
doprz
8f7e1bc0af feat(env): add SENTRY env vars 2025-10-07 16:11:14 -05:00
doprz
9fc1098ef7 chore(env): add .env.example 2025-10-07 16:00:40 -05:00
Warith Rahman
ae094416fc chore(ui): added spring 2026 course schedule (#628) 2025-10-07 15:26:15 -05:00
ishita778
2e7dac1e3e feat: show warning for courses of different semesters (#570)
* chore: removed extra space at calendar footer

* chore: fixed eslint issues

* chore: changed return type to react node

* chore: displaycourses true fixes and checks fixed

* chore: prettier fix

* feat: not working same semester course issue

* feat: modifying components to use the new hook

* feat: small fixes

* fix: remove comments and spaces

* fix: dialog error solved

* fix: add to new schedule

* fix: prettier

* fix: delete unnecessary custom hook and p[rettier

* fix: checks all passing

* fix: added requested changes

* fix: added new conditions

* fix: description fixed

* style: fix Roboto Flex not being used as font in dialog

* fix: made requested changes

---------

Co-authored-by: doprz <52579214+doprz@users.noreply.github.com>
Co-authored-by: Razboy20 <razboy20@gmail.com>
Co-authored-by: Samuel Gunter <29130894+Samathingamajig@users.noreply.github.com>
2025-08-27 13:41:36 -05:00
doprz
7bea23a655 refactor: nix flake (#625)
* chore(nix): update flake

* chore(nix): remove just and update comment

* chore(nix): update node version + volta config

* refactor: nix flake
2025-08-25 11:33:44 -07:00
Samuel Gunter
3d28869e92 chore: spring 2025 grades (#624) 2025-08-18 00:29:59 -05:00
doprz
f0f1f0b365 chore: bump node and pnpm version (#620)
* chore(nix): update flake

* chore(nix): remove just and update comment

* chore(nix): update node version + volta config
2025-08-12 14:00:45 -05:00
be861b823c feat: search result shading (#617)
* feat: site support kws

* feat: function

* feat: stuff before bedtime

* feat: shading function

* feat: shading

* feat: shading the table children

* chore: fix lint issues

* feat: dependency array

* feat: remove

* feat: remove temp console log
2025-08-07 13:28:56 -05:00
Samuel Gunter
95de8df372 fix: fix or ignore various eslint warning (#609) 2025-07-16 07:54:40 -07:00
5994ded8be feat: export schedule button add to calendar (#594)
* feat: export schedule button add to calendar add to util too

* docs: hypen bruh

* chore: lowercase

* style: filecode icon

* chore: unused import

* refactor: use export json deleted old function

* chore: linting

* chore: remove useless import

---------

Co-authored-by: Samuel Gunter <29130894+Samathingamajig@users.noreply.github.com>
2025-06-17 11:57:48 -07:00
doprz
7b401add15 feat: add nix flake (#593)
Co-authored-by: Samuel Gunter <29130894+Samathingamajig@users.noreply.github.com>
2025-06-08 23:16:43 -05:00
Samuel Gunter
2d92dd47f0 feat: support summer grades, fix summer course parser (#596)
* feat: support summer grades, fix summer course parser

* chore: lint

* docs: mention summer terms in Course::number description

* feat: Course::getNumberWithoutTerm, strip summer term indicator when displaying grades

---------

Co-authored-by: doprz <52579214+doprz@users.noreply.github.com>
2025-06-08 21:10:05 -07:00
Aiyaz Mostofa
eb8141ee8c fix: limit height of schedule list dropdown in the extension popup (#543)
* fix: limit height of schedule list dropdown in the extension popup

* fix: limit the entire dropdown to 200px, not just the schedule list

* fix: use flexbox for dropdown and wedge scrollbar inside margin

* fix: use DisclosurePanel in schedule dropdown, do Uno class sorting

---------

Co-authored-by: Ethan Lanting <ethanlanting@gmail.com>
Co-authored-by: Samuel Gunter <29130894+Samathingamajig@users.noreply.github.com>
Co-authored-by: doprz <52579214+doprz@users.noreply.github.com>
2025-06-08 20:54:36 -07:00
sjalkote
2a50f5580d feat: automatically select new or duplicated schedules (#583) (#589)
Co-authored-by: doprz <52579214+doprz@users.noreply.github.com>
Co-authored-by: Samuel Gunter <29130894+Samathingamajig@users.noreply.github.com>
2025-06-08 20:39:46 -07:00
doprz
65bfb1d129 docs: add pnpm and update versions (#597) 2025-06-08 15:57:12 -05:00
doprz
234f3d627d feat(release): v2.2.1 2025-06-03 19:46:36 -05:00
Ethan Lanting
be1dccfcb9 feat: add dining app promo (#598)
* feat: add DiningAppPromo component and integrate it into Calendar

* feat: update WhatsNewPopup with new features and app download link

* fix: remove outdated links

* chore: run lint

* chore: run prettier

* feat: enhance DiningAppPromo with close button and integrate user preference for promo visibility

* chore: run lint

* chore: run check types

* fix: correct promo visibility logic in Calendar component

* feat: centralize app store URLs in appUrls.ts

* chore: run lint

* feat: integrate UT Dining promo image

* chore: run lint

* fix: update logo in WhatsNew popup to use LD icon

* fix: convert URLs to URL objects for consistency

* fix: update LD icon in WhatsNew popup to new version

* fix: update description for Coffee Shops feature to clarify operating times

* fix: rename promo state and storage key to showUTDiningPromo for clarity

---------

Co-authored-by: doprz <52579214+doprz@users.noreply.github.com>
2025-05-28 20:13:45 -05:00
Razboy20
454e5e807a fix: hide sentry instrumentation on debug builds (#604)
* fix: hide sentry instrumentation on debug builds

* fix: amend documentation to reference zip:to-public rather than zip
2025-05-27 23:35:11 -05:00
Razboy20
29d20d5c5a chore: setup dependabot configuration (#603)
* chore: setup dependabot configuration
2025-05-27 22:55:11 -05:00
doprz
e29546c727 chore: update issue templates 2025-05-27 21:55:36 -05:00
doprz
5a89be6238 chore: update issue templates 2025-05-27 21:53:42 -05:00
Samuel Gunter
cfb5faa09b fix: course columns on calendar (#587)
* fix: course columns on calendar

* test: new tests for course cell columns, extract calls to help function

* fix: gracefully handle async courses

* refactor: split course cell column logic into multiple functions, add comments, and derive fields

* chore: comments, for-index to for-of

* chore: fix typo

* fix: don't use sentry in storybook contexts

* fix: silence, brand

* refactor: don't rely on calculating columns, find as you go

---------

Co-authored-by: doprz <52579214+doprz@users.noreply.github.com>
2025-05-06 16:07:27 -05:00
37471efb74 feat: inside jokes005 (#590)
* feat: moved some of my lines together removed one of mine and added jack black

* feat: just ctrl x ctrl v a few lines

* Update insideJokes.tsx
2025-04-13 21:33:52 -05:00
doprz
7a4f40a765 feat(release): v2.2.0 2025-04-06 18:11:27 -05:00
doprz
d11d55db66 chore: update exec list (#580)
* chore: update exec list

* chore: update roles

* chore: update h2

* fix: key

* chore: caps
2025-04-05 14:33:44 -05:00
Samuel Gunter
76b6aa7c15 fix: include logo in screenshot, fix screenshots on small/zoomed windows (#579)
* fix: include logo in screenshot

* fix: screenshots on small/zoomed windows, screenshots with no async/other

---------

Co-authored-by: Razboy20 <razboy20@gmail.com>
2025-04-05 11:21:37 -05:00
Samuel Gunter
70d4fecad6 feat: recruitment banner for designer (#578) 2025-04-04 09:56:37 -05:00
Samuel Gunter
c3fa91752c chore: bump migration dialog message number, remove unused UpdateText component (#577) 2025-04-02 10:00:05 -05:00
Ethan Lanting
7c2beef193 feat: auto create empty schedule when deleted all schedules (#552)
* feat: enhance schedule deletion to create a new schedule if none remain

* feat: set active index to new schedule if only one exists

* chore: run lint

* feat: enhance schedule deletion to create a new schedule if none remain

* feat: set active index to new schedule if only one exists

* chore: run lint

* feat: reset schedules on update, refactor invariant to within deleteSchedule

* chore: pnpm lint

---------

Co-authored-by: Samuel Gunter <29130894+Samathingamajig@users.noreply.github.com>
Co-authored-by: Samuel Gunter <sgunter@utexas.edu>
2025-04-01 13:24:08 -05:00
Samuel Gunter
630d0d80d2 chore: professionalism in jokes (#572) 2025-03-26 14:16:06 -05:00
Samuel Gunter
695743104c feat: persist sidebar toggle state (#569) 2025-03-26 13:50:34 -05:00
Samuel Gunter
d014244b28 chore: pin volta pnpm version (#573) 2025-03-25 23:00:34 -05:00
Samuel Gunter
5cd56259f7 test: fix flaky sleep test (#571) 2025-03-24 02:28:41 -05:00
Samuel Gunter
fa9f78b46e feat: sticky calendar header and days (#568)
* feat: sticky calendar days

* feat: partial height borders for day labels

* feat: make calendar header actually sticky

* fix: remove unneeded gap

* refactor: add preston as co-author

Co-authored-by: Preston-Cook <preston.l.cook@gmail.com>

* fix: z-index issues with export sub-buttons

---------

Co-authored-by: Preston-Cook <preston.l.cook@gmail.com>
Co-authored-by: doprz <52579214+doprz@users.noreply.github.com>
2025-03-23 19:49:11 -05:00
Samuel Gunter
4a5f67f0fd fix: ics calendar export dates (#535)
* feat: academicCalendars object

* feat: seemingly working start, end, and until dates

* feat: seemingly working everything

* style: removed unnecessary deps, reorganized code

* style: code comments yay

* chore: old version of pnpm?

* ci: force github actions to rerun

* feat: list instructors in ics string, basic tests

* feat: testable code for ICS, tests for ICS, filter excluded dates

* style: eslint autofix

* test: check for graceful handling of errors in ICS

* fix: actually use scheduleToIcsString

* chore: eslint didn't include a space where it should've

* fix: ensure tz everywhere

* refactor: move string util to string util file

* feat: em dash in calendar event title

* feat: academic calendars 22-23 and 23-24

* fix: en dash instead of em dash
2025-03-22 22:55:16 -05:00
Yash Kukrecha
3bed9cc27f fix(schedule): truncate long schedule names in popup (#564) 2025-03-22 21:10:21 -05:00
ishita778
0dcae25b93 chore: removed extra space at calendar footer (#557)
* chore: removed extra space at calendar footer

* chore: fixed eslint issues

* chore: changed return type to react node

* chore: displaycourses true fixes and checks fixed

* chore: prettier fix
2025-03-18 04:00:46 -05:00
beastgwert
ca734dcd39 feat: rework start time to checkboxes (#553)
* feat: replace dropdown with checkbox

* refactor: remove console logs

* refactor: eslint happy

* refactor: change daysValue from string to array

* style: match course schedule page styling

* style: remove label font-normal

* style: finalize course schedule page style match

---------

Co-authored-by: Samuel Gunter <29130894+Samathingamajig@users.noreply.github.com>
2025-03-15 22:37:51 -05:00
Samuel Gunter
9448072112 feat: ensure unique splash text on schedule change (#554) 2025-03-10 18:57:54 -05:00
ishita778
b1e98ca9d7 chore: Modify the schedule creation prompt (#550)
* chore: modify the schedule creation prompt

* chore: changed border color to offwhite

---------

Co-authored-by: Samuel Gunter <29130894+Samathingamajig@users.noreply.github.com>
2025-03-08 21:01:46 -06:00
Abdulrahman Alshahrani
f036d409e6 feat: implement a What's New prompt (#539)
* feat: create whats new initial component

* feat: create initial whats-new hook

* feat: create whats-new story

* feat: add button to open dialog in storybook

* feat: complete popup ui

* feat: add check for new updates or installs

* fix: fix linter issues

* fix: use proper features and add video

* fix: properly fetch version from manifest

* feat: add a link to open the popup

* fix: update spacing and features' content

* fix: update UTRP Map name

* fix: increase icon size and display version correctly

* feat: update the features video

* fix: update offwhite color

* fix: color typo

* fix: fixing colors again

* feat: use numbers instead of boolean

* fix: typo in import

* feat: add type safety to features array

* feat: cdn video url

* fix: delete mp4 video

* feat: handle video failure to load

* fix: make border outline tight to video

* feat: make design responsive

* fix: make features array readonly

---------

Co-authored-by: doprz <52579214+doprz@users.noreply.github.com>
Co-authored-by: Derek Chen <derex1987@gmail.com>
2025-03-08 15:41:09 -06:00
ishita778
5493c63f18 chore: Change the highlight color on-hover over grade distribution bars to off-white/50 (#547)
* chore: opacity changed to 50 percent

* chore: fix pnpm lock file

* chore: pnpm checks pass attempt

* chore: pnpm lock checks should work

* fix: opacity 50 and pnpm version

* chore: pnpm lock file fix
2025-03-07 13:31:23 -06:00
ishita778
6c3139bf0f fix: merge course labels across pages (#541)
* fix: merge course labels across pages

* fix: merge same course

* fix: all checks pass

* fix: updated addrows function

* fix: prettier check

* fix: all checks

* fix: all checks pass

* fix: moved query tbody outside

* fix: uses row element

* fix: checks pass now

---------

Co-authored-by: Samuel Gunter <29130894+Samathingamajig@users.noreply.github.com>
2025-03-05 15:08:33 -06:00
Krish Patel
28ebb69612 style: update delete schedule prompt (#546)
Co-authored-by: Samuel Gunter <29130894+Samathingamajig@users.noreply.github.com>
2025-03-05 14:15:59 -06:00
Samuel Gunter
008cb40cb8 style: move input click style to central place (#532)
Co-authored-by: doprz <52579214+doprz@users.noreply.github.com>
2025-03-05 14:05:34 -06:00
165 changed files with 11082 additions and 5067 deletions

View File

@@ -7,3 +7,6 @@ insert_final_newline = true
trim_trailing_whitespace = true trim_trailing_whitespace = true
indent_size = 4 indent_size = 4
indent_style = space indent_style = space
[*.{nix,yaml,yml}]
indent_size = 2

3
.env.example Normal file
View File

@@ -0,0 +1,3 @@
SENTRY_ORG=longhorn-developers
SENTRY_PROJECT=ut-registration-plus
SENTRY_AUTH_TOKEN=

1
.envrc Normal file
View File

@@ -0,0 +1 @@
use flake

View File

@@ -94,3 +94,5 @@ typings/
config config
.eslintrc.js .eslintrc.js
!.storybook !.storybook
src/lib/chrome-extension-toolkit

View File

@@ -205,7 +205,7 @@ module.exports = {
{ {
target: './src/shared', target: './src/shared',
from: './', from: './',
except: ['./src/shared', './node_modules'], except: ['./src/shared', './node_modules', './src/lib/chrome-extension-toolkit'],
message: 'You cannot import into `shared` from an external directory.', message: 'You cannot import into `shared` from an external directory.',
}, },
], ],
@@ -227,6 +227,6 @@ module.exports = {
'simple-import-sort/imports': 'error', 'simple-import-sort/imports': 'error',
'simple-import-sort/exports': 'error', 'simple-import-sort/exports': 'error',
'import-essentials/restrict-import-depth': 'error', 'import-essentials/restrict-import-depth': 'error',
'import-essentials/check-path-alias': 'error', // 'import-essentials/check-path-alias': 'error',
}, },
}; };

View File

@@ -2,7 +2,7 @@
name: Bug report name: Bug report
about: Create a report to help us improve about: Create a report to help us improve
title: '[BUG] ' title: '[BUG] '
labels: 'bug' labels: ''
assignees: '' assignees: ''
--- ---
@@ -29,11 +29,11 @@ assignees: ''
**Expected Behavior** **Expected Behavior**
<!-- A clear and concise description of what you expected to happen --> <!-- What you expected to happen -->
**Current Behavior** **Current Behavior**
<!-- A clear and concise description of what actually happened --> <!-- What actually happened -->
**Screenshots** **Screenshots**

View File

@@ -2,7 +2,7 @@
name: Feature Request name: Feature Request
about: Suggest an idea for this project about: Suggest an idea for this project
title: '[FEATURE] ' title: '[FEATURE] '
labels: 'feature' labels: feature
assignees: '' assignees: ''
--- ---
@@ -16,18 +16,14 @@ assignees: ''
- [ ] I have reviewed the documentation to confirm this feature doesn't exist - [ ] I have reviewed the documentation to confirm this feature doesn't exist
- [ ] I have completed all sections below with detailed information - [ ] I have completed all sections below with detailed information
**Feature Description** **Your Idea**
<!-- A clear and concise description of the feature you'd like to see --> <!-- A clear and concise description of the feature you'd like to see, and how it would work -->
**Proposed Solution**
<!-- A clear and concise description of what you want to happen -->
**UI/UX Considerations** **UI/UX Considerations**
<!-- If this feature involves UI changes, please describe the visual aspects --> <!-- If this feature involves UI changes (aka how it looks), please describe the visual aspects -->
**Technical Implementation Details** **Other**
<!-- If you have specific technical suggestions, list them here --> <!-- Any other comments you have can go here! -->

View File

@@ -0,0 +1,11 @@
---
name: Updating Build Dependencies
about: Updating Build Dependencies
title: ''
labels: build, dependencies
assignees: doprz, Razboy20
---
- [ ] Updated Nix Flake
- [ ] Update Dockerfile
- [ ] Update Docs

20
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,20 @@
version: 2
updates:
- package-ecosystem: 'npm'
directory: '/'
schedule:
interval: 'weekly'
day: 'monday'
time: '09:00'
timezone: 'America/Chicago'
groups:
minor-and-patch-updates:
update-types:
- 'minor'
- 'patch'
major-updates:
update-types:
- 'major'
ignore:
- dependency-name: '@crxjs/vite-plugin'
- dependency-name: '@unocss/vite'

View File

@@ -1,43 +1,33 @@
name: Best Practices name: Best Practices
on: [push, pull_request] on: [push, pull_request]
jobs: jobs:
lint: lint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Setup pnpm - name: Setup pnpm
uses: pnpm/action-setup@v4 uses: pnpm/action-setup@v4
with: with:
version: 10 version: 10
- name: Install dependencies - name: Install dependencies
run: pnpm install run: pnpm install
- name: Run ESLint - name: Run ESLint
run: pnpm run lint run: pnpm run lint
format: format:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Setup pnpm - name: Setup pnpm
uses: pnpm/action-setup@v4 uses: pnpm/action-setup@v4
with: with:
version: 10 version: 10
- name: Install dependencies - name: Install dependencies
run: pnpm install run: pnpm install
- name: Run Prettier - name: Run Prettier
run: pnpm run prettier run: pnpm run prettier

View File

@@ -1,24 +1,18 @@
name: Type Check name: Type Check
on: [push, pull_request] on: [push, pull_request]
jobs: jobs:
type-check: type-check:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Setup pnpm - name: Setup pnpm
uses: pnpm/action-setup@v4 uses: pnpm/action-setup@v4
with: with:
version: 10 version: 10
- name: Install dependencies - name: Install dependencies
run: pnpm install run: pnpm install
- name: Run tests - name: Run tests
run: pnpm run check-types run: pnpm run check-types

View File

@@ -1,7 +1,5 @@
name: 'Chromatic' name: 'Chromatic'
on: [push, pull_request] on: [push, pull_request]
jobs: jobs:
chromatic: chromatic:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -14,10 +12,8 @@ jobs:
uses: pnpm/action-setup@v4 uses: pnpm/action-setup@v4
with: with:
version: 10 version: 10
- name: Install dependencies - name: Install dependencies
run: pnpm install run: pnpm install
- name: Publish to Chromatic - name: Publish to Chromatic
uses: chromaui/action@latest uses: chromaui/action@latest
with: with:

View File

@@ -15,7 +15,6 @@ jobs:
- uses: actions/checkout@master - uses: actions/checkout@master
- name: Get file permission - name: Get file permission
run: chmod -R 777 . run: chmod -R 777 .
- name: Install dependencies - name: Install dependencies
run: npm ci run: npm ci
- name: Release with semantic-release - name: Release with semantic-release

View File

@@ -1,24 +1,18 @@
name: Tests name: Tests
on: [push, pull_request] on: [push, pull_request]
jobs: jobs:
test: test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Setup pnpm - name: Setup pnpm
uses: pnpm/action-setup@v4 uses: pnpm/action-setup@v4
with: with:
version: 10 version: 10
- name: Install dependencies - name: Install dependencies
run: pnpm install run: pnpm install
- name: Run tests - name: Run tests
run: pnpm test run: pnpm test

View File

@@ -1,8 +1,6 @@
name: Validate PR Title name: Validate PR Title
# thank you ben limmer for this workflow: # thank you ben limmer for this workflow:
# https://github.com/blimmer/semantic-release-demo-2/blob/main/.github/workflows/lint-pr.yml # https://github.com/blimmer/semantic-release-demo-2/blob/main/.github/workflows/lint-pr.yml
on: on:
pull_request_target: pull_request_target:
types: types:
@@ -10,7 +8,6 @@ on:
- reopened - reopened
- edited - edited
- synchronize - synchronize
jobs: jobs:
main: main:
runs-on: ubuntu-latest runs-on: ubuntu-latest

7
.gitignore vendored
View File

@@ -211,3 +211,10 @@ sketch
package-lock.json package-lock.json
storybook-static/ storybook-static/
package/ package/
# Nix
result
result-*
# direnv
.direnv

View File

@@ -23,6 +23,7 @@ export default defineConfig({
'@shared': resolve(root, 'shared'), '@shared': resolve(root, 'shared'),
'@background': resolve(pagesDir, 'background'), '@background': resolve(pagesDir, 'background'),
'@views': resolve(root, 'views'), '@views': resolve(root, 'views'),
'@chrome-extension-toolkit': resolve(root, 'lib/chrome-extension-toolkit'),
}, },
}, },
}); });

8
.vscode/launch.json vendored
View File

@@ -6,13 +6,9 @@
"request": "launch", "request": "launch",
"name": "Run current script", "name": "Run current script",
"runtimeExecutable": "npx", "runtimeExecutable": "npx",
"runtimeArgs": [ "runtimeArgs": ["tsx"],
"tsx"
],
"program": "${file}", "program": "${file}",
"skipFiles": [ "skipFiles": ["<node_internals>/**"]
"<node_internals>/**"
],
} }
] ]
} }

View File

@@ -26,7 +26,7 @@
"navigation": "Routes", "navigation": "Routes",
"logging": "log", "logging": "log",
"popup": "Layout", "popup": "Layout",
"storage": "Database", "storage": "Database"
}, },
"material-icon-theme.files.associations": { "material-icon-theme.files.associations": {
"tsconfig.extension.json": "tsconfig", "tsconfig.extension.json": "tsconfig",
@@ -36,5 +36,5 @@
"[html]": { "[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode" "editor.defaultFormatter": "esbenp.prettier-vscode"
}, },
"typescript.tsdk": "node_modules/typescript/lib", "typescript.tsdk": "node_modules/typescript/lib"
} }

View File

@@ -1,346 +1,406 @@
## [2.3.0](https://github.com/Longhorn-Developers/UT-Registration-Plus/compare/v2.2.2...v2.3.0) (2026-01-07)
### Features
* add drag-and-drop import for schedules ([#661](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/661)) ([549c52a](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/549c52a39fee718f2bb07cfce33a294835a2246b)), closes [#446](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/446)
* allow bypassing the 10-schedule limit ([#675](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/675)) ([6a67a32](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/6a67a32e4f50a5bdd20aa43789f199b822483e2d))
* condense resourceLinks course schedule ([#676](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/676)) ([cee5f02](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/cee5f0284f09f39ca5ae64559d0b697646c77e74))
* LHD birthday ([#717](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/717)) ([2d18553](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/2d18553f98c5146fa18699ae20462e7dcbc9d35c))
* **nix:** add prettier-version-match check ([#713](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/713)) ([8ccf7fb](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/8ccf7fb37e769ba445f39c140ca9c1c4245cc1c1))
* **nix:** build UTRP ([#714](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/714)) ([38bb29b](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/38bb29b20b97ed3cf8fd6511df16553fed1d58bb))
### Bug Fixes
* .editorconfig syntax for nix files ([b406d4d](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b406d4dd244a25688c2b9621cf5d441228bd8913))
* toSorted outdated chrome bug ([#694](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/694)) ([4f5d8c6](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/4f5d8c6d20e3cfeb7b62520ba1819e297d2cc60f))
## [2.2.2](https://github.com/Longhorn-Developers/UT-Registration-Plus/compare/v2.2.1...v2.2.2) (2025-10-13)
### Features
* add nix flake ([#593](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/593)) ([7b401ad](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/7b401add1565ff401bad99745ff9e53b9a7f899f))
* automatically select new or duplicated schedules ([#583](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/583)) ([#589](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/589)) ([2a50f55](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/2a50f5580d3dbeb0d66546c23cf29bbb37d80da2))
* **env:** add SENTRY env vars ([8f7e1bc](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/8f7e1bc0af6336549068e02b80df21d4e8f4ef9c))
* export schedule button add to calendar ([#594](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/594)) ([5994ded](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/5994ded8be876cb55174d27d3fdb0832b21a0ff9))
* **release:** v2.2.2 ([c21cbd7](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/c21cbd77f0764c03a711589ff4f957cb8c936eec))
* search result shading ([#617](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/617)) ([be861b8](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/be861b823cb2cb7f6f4a1f266351eec3fc1c2f99))
* show warning for courses of different semesters ([#570](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/570)) ([2e7dac1](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/2e7dac1e3eba757231ac07ac966231c08c703a16))
* support summer grades, fix summer course parser ([#596](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/596)) ([2d92dd4](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/2d92dd47f00a44b7d48e92a8ffba94480e4e73f9))
### Bug Fixes
* fix or ignore various eslint warning ([#609](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/609)) ([95de8df](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/95de8df37243b6d59625df515a60442f11b7a9d3))
* limit height of schedule list dropdown in the extension popup ([#543](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/543)) ([eb8141e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/eb8141ee8c3d32bce901457178d50781b78f86dd))
* whitespace wrapping in semester warning ([#629](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/629)) ([46fe591](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/46fe591fa72ef017eea7cfb8aa37d12d8f223926))
## [2.2.1](https://github.com/Longhorn-Developers/UT-Registration-Plus/compare/v2.2.0...v2.2.1) (2025-06-04)
### Features
* add dining app promo ([#598](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/598)) ([be1dccf](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/be1dccfcb9d052c6b291b50cc53418d6bb645beb))
* inside jokes005 ([#590](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/590)) ([37471ef](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/37471efb740c7a5828cf3b54bac70954694359d7))
* **release:** v2.2.1 ([234f3d6](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/234f3d627d603adf8555b4d0e93106d198918169))
### Bug Fixes
* course columns on calendar ([#587](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/587)) ([cfb5faa](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/cfb5faa09bb0788e270d100f1f36536a53bcff75))
* hide sentry instrumentation on debug builds ([#604](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/604)) ([454e5e8](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/454e5e807af29ae0384cc3a3b8b691df5edc69d1))
## [2.2.0](https://github.com/Longhorn-Developers/UT-Registration-Plus/compare/v2.1.1...v2.2.0) (2025-04-06)
### Features
* auto create empty schedule when deleted all schedules ([#552](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/552)) ([7c2beef](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/7c2beef1930fbc887e8ec1aea789016b3150cd21))
* ensure unique splash text on schedule change ([#554](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/554)) ([9448072](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/94480721124e052426c1f3236e8605c7088df79c))
* implement a What's New prompt ([#539](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/539)) ([f036d40](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/f036d409e60a39fd1d3cb2f0db53a6056615f336))
* persist sidebar toggle state ([#569](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/569)) ([6957431](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/695743104c57951ba1957258c60c843f8fae793f))
* recruitment banner for designer ([#578](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/578)) ([70d4fec](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/70d4fecad61ec3cd3ba839de302fd851e075d073))
* **release:** v2.2.0 ([7a4f40a](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/7a4f40a765d704bf32a3b515d695916ed84f9397))
* rework start time to checkboxes ([#553](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/553)) ([ca734dc](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/ca734dcd39a433cfd2e930ea04adeba959b32c36))
* sticky calendar header and days ([#568](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/568)) ([fa9f78b](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/fa9f78b46e3a2270a44d4cc0691195a7c695cb93))
### Bug Fixes
* ics calendar export dates ([#535](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/535)) ([4a5f67f](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/4a5f67f0fda9f0ef57f821e4b7a55d63f099f579))
* include logo in screenshot, fix screenshots on small/zoomed windows ([#579](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/579)) ([76b6aa7](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/76b6aa7c150299dfcfa4b3dc00ce2de32f90f75c))
* merge course labels across pages ([#541](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/541)) ([6c3139b](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/6c3139bf0f324c9a7be826b6c24e8bf142fc53b1))
* **schedule:** truncate long schedule names in popup ([#564](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/564)) ([3bed9cc](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/3bed9cc27febfe795af0766a913c4845e74cc2da))
## [2.1.1](https://github.com/Longhorn-Developers/UT-Registration-Plus/compare/v2.1.0...v2.1.1) (2025-03-03) ## [2.1.1](https://github.com/Longhorn-Developers/UT-Registration-Plus/compare/v2.1.0...v2.1.1) (2025-03-03)
### Features ### Features
- add isDeveloper ([c6452c4](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/c6452c4f2b174487e6f51ad546ca1c3f8b4dbc1f)) * add isDeveloper ([c6452c4](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/c6452c4f2b174487e6f51ad546ca1c3f8b4dbc1f))
- map page ([#390](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/390)) ([2184774](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/218477404fdeacda7b39cd233e4e1e65995935d4)) * map page ([#390](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/390)) ([2184774](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/218477404fdeacda7b39cd233e4e1e65995935d4))
### Bug Fixes ### Bug Fixes
- import schedule file upload button ([#515](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/515)) ([766c0bc](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/766c0bc1b4a75f8146a922cb2eca8871032c1dc9)) * import schedule file upload button ([#515](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/515)) ([766c0bc](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/766c0bc1b4a75f8146a922cb2eca8871032c1dc9))
## [2.1.0](https://github.com/Longhorn-Developers/UT-Registration-Plus/compare/v2.0.2...v2.1.0) (2025-02-20) ## [2.1.0](https://github.com/Longhorn-Developers/UT-Registration-Plus/compare/v2.0.2...v2.1.0) (2025-02-20)
### Features ### Features
- add 'new search' link to the course catalog page ([#456](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/456)) ([ca5e4c1](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/ca5e4c13d31aeb603660972536712ea161c6f870)) * add 'new search' link to the course catalog page ([#456](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/456)) ([ca5e4c1](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/ca5e4c13d31aeb603660972536712ea161c6f870))
- add 404 page ([#426](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/426)) ([46c76b1](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/46c76b1703ea2344c3330c4cfa82560663be1c4c)) * add 404 page ([#426](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/426)) ([46c76b1](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/46c76b1703ea2344c3330c4cfa82560663be1c4c))
- add CacheStore for GitHub stats and use names instead of usernames ([#405](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/405)) ([b732a80](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b732a80eaa6f6cbf5b627ffc31ab321de3a8e8f4)) * add CacheStore for GitHub stats and use names instead of usernames ([#405](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/405)) ([b732a80](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b732a80eaa6f6cbf5b627ffc31ab321de3a8e8f4))
- add eslint-plugin-tsdoc ([#430](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/430)) ([e987fbb](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/e987fbbe8e733de6767d62811c2d4d6eaccf2d24)) * add eslint-plugin-tsdoc ([#430](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/430)) ([e987fbb](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/e987fbbe8e733de6767d62811c2d4d6eaccf2d24))
- add explanation to grade distribution ([#325](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/325)) ([9ad3239](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/9ad32390d13e1d413ca01b1bc45d02c695bc23dd)) * add explanation to grade distribution ([#325](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/325)) ([9ad3239](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/9ad32390d13e1d413ca01b1bc45d02c695bc23dd))
- add open calendar button ([#457](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/457)) ([93733e3](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/93733e37214f00543479e77209ca03864776a1a6)) * add open calendar button ([#457](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/457)) ([93733e3](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/93733e37214f00543479e77209ca03864776a1a6))
- add spacing system ([#474](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/474)) ([e61ab56](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/e61ab565c35a197609d205adcaac9c7ffe0fc6da)) * add spacing system ([#474](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/474)) ([e61ab56](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/e61ab565c35a197609d205adcaac9c7ffe0fc6da))
- **build:** add Docker support ([#322](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/322)) ([a5e921f](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/a5e921fd75109a50f17d05c9682e73ba246f3dd1)) * **build:** add Docker support ([#322](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/322)) ([a5e921f](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/a5e921fd75109a50f17d05c9682e73ba246f3dd1))
- **build:** add vite-build-logger ([#507](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/507)) ([1aa4e8c](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/1aa4e8c5fb2d1aea308e4cccea3e2818a9c946ec)) * **build:** add vite-build-logger ([#507](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/507)) ([1aa4e8c](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/1aa4e8c5fb2d1aea308e4cccea3e2818a9c946ec))
- **build:** refactor gulpfile to use gulp-execa ([#323](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/323)) ([db04bbb](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/db04bbb52e4ab19730dd66f417e68ab013ce2f79)) * **build:** refactor gulpfile to use gulp-execa ([#323](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/323)) ([db04bbb](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/db04bbb52e4ab19730dd66f417e68ab013ce2f79))
- export/import functionality (backup/restore/share with friends) + a new input component ([#433](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/433)) ([7dbffc6](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/7dbffc6eef346747042f1596da627ad0a2fcae1a)) * export/import functionality (backup/restore/share with friends) + a new input component ([#433](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/433)) ([7dbffc6](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/7dbffc6eef346747042f1596da627ad0a2fcae1a))
- injected button - add all courses from MyUT AND passing URL to handler ([#291](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/291)) ([c41467c](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/c41467c6176d31f70cd3ecdcf56eeb73696c6c23)) * injected button - add all courses from MyUT AND passing URL to handler ([#291](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/291)) ([c41467c](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/c41467c6176d31f70cd3ecdcf56eeb73696c6c23))
- modify Course Block text style and time and location text ([#409](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/409)) ([0d51cae](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0d51cae4c8b27201b09c0898f4d7a6e7abb3c100)) * modify Course Block text style and time and location text ([#409](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/409)) ([0d51cae](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0d51cae4c8b27201b09c0898f4d7a6e7abb3c100))
- **settings:** add option to always open calendar in new tab ([#488](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/488)) ([009de62](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/009de628285ce9c6571e492f8e3f52cdeeed4459)) * **settings:** add option to always open calendar in new tab ([#488](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/488)) ([009de62](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/009de628285ce9c6571e492f8e3f52cdeeed4459))
- **settings:** allow disabling of auto-loading courses ([#489](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/489)) ([b74c698](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b74c698866c1074ce2236ede549c94555667e6a5)) * **settings:** allow disabling of auto-loading courses ([#489](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/489)) ([b74c698](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b74c698866c1074ce2236ede549c94555667e6a5))
- **ui:** add schedule list icons ([#500](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/500)) ([f0b257a](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/f0b257aa124a8fff0bb31e3396715aecb09948d5)) * **ui:** add schedule list icons ([#500](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/500)) ([f0b257a](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/f0b257aa124a8fff0bb31e3396715aecb09948d5))
- **ui:** added shadows to popup buttons and course blocks ([#378](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/378)) ([a20332e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/a20332e53da9bda873fabb8395afe6ff6303799c)) * **ui:** added shadows to popup buttons and course blocks ([#378](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/378)) ([a20332e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/a20332e53da9bda873fabb8395afe6ff6303799c))
- **ui:** calendar header redesign ([#479](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/479)) ([9c766c2](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/9c766c26959673389e372c3a440c1a73d5887b1d)) * **ui:** calendar header redesign ([#479](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/479)) ([9c766c2](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/9c766c26959673389e372c3a440c1a73d5887b1d))
- **ui:** calendar sidebar redesign ([#464](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/464)) ([843cb5b](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/843cb5b4430885527592feee33656dfae50c95c2)) * **ui:** calendar sidebar redesign ([#464](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/464)) ([843cb5b](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/843cb5b4430885527592feee33656dfae50c95c2))
- **ui:** change icons to phosphor-icons [#467](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/467) ([#469](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/469)) ([37bd7e7](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/37bd7e79d9202d55c7d0f566518526b0aed53c68)) * **ui:** change icons to phosphor-icons [#467](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/467) ([#469](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/469)) ([37bd7e7](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/37bd7e79d9202d55c7d0f566518526b0aed53c68))
- **ui:** change red text when instructor not found ([#483](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/483)) ([52347fd](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/52347fd56dff95190915d9f375dbebe1383e76c8)) * **ui:** change red text when instructor not found ([#483](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/483)) ([52347fd](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/52347fd56dff95190915d9f375dbebe1383e76c8))
- **ui:** color picker final touches ([#491](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/491)) ([c2328e4](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/c2328e461ea0a846f399a22bc525540da2796dcd)) * **ui:** color picker final touches ([#491](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/491)) ([c2328e4](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/c2328e461ea0a846f399a22bc525540da2796dcd))
- **ui:** course color picker ([#382](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/382)) ([1f635d2](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/1f635d2515fc403ad7f08fc3a244a17d262e3f7b)) * **ui:** course color picker ([#382](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/382)) ([1f635d2](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/1f635d2515fc403ad7f08fc3a244a17d262e3f7b))
- **ui:** course unique number copy button ([#490](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/490)) ([501f506](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/501f50667725aa1515391869b133908b8383d868)) * **ui:** course unique number copy button ([#490](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/490)) ([501f506](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/501f50667725aa1515391869b133908b8383d868))
- **ui:** Modify Calendar Footer design and Unscheduled courses ([#503](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/503)) ([b171f01](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b171f01d01f47c75e7df5e5c8e4e7b15b7397c52)) * **ui:** Modify Calendar Footer design and Unscheduled courses ([#503](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/503)) ([b171f01](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b171f01d01f47c75e7df5e5c8e4e7b15b7397c52))
- **ui:** redesign grade distribution tooltip ([#485](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/485)) ([a61bddf](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/a61bddf0e8a76c89d4963d9e580fb063309bee92)) * **ui:** redesign grade distribution tooltip ([#485](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/485)) ([a61bddf](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/a61bddf0e8a76c89d4963d9e580fb063309bee92))
- **ui:** update button variants following figma ([#482](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/482)) ([0aa469a](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0aa469af81e7912a6b26ee1b80c5920f677b5fbd)) * **ui:** update button variants following figma ([#482](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/482)) ([0aa469a](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0aa469af81e7912a6b26ee1b80c5920f677b5fbd))
- **ui:** update popup and course blocks ([#506](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/506)) ([ee4c6ce](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/ee4c6ce6999ad35821b9be5d657790f2dee017b3)) * **ui:** update popup and course blocks ([#506](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/506)) ([ee4c6ce](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/ee4c6ce6999ad35821b9be5d657790f2dee017b3))
- **ui:** update theme colors [#466](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/466) ([#473](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/473)) ([0d73b13](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0d73b13b288bf8b18444f26455da24c2f4acedf6)) * **ui:** update theme colors [#466](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/466) ([#473](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/473)) ([0d73b13](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0d73b13b288bf8b18444f26455da24c2f4acedf6))
- update SWE list ([aa29bcf](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/aa29bcf9fe4bad7812336d55d7575a6032aea91c)) * update SWE list ([aa29bcf](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/aa29bcf9fe4bad7812336d55d7575a6032aea91c))
- update text styles ([#468](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/468)) ([918f4e4](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/918f4e419cf5fa71bda1112597e9a373daca69ea)), closes [#465](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/465) * update text styles ([#468](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/468)) ([918f4e4](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/918f4e419cf5fa71bda1112597e9a373daca69ea)), closes [#465](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/465)
- validate login passed to background and implemented into add all injected button ([#443](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/443)) ([cd05e5e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/cd05e5e7fcaa02dab30f230c178f189d8052a7c9)) * validate login passed to background and implemented into add all injected button ([#443](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/443)) ([cd05e5e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/cd05e5e7fcaa02dab30f230c178f189d8052a7c9))
### Bug Fixes ### Bug Fixes
- 4th attempt for: now able to delete schedule even if active ([#435](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/435)) ([2425679](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/24256798ba7b877dd170d77ce4970b13b8a69a68)) * 4th attempt for: now able to delete schedule even if active ([#435](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/435)) ([2425679](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/24256798ba7b877dd170d77ce4970b13b8a69a68))
- instructor formatting errors ([#425](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/425)) ([8b92208](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/8b922082a79ebdbf50a09f37ecb9dfea1be6e1f3)) * instructor formatting errors ([#425](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/425)) ([8b92208](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/8b922082a79ebdbf50a09f37ecb9dfea1be6e1f3))
- place hours and courses under schedule name ([#388](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/388)) ([7dd9369](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/7dd93690d6dbd206cb50442f42ec85d6bbfc1da8)) * place hours and courses under schedule name ([#388](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/388)) ([7dd9369](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/7dd93690d6dbd206cb50442f42ec85d6bbfc1da8))
- transition added ([#381](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/381)) ([598bafe](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/598bafe67f47ad57b3801a425e61f86093ba2be8)) * transition added ([#381](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/381)) ([598bafe](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/598bafe67f47ad57b3801a425e61f86093ba2be8))
- **ui:** fix longstanding drag-and-drop duplication issue ([#502](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/502)) ([4752f58](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/4752f5860a96e08a1177c0ddf57a0fa269d89072)) * **ui:** fix longstanding drag-and-drop duplication issue ([#502](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/502)) ([4752f58](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/4752f5860a96e08a1177c0ddf57a0fa269d89072))
- **ui:** reduce left side grade distribution margin/padding ([#427](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/427)) ([91fa78e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/91fa78e2d0532a73e24ecc013d2ba6c0f62c1fcd)) * **ui:** reduce left side grade distribution margin/padding ([#427](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/427)) ([91fa78e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/91fa78e2d0532a73e24ecc013d2ba6c0f62c1fcd))
- **ui:** stop import button dropdown from squishing ([#504](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/504)) ([846070e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/846070ebb5e13e0fc0df94666dbce75194100049)) * **ui:** stop import button dropdown from squishing ([#504](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/504)) ([846070e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/846070ebb5e13e0fc0df94666dbce75194100049))
- updated text when time/location not provided ([#289](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/289)) ([ebcc0aa](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/ebcc0aa76a89f0d1a9e90cfc50d70f017c9bed42)) * updated text when time/location not provided ([#289](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/289)) ([ebcc0aa](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/ebcc0aa76a89f0d1a9e90cfc50d70f017c9bed42))
## [2.0.2](https://github.com/Longhorn-Developers/UT-Registration-Plus/compare/v2.0.1...v2.0.2) (2024-11-05) ## [2.0.2](https://github.com/Longhorn-Developers/UT-Registration-Plus/compare/v2.0.1...v2.0.2) (2024-11-05)
### Features ### Features
- add core curriculum chips to injected popup ([#372](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/372)) ([6f1afc5](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/6f1afc5b25441c6a1fbfdf57b3c8b5b74e36f5a0)) * add core curriculum chips to injected popup ([#372](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/372)) ([6f1afc5](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/6f1afc5b25441c6a1fbfdf57b3c8b5b74e36f5a0))
- Add linkedin social to calendar ([#368](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/368)) ([b6eccac](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b6eccaca6a2cdba9b57d2f49f064ae8504bbd5cb)) * Add linkedin social to calendar ([#368](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/368)) ([b6eccac](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b6eccaca6a2cdba9b57d2f49f064ae8504bbd5cb))
- add more relevant links to the From the Team section ([#380](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/380)) ([643ea13](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/643ea1320798aabb7783d267f5e6fd7c00fc2e3f)) * add more relevant links to the From the Team section ([#380](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/380)) ([643ea13](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/643ea1320798aabb7783d267f5e6fd7c00fc2e3f))
- bold course number in grade distribution chart, change text to ut-black ([#406](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/406)) ([638ee88](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/638ee88c96510a779c157b524903caaeffc9ef19)) * bold course number in grade distribution chart, change text to ut-black ([#406](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/406)) ([638ee88](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/638ee88c96510a779c157b524903caaeffc9ef19))
- disable/some actions when no instructor ([#319](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/319)) ([839f9c6](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/839f9c6d6afd4a1eae1a0bdf8893ab2e19b9fdff)) * disable/some actions when no instructor ([#319](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/319)) ([839f9c6](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/839f9c6d6afd4a1eae1a0bdf8893ab2e19b9fdff))
- **ui:** changed popup close icon to ut-black ([#394](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/394)) ([0077ae7](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0077ae70d22f24549c4c3b243188d19adbfbac14)), closes [#333F48](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/333F48) * **ui:** changed popup close icon to ut-black ([#394](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/394)) ([0077ae7](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0077ae70d22f24549c4c3b243188d19adbfbac14)), closes [#333F48](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/333F48)
- update senior swe admins ([#326](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/326)) ([b967240](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b967240f8fbb7a790a78f4aa256f0a77a491abb8)) * update senior swe admins ([#326](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/326)) ([b967240](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b967240f8fbb7a790a78f4aa256f0a77a491abb8))
- update useful links ([#367](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/367)) ([cef99c2](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/cef99c2d72d3a2800f8a918d01cb116f8795d0c8)) * update useful links ([#367](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/367)) ([cef99c2](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/cef99c2d72d3a2800f8a918d01cb116f8795d0c8))
- use "copy of" for duplicated schedules and place them under the original schedule [#358](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/358) ([#397](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/397)) ([94744e0](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/94744e01b94819fb4f5d64616ea56857b906c2dd)) * use "copy of" for duplicated schedules and place them under the original schedule [#358](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/358) ([#397](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/397)) ([94744e0](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/94744e01b94819fb4f5d64616ea56857b906c2dd))
### Bug Fixes ### Bug Fixes
- added descending sort for commits on contributor section in settings page ([#365](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/365)) ([a715bbd](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/a715bbd933a87742e7bce3a44e8ba1bd419ad5eb)), closes [#363](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/363) [#363](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/363) [#363](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/363) * added descending sort for commits on contributor section in settings page ([#365](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/365)) ([a715bbd](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/a715bbd933a87742e7bce3a44e8ba1bd419ad5eb)), closes [#363](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/363) [#363](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/363) [#363](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/363)
- change schedule total courses text color to UTRP black ([#369](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/369)) ([b00bf6c](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b00bf6c180f1c6c3a61c5ef855e160ddf4af3ea4)) * change schedule total courses text color to UTRP black ([#369](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/369)) ([b00bf6c](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b00bf6c180f1c6c3a61c5ef855e160ddf4af3ea4))
- changed the font-weight of h1-course ([#370](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/370)) ([4f609ae](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/4f609aeec797c1f99f0a57e5aeef7b82756ea4bc)), closes [#347](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/347) * changed the font-weight of h1-course ([#370](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/370)) ([4f609ae](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/4f609aeec797c1f99f0a57e5aeef7b82756ea4bc)), closes [#347](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/347)
- ensure input elements take full width of parent ([#364](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/364)) ([c2007ef](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/c2007ef090aab3bbfcb8bca1ebc476255d09cb90)) * ensure input elements take full width of parent ([#364](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/364)) ([c2007ef](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/c2007ef090aab3bbfcb8bca1ebc476255d09cb90))
- remove screenshot padding class for png download for [#344](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/344) ([#376](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/376)) ([768ac77](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/768ac776ed4d5ca2113a032a93c2dc7432915aa1)), closes [#334](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/334) * remove screenshot padding class for png download for [#344](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/344) ([#376](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/376)) ([768ac77](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/768ac776ed4d5ca2113a032a93c2dc7432915aa1)), closes [#334](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/334)
- sentry issues ([#389](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/389)) ([2d0804f](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/2d0804f90e5d7a9ff83f7fd5c5acfdc7c1b1cc84)) * sentry issues ([#389](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/389)) ([2d0804f](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/2d0804f90e5d7a9ff83f7fd5c5acfdc7c1b1cc84))
- typo in settings page ([#386](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/386)) ([d357735](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/d3577358d0d1fb60f2c776ae4b01e255fcf9109e)) * typo in settings page ([#386](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/386)) ([d357735](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/d3577358d0d1fb60f2c776ae4b01e255fcf9109e))
- **ui:** add space before/after forward slash in "ASYNC/OTHER" text ([#366](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/366)) ([86792eb](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/86792eb56f04b615f7d52b2f417b88f4cb9a82ec)) * **ui:** add space before/after forward slash in "ASYNC/OTHER" text ([#366](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/366)) ([86792eb](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/86792eb56f04b615f7d52b2f417b88f4cb9a82ec))
- **ui:** duplicate schedule warning ([#295](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/295)) ([7346720](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/73467208947e0116ce8538052ee75dea1d8038f9)) * **ui:** duplicate schedule warning ([#295](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/295)) ([7346720](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/73467208947e0116ce8538052ee75dea1d8038f9))
- **ui:** main popup now shows 0 for empty schedule ([#395](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/395)) ([8de88d6](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/8de88d6ad7d4c2b5c3aa08e1efc59f7226b40c6b)) * **ui:** main popup now shows 0 for empty schedule ([#395](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/395)) ([8de88d6](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/8de88d6ad7d4c2b5c3aa08e1efc59f7226b40c6b))
- **ui:** multiple instructors are formatted properly, displays last name only, and are capitalized in all course blocks ([#342](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/342)) ([#403](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/403)) ([50e88fa](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/50e88fa015e0290fbe0dab8a19f8fcdbc4dd02b0)) * **ui:** multiple instructors are formatted properly, displays last name only, and are capitalized in all course blocks ([#342](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/342)) ([#403](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/403)) ([50e88fa](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/50e88fa015e0290fbe0dab8a19f8fcdbc4dd02b0))
- **ui:** placeholder text for no instructor course [#400](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/400) ([#402](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/402)) ([b3ae91d](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b3ae91d8f3cebb89e5e5cea7f1200d28326afb4d)) * **ui:** placeholder text for no instructor course [#400](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/400) ([#402](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/402)) ([b3ae91d](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b3ae91d8f3cebb89e5e5cea7f1200d28326afb4d))
## [2.0.1](https://github.com/Longhorn-Developers/UT-Registration-Plus/compare/v2.0.0...v2.0.1) (2024-10-17) ## [2.0.1](https://github.com/Longhorn-Developers/UT-Registration-Plus/compare/v2.0.0...v2.0.1) (2024-10-17)
### Features ### Features
- spring 2024 instructors db ([#317](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/317)) ([79dd29c](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/79dd29cfc9e849b09e7d91bd0eed51c1c93b3352)) * spring 2024 instructors db ([#317](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/317)) ([79dd29c](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/79dd29cfc9e849b09e7d91bd0eed51c1c93b3352))
### Bug Fixes ### Bug Fixes
- add a little error checking to settings ([#315](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/315)) ([e261641](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/e261641e5985d8bd5047d8a0be5d1caae844e40f)) * add a little error checking to settings ([#315](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/315)) ([e261641](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/e261641e5985d8bd5047d8a0be5d1caae844e40f))
- gulp zip ([#314](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/314)) ([05f00b2](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/05f00b23d26b90f564710db4364426e90c8d6831)) * gulp zip ([#314](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/314)) ([05f00b2](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/05f00b23d26b90f564710db4364426e90c8d6831))
- migration loop ([aeff5e0](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/aeff5e09a238503293c3882d97d40270da1e4883)) * migration loop ([aeff5e0](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/aeff5e09a238503293c3882d97d40270da1e4883))
- show calendar in active window ([#312](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/312)) ([ceba38b](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/ceba38b1ac74ec9e6630222183bd466a8d12c27d)) * show calendar in active window ([#312](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/312)) ([ceba38b](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/ceba38b1ac74ec9e6630222183bd466a8d12c27d))
## [2.0.0](https://github.com/Longhorn-Developers/UT-Registration-Plus/compare/b4e8c7589e53f1064d70703459cc6d66fae1b04c...v2.0.0) (2024-10-15) ## [2.0.0](https://github.com/Longhorn-Developers/UT-Registration-Plus/compare/b4e8c7589e53f1064d70703459cc6d66fae1b04c...v2.0.0) (2024-10-15)
### Features ### Features
- abhinavchadaga/course-catalog-popup ([#128](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/128)) ([745f9dd](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/745f9dd6fb96ccc0eace7189b87abf9a38f03828)) * abhinavchadaga/course-catalog-popup ([#128](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/128)) ([745f9dd](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/745f9dd6fb96ccc0eace7189b87abf9a38f03828))
- abhinavchadaga/reusable-popup-prompt ([#148](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/148)) ([44af9e1](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/44af9e16e4bf3b92c9a4fa0e779197f4f9ecb237)) * abhinavchadaga/reusable-popup-prompt ([#148](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/148)) ([44af9e1](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/44af9e16e4bf3b92c9a4fa0e779197f4f9ecb237))
- actually sum for duplicate semesters (different uniques) ([#202](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/202)) ([d3f64ec](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/d3f64ec79eb64ebe72ae28991127dbe521823842)) * actually sum for duplicate semesters (different uniques) ([#202](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/202)) ([d3f64ec](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/d3f64ec79eb64ebe72ae28991127dbe521823842))
- add button to the rows, use new ConflictsWithWarning component ([bec2649](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/bec2649fc1244bffb5cb03809db62cc0ea477260)) * add button to the rows, use new ConflictsWithWarning component ([bec2649](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/bec2649fc1244bffb5cb03809db62cc0ea477260))
- add buttons with icons in tailwind ([93b65ac](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/93b65ac2edef3fc728305cc51d1a32ecf5073274)) * add buttons with icons in tailwind ([93b65ac](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/93b65ac2edef3fc728305cc51d1a32ecf5073274))
- add cal save buttons (no functionality) ([53e7c7f](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/53e7c7fedaf1f268d2d7d06ff1a5df9e2af2306d)) * add cal save buttons (no functionality) ([53e7c7f](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/53e7c7fedaf1f268d2d7d06ff1a5df9e2af2306d))
- add Calendar Component ([e0212d5](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/e0212d510928e5e95d3ba75e391c34714f1bb035)) * add Calendar Component ([e0212d5](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/e0212d510928e5e95d3ba75e391c34714f1bb035))
- add Calendar schedules component (clicking on storybook not working) ([d1a336e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/d1a336e903f09b04b89f11ba7ede2f7d26e0ac3c)) * add Calendar schedules component (clicking on storybook not working) ([d1a336e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/d1a336e903f09b04b89f11ba7ede2f7d26e0ac3c))
- add CalendarHeader and its Storybook, need to resize ([23276e5](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/23276e5c7c907261b1d02e9006d8021d99b43984)) * add CalendarHeader and its Storybook, need to resize ([23276e5](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/23276e5c7c907261b1d02e9006d8021d99b43984))
- add check-path-alias custom ESLint rule ([#123](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/123)) ([208103d](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/208103d7081abcf5b31bf36335320aaf7d213464)) * add check-path-alias custom ESLint rule ([#123](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/123)) ([208103d](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/208103d7081abcf5b31bf36335320aaf7d213464))
- add chrome.storage api mocks for storybook use ([#141](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/141)) ([3839bff](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/3839bff29ef6f0ecfad1e975e685df9a64d96c92)) * add chrome.storage api mocks for storybook use ([#141](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/141)) ([3839bff](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/3839bff29ef6f0ecfad1e975e685df9a64d96c92))
- add CSS for calendarCell div ([6cdcf49](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/6cdcf4930d9868c0ed45820f66102d89a644cfb6)) * add CSS for calendarCell div ([6cdcf49](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/6cdcf4930d9868c0ed45820f66102d89a644cfb6))
- add CSS for hourLine div ([0ba6153](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0ba61534cbfc83408cb64eb1145ecacef1ee8f04)) * add CSS for hourLine div ([0ba6153](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0ba61534cbfc83408cb64eb1145ecacef1ee8f04))
- add CSS for timeLabelContainer div ([56f6456](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/56f6456ce85f77edb9d6fa64ecb82a8388feec41)) * add CSS for timeLabelContainer div ([56f6456](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/56f6456ce85f77edb9d6fa64ecb82a8388feec41))
- add custom ESLint rule restrict-import-depth ([#110](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/110)) ([8c069b7](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/8c069b7ad339ed8db97bb5e3e6e88ab8d332489b)) * add custom ESLint rule restrict-import-depth ([#110](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/110)) ([8c069b7](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/8c069b7ad339ed8db97bb5e3e6e88ab8d332489b))
- add downloadBlob util ([2af351e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/2af351efa85264da5abeee27fbd091d4ce637041)) * add downloadBlob util ([2af351e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/2af351efa85264da5abeee27fbd091d4ce637041))
- add empty settings component - waiting on design ([9d0f210](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/9d0f2105481cc3d5affdb4bd69d428379ea92de3)) * add empty settings component - waiting on design ([9d0f210](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/9d0f2105481cc3d5affdb4bd69d428379ea92de3))
- add ImportantLinks Component ([5dbee6f](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/5dbee6f0c39e620c3b65a5e0156fd59ec8217ca7)) * add ImportantLinks Component ([5dbee6f](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/5dbee6f0c39e620c3b65a5e0156fd59ec8217ca7))
- add List component ([e6b4049](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/e6b40494031ca88894b2f918bb18448b70124481)) * add List component ([e6b4049](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/e6b40494031ca88894b2f918bb18448b70124481))
- add MIMEType ([0c76052](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0c760524781556cf089f1885dc4ff3fd567bfc2b)) * add MIMEType ([0c76052](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0c760524781556cf089f1885dc4ff3fd567bfc2b))
- add new db powered by UT_Grade_Parser ([#163](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/163)) ([60d1f48](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/60d1f48bd95132f0517258f017a7644d8aff5101)) * add new db powered by UT_Grade_Parser ([#163](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/163)) ([60d1f48](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/60d1f48bd95132f0517258f017a7644d8aff5101))
- add react-loading-skeleton package ([#244](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/244)) ([b4dd91a](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b4dd91ad2595d9583a60530c2c2ff6d829d2d5e5)) * add react-loading-skeleton package ([#244](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/244)) ([b4dd91a](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b4dd91ad2595d9583a60530c2c2ff6d829d2d5e5))
- add skeleton loader for course description + distribution ([#267](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/267)) ([c2cab40](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/c2cab407f3a07c1d3073e936c9d23cb1cecc9cb9)) * add skeleton loader for course description + distribution ([#267](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/267)) ([c2cab40](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/c2cab407f3a07c1d3073e936c9d23cb1cecc9cb9))
- add story for CalendarGridCell ([fd91c3b](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/fd91c3b12ef5670563e689d190be75ef1f695d1c)) * add story for CalendarGridCell ([fd91c3b](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/fd91c3b12ef5670563e689d190be75ef1f695d1c))
- add Storybook story ([cb3cb5d](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/cb3cb5d5fc18a68ca5a825f97b808b535aa1fe29)) * add Storybook story ([cb3cb5d](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/cb3cb5d5fc18a68ca5a825f97b808b535aa1fe29))
- add tailwind version of Button component ([28d93b3](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/28d93b3c25e1cbca3baea992a299d626ca823570)) * add tailwind version of Button component ([28d93b3](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/28d93b3c25e1cbca3baea992a299d626ca823570))
- add tickmarks to day div ([8b9cb06](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/8b9cb065c28b5dd38b7e1681839a81f55691a3c6)) * add tickmarks to day div ([8b9cb06](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/8b9cb065c28b5dd38b7e1681839a81f55691a3c6))
- add time column to Calendar Component ([9d68211](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/9d6821127e7ff9bf63cef659932ee7408de4c969)) * add time column to Calendar Component ([9d68211](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/9d6821127e7ff9bf63cef659932ee7408de4c969))
- add timeAndGrid div ([95e0544](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/95e0544b7301d382439b74038fb1b3e25dfe6d30)) * add timeAndGrid div ([95e0544](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/95e0544b7301d382439b74038fb1b3e25dfe6d30))
- added flag ;-; ([#195](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/195)) ([9b4d61c](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/9b4d61c2b0d8806b5d4a10296c1cc1266ac4229f)) * added flag ;-; ([#195](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/195)) ([9b4d61c](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/9b4d61c2b0d8806b5d4a10296c1cc1266ac4229f))
- added scrapedAt property ([#149](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/149)) ([8e181b3](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/8e181b3010dfe25ea1e4b4ba181cbe9944d6e92e)) * added scrapedAt property ([#149](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/149)) ([8e181b3](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/8e181b3010dfe25ea1e4b4ba181cbe9944d6e92e))
- additional changes to [#201](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/201) ([#224](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/224)) ([bc354f3](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/bc354f3798a02e6ebc3c66a8b5eee553c25a19d4)) * additional changes to [#201](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/201) ([#224](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/224)) ([bc354f3](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/bc354f3798a02e6ebc3c66a8b5eee553c25a19d4))
- aesthetically pleasing squishier course blocks when compressed ([#232](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/232)) ([438c82b](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/438c82bfb5db0f570b261d15368a05447939b0fb)) * aesthetically pleasing squishier course blocks when compressed ([#232](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/232)) ([438c82b](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/438c82bfb5db0f570b261d15368a05447939b0fb))
- align day labels and add to grid ([1bb6191](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/1bb6191244f40220a9af66cced4fe8f0c1e546a0)) * align day labels and add to grid ([1bb6191](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/1bb6191244f40220a9af66cced4fe8f0c1e546a0))
- alignment on calendar and header ([#109](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/109)) ([07ec5ab](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/07ec5abc3e1b40b801b7c977d21399b31222a4d3)) * alignment on calendar and header ([#109](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/109)) ([07ec5ab](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/07ec5abc3e1b40b801b7c977d21399b31222a4d3))
- async course adding and async/other course block adjustments ([#273](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/273)) ([668c8d0](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/668c8d00756a5e3e3daaade46380967c74eec1ae)) * async course adding and async/other course block adjustments ([#273](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/273)) ([668c8d0](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/668c8d00756a5e3e3daaade46380967c74eec1ae))
- async text hiding on Calendar's Bottom Bar when there are no async courses ([#152](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/152)) ([0dff122](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0dff12232c29415fa7bc5ac3771393a406ab738d)) * async text hiding on Calendar's Bottom Bar when there are no async courses ([#152](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/152)) ([0dff122](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0dff12232c29415fa7bc5ac3771393a406ab738d))
- basic CalendarCourseMeeting component laid out - missing Text and Right Icon ([da9e7aa](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/da9e7aac4135afa5184e4949c36a288ef6ab62a7)) * basic CalendarCourseMeeting component laid out - missing Text and Right Icon ([da9e7aa](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/da9e7aac4135afa5184e4949c36a288ef6ab62a7))
- Best Practices ([#102](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/102)) ([5eb7be2](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/5eb7be246cd2a1db27c7ca777d81074ae7bb3b82)) * Best Practices ([#102](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/102)) ([5eb7be2](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/5eb7be246cd2a1db27c7ca777d81074ae7bb3b82))
- beta builds ([#187](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/187)) ([8a5e12e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/8a5e12ec63539ae7199f0f1561f642cb9cf19302)) * beta builds ([#187](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/187)) ([8a5e12e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/8a5e12ec63539ae7199f0f1561f642cb9cf19302))
- better discord icon ([#205](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/205)) ([a3f5e0f](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/a3f5e0f27ffdfcb4e3ddd47140979aca379f9f42)) * better discord icon ([#205](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/205)) ([a3f5e0f](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/a3f5e0f27ffdfcb4e3ddd47140979aca379f9f42))
- bold red refresh error ([#220](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/220)) ([229a8a2](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/229a8a29e8d04dfbe15de200ceffc53b4f758413)) * bold red refresh error ([#220](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/220)) ([229a8a2](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/229a8a29e8d04dfbe15de200ceffc53b4f758413))
- bottom bar for the calendar page ([#91](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/91)) ([0f730d6](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0f730d6c50462c9f7d0428ebb379742305212ef6)) * bottom bar for the calendar page ([#91](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/91)) ([0f730d6](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0f730d6c50462c9f7d0428ebb379742305212ef6))
- build without errors ([babc925](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/babc925967b01f1064b8d8e067e7bc792dd57b0a)) * build without errors ([babc925](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/babc925967b01f1064b8d8e067e7bc792dd57b0a))
- calendar components 3rd attempt at merging ([#60](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/60)) ([4faca8c](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/4faca8c43befe19c9b05ff4f3afba420e016bb59)) * calendar components 3rd attempt at merging ([#60](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/60)) ([4faca8c](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/4faca8c43befe19c9b05ff4f3afba420e016bb59))
- Calendar Components 3rd Attempt at Merging ([#60](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/60)) ([ab2cd68](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/ab2cd688fae616742b39c0637291a65e508e23bd)) * Calendar Components 3rd Attempt at Merging ([#60](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/60)) ([ab2cd68](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/ab2cd688fae616742b39c0637291a65e508e23bd))
- calendar course block component ([#75](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/75)) ([00e0019](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/00e00197efb807d420196f2b030fc4dc71e9cd42)) * calendar course block component ([#75](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/75)) ([00e0019](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/00e00197efb807d420196f2b030fc4dc71e9cd42))
- calendar course block component ([#75](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/75)) ([a41cb3e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/a41cb3ed8711eff9a2fbbe435e867c073904f452)) * calendar course block component ([#75](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/75)) ([a41cb3e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/a41cb3ed8711eff9a2fbbe435e867c073904f452))
- calendar grid and grid cells ([#81](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/81)) ([bfeb239](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/bfeb2398aacf9a1fba892737b6ef0286acbc326f)) * calendar grid and grid cells ([#81](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/81)) ([bfeb239](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/bfeb2398aacf9a1fba892737b6ef0286acbc326f))
- Calendar Grid and Grid Cells ([#81](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/81)) ([dd2f696](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/dd2f696f8de2c0b291e917ef4d4cb2171b76712c)) * Calendar Grid and Grid Cells ([#81](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/81)) ([dd2f696](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/dd2f696f8de2c0b291e917ef4d4cb2171b76712c))
- calendar header formatting and data displaying ([#160](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/160)) ([5cce1c7](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/5cce1c79fc2b50843426ed290a1b53849375e4eb)) * calendar header formatting and data displaying ([#160](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/160)) ([5cce1c7](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/5cce1c79fc2b50843426ed290a1b53849375e4eb))
- calendar matchings ([#173](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/173)) ([791a42b](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/791a42bcd49478024b6f1a237a2d2a9f6211749e)) * calendar matchings ([#173](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/173)) ([791a42b](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/791a42bcd49478024b6f1a237a2d2a9f6211749e))
- Calendar Schedule component finished, fix: list didn't allow updates when adding a new schedule ([#115](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/115)) ([a99a557](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/a99a55788a0b9791ff048c8bbbaad5bada47c41f)) * Calendar Schedule component finished, fix: list didn't allow updates when adding a new schedule ([#115](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/115)) ([a99a557](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/a99a55788a0b9791ff048c8bbbaad5bada47c41f))
- calendar-course-cell-color-picker ([#157](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/157)) ([df18491](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/df1849180de2c793c10e3a49d2c862d236456ec2)) * calendar-course-cell-color-picker ([#157](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/157)) ([df18491](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/df1849180de2c793c10e3a49d2c862d236456ec2))
- can open tabs, updated injected popup heading. basically done ([35fab34](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/35fab3444582b436f63c7b16a26ebd5989c4bf3e)) * can open tabs, updated injected popup heading. basically done ([35fab34](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/35fab3444582b436f63c7b16a26ebd5989c4bf3e))
- change Chip to tailwind css. Fixed eslint for ConflictsWithWarning ([3568b8e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/3568b8eb5ee9ce3fe17f77f5641c0583bacc17a4)) * change Chip to tailwind css. Fixed eslint for ConflictsWithWarning ([3568b8e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/3568b8eb5ee9ce3fe17f77f5641c0583bacc17a4))
- check-path-alias autofix ([#124](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/124)) ([265652c](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/265652c4200a56b1ae62e6e94e0609fb4604c188)) * check-path-alias autofix ([#124](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/124)) ([265652c](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/265652c4200a56b1ae62e6e94e0609fb4604c188))
- chrome extension works ([35f3c72](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/35f3c7225049d760c6061ed827aa796514291e62)) * chrome extension works ([35f3c72](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/35f3c7225049d760c6061ed827aa796514291e62))
- color palette for calendar ([#118](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/118)) ([471e55d](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/471e55dcea1ae439658d00ed41570e2f218f0c3d)) * color palette for calendar ([#118](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/118)) ([471e55d](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/471e55dcea1ae439658d00ed41570e2f218f0c3d))
- Conventional Commits ([#103](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/103)) ([fe599df](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/fe599dfe7514ead880596d3b75c8370bde796e09)) * Conventional Commits ([#103](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/103)) ([fe599df](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/fe599dfe7514ead880596d3b75c8370bde796e09))
- convert all LabelsAndDetails Components to Tailwind ([9e0f9df](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/9e0f9df9de1a5c99657ddcef3b2eb101dd825b84)) * convert all LabelsAndDetails Components to Tailwind ([9e0f9df](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/9e0f9df9de1a5c99657ddcef3b2eb101dd825b84))
- course color generation ([#179](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/179)) ([5ed81e4](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/5ed81e4be99a8b7f3c68a3ba70358e4cbe5cc613)) * course color generation ([#179](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/179)) ([5ed81e4](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/5ed81e4be99a8b7f3c68a3ba70358e4cbe5cc613))
- course colors ([#175](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/175)) ([dc77cc2](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/dc77cc27da7ab521e290a8c9ba810573e677b6b8)) * course colors ([#175](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/175)) ([dc77cc2](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/dc77cc27da7ab521e290a8c9ba810573e677b6b8))
- Course Flag Tooltips ([#178](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/178)) ([ba2bc60](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/ba2bc60add2b87ccd4e9894c454d7a8d8382f0dd)) * Course Flag Tooltips ([#178](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/178)) ([ba2bc60](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/ba2bc60add2b87ccd4e9894c454d7a8d8382f0dd))
- course-catalog-injected-popup ([#98](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/98)) ([89d03f4](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/89d03f4244d324915cadadaf75a827221525d43f)) * course-catalog-injected-popup ([#98](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/98)) ([89d03f4](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/89d03f4244d324915cadadaf75a827221525d43f))
- CourseStatus Component implemented ([#83](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/83)) ([58d7df4](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/58d7df499ca9a8dfd4dc3aa47bc9d76837f21bf7)) * CourseStatus Component implemented ([#83](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/83)) ([58d7df4](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/58d7df499ca9a8dfd4dc3aa47bc9d76837f21bf7))
- CourseStatus Component implemented ([#83](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/83)) ([fa1d737](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/fa1d7374bcafbe19673dc31f33b3f8075e45f37a)) * CourseStatus Component implemented ([#83](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/83)) ([fa1d737](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/fa1d7374bcafbe19673dc31f33b3f8075e45f37a))
- create empty Popup story ([ad83ba4](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/ad83ba4cdc67f86096d0cbc2cb6659aa9be98a0b)) * create empty Popup story ([ad83ba4](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/ad83ba4cdc67f86096d0cbc2cb6659aa9be98a0b))
- Create icon helper ([#77](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/77)) ([ccea0f4](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/ccea0f4bd1e8d66dc0717d92c9e970040d9fbe9e)) * Create icon helper ([#77](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/77)) ([ccea0f4](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/ccea0f4bd1e8d66dc0717d92c9e970040d9fbe9e))
- Create icon helper ([#77](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/77)) ([1b51d65](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/1b51d65c89a4b544f4f2a9c60106e14300f9a3b0)) * Create icon helper ([#77](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/77)) ([1b51d65](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/1b51d65c89a4b544f4f2a9c60106e14300f9a3b0))
- Derek vinson/calendar header ([#94](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/94)) ([12d09b5](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/12d09b54cbf840993d17323b96cf274ec24c67ce)) * Derek vinson/calendar header ([#94](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/94)) ([12d09b5](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/12d09b54cbf840993d17323b96cf274ec24c67ce))
- Derek/disable updating ([#239](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/239)) ([0ab83ef](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0ab83efd47d75fb6c278994c7dc8a6d22b4b6b83)) * Derek/disable updating ([#239](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/239)) ([0ab83ef](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0ab83efd47d75fb6c278994c7dc8a6d22b4b6b83))
- Derek/export png ([#95](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/95)) ([58c2b46](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/58c2b4634a9d065ca156d27c4af69a504b7c2d2d)) * Derek/export png ([#95](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/95)) ([58c2b46](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/58c2b4634a9d065ca156d27c4af69a504b7c2d2d))
- DialogProvider component ([#198](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/198)) ([d1b921a](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/d1b921a5b000693d7f3dabaf84d8b9580c361941)) * DialogProvider component ([#198](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/198)) ([d1b921a](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/d1b921a5b000693d7f3dabaf84d8b9580c361941))
- dividers in calendar bottom bar ([#120](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/120)) ([eba5d9f](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/eba5d9f508576d2648bd2501e5d5aaff32592566)) * dividers in calendar bottom bar ([#120](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/120)) ([eba5d9f](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/eba5d9f508576d2648bd2501e5d5aaff32592566))
- **docs:** add extra acknowledgements ([e2cbfa3](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/e2cbfa3f48cb0b10a43134cf9784a44b13aa542d)) * **docs:** add extra acknowledgements ([e2cbfa3](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/e2cbfa3f48cb0b10a43134cf9784a44b13aa542d))
- drag only on vertical axis ([34a6449](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/34a644952995d4aedd18d11d327bd8589f5b2610)) * drag only on vertical axis ([34a6449](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/34a644952995d4aedd18d11d327bd8589f5b2610))
- early iteration of non-virtual list ([677aa62](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/677aa624d7fb2bbb922aaf8806abe979c3399e4e)) * early iteration of non-virtual list ([677aa62](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/677aa624d7fb2bbb922aaf8806abe979c3399e4e))
- enable TS strict mode ([#168](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/168)) ([efed1c0](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/efed1c0edbf93987c551952a03c9c4b3c461d819)) * enable TS strict mode ([#168](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/168)) ([efed1c0](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/efed1c0edbf93987c551952a03c9c4b3c461d819))
- experimental toggle for icons, left off for now ([#237](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/237)) ([f34dd95](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/f34dd95d7765322b6cecb2e817a46e0549d929a5)) * experimental toggle for icons, left off for now ([#237](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/237)) ([f34dd95](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/f34dd95d7765322b6cecb2e817a46e0549d929a5))
- fall 2023 grades ([#226](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/226)) ([863d980](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/863d980b2d1c706b1fc648f1a0de2a31515e339e)) * fall 2023 grades ([#226](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/226)) ([863d980](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/863d980b2d1c706b1fc648f1a0de2a31515e339e))
- finally fix grid JSX.Element generation ([e49fc29](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/e49fc295ba40a37f9bf59686adbd8b4f523cd9c6)) * finally fix grid JSX.Element generation ([e49fc29](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/e49fc295ba40a37f9bf59686adbd8b4f523cd9c6))
- finish ScheduleTotalHoursAndCourses ([12f680d](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/12f680d7e9aef826281c8f769825408dc6f9f9de)) * finish ScheduleTotalHoursAndCourses ([12f680d](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/12f680d7e9aef826281c8f769825408dc6f9f9de))
- fix icons on PopupMain and convert to tailwind ([#108](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/108)) ([87799d8](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/87799d8f02aa5986025982f768639afdb1b0267a)) * fix icons on PopupMain and convert to tailwind ([#108](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/108)) ([87799d8](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/87799d8f02aa5986025982f768639afdb1b0267a))
- fix save as button dividers ([#153](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/153)) ([7986549](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/7986549fdd40834a85bedbfd0862cdb21c9ae657)) * fix save as button dividers ([#153](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/153)) ([7986549](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/7986549fdd40834a85bedbfd0862cdb21c9ae657))
- grades by professor ([#225](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/225)) ([78d749a](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/78d749a8a96f63c32663b464e5b663f932c28ed0)) * grades by professor ([#225](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/225)) ([78d749a](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/78d749a8a96f63c32663b464e5b663f932c28ed0))
- html2canvas -> htmlToImage and fix derick's bugs ([bda0282](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/bda02826b14b96fd65a6f24218950e510c5aa3d8)) * html2canvas -> htmlToImage and fix derick's bugs ([bda0282](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/bda02826b14b96fd65a6f24218950e510c5aa3d8))
- icon added successfully ([3b588c2](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/3b588c20394523ddf90456e1ca58546e5b820c74)) * icon added successfully ([3b588c2](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/3b588c20394523ddf90456e1ca58546e5b820c74))
- implement Chip component ([23e881f](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/23e881f14cc80100d8f8deef6a25daaa72d83f07)) * implement Chip component ([23e881f](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/23e881f14cc80100d8f8deef6a25daaa72d83f07))
- implement flatten course schedule helper function ([e54f488](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/e54f488b170d5a9af646c1ac82e8b33579fef61d)) * implement flatten course schedule helper function ([e54f488](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/e54f488b170d5a9af646c1ac82e8b33579fef61d))
- implemented ConflictsWithWarning ([93f3a30](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/93f3a307b4acce6cc55fc411f1ea2d7576006b00)) * implemented ConflictsWithWarning ([93f3a30](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/93f3a307b4acce6cc55fc411f1ea2d7576006b00))
- implemented InfoCard ([21b6430](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/21b643000d884442e025534802be6bb1f6ba68e2)) * implemented InfoCard ([21b6430](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/21b643000d884442e025534802be6bb1f6ba68e2))
- Initial Splash Text Commit ([#208](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/208)) ([0534f60](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0534f607a51f1dd0905f6f45f08519cba65ea05a)) * Initial Splash Text Commit ([#208](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/208)) ([0534f60](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0534f607a51f1dd0905f6f45f08519cba65ea05a))
- limit schedules to 10 ([#272](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/272)) ([290b841](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/290b8415170bca631e5d71b08d88db80b02163f0)) * limit schedules to 10 ([#272](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/272)) ([290b841](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/290b8415170bca631e5d71b08d88db80b02163f0))
- link to your registered courses ([#228](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/228)) ([f83e012](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/f83e012d62e268d95dce19a30e54e34f3779142b)) * link to your registered courses ([#228](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/228)) ([f83e012](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/f83e012d62e268d95dce19a30e54e34f3779142b))
- list reordering ([#154](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/154)) ([038ebaa](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/038ebaa2689c14bc9906afb542ef62c21cb13177)) * list reordering ([#154](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/154)) ([038ebaa](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/038ebaa2689c14bc9906afb542ef62c21cb13177))
- listed versioning for beta builds ([#192](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/192)) ([0c42979](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0c429794230a91c4fd949715b7eea210ac18fee3)) * listed versioning for beta builds ([#192](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/192)) ([0c42979](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0c429794230a91c4fd949715b7eea210ac18fee3))
- lowercase instructor! ([#268](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/268)) ([9ec05ef](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/9ec05ef764b2451c05e2d084d92074fb1e984268)) * lowercase instructor! ([#268](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/268)) ([9ec05ef](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/9ec05ef764b2451c05e2d084d92074fb1e984268))
- made List more extensible ([cd34601](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/cd34601379d5cd2b53d967afbc954178834823b9)) * made List more extensible ([cd34601](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/cd34601379d5cd2b53d967afbc954178834823b9))
- match calendar designs & add functionality ([#176](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/176)) ([8027c3d](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/8027c3d1bf228053acbad3e232b030c9ddbaca6a)) * match calendar designs & add functionality ([#176](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/176)) ([8027c3d](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/8027c3d1bf228053acbad3e232b030c9ddbaca6a))
- migrate styles to TailwindCSS ([7e2f5ea](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/7e2f5eaed7d782bc886545f7241e0891d55cfae0)) * migrate styles to TailwindCSS ([7e2f5ea](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/7e2f5eaed7d782bc886545f7241e0891d55cfae0))
- migration update showing ([#293](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/293)) ([aede681](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/aede681d4bb5b01723eb9d68527f4e64991adfab)) * migration update showing ([#293](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/293)) ([aede681](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/aede681d4bb5b01723eb9d68527f4e64991adfab))
- missed one chip toggle there ([#245](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/245)) ([5ca24da](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/5ca24dab82509d34cf43af4359940476159d052f)) * missed one chip toggle there ([#245](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/245)) ([5ca24da](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/5ca24dab82509d34cf43af4359940476159d052f))
- newer grades and parameterized queries ([#238](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/238)) ([75ad416](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/75ad4167b6639bbcf58e2dc6dafc80ed4656a899)) * newer grades and parameterized queries ([#238](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/238)) ([75ad416](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/75ad4167b6639bbcf58e2dc6dafc80ed4656a899))
- one single exclamation mark did all that ([#235](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/235)) ([be87e41](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/be87e4181430e0df41683be5c9d0a1ce992b2c61)) * one single exclamation mark did all that ([#235](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/235)) ([be87e41](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/be87e4181430e0df41683be5c9d0a1ce992b2c61))
- open an injected course page on course block click in popup main ([#146](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/146)) ([2709484](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/27094846f70feb8d83c8d464ab0fa8dcd99b3e71)) * open an injected course page on course block click in popup main ([#146](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/146)) ([2709484](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/27094846f70feb8d83c8d464ab0fa8dcd99b3e71))
- pad unique ids to 5 digits ([#170](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/170)) ([b4ad687](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b4ad6870bfc88f68bdd7f87fe1d94c23d0a02b95)) * pad unique ids to 5 digits ([#170](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/170)) ([b4ad687](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b4ad6870bfc88f68bdd7f87fe1d94c23d0a02b95))
- parallelize initializeDB.ts promises ([9f1dcc6](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/9f1dcc667df9857e3d0469fe7112a9f985aad490)) * parallelize initializeDB.ts promises ([9f1dcc6](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/9f1dcc667df9857e3d0469fe7112a9f985aad490))
- popout icon for ccip in calendar ([#221](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/221)) ([6812d68](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/6812d685d08902f7b3d9d2e5293350c8170c6f06)) * popout icon for ccip in calendar ([#221](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/221)) ([6812d68](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/6812d685d08902f7b3d9d2e5293350c8170c6f06))
- popup schedule select ([#126](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/126)) ([7f2a589](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/7f2a5893d4dd82a0f077dca6dfd28e79f929766f)) * popup schedule select ([#126](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/126)) ([7f2a589](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/7f2a5893d4dd82a0f077dca6dfd28e79f929766f))
- PopupCourseBlock Component ([#79](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/79)) ([9accd17](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/9accd17bd418f8c9334e80b0f7e38673092ba208)) * PopupCourseBlock Component ([#79](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/79)) ([9accd17](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/9accd17bd418f8c9334e80b0f7e38673092ba208))
- PopupCourseBlock Component ([#79](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/79)) ([f045b40](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/f045b400a56569f7353eb00ecd0d081b68660fc5)) * PopupCourseBlock Component ([#79](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/79)) ([f045b40](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/f045b400a56569f7353eb00ecd0d081b68660fc5))
- proper injected styles ([#164](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/164)) ([e919e96](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/e919e96c53bc9bec7db3d09693d1ff0684b56e87)) * proper injected styles ([#164](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/164)) ([e919e96](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/e919e96c53bc9bec7db3d09693d1ff0684b56e87))
- readme animation ([#281](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/281)) ([da6d86c](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/da6d86c785f92f70f52ef0b4cab3dc14e0bd9790)) * readme animation ([#281](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/281)) ([da6d86c](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/da6d86c785f92f70f52ef0b4cab3dc14e0bd9790))
- refactor all components in common ([e544312](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/e5443122b422266a126de497b475020e298b2f1c)) * refactor all components in common ([e544312](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/e5443122b422266a126de497b475020e298b2f1c))
- refactor all components in injected ([0c44849](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0c44849e15333c3a5cbdf8972eb31ada0e830b0a)) * refactor all components in injected ([0c44849](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0c44849e15333c3a5cbdf8972eb31ada0e830b0a))
- refactor calendar ([28f1924](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/28f192472b7f244253b6a0b5339491b9740880f7)) * refactor calendar ([28f1924](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/28f192472b7f244253b6a0b5339491b9740880f7))
- Refactor database initialization code ([5e98f45](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/5e98f45210346f0e7bb69af5cf25e336c76416ca)) * Refactor database initialization code ([5e98f45](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/5e98f45210346f0e7bb69af5cf25e336c76416ca))
- release notes ([#283](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/283)) ([bd17e33](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/bd17e3353792df70ca2e33c8b7a32b5fb9acc7d2)) * release notes ([#283](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/283)) ([bd17e33](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/bd17e3353792df70ca2e33c8b7a32b5fb9acc7d2))
- report issue popup ([#261](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/261)) ([65ff6bf](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/65ff6bfbbfc6b696621628e448865155d0405f7f)) * report issue popup ([#261](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/261)) ([65ff6bf](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/65ff6bfbbfc6b696621628e448865155d0405f7f))
- rerouted directory to syllabus when click on professor name ([#211](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/211)) ([8959e0d](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/8959e0d9f7fdd82125f391f1ec51aa390ba9450d)) * rerouted directory to syllabus when click on professor name ([#211](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/211)) ([8959e0d](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/8959e0d9f7fdd82125f391f1ec51aa390ba9450d))
- sam's jokes ([#278](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/278)) ([895cd31](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/895cd31d8eb40e7e99fc0969b543e95bd070f6b7)) * sam's jokes ([#278](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/278)) ([895cd31](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/895cd31d8eb40e7e99fc0969b543e95bd070f6b7))
- save as PNG functionality ([ad18fbd](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/ad18fbd16235be0c75121b527867fac708670300)) * save as PNG functionality ([ad18fbd](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/ad18fbd16235be0c75121b527867fac708670300))
- schedule list item action menu ([#230](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/230)) ([15fc369](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/15fc3699cfda3ad56e5a262bd37dca166e2685dd)) * schedule list item action menu ([#230](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/230)) ([15fc369](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/15fc3699cfda3ad56e5a262bd37dca166e2685dd))
- screenshot whole page, hide certain elements, screenshot fixed size ([#180](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/180)) ([7d4c5d7](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/7d4c5d7be8b266b5f3caf2135c4f3fecb96d75be)) * screenshot whole page, hide certain elements, screenshot fixed size ([#180](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/180)) ([7d4c5d7](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/7d4c5d7be8b266b5f3caf2135c4f3fecb96d75be))
- settings page ([#260](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/260)) ([7a5c3a2](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/7a5c3a2e62c3a726735f9fe921f9e08d4092d0f9)) * settings page ([#260](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/260)) ([7a5c3a2](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/7a5c3a2e62c3a726735f9fe921f9e08d4092d0f9))
- show async courses in the bottom bar ([#204](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/204)) ([227de53](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/227de53e8453804f0791f269dae64ec388136390)) * show async courses in the bottom bar ([#204](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/204)) ([227de53](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/227de53e8453804f0791f269dae64ec388136390))
- some small changes for colors and font ([#201](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/201)) ([bae1da4](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/bae1da43d3373e12d593682e9fb69e19557b5749)) * some small changes for colors and font ([#201](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/201)) ([bae1da4](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/bae1da43d3373e12d593682e9fb69e19557b5749))
- splash text additions before v2 release ([#296](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/296)) ([e774f31](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/e774f316e3f92c03e79274a55f1f729178c9a14a)) * splash text additions before v2 release ([#296](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/296)) ([e774f31](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/e774f316e3f92c03e79274a55f1f729178c9a14a))
- splash text has arrived! ([#246](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/246)) ([9971435](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/9971435716dec11e954dc26c14bf7d1505563d0d)) * splash text has arrived! ([#246](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/246)) ([9971435](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/9971435716dec11e954dc26c14bf7d1505563d0d))
- Storybook for Vite ([#52](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/52)) ([9cc299c](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/9cc299ced6132644a5c2375b95a8a16a3482601b)) * Storybook for Vite ([#52](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/52)) ([9cc299c](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/9cc299ced6132644a5c2375b95a8a16a3482601b))
- swe title updates ([#310](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/310)) ([4629626](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/4629626a31934c491758ddca874e5018d9c22e57)) * swe title updates ([#310](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/310)) ([4629626](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/4629626a31934c491758ddca874e5018d9c22e57))
- switch button ([#229](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/229)) ([abae7a5](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/abae7a5c22ab944262d66ae897298b008a03c5f1)) * switch button ([#229](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/229)) ([abae7a5](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/abae7a5c22ab944262d66ae897298b008a03c5f1))
- temporary removal of waitlist etc ([#236](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/236)) ([d424ccc](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/d424ccce49ba05305b24cb61aeb4ffeada5bab33)) * temporary removal of waitlist etc ([#236](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/236)) ([d424ccc](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/d424ccce49ba05305b24cb61aeb4ffeada5bab33))
- UnoCSS (TailwindCSS) (Storybook only) ([#61](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/61)) ([85c7f78](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/85c7f7817c58f13f6a4e8bec13a45f6412ad87db)) * UnoCSS (TailwindCSS) (Storybook only) ([#61](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/61)) ([85c7f78](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/85c7f7817c58f13f6a4e8bec13a45f6412ad87db))
- UnoCSS (TailwindCSS) (Storybook only) ([#61](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/61)) ([6521a4b](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/6521a4b2a90af06e182c779f2fc7cb1a3b1e55c1)) * UnoCSS (TailwindCSS) (Storybook only) ([#61](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/61)) ([6521a4b](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/6521a4b2a90af06e182c779f2fc7cb1a3b1e55c1))
- unplugin-icons ([#62](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/62)) ([2d67b12](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/2d67b1218ff852c59901b77909615c5f54794a67)) * unplugin-icons ([#62](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/62)) ([2d67b12](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/2d67b1218ff852c59901b77909615c5f54794a67))
- unplugin-icons ([#62](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/62)) ([945e09b](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/945e09b49e4ffa9bd4b02442f6567bb99831923e)) * unplugin-icons ([#62](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/62)) ([945e09b](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/945e09b49e4ffa9bd4b02442f6567bb99831923e))
- update admin titles ([4cf8c3f](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/4cf8c3f9645cd8fda07244413cdc406105b12fec)) * update admin titles ([4cf8c3f](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/4cf8c3f9645cd8fda07244413cdc406105b12fec))
- update badge count when schedule changes ([#150](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/150)) ([a5e9e3c](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/a5e9e3c2145d61d8cc5788eb50fa19718e6d13bf)) * update badge count when schedule changes ([#150](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/150)) ([a5e9e3c](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/a5e9e3c2145d61d8cc5788eb50fa19718e6d13bf))
- update Button to v2 design ([863521f](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/863521fb3bb268131bd3f369064ae10a442b4fbc)) * update Button to v2 design ([863521f](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/863521fb3bb268131bd3f369064ae10a442b4fbc))
- update dialog component to headlessui ([#159](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/159)) ([442be8c](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/442be8cbee06ec403467b100d8d5300dd4a7ea72)) * update dialog component to headlessui ([#159](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/159)) ([442be8c](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/442be8cbee06ec403467b100d8d5300dd4a7ea72))
- update with TailwindCSS ([f3a8a7d](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/f3a8a7db560a6b28f96a2e976c8ed33af97fe77a)) * update with TailwindCSS ([f3a8a7d](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/f3a8a7db560a6b28f96a2e976c8ed33af97fe77a))
- updated calendar page and recruitment banner links ([#219](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/219)) ([a2303ee](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/a2303ee35f10aba5fa7ff5e307d0092a39f18830)) * updated calendar page and recruitment banner links ([#219](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/219)) ([a2303ee](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/a2303ee35f10aba5fa7ff5e307d0092a39f18830))
- updated divider component ([#99](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/99)) ([8ab60c9](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/8ab60c9f018143df594e7bfd0d321666289cc28c)) * updated divider component ([#99](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/99)) ([8ab60c9](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/8ab60c9f018143df594e7bfd0d321666289cc28c))
- updated Text component to latest design specification ([#70](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/70)) ([8b8433d](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/8b8433deaf8fe66f917fd66fb56cb0a748bc6e6e)) * updated Text component to latest design specification ([#70](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/70)) ([8b8433d](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/8b8433deaf8fe66f917fd66fb56cb0a748bc6e6e))
- updated Text component to latest design specification ([#70](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/70)) ([bb727f7](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/bb727f70bea5a4c2ff5dba7e9b4428c0c84de7b2)) * updated Text component to latest design specification ([#70](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/70)) ([bb727f7](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/bb727f70bea5a4c2ff5dba7e9b4428c0c84de7b2))
- updating joke styling and updating jokes array ([#277](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/277)) ([0da27e2](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0da27e2c46e9fc32efb80808715053c1f9f5165a)) * updating joke styling and updating jokes array ([#277](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/277)) ([0da27e2](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0da27e2c46e9fc32efb80808715053c1f9f5165a))
- use display: grid for calendarGrid ([b535a6e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b535a6eb32ac1091c8b5309ca3cfb6bab0b62526)) * use display: grid for calendarGrid ([b535a6e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b535a6eb32ac1091c8b5309ca3cfb6bab0b62526))
- use downloadBlob util ([#186](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/186)) ([2dfb10e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/2dfb10e57b51a08fcde2dc6638a81b5ec9bbc7ab)) * use downloadBlob util ([#186](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/186)) ([2dfb10e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/2dfb10e57b51a08fcde2dc6638a81b5ec9bbc7ab))
- use filter() instead of pop() ([063349d](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/063349d96d0ad008fa0dc1f0a8c7a27cf3f108ce)) * use filter() instead of pop() ([063349d](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/063349d96d0ad008fa0dc1f0a8c7a27cf3f108ce))
- use React-icons ([8df9ea5](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/8df9ea55a9f0bcb04c90314cb311bba9d1ebf2e3)) * use React-icons ([8df9ea5](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/8df9ea55a9f0bcb04c90314cb311bba9d1ebf2e3))
- UTRP v2 migration ([#292](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/292)) ([d22237d](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/d22237d561ddf6a2f8ed699ca4c11088a8b408e8)) * UTRP v2 migration ([#292](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/292)) ([d22237d](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/d22237d561ddf6a2f8ed699ca4c11088a8b408e8))
- working PNG and CAL downloads ([#119](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/119)) ([d9ee23c](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/d9ee23c5bbe27240a0e2849aae2eae81d7960bb5)) * working PNG and CAL downloads ([#119](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/119)) ([d9ee23c](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/d9ee23c5bbe27240a0e2849aae2eae81d7960bb5))
### Bug Fixes ### Bug Fixes
- add margin-top: -10px to p ([18406b0](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/18406b0c94604b1b524de03bf97e78cffe7a5bbf)) * add margin-top: -10px to p ([18406b0](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/18406b0c94604b1b524de03bf97e78cffe7a5bbf))
- added room number to course popup ([#231](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/231)) ([9eaff24](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/9eaff24cbb6d78d7f28521a07c32630a90a96f82)) * added room number to course popup ([#231](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/231)) ([9eaff24](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/9eaff24cbb6d78d7f28521a07c32630a90a96f82))
- align timeBlock div ([4dc8957](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/4dc8957c459d0ee57e40c67fa61194ace832327e)) * align timeBlock div ([4dc8957](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/4dc8957c459d0ee57e40c67fa61194ace832327e))
- async course display size ([#181](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/181)) ([949bbb0](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/949bbb0835bfb55a81f0800850aa084b4ed1bfc4)) * async course display size ([#181](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/181)) ([949bbb0](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/949bbb0835bfb55a81f0800850aa084b4ed1bfc4))
- broken close bracket ([b34aacb](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b34aacb06772af6f83d1f7bafe828ba43a10db85)) * broken close bracket ([b34aacb](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b34aacb06772af6f83d1f7bafe828ba43a10db85))
- broken file ([92462cf](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/92462cf0dffa222d75965885ee0e63181bce9890)) * broken file ([92462cf](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/92462cf0dffa222d75965885ee0e63181bce9890))
- bugs ([2a01506](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/2a0150600f26af5b7394f878e13c4d19611f3f64)) * bugs ([2a01506](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/2a0150600f26af5b7394f878e13c4d19611f3f64))
- build ([60ab140](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/60ab140c556ec56eca78b1f4e280dfb6e9dbb538)) * build ([60ab140](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/60ab140c556ec56eca78b1f4e280dfb6e9dbb538))
- build errors and merge in Casey's branch (driodiwb) ([39947b3](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/39947b3694f42f9d5ad2f21d044585aa3d12c407)) * build errors and merge in Casey's branch (driodiwb) ([39947b3](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/39947b3694f42f9d5ad2f21d044585aa3d12c407))
- build errors and restructure Calendar page ([c6a48dd](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/c6a48dd3f6025fe531c18e12b8730683d63f67ed)) * build errors and restructure Calendar page ([c6a48dd](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/c6a48dd3f6025fe531c18e12b8730683d63f67ed))
- calendar course cell colors ([74be880](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/74be880f9d2dc340ba48416429711fb28915baa2)) * calendar course cell colors ([74be880](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/74be880f9d2dc340ba48416429711fb28915baa2))
- calendar storybook issue ([#125](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/125)) ([0c5bec8](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0c5bec8002022cb4702f3879f43fcd32b9fa6b5a)) * calendar storybook issue ([#125](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/125)) ([0c5bec8](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0c5bec8002022cb4702f3879f43fcd32b9fa6b5a))
- Calendar View/Scaling Issues ([#144](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/144)) ([4c61ebd](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/4c61ebd3fc93240903f1224f9dd3057a23d30046)) * Calendar View/Scaling Issues ([#144](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/144)) ([4c61ebd](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/4c61ebd3fc93240903f1224f9dd3057a23d30046))
- CalendarCourseCell spacing ([13c69ef](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/13c69ef862f0214dfa6c9368fc3463519aa8f2f0)) * CalendarCourseCell spacing ([13c69ef](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/13c69ef862f0214dfa6c9368fc3463519aa8f2f0))
- change Chromatic action to build current branch, not base branch ([#100](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/100)) ([e73c9fe](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/e73c9fe417169e73c395cde1aeb841eee8add579)) * change Chromatic action to build current branch, not base branch ([#100](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/100)) ([e73c9fe](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/e73c9fe417169e73c395cde1aeb841eee8add579))
- change material icons to material symbols ([#71](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/71)) ([52e34cb](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/52e34cb830ff1f12659703776bd3d9a24815ee00)) * change material icons to material symbols ([#71](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/71)) ([52e34cb](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/52e34cb830ff1f12659703776bd3d9a24815ee00))
- chromatic build ([11303da](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/11303daebcc1e4de340463e6266082dc0920582d)) * chromatic build ([11303da](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/11303daebcc1e4de340463e6266082dc0920582d))
- chromatic builds on PRs ([#140](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/140)) ([78a6939](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/78a69399292767a1f8eac66e4c86cbcb8aad019d)) * chromatic builds on PRs ([#140](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/140)) ([78a6939](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/78a69399292767a1f8eac66e4c86cbcb8aad019d))
- chromatic storybook - CourseCatalogInjectedPopup ([#106](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/106)) ([ced2997](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/ced29975b20a2a5beac51ea875627a2b1042e5c2)) * chromatic storybook - CourseCatalogInjectedPopup ([#106](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/106)) ([ced2997](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/ced29975b20a2a5beac51ea875627a2b1042e5c2))
- clean up [#173](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/173) ([#174](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/174)) ([afa634f](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/afa634f0853dc16cf313c129434d49bf132388d0)) * clean up [#173](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/173) ([#174](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/174)) ([afa634f](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/afa634f0853dc16cf313c129434d49bf132388d0))
- cleanup imports ([#112](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/112)) ([b17c3fa](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b17c3fae6d9a8fdb2f6de84dc28d00bc31e7bcc8)) * cleanup imports ([#112](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/112)) ([b17c3fa](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b17c3fae6d9a8fdb2f6de84dc28d00bc31e7bcc8))
- conflict row bug ([#130](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/130)) ([a8ea3bc](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/a8ea3bc683f88fc33191a8cacf649be83f6758f8)) * conflict row bug ([#130](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/130)) ([a8ea3bc](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/a8ea3bc683f88fc33191a8cacf649be83f6758f8))
- ConflictsWithWarning ([1599e48](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/1599e48d75d4877b3515c943120d83b59d084a55)) * ConflictsWithWarning ([1599e48](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/1599e48d75d4877b3515c943120d83b59d084a55))
- correct parsing of noon ([#155](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/155)) ([91f62e1](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/91f62e1943633eaef7dc8d437e6a7397456a9123)) * correct parsing of noon ([#155](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/155)) ([91f62e1](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/91f62e1943633eaef7dc8d437e6a7397456a9123))
- db with proper insertion order ([8e79d6a](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/8e79d6a6a87210e0a30584c0c9ceb60bd3a33665)) * db with proper insertion order ([8e79d6a](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/8e79d6a6a87210e0a30584c0c9ceb60bd3a33665))
- delete storybook timestamp file ([f93a98e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/f93a98e46ae76e9b1474c8143bfc3f5076e8b91f)) * delete storybook timestamp file ([f93a98e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/f93a98e46ae76e9b1474c8143bfc3f5076e8b91f))
- dialog movement ([#227](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/227)) ([bc5d68c](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/bc5d68ce18f818c285ef7f5eda03f499365ee2e8)) * dialog movement ([#227](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/227)) ([bc5d68c](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/bc5d68ce18f818c285ef7f5eda03f499365ee2e8))
- disabled [object Object] hover message on dialog popups ([#284](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/284)) ([dcc1d81](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/dcc1d81a74922ba27ad2a6859f978f3f20136178)) * disabled [object Object] hover message on dialog popups ([#284](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/284)) ([dcc1d81](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/dcc1d81a74922ba27ad2a6859f978f3f20136178))
- divider usage in HeaderAndActions ([#113](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/113)) ([84e8320](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/84e8320e8fce5961877a5745e89419a722055ed5)) * divider usage in HeaderAndActions ([#113](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/113)) ([84e8320](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/84e8320e8fce5961877a5745e89419a722055ed5))
- doesn't autoload on pages that don't have pages to load ([#270](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/270)) ([88eeb62](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/88eeb620aec52d6e4172cc908843339412ade90b)) * doesn't autoload on pages that don't have pages to load ([#270](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/270)) ([88eeb62](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/88eeb620aec52d6e4172cc908843339412ade90b))
- don't crash on cultural diversity flag ([#196](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/196)) ([5b1e451](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/5b1e4513e29203a54ed9f4913c227d6c45d2e67a)) * don't crash on cultural diversity flag ([#196](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/196)) ([5b1e451](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/5b1e4513e29203a54ed9f4913c227d6c45d2e67a))
- eslint and remove React-beautiful-dnd ([6af805b](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/6af805ba3a7b04b7e5705d3d597b5ace686d61e0)) * eslint and remove React-beautiful-dnd ([6af805b](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/6af805ba3a7b04b7e5705d3d597b5ace686d61e0))
- extra space ([0f43796](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0f43796cd864acd012fc1242cbdf34844df62406)) * extra space ([0f43796](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0f43796cd864acd012fc1242cbdf34844df62406))
- Fix popup drag hitbox ([#216](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/216)) ([7a40008](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/7a40008c1e3846f09ac4eeadc4a50f810ffc0d90)) * Fix popup drag hitbox ([#216](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/216)) ([7a40008](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/7a40008c1e3846f09ac4eeadc4a50f810ffc0d90))
- fixed bug where activeSchedule doesn't update correctly ([#158](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/158)) ([a409090](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/a409090b904686b76a5db52af980e81108b97082)) * fixed bug where activeSchedule doesn't update correctly ([#158](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/158)) ([a409090](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/a409090b904686b76a5db52af980e81108b97082))
- fixed bug with course cells after 12 PM extending past midnight ([#122](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/122)) ([f22a3cd](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/f22a3cd7c0df138ca6ecd4b4a4efaa7ce845c3dd)) * fixed bug with course cells after 12 PM extending past midnight ([#122](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/122)) ([f22a3cd](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/f22a3cd7c0df138ca6ecd4b4a4efaa7ce845c3dd))
- fixed issues involving course meeting objects not being recognized as course meeting objects ([#132](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/132)) ([3406e9a](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/3406e9a0e2644218fc06cbd0b05046df5339264c)) * fixed issues involving course meeting objects not being recognized as course meeting objects ([#132](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/132)) ([3406e9a](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/3406e9a0e2644218fc06cbd0b05046df5339264c))
- Fixed typescript error ([#161](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/161)) ([df7a7c6](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/df7a7c65d695cb5c5a825ac9f5ecc48438735b65)) * Fixed typescript error ([#161](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/161)) ([df7a7c6](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/df7a7c65d695cb5c5a825ac9f5ecc48438735b65))
- grade dist when no instructor ([#269](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/269)) ([6a363ae](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/6a363aeb5ccb1c11e15db317b34c4f04a3c9aafc)) * grade dist when no instructor ([#269](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/269)) ([6a363ae](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/6a363aeb5ccb1c11e15db317b34c4f04a3c9aafc))
- grid JSX.Element generation ([b691bf3](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b691bf3231d5002a631687f26c7409e311237662)) * grid JSX.Element generation ([b691bf3](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b691bf3231d5002a631687f26c7409e311237662))
- icon library resolution ([#74](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/74)) ([bb3b313](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/bb3b313fd272bba12f99270c912e046df5358fed)) * icon library resolution ([#74](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/74)) ([bb3b313](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/bb3b313fd272bba12f99270c912e046df5358fed))
- idk why that comment was there ([#177](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/177)) ([c5fc621](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/c5fc6219e1540e1fb889d8bedc7296190103a56b)) * idk why that comment was there ([#177](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/177)) ([c5fc621](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/c5fc6219e1540e1fb889d8bedc7296190103a56b))
- import error ([152bc45](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/152bc4577685605ae95f39d9e670b5449e32e0e9)) * import error ([152bc45](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/152bc4577685605ae95f39d9e670b5449e32e0e9))
- improper list data propagation ([#240](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/240)) ([149fda3](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/149fda3b721dcc3d8ffa6c2398c28e39dcb62aaa)) * improper list data propagation ([#240](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/240)) ([149fda3](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/149fda3b721dcc3d8ffa6c2398c28e39dcb62aaa))
- improve dialog handling and error management in list items ([#257](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/257)) ([1942508](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/1942508d8d11f51b62806894ae13162b6404753b)) * improve dialog handling and error management in list items ([#257](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/257)) ([1942508](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/1942508d8d11f51b62806894ae13162b6404753b))
- injection not working from som/elie commit ([#145](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/145)) ([591687e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/591687eee8731b3649a5f8c1357a416eb2992a93)) * injection not working from som/elie commit ([#145](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/145)) ([591687e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/591687eee8731b3649a5f8c1357a416eb2992a93))
- list component fixed ([#162](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/162)) ([5714ed1](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/5714ed16d72c5442f58366ac51f40cc32ea406ab)) * list component fixed ([#162](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/162)) ([5714ed1](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/5714ed16d72c5442f58366ac51f40cc32ea406ab))
- made list draggable only by handle ([cbb190b](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/cbb190bf4b3ad694c87b650489e1fca5aa6b7826)) * made list draggable only by handle ([cbb190b](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/cbb190bf4b3ad694c87b650489e1fca5aa6b7826))
- margins on list component ([cc71389](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/cc7138949cf77d1bcf1520633d669e939540575e)) * margins on list component ([cc71389](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/cc7138949cf77d1bcf1520633d669e939540575e))
- non-determinstic options page generation ([#137](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/137)) ([d700110](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/d70011016a45f5de62b06839a31c634637024f4a)) * non-determinstic options page generation ([#137](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/137)) ([d700110](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/d70011016a45f5de62b06839a31c634637024f4a))
- non-virtual dnd ([837fddf](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/837fddf8048350b0b25a58bbd16c1957fbad6edb)) * non-virtual dnd ([837fddf](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/837fddf8048350b0b25a58bbd16c1957fbad6edb))
- old icon removed in .tsx ([4d387e8](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/4d387e8063314c7c6d7452b746728e2cf85a1787)) * old icon removed in .tsx ([4d387e8](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/4d387e8063314c7c6d7452b746728e2cf85a1787))
- only show button hover effects when not disabled ([8e3aa7e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/8e3aa7ef3380836fd36a12698b1f6982e110c0f7)) * only show button hover effects when not disabled ([8e3aa7e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/8e3aa7ef3380836fd36a12698b1f6982e110c0f7))
- openTabFromContentScript TS issue ([3a48859](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/3a48859dddc0e85649ff6a949e9afd22c962825d)) * openTabFromContentScript TS issue ([3a48859](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/3a48859dddc0e85649ff6a949e9afd22c962825d))
- options page ([#131](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/131)) ([dc100b5](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/dc100b5d3ac1db5f1dc011ea2536c286f56fa55b)) * options page ([#131](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/131)) ([dc100b5](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/dc100b5d3ac1db5f1dc011ea2536c286f56fa55b))
- reactivity ([#188](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/188)) ([4f4f34e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/4f4f34e281e8aabcdbf8b06652d05bca3554b11f)) * reactivity ([#188](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/188)) ([4f4f34e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/4f4f34e281e8aabcdbf8b06652d05bca3554b11f))
- README.md ([a30fecf](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/a30fecf8ec76ecae03be9bb4d813803b9ffdb490)) * README.md ([a30fecf](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/a30fecf8ec76ecae03be9bb4d813803b9ffdb490))
- README.md ([b27b21b](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b27b21bbfcc8fbdc130c3fa85776479451745b7b)) * README.md ([b27b21b](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b27b21bbfcc8fbdc130c3fa85776479451745b7b))
- refactor AST parsing for custom ESLint rule ([62f0851](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/62f0851406bf82d3d0481fed40462bdd30ffcf1b)) * refactor AST parsing for custom ESLint rule ([62f0851](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/62f0851406bf82d3d0481fed40462bdd30ffcf1b))
- remote react-window fully (from List component) ([#114](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/114)) ([5f1c023](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/5f1c0231e483bc571ef944bbc0b950ab20d31028)) * remote react-window fully (from List component) ([#114](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/114)) ([5f1c023](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/5f1c0231e483bc571ef944bbc0b950ab20d31028))
- remove course name from the syllabi lookup ([#200](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/200)) ([bcb5a8c](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/bcb5a8c469c4b5c1909880ab6789d67d04487ed2)) * remove course name from the syllabi lookup ([#200](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/200)) ([bcb5a8c](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/bcb5a8c469c4b5c1909880ab6789d67d04487ed2))
- remove extra spacing ([#121](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/121)) ([6ba8b68](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/6ba8b68654dc182bd2a084f93b0f4f7d5c132862)) * remove extra spacing ([#121](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/121)) ([6ba8b68](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/6ba8b68654dc182bd2a084f93b0f4f7d5c132862))
- remove white space after duplicate schedule regex matching ([#286](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/286)) ([d73615e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/d73615e28129ee7d78604c6b295ec572b11be46e)) * remove white space after duplicate schedule regex matching ([#286](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/286)) ([d73615e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/d73615e28129ee7d78604c6b295ec572b11be46e))
- rename to course block and fix line height for styling ([b602b0b](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b602b0b895416a26214e934f9650a8ec0a10711e)) * rename to course block and fix line height for styling ([b602b0b](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b602b0b895416a26214e934f9650a8ec0a10711e))
- revert "chore: add default story" ([aef8c3d](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/aef8c3d9873c6df79f6a54ab4c669ee1849b5ea5)) * revert "chore: add default story" ([aef8c3d](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/aef8c3d9873c6df79f6a54ab4c669ee1849b5ea5))
- revert "rename to course block and fix line height for styling" ([0273a23](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0273a239139c0f3c0ad773ed8ab1cd4ad8d22fa3)) * revert "rename to course block and fix line height for styling" ([0273a23](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/0273a239139c0f3c0ad773ed8ab1cd4ad8d22fa3))
- revert CalendarGrid and CalendarGridCell back to SCSS from Tailwind ([56306ab](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/56306ab9440baf5ca1158f95d788de7ba42d73d8)) * revert CalendarGrid and CalendarGridCell back to SCSS from Tailwind ([56306ab](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/56306ab9440baf5ca1158f95d788de7ba42d73d8))
- revert last commit ([27d945f](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/27d945f57c76a1c2f31fee9f98c324fab6183bb6)) * revert last commit ([27d945f](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/27d945f57c76a1c2f31fee9f98c324fab6183bb6))
- Schedule Switching Bugs ([#138](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/138)) ([c51e688](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/c51e6881d186e8bef056e483e2bca95585d5eac6)) * Schedule Switching Bugs ([#138](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/138)) ([c51e688](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/c51e6881d186e8bef056e483e2bca95585d5eac6))
- support classes with no location ([#242](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/242)) ([3ff06e0](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/3ff06e043b112bc232c9c173e72b2ea99609cf7a)) * support classes with no location ([#242](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/242)) ([3ff06e0](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/3ff06e043b112bc232c9c173e72b2ea99609cf7a))
- theme colors ([2f537b4](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/2f537b4f3e3946241f2e287d9ae075e5a2aa7087)) * theme colors ([2f537b4](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/2f537b4f3e3946241f2e287d9ae075e5a2aa7087))
- type issues by using correct import ([#111](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/111)) ([19fe070](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/19fe070491be9e2d40f12918561f6f6ac5921237)) * type issues by using correct import ([#111](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/111)) ([19fe070](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/19fe070491be9e2d40f12918561f6f6ac5921237))
- **ui:** unhid settings button ([#288](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/288)) ([db1eac3](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/db1eac33a2786a3db87f0e6b3679233a85ab923f)) * **ui:** unhid settings button ([#288](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/288)) ([db1eac3](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/db1eac33a2786a3db87f0e6b3679233a85ab923f))
- undefined color case ([9aa78a0](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/9aa78a02a5d4f68daa062e4892875cf5f568306c)) * undefined color case ([9aa78a0](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/9aa78a02a5d4f68daa062e4892875cf5f568306c))
- unocss theme color namings ([79d7832](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/79d7832d0987b8a7c9650b984f72ffd702682423)) * unocss theme color namings ([79d7832](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/79d7832d0987b8a7c9650b984f72ffd702682423))
- update alignment ([7eb3113](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/7eb3113adaa0917c0275576c3366c387bfe77440)) * update alignment ([7eb3113](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/7eb3113adaa0917c0275576c3366c387bfe77440))
- update daysOfWeek with new DAY_MAP keys ([ecdaadb](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/ecdaadb83eb21b144d07d573613fd8971f0a5ce2)) * update daysOfWeek with new DAY_MAP keys ([ecdaadb](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/ecdaadb83eb21b144d07d573613fd8971f0a5ce2))
- visual overflow bug when editing schedule name ([#251](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/251)) ([e8d2c2e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/e8d2c2e1429072fcc1173ee770f06b07e9ddda20)) * visual overflow bug when editing schedule name ([#251](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/251)) ([e8d2c2e](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/e8d2c2e1429072fcc1173ee770f06b07e9ddda20))
- vitest path alias bug ([ee37897](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/ee37897df4f65cd2d285e2ad628be43aebb21ea1)) * vitest path alias bug ([ee37897](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/ee37897df4f65cd2d285e2ad628be43aebb21ea1))
### Reverts ### Reverts
- Revert "individual bug fix" ([b4e8c75](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b4e8c7589e53f1064d70703459cc6d66fae1b04c)) * Revert "individual bug fix" ([b4e8c75](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/b4e8c7589e53f1064d70703459cc6d66fae1b04c))
- color palette for calendar ([#118](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/118)) ([51bbd65](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/51bbd6590bf284ce54644b014466c8b2c73b8925)) * color palette for calendar ([#118](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues/118)) ([51bbd65](https://github.com/Longhorn-Developers/UT-Registration-Plus/commit/51bbd6590bf284ce54644b014466c8b2c73b8925))

32
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,32 @@
# UT Registration Plus Code of Conduct
Like the technical community as a whole, the UT Registration Plus team and community is made up of a mixture of professionals and volunteers from all over the world, working on every aspect of the mission - including mentorship, teaching, and connecting people.
Diversity is one of our huge strengths, but it can also lead to communication issues and unhappiness. To that end, we have a few ground rules that we ask people to adhere to. This code applies equally to founders, mentors and those seeking help and guidance.
This isnt an exhaustive list of things that you cant do. Rather, take it in the spirit in which its intended - a guide to make it easier to enrich all of us and the technical communities in which we participate.
This code of conduct applies to all spaces managed by the UT Registration Plus project or Longhorn Developers. This includes IRC, the mailing lists, the issue tracker, DSF events, and any other forums created by the project team which the community uses for communication. In addition, violations of this code outside these spaces may affect a person's ability to participate within them.
If you believe someone is violating the code of conduct, we ask that you report it by emailing [contact@longhorns.dev](mailto:contact@longhorns.dev). For more details please see our
- **Be friendly and patient.**
- **Be welcoming.** We strive to be a community that welcomes and supports people of all backgrounds and identities. This includes, but is not limited to members of any race, ethnicity, culture, national origin, colour, immigration status, social and economic class, educational level, sex, sexual orientation, gender identity and expression, age, size, family status, political belief, religion, and mental and physical ability.
- **Be considerate.** Your work will be used by other people, and you in turn will depend on the work of others. Any decision you take will affect users and colleagues, and you should take those consequences into account when making decisions. Remember that we're a world-wide community, so you might not be communicating in someone else's primary language.
- **Be respectful.** Not all of us will agree all the time, but disagreement is no excuse for poor behavior and poor manners. We might all experience some frustration now and then, but we cannot allow that frustration to turn into a personal attack. Its important to remember that a community where people feel uncomfortable or threatened is not a productive one. Members of the UT Registration Plus community should be respectful when dealing with other members as well as with people outside the UT Registration Plus community.
- **Be careful in the words that you choose.** We are a community of professionals, and we conduct ourselves professionally. Be kind to others. Do not insult or put down other participants. Harassment and other exclusionary behavior aren't acceptable. This includes, but is not limited to:
- Violent threats or language directed against another person.
- Discriminatory jokes and language.
- Posting sexually explicit or violent material.
- Posting (or threatening to post) other people's personally identifying information ("doxing").
- Personal insults, especially those using racist or sexist terms.
- Unwelcome sexual attention.
- Advocating for, or encouraging, any of the above behavior.
- Repeated harassment of others. In general, if someone asks you to stop, then stop.
- **When we disagree, try to understand why.** Disagreements, both social and technical, happen all the time and UT Registration Plus is no exception. It is important that we resolve disagreements and differing views constructively. Remember that were different. The strength of UT Registration Plus comes from its varied community, people from a wide range of backgrounds. Different people have different perspectives on issues. Being unable to understand why someone holds a viewpoint doesnt mean that theyre wrong. Dont forget that it is human to err and blaming each other doesnt get us anywhere. Instead, focus on helping to resolve issues and learning from mistakes.
Original text courtesy of the [Speak Up! project](http://web.archive.org/web/20141109123859/http://speakup.io/coc.html).
## Questions?
If you have questions, please see . If that doesn't answer your questions, feel free to [contact us](mailto:contact@longhorns.dev).

View File

@@ -26,8 +26,9 @@
## Toolchain ## Toolchain
- React v20.9.0 (LTS) - React v20.9.0 (LTS)
- TypeScript - TypeScript v5.x
- Vite 5 - Vite v5.x
- pnpm v10.x
- UnoCSS - UnoCSS
- ESLint - ESLint
- Prettier - Prettier
@@ -184,8 +185,9 @@ We maintain a strict code of conduct. By contributing, you agree to adhere to th
Special thanks to the developers and contributors behind these amazing tools and libraries: Special thanks to the developers and contributors behind these amazing tools and libraries:
- React v20.9.0 (LTS) - React v20.9.0 (LTS)
- TypeScript - TypeScript v5.x
- Vite 5 - Vite v5.x
- pnpm v10.x
- UnoCSS - UnoCSS
- ESLint - ESLint
- Prettier - Prettier
@@ -203,7 +205,7 @@ Special thanks to the developers and contributors behind these amazing tools and
## Activity ## Activity
![UT-Registration-Plus Activity](https://repobeats.axiom.co/api/embed/47930fa3916ac1b475cd63a05948c449eb5ad502.svg "UT-Registration-Plus Repobeats analytics image") ![UT-Registration-Plus Activity](https://repobeats.axiom.co/api/embed/47930fa3916ac1b475cd63a05948c449eb5ad502.svg 'UT-Registration-Plus Repobeats analytics image')
## Star History ## Star History

10
default.nix Normal file
View File

@@ -0,0 +1,10 @@
(import (
let
rev = "v1.1.0";
sha256 = "sha256:19d2z6xsvpxm184m41qrpi1bplilwipgnzv9jy17fgw421785q1m";
in
fetchTarball {
inherit sha256;
url = "https://github.com/NixOS/flake-compat/archive/${rev}.tar.gz";
}
) { src = ./.; }).defaultNix

View File

@@ -24,7 +24,7 @@ else
fi fi
# Validate the mode # Validate the mode
if [[ ! " ${SUPPORTED_MODES[*]} " =~ " ${mode} " ]]; then if [[ ! " ${SUPPORTED_MODES[*]} " =~ ${mode} ]]; then
echo "Error: Invalid mode '${mode}'" >&2 echo "Error: Invalid mode '${mode}'" >&2
usage usage
fi fi

96
flake.lock generated Normal file
View File

@@ -0,0 +1,96 @@
{
"nodes": {
"flake-parts": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1767609335,
"narHash": "sha256-feveD98mQpptwrAEggBQKJTYbvwwglSbOv53uCfH9PY=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "250481aafeb741edfe23d29195671c19b36b6dca",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1767640445,
"narHash": "sha256-UWYqmD7JFBEDBHWYcqE6s6c77pWdcU/i+bwD6XxMb8A=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "9f0c42f8bc7151b8e7e5840fb3bd454ad850d8c5",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-lib": {
"locked": {
"lastModified": 1765674936,
"narHash": "sha256-k00uTP4JNfmejrCLJOwdObYC9jHRrr/5M/a/8L2EIdo=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "2075416fcb47225d9b68ac469a5c4801a9c4dd85",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs.lib",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1761236834,
"narHash": "sha256-+pthv6hrL5VLW2UqPdISGuLiUZ6SnAXdd2DdUE+fV2Q=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "d5faa84122bc0a1fd5d378492efce4e289f8eac1",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"flake-parts": "flake-parts",
"nixpkgs": "nixpkgs",
"treefmt-nix": "treefmt-nix"
}
},
"treefmt-nix": {
"inputs": {
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1767468822,
"narHash": "sha256-MpffQxHxmjVKMiQd0Tg2IM/bSjjdQAM+NDcX6yxj7rE=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "d56486eb9493ad9c4777c65932618e9c2d0468fc",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

33
flake.nix Normal file
View File

@@ -0,0 +1,33 @@
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-parts.url = "github:hercules-ci/flake-parts";
treefmt-nix.url = "github:numtide/treefmt-nix";
};
outputs =
inputs@{ flake-parts, ... }:
flake-parts.lib.mkFlake { inherit inputs; } {
systems = inputs.nixpkgs.lib.systems.flakeExposed;
imports = [
./nix/packages.nix
./nix/devShells.nix
./nix/treefmt.nix
];
perSystem =
{ system, ... }:
{
_module.args.pkgs = import inputs.nixpkgs {
inherit system;
overlays = [
(final: prev: {
nodejs = prev.nodejs_20; # v20.19.5
})
];
config = { };
};
};
};
}

View File

@@ -35,9 +35,13 @@ function removeExtraDatabaseDir(cb) {
// Instrument with Sentry // Instrument with Sentry
// Make sure sentry is configured https://docs.sentry.io/platforms/javascript/sourcemaps/uploading/typescript/#2-configure-sentry-cli // Make sure sentry is configured https://docs.sentry.io/platforms/javascript/sourcemaps/uploading/typescript/#2-configure-sentry-cli
async function instrumentWithSentry(cb) { async function instrumentWithSentry(cb) {
if (process.env.SENTRY_ENV && process.env.SENTRY_ENV !== 'development') {
await exec(`sentry-cli sourcemaps inject ${DIST_DIR}`); await exec(`sentry-cli sourcemaps inject ${DIST_DIR}`);
await exec(`sentry-cli sourcemaps upload ${DIST_DIR}`); await exec(`sentry-cli sourcemaps upload ${DIST_DIR}`);
log('Sentry instrumentation completed.'); log('Sentry instrumentation completed.');
} else {
logWarn('Skipping uploading/creating Sentry source maps. (development build)');
}
cb(); cb();
} }

30
nix/devShells.nix Normal file
View File

@@ -0,0 +1,30 @@
{
perSystem =
{
pkgs,
...
}:
let
commonPackages = with pkgs; [
nodejs # Defined in overlay
pnpm_10 # v10.18.2
];
additionalPackages = with pkgs; [
bun
nodePackages.conventional-changelog-cli
sentry-cli
];
in
{
devShells.default = pkgs.mkShell {
name = "utrp-dev";
packages = commonPackages;
};
devShells.full = pkgs.mkShell {
name = "utrp-dev-full";
packages = commonPackages ++ additionalPackages;
};
};
}

51
nix/package.nix Normal file
View File

@@ -0,0 +1,51 @@
{
stdenv,
lib,
nodejs,
pnpm_10,
git,
version ? "dev",
gitRev ? "unknown",
gitBranch ? "unknown",
buildScript ? "build",
}:
stdenv.mkDerivation (finalAttrs: {
inherit version;
pname = "ut-registration-plus";
src = ../.;
nativeBuildInputs = [
nodejs
pnpm_10.configHook
git
];
pnpmDeps = pnpm_10.fetchDeps {
inherit (finalAttrs) pname version src;
fetcherVersion = 2;
hash = "sha256-UqHymJWvlTV4glra/6DkxuCxbG5dpPkFcnvq3vuxsJ8=";
};
# Pass git info to the build
VITE_GIT_COMMIT = gitRev;
VITE_GIT_BRANCH = gitBranch;
buildPhase = ''
pnpm run ${buildScript}
'';
installPhase = ''
mkdir -p $out
cp -r dist/* $out/
'';
meta = {
description = "UT Registration Plus";
homepage = "https://github.com/Longhorn-Developers/UT-Registration-Plus";
license = lib.licenses.mit;
maintainers = lib.maintainers.doprz;
platforms = lib.platforms.unix;
};
})

40
nix/packages.nix Normal file
View File

@@ -0,0 +1,40 @@
{ inputs, ... }:
{
perSystem =
{ pkgs, ... }:
let
packageJson = builtins.fromJSON (builtins.readFile ../package.json);
gitRev = inputs.self.shortRev or inputs.self.dirtyShortRev or "dev";
gitBranch = if inputs.self ? ref then inputs.self.ref else "unknown";
baseVersion = packageJson.version;
commonArgs = {
inherit gitRev gitBranch;
};
# Prod variant
ut-registration-plus = pkgs.callPackage ./package.nix (
commonArgs
// {
version = "${baseVersion}+git.${gitRev}";
buildScript = "build";
}
);
# Dev variant
ut-registration-plus-dev = pkgs.callPackage ./package.nix (
commonArgs
// {
version = "${baseVersion}-dev+git.${gitRev}";
buildScript = "build:dev";
}
);
in
{
packages = {
inherit ut-registration-plus ut-registration-plus-dev;
default = ut-registration-plus;
dev = ut-registration-plus-dev;
};
};
}

63
nix/treefmt.nix Normal file
View File

@@ -0,0 +1,63 @@
{ inputs, ... }:
{
imports = [
inputs.treefmt-nix.flakeModule
];
perSystem =
{ pkgs, ... }:
{
treefmt = {
projectRootFile = "flake.nix";
programs.nixfmt.enable = pkgs.lib.meta.availableOn pkgs.stdenv.buildPlatform pkgs.nixfmt-rfc-style.compiler;
programs.nixfmt.package = pkgs.nixfmt-rfc-style;
# NOTE: Make sure the prettier version in package.json and the one used by treefmt are the same for consistent results
programs.prettier.enable = true;
programs.shellcheck.enable = true;
programs.yamlfmt.enable = true;
programs.dockerfmt.enable = true;
settings.formatter.prettier.excludes = [ "pnpm-lock.yaml" ];
settings.formatter.shellcheck.excludes = [ ".envrc" ];
settings.formatter.yamlfmt.excludes = [ "pnpm-lock.yaml" ];
};
checks = {
prettier-version-match =
pkgs.runCommand "check-prettier-version"
{
buildInputs = [ pkgs.jq ];
}
''
# Extract prettier version from package.json
packageJsonVersion=$(jq -r '.devDependencies.prettier // empty' ${../package.json})
if [ -z "$packageJsonVersion" ]; then
echo "Error: prettier not found in package.json devDependencies"
exit 1
fi
# Remove any semver prefix characters (^, ~, etc...)
packageJsonVersion=$(echo "$packageJsonVersion" | sed 's/^[\^~>=<]*//')
# Get prettier version from nixpkgs
nixVersion="${pkgs.nodePackages.prettier.version}"
if [ "$packageJsonVersion" != "$nixVersion" ]; then
echo ""
echo "ERROR: Prettier version mismatch!"
echo " package.json: $packageJsonVersion"
echo " nixpkgs: $nixVersion"
echo ""
echo "Please update one of the following:"
echo " - Update prettier in package.json to match nixpkgs: $nixVersion"
echo " - Override prettier in your flake to match package.json"
exit 1
fi
touch $out
'';
};
};
}

View File

@@ -1,7 +1,7 @@
{ {
"name": "ut-registration-plus", "name": "ut-registration-plus",
"displayName": "UT Registration Plus", "displayName": "UT Registration Plus",
"version": "2.1.1", "version": "2.3.0",
"description": "UT Registration Plus is a Chrome extension that allows students to easily register for classes.", "description": "UT Registration Plus is a Chrome extension that allows students to easily register for classes.",
"private": true, "private": true,
"homepage": "https://github.com/Longhorn-Developers/UT-Registration-Plus", "homepage": "https://github.com/Longhorn-Developers/UT-Registration-Plus",
@@ -9,8 +9,10 @@
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "tsc && vite build", "build": "tsc && vite build",
"build:dev": "tsc && NODE_ENV='development' vite build --mode development",
"build:watch": "NODE_ENV='development' vite build --mode development -w", "build:watch": "NODE_ENV='development' vite build --mode development -w",
"zip": "PROD=true pnpm build && pnpm gulp zipProdBuild", "zip": "pnpm build && pnpm gulp zipProdBuild",
"zip:to-publish": "SENTRY_ENV='production' pnpm zip",
"prettier": "prettier src --check", "prettier": "prettier src --check",
"prettier:fix": "prettier src --write", "prettier:fix": "prettier src --write",
"lint": "eslint src --ext ts,tsx --report-unused-disable-directives", "lint": "eslint src --ext ts,tsx --report-unused-disable-directives",
@@ -27,40 +29,45 @@
"prepare": "husky" "prepare": "husky"
}, },
"dependencies": { "dependencies": {
"@date-fns/tz": "^1.2.0",
"@dnd-kit/core": "^6.3.1", "@dnd-kit/core": "^6.3.1",
"@dnd-kit/modifiers": "^9.0.0", "@dnd-kit/modifiers": "^9.0.0",
"@dnd-kit/sortable": "^10.0.0", "@dnd-kit/sortable": "^10.0.0",
"@dnd-kit/utilities": "^3.2.2", "@dnd-kit/utilities": "^3.2.2",
"@headlessui/react": "^2.2.0", "@headlessui/react": "^2.2.0",
"@octokit/rest": "^21.1.1", "@octokit/rest": "^22.0.1",
"@phosphor-icons/react": "^2.1.7", "@phosphor-icons/react": "^2.1.7",
"@sentry/react": "^8.55.0", "@sentry/react": "^10.39.0",
"@tanstack/react-query": "^5.69.0",
"@tsparticles/engine": "^3.9.1",
"@tsparticles/react": "^3.0.0",
"@tsparticles/slim": "^3.9.1",
"@unocss/vite": "^0.63.6", "@unocss/vite": "^0.63.6",
"@vitejs/plugin-react": "^4.3.4", "@vitejs/plugin-react": "^5.1.4",
"chrome-extension-toolkit": "^0.0.54",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"conventional-changelog": "^6.0.0", "conventional-changelog": "^7.1.1",
"highcharts": "^11.4.8", "date-fns": "^4.1.0",
"highcharts": "^12.5.0",
"highcharts-react-official": "^3.2.1", "highcharts-react-official": "^3.2.1",
"html-to-image": "^1.11.13", "html-to-image": "^1.11.13",
"husky": "^9.1.7", "husky": "^9.1.7",
"kc-dabr-wasm": "^0.1.2", "kc-dabr-wasm": "^0.1.2",
"nanoid": "^5.1.2", "nanoid": "^5.1.2",
"react": "^18.3.1", "react": "^19.2.4",
"react-dom": "^18.3.1", "react-dom": "^19.2.4",
"react-loading-skeleton": "^3.5.0", "react-loading-skeleton": "^3.5.0",
"react-markdown": "^9.1.0", "react-markdown": "^10.1.0",
"react-syntax-highlighter": "^15.6.1", "react-syntax-highlighter": "^16.1.0",
"remark-gfm": "^4.0.1", "remark-gfm": "^4.0.1",
"sass": "^1.85.1", "sass": "^1.85.1",
"simple-git": "^3.27.0", "simple-git": "^3.27.0",
"sql.js": "1.11.0" "sql.js": "1.11.0"
}, },
"devDependencies": { "devDependencies": {
"@chromatic-com/storybook": "^2.0.2", "@chromatic-com/storybook": "^5.0.1",
"@commitlint/cli": "^19.7.1", "@commitlint/cli": "^20.4.1",
"@commitlint/config-conventional": "^19.7.1", "@commitlint/config-conventional": "^20.4.1",
"@commitlint/types": "^19.5.0", "@commitlint/types": "^20.4.0",
"@crxjs/vite-plugin": "2.0.0-beta.21", "@crxjs/vite-plugin": "2.0.0-beta.21",
"@iconify-json/bi": "^1.2.2", "@iconify-json/bi": "^1.2.2",
"@iconify-json/ic": "^1.2.2", "@iconify-json/ic": "^1.2.2",
@@ -68,80 +75,81 @@
"@iconify-json/material-symbols": "^1.2.14", "@iconify-json/material-symbols": "^1.2.14",
"@iconify-json/ri": "^1.2.5", "@iconify-json/ri": "^1.2.5",
"@iconify-json/streamline": "^1.2.2", "@iconify-json/streamline": "^1.2.2",
"@semantic-release/exec": "^6.0.3", "@semantic-release/exec": "^7.1.0",
"@sentry/types": "^8.55.0", "@sentry/types": "^10.39.0",
"@storybook/addon-designs": "^8.2.0", "@storybook/addon-designs": "^11.1.2",
"@storybook/addon-essentials": "^8.6.0", "@storybook/addon-essentials": "^8.6.0",
"@storybook/addon-links": "^8.6.0", "@storybook/addon-links": "^10.2.8",
"@storybook/blocks": "^8.6.0", "@storybook/blocks": "^8.6.0",
"@storybook/react": "^8.6.0", "@storybook/react": "^10.2.8",
"@storybook/react-vite": "^8.6.0", "@storybook/react-vite": "^10.2.8",
"@storybook/test": "^8.6.0", "@storybook/test": "^8.6.0",
"@svgr/core": "^8.1.0", "@svgr/core": "^8.1.0",
"@svgr/plugin-jsx": "^8.1.0", "@svgr/plugin-jsx": "^8.1.0",
"@types/chrome": "^0.0.273", "@types/chrome": "^0.0.273",
"@types/conventional-changelog": "^3.1.5", "@types/conventional-changelog": "^6.0.1",
"@types/gulp": "^4.0.17", "@types/gulp": "^4.0.17",
"@types/gulp-zip": "^4.0.4", "@types/gulp-zip": "^4.0.4",
"@types/node": "^22.13.5", "@types/node": "^25.2.3",
"@types/prompts": "^2.4.9", "@types/prompts": "^2.4.9",
"@types/react": "^18.3.18", "@types/react": "^19.2.14",
"@types/react-dom": "^18.3.5", "@types/react-dom": "^19.2.3",
"@types/react-syntax-highlighter": "^15.5.13", "@types/react-syntax-highlighter": "^15.5.13",
"@types/semantic-release": "^20.0.6", "@types/semantic-release": "^20.0.6",
"@types/semver": "^7.5.8", "@types/semver": "^7.5.8",
"@types/sql.js": "^1.4.9", "@types/sql.js": "^1.4.9",
"@typescript-eslint/eslint-plugin": "^7.18.0", "@typescript-eslint/eslint-plugin": "^8.55.0",
"@typescript-eslint/parser": "^7.18.0", "@typescript-eslint/parser": "^8.55.0",
"@unocss/eslint-config": "^0.63.6", "@unocss/eslint-config": "^66.6.0",
"@unocss/postcss": "^0.63.6", "@unocss/postcss": "^66.6.0",
"@unocss/preset-uno": "^0.63.6", "@unocss/preset-uno": "^66.6.0",
"@unocss/preset-web-fonts": "^0.63.6", "@unocss/preset-web-fonts": "^66.6.0",
"@unocss/reset": "^0.63.6", "@unocss/reset": "^66.6.0",
"@unocss/transformer-directives": "^0.63.6", "@unocss/transformer-directives": "^66.6.0",
"@unocss/transformer-variant-group": "^0.63.6", "@unocss/transformer-variant-group": "^66.6.0",
"@vitejs/plugin-react-swc": "^3.8.0", "@vitejs/plugin-react-swc": "^4.2.3",
"@vitest/coverage-v8": "^2.1.9", "@vitest/coverage-v8": "^4.0.18",
"@vitest/ui": "^2.1.9", "@vitest/ui": "^4.0.18",
"chalk": "^5.4.1", "chalk": "^5.4.1",
"chromatic": "^11.26.0", "chromatic": "^15.1.0",
"cssnano": "^7.0.6", "cssnano": "^7.0.6",
"cssnano-preset-advanced": "^7.0.6", "cssnano-preset-advanced": "^7.0.6",
"dotenv": "^16.4.7", "dotenv": "^17.3.1",
"es-module-lexer": "^1.6.0", "es-module-lexer": "^2.0.0",
"eslint": "^8.57.1", "eslint": "^10.0.0",
"eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb": "^19.0.4",
"eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-base": "^15.0.0",
"eslint-config-airbnb-typescript": "^18.0.0", "eslint-config-airbnb-typescript": "^18.0.0",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^10.1.8",
"eslint-import-resolver-typescript": "^3.8.3", "eslint-import-resolver-typescript": "^4.4.4",
"eslint-plugin-import": "^2.31.0", "eslint-plugin-import": "^2.31.0",
"eslint-plugin-import-essentials": "^0.2.1", "eslint-plugin-import-essentials": "^0.2.1",
"eslint-plugin-jsdoc": "^50.6.3", "eslint-plugin-jsdoc": "^62.5.5",
"eslint-plugin-prettier": "^5.2.3", "eslint-plugin-prettier": "^5.2.3",
"eslint-plugin-react": "^7.37.4", "eslint-plugin-react": "^7.37.4",
"eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-prefer-function-component": "^3.4.0", "eslint-plugin-react-prefer-function-component": "^5.0.0",
"eslint-plugin-react-refresh": "^0.4.19", "eslint-plugin-react-refresh": "^0.4.19",
"eslint-plugin-simple-import-sort": "^12.1.1", "eslint-plugin-simple-import-sort": "^12.1.1",
"eslint-plugin-storybook": "^0.9.0", "eslint-plugin-storybook": "^10.2.8",
"eslint-plugin-tsdoc": "^0.3.0", "eslint-plugin-tsdoc": "^0.3.0",
"gulp": "^5.0.0", "gulp": "^5.0.0",
"gulp-execa": "^7.0.1", "gulp-execa": "^8.0.1",
"gulp-zip": "^6.1.0", "gulp-zip": "^6.1.0",
"jsdom": "^28.0.0",
"path": "^0.12.7", "path": "^0.12.7",
"postcss": "^8.5.3", "postcss": "^8.5.3",
"prettier": "^3.5.2", "prettier": "3.6.2",
"react-dev-utils": "^12.0.1", "react-dev-utils": "^12.0.1",
"semantic-release": "^24.2.3", "semantic-release": "^25.0.3",
"storybook": "^8.6.0", "storybook": "^10.2.8",
"typescript": "^5.7.3", "typescript": "^5.7.3",
"unocss": "^0.63.6", "unocss": "^66.6.0",
"unocss-preset-primitives": "0.0.2-beta.1", "unocss-preset-primitives": "0.0.2-beta.1",
"unplugin-icons": "^0.19.3", "unplugin-icons": "^23.0.1",
"vite": "^5.4.14", "vite": "^7.3.1",
"vite-plugin-inspect": "^0.8.9", "vite-plugin-inspect": "^11.3.3",
"vitest": "^2.1.9" "vitest": "^4.0.18"
}, },
"engineStrict": true, "engineStrict": true,
"engines": { "engines": {
@@ -154,9 +162,13 @@
}, },
"overrides": { "overrides": {
"es-module-lexer": "^1.5.4" "es-module-lexer": "^1.5.4"
} },
"onlyBuiltDependencies": [
"@tsparticles/engine"
]
}, },
"volta": { "volta": {
"node": "20.9.0" "node": "20.19.4",
"pnpm": "10.14.0"
} }
} }

8149
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

10
shell.nix Normal file
View File

@@ -0,0 +1,10 @@
(import (
let
rev = "v1.1.0";
sha256 = "sha256:19d2z6xsvpxm184m41qrpi1bplilwipgnzv9jy17fgw421785q1m";
in
fetchTarball {
inherit sha256;
url = "https://github.com/NixOS/flake-compat/archive/${rev}.tar.gz";
}
) { src = ./.; }).shellNix

BIN
src/assets/LD-icon-new.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

View File

@@ -8,15 +8,27 @@ const splashText: string[] = [
'The squirrels, they have mastered begging for food better than students. Impressive... but worrying.', 'The squirrels, they have mastered begging for food better than students. Impressive... but worrying.',
"Do you study often? Ha! What am I saying? Of course you don't.", "Do you study often? Ha! What am I saying? Of course you don't.",
"Hey, you, you're finally awake. You were trying to skip class right?", "Hey, you, you're finally awake. You were trying to skip class right?",
'Mmm... Brutalist architecture...',
'The course syllabus: more than meets the eye',
'Pain is temporary, GPA is forever.',
"You've Yee'd Your Last Haw.",
'lol everything is already waitlisted.',
'Could be worse. Could be A&M.',
"Should you major in Compsci? well, here's a better question. do you wanna have a bad time?",
'A pen and paper is old fashioned, but sometimes old ways are best',
'A heart is like bedrock, destroyable only by cheating',
'You may not rest now, there are Canvas assignments nearby',
'You are filled with DETERMINATION',
'60k+ users!',
'Almost Turing complete',
'#BF5700',
'The waitlist is a lie!',
'BEVO JOCKEY 🗣️🗣️🗣️',
'RIP Domino, you beloved campus feline.', 'RIP Domino, you beloved campus feline.',
"The year is 2055 and Welch still isn't finished.", "The year is 2055 and Welch still isn't finished.",
'Motivation dropping faster than ur GPA', 'Motivation dropping faster than ur GPA',
'No Work Happens On PCL 5th Floor.', 'No Work Happens On PCL 5th Floor.',
'I may be a sophomore in name, but my credit count screams freshman!', 'I may be a sophomore in name, but my credit count screams freshman!',
'Pain is temporary, GPA is forever.',
"You've Yee'd Your Last Haw.",
'lol everything is already waitlisted.',
'Could be worse. Could be A&M.',
// 'TeXAs iS BaCK GuYZ', // 'TeXAs iS BaCK GuYZ',
'mAke iT yOuR tExAS', 'mAke iT yOuR tExAS',
'change yOur slogan', 'change yOur slogan',
@@ -24,7 +36,7 @@ const splashText: string[] = [
'Does McCombs teach Parseltongue?', 'Does McCombs teach Parseltongue?',
'No Cruce Enfrente Del Bus.', 'No Cruce Enfrente Del Bus.',
'Omae Wa Mou Shindeiru...', 'Omae Wa Mou Shindeiru...',
'Every day another brick disappears from Speedway', "They say each day, another brick disappears from Speedway. No one's sure where to.",
'The GDC will annex the EER one day', 'The GDC will annex the EER one day',
'To hike to Kins or not to hike to Kins...', 'To hike to Kins or not to hike to Kins...',
"C'mon you Longhorns! You want to study forever?", "C'mon you Longhorns! You want to study forever?",
@@ -34,15 +46,11 @@ const splashText: string[] = [
"The Block of Butter incident of '22", "The Block of Butter incident of '22",
'Begun, the midterms have.', 'Begun, the midterms have.',
'You must construct additional schedules', 'You must construct additional schedules',
"Arrows of Christ vs Church of Scientology was the crossover we didn't know we needed",
'THE WALK SIGN IS ON TO CROSS GUADALUPE AND 21ST', 'THE WALK SIGN IS ON TO CROSS GUADALUPE AND 21ST',
'Pay attention. Might learn something.', 'Pay attention. Might learn something.',
'Long ago, apartment rates lived together in harmony. Then, everything changed when American Campus Communities Inc attacked.',
'Roll for Initiative!', 'Roll for Initiative!',
'The line at the on-campus Starbucks is longer than your course waitlist.', 'The line at the on-campus Starbucks is longer than your course waitlist.',
'The weather changes more often than your class schedule.', 'The weather changes more often than your class schedule.',
'Mmm... Brutalist architecture...',
'The course syllabus: more than meets the eye',
"'studying' often means refreshing Canvas every five minutes to see if the professor posted lecture slides.", "'studying' often means refreshing Canvas every five minutes to see if the professor posted lecture slides.",
"It's over Bevo! I have the high ground!", "It's over Bevo! I have the high ground!",
"I'll just skip this lecture and watch the recording later. What's the worst that could happen?", "I'll just skip this lecture and watch the recording later. What's the worst that could happen?",
@@ -59,23 +67,15 @@ const splashText: string[] = [
'follow @sghsri!', 'follow @sghsri!',
'Officially part of the SEC', 'Officially part of the SEC',
'Planner is now acquired by Plus', 'Planner is now acquired by Plus',
'Longhorn-Developers is the best UT Student Org', 'Longhorn Developers is the best UT Student Org',
'The Eiffel Tower is the UT Tower of Paris', 'The Eiffel Tower is the UT Tower of Paris',
'A pen and paper is old fashioned, but sometimes old ways are best', "He's a CS Major, but he showers regularly. 🧢",
'A heart is like bedrock, destroyable only by cheating',
'You may not rest now, there are Canvas assignments nearby',
'You are filled with DETERMINATION',
'60k+ users!',
'Almost Turing complete',
'#BF5700',
'The waitlist is a lie!',
`He's a CS Major, but he showers regularly. 🧢`,
'A CS major walks into a bar. The bar is empty because it is a CS major.', 'A CS major walks into a bar. The bar is empty because it is a CS major.',
'UT Registration Plus - The only thing that can make registration worse is not having it', 'UT Registration Plus - The only thing that can make registration worse is not having it',
'UT Registration Plus - We make registration slightly less painful. Slightly.', 'UT Registration Plus - We make registration slightly less painful. Slightly.',
'UT Registration Plus - Do you really want to figure out which professors will ruin your GPA by yourself?', 'UT Registration Plus - Do you really want to figure out which professors will ruin your GPA by yourself?',
'Ayo tf is a memory leak', "Ayo what's is a memory leak",
"lowkey we never thought we'd get this far, how tf are 60k of you people using this", "lowkey we never thought we'd get this far, how are 60k of you people using this",
"dang we're really out here making a splash", "dang we're really out here making a splash",
"We'd make a joke about A&M, but we're not sure they can read", "We'd make a joke about A&M, but we're not sure they can read",
"We've only caused one or two outages, we swear!", "We've only caused one or two outages, we swear!",
@@ -113,8 +113,7 @@ const splashText: string[] = [
"Stop trying to make UTRP happen, it's not going to happen!", "Stop trying to make UTRP happen, it's not going to happen!",
'Befriend the raccoons on campus', 'Befriend the raccoons on campus',
`It's ${new Date().toLocaleString('en-US', { month: 'long', day: 'numeric' })} and OU still sucks`, `It's ${new Date().toLocaleString('en-US', { month: 'long', day: 'numeric' })} and OU still sucks`,
'As seen on TV! ', 'As seen on TV!',
"Should you major in Compsci? well, here's a better question. do you wanna have a bad time?",
]; ];
export default splashText; export default splashText;

View File

@@ -0,0 +1,8 @@
# chrome-extension-toolkit
Repo: https://github.com/sghsri/chrome-extension-toolkit
Author: sghsri
License: MIT
Version: 0.0.96
This library has been inlined into UTRP due to the package being removed from npm.

View File

@@ -0,0 +1,62 @@
import React, { useState } from 'react';
const containerStyle: React.CSSProperties = {
position: 'fixed',
bottom: 0,
left: 0,
right: 0,
padding: '8px',
fontSize: '20px',
textAlign: 'center',
borderTopLeftRadius: '20px',
borderTopRightRadius: '20px',
zIndex: 999999999999,
cursor: 'pointer',
};
const closeButtonStyle: React.CSSProperties = {
position: 'absolute',
top: 0,
right: 0,
padding: '8px',
paddingRight: '20px',
fontSize: '20px',
cursor: 'pointer',
};
interface Props {
className?: string;
onClick?: () => void;
}
/**
* A component that displays a message onto a content script when the context extension is invalidated.
*/
export function ContextInvalidated(props: Props): JSX.Element | null {
const [isShowing, setIsShowing] = useState(true);
const hide = (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
e.stopPropagation();
setIsShowing(false);
};
const reload = () => {
window.location.reload();
};
return isShowing ? (
<div
style={{
...containerStyle,
}}
id='extension-context-invalidated'
className={props.className}
onClick={props.onClick ?? reload}
>
Context Extension Context invalidated. Click to reload
<div style={closeButtonStyle} onClick={hide}>
</div>
</div>
) : null;
}

View File

@@ -0,0 +1,2 @@
export * from './ContextInvalidated';
export * from './onContextInvalidated';

View File

@@ -0,0 +1,14 @@
/**
* A content script can be invalidated if a chrome extension is reloaded / updated.
* This function is used to detect when the extension's context has been invalidated, and to call a callback.
* @param callback A callback to be called when the extension's context has been invalidated
*/
export function onContextInvalidated(callback: () => void) {
const interval = setInterval(() => {
// this means the current tab's context has been invalidated
if (!chrome.runtime.id) {
clearInterval(interval);
callback();
}
}, 1 * 1000);
}

View File

@@ -0,0 +1,55 @@
/**
* An extension of HTMLDivElement that represents a shadow root for use within an Extension Content Script.
*/
interface HTMLShadowDOMElement extends HTMLDivElement {
shadowRoot: ShadowRoot & {
INJECTION_POINT: HTMLDivElement;
};
/**
* Adds a style sheet to the shadow root.
* @param path the path to the style sheet relative to the extension's root directory. uses chrome.runtime.getURL to get the absolute path.
*/
addStyle(path: string): Promise<void>;
}
/**
* In extension content scripts, often times the parent site's styles will override the styles of the extension.
* To get around this, we create a shadow DOM and isolate the extension's html and styles in the shadow DOM.
* from the parent site's styles to prevent conflicts.
* @param id the id of the shadow root.
* @param options the optional options for the shadow root.
* @param isolate whether or not to isolate the extension's document flow from the parent site's document flow.
* @returns A Div that represents the shadow root with some additional methods added to it.
*/
export function createShadowDOM(id: string, options?: ShadowRootInit, isolate = false): HTMLShadowDOMElement {
const html = document.querySelector('html');
if (!html) {
throw new Error('Could not find html element');
}
const div = document.createElement('div') as HTMLShadowDOMElement;
div.id = id;
div.style.all = 'initial';
div.attachShadow({
mode: 'open',
...(options || {}),
});
const INJECTION_POINT = document.createElement('div');
INJECTION_POINT.id = 'INJECTION_POINT';
div.shadowRoot.appendChild(INJECTION_POINT);
div.shadowRoot.INJECTION_POINT = INJECTION_POINT;
div.addStyle = async (path: string) => {
const style = await fetch(chrome.runtime.getURL(path));
const styleNode = document.createElement('style');
const parsedStyle = await style.text();
styleNode.textContent = parsedStyle;
div.shadowRoot.appendChild(styleNode);
};
html.appendChild(div);
if (isolate) document.body.style.isolation = 'isolate';
return div as HTMLShadowDOMElement;
}

View File

@@ -0,0 +1 @@
export * from './createShadowRoot';

View File

@@ -0,0 +1,70 @@
/**
* Possible contexts in which a chrome extension can run.
*/
export enum ScriptType {
CONTENT_SCRIPT = 'content_script',
BACKGROUND_SCRIPT = 'background_script',
EXTENSION_POPUP = 'extension_popup',
EXTENSION_PAGE = 'extension_page',
}
/**
* Chrome extension code can run in different contexts.
* These different contexts have different capabilities and access to certain parts of the chrome extensions API.
* For example, the chrome.tabs api is not readily available in the content scripts.
* This function is used to identify the context in which the code is running.
* @returns The context in which the code is running, or null if the code is not running in a chrome extension.
*/
export default function getScriptType(): ScriptType | null {
if (!chrome?.runtime?.id) {
// we are not in a chrome extension
return null;
}
const manifest = chrome.runtime.getManifest();
if (globalThis.window === undefined) {
return ScriptType.BACKGROUND_SCRIPT;
}
if (window.location.href.startsWith(`chrome-extension://${chrome.runtime.id}`)) {
if (manifest.action?.default_popup && window.location.href.includes(manifest.action.default_popup)) {
return ScriptType.EXTENSION_POPUP;
}
return ScriptType.EXTENSION_PAGE;
}
return ScriptType.CONTENT_SCRIPT;
}
/**
* A helper function to check if the code is running in a content script.
* @returns true if the code is running in a content script, false otherwise.
*/
export function isContentScript(): boolean {
return getScriptType() === ScriptType.CONTENT_SCRIPT;
}
/**
* A helper function to check if the code is running in the background script.
* @returns true if the code is running in the background script, false otherwise.
*/
export function isBackgroundScript(): boolean {
return getScriptType() === ScriptType.BACKGROUND_SCRIPT;
}
/**
* A helper function to check if the code is running in the extension popup.
* @returns true if the code is running in the extension popup, false otherwise.
*/
export function isExtensionPopup(): boolean {
return getScriptType() === ScriptType.EXTENSION_POPUP;
}
/**
* A helper function to check if the code is running in an extension page (popup, options, etc.).
* @returns true if the code is running in an extension page (popup, options, etc.), false otherwise.
* @param pageName The name of the page to check for. ex: 'options.html'
*/
export function isExtensionPage(pageName?: string): boolean {
const isPage = getScriptType() === ScriptType.EXTENSION_PAGE;
return isPage && pageName ? window.location.href.includes(pageName) : isPage;
}

View File

@@ -0,0 +1,6 @@
export * from './context';
export * from './dom';
export * from './getScriptType';
export * from './messaging';
export * from './storage';
export * from './types';

View File

@@ -0,0 +1,127 @@
import getScriptType, { ScriptType } from '../getScriptType';
import type { IMessageListener, Message, MessageHandler, Serializable } from '../types';
import { MessageEndpoint } from '../types';
/**
* Options for configuring a message listener.
*/
export interface MessageListenerOptions {
/**
* A callback function that will be called when an error occurs.
* Useful if you want to log errors to a service like Sentry or Bugsnag.
* @param error The error that occurred.
*/
onError?: (error: Error) => void;
/**
* A flag indicating whether verbose logging should be enabled.
*/
verbose?: boolean;
}
/**
* An object that can be used to listen for and handle messages coming from another extension context.
*/
export class MessageListener<M> implements IMessageListener<M> {
private handlers: MessageHandler<M>;
private scriptType: ScriptType;
private myEndpoint: MessageEndpoint;
private listeningFor: MessageEndpoint;
private onError?: (error: Error) => void;
private isVerbose: boolean = false;
/**
* An object that can be used to listen for and handle messages coming from another extension context.
* @param handlers the message handlers for the messages that this listener will handle. When a message is received, the corresponding message handler is called.
*/
constructor(handlers: MessageHandler<M>) {
this.handlers = handlers;
// we want to know what type of script we are running in so we can determine what endpoint we are (background or foreground)
const scriptType = getScriptType();
if (!scriptType) {
throw new Error('[crx-kit]: Unable to determine extension script type.');
}
this.scriptType = scriptType;
if (this.scriptType === ScriptType.BACKGROUND_SCRIPT) {
this.myEndpoint = MessageEndpoint.BACKGROUND;
this.listeningFor = MessageEndpoint.FOREGROUND;
} else {
this.myEndpoint = MessageEndpoint.FOREGROUND;
this.listeningFor = MessageEndpoint.BACKGROUND;
}
}
private handleMessage = (
message: Message<M>,
sender: chrome.runtime.MessageSender,
sendResponse: (response: any) => void
): boolean => {
if (message.to !== this.myEndpoint && message.from !== this.listeningFor) {
// this message is not for my current context, so ignore it
return true;
}
const messageName = message.name as string;
// @ts-expect-error
const handler = this.handlers[messageName];
if (!handler) {
// this message is for my current context, but I don't have a handler for it, so ignore it
return true;
}
try {
if (this.isVerbose) {
console.log(`[crx-kit]: message received: ${messageName}`, {
name: messageName,
data: message.data,
sender,
});
}
// this message is for my current context, and I have a handler for it, so handle it
handler({
data: message.data as Serializable<typeof message.data>,
sendResponse,
sender,
});
} catch (error) {
console.error(`[crx-kit]: Error handling message ${messageName}`, {
name: messageName,
error,
message,
sender,
});
if (this.onError) {
// @ts-expect-error
this.onError(error);
}
}
return true;
};
/**
* Listens for messages from the specified source.
* @param options - The options for the message listener.
*/
public listen(options: MessageListenerOptions = { verbose: false }) {
this.isVerbose = options.verbose ?? false;
this.onError = options.onError;
console.log(`[crx-kit]: ${this.toString()} listening for messages from ${this.listeningFor}`);
chrome.runtime.onMessage.addListener(this.handleMessage);
}
/**
* Stops listening for messages
*/
public unlisten() {
console.log(`[crx-kit]: ${this.toString()} no longer listening for messages from ${this.listeningFor}`);
chrome.runtime.onMessage.removeListener(this.handleMessage);
}
private toString() {
return `MessageListener(${this.myEndpoint})`;
}
}

View File

@@ -0,0 +1,94 @@
import type { Message, MessageData, MessageResponse } from '../types';
import { MessageEndpoint } from '../types';
/**
* An object that can be used to send messages to the background script.
*/ export type BackgroundMessenger<M> = {
[K in keyof M]: MessageData<M, K> extends undefined
? () => Promise<MessageResponse<M, K>>
: (data: MessageData<M, K>) => Promise<MessageResponse<M, K>>;
};
/**
* Where the foreground message is being sent to specifically (which tab or frame)
*/
type ForegroundMessageOptions =
| {
tabId: number;
frameId?: number;
}
| {
tabId: 'ALL' | 'ACTIVE_TAB';
};
/**
* an object that can be used to send messages to the foreground (tabs OR extension pages (popup, options, etc.))
*/
export type ForegroundMessenger<M> = {
[K in keyof M]: MessageData<M, K> extends undefined
? (options: ForegroundMessageOptions) => Promise<MessageResponse<M, K>>
: (data: MessageData<M, K>, options: ForegroundMessageOptions) => Promise<MessageResponse<M, K>>;
};
/**
* A wrapper for chrome extension messaging with a type-safe API.
* @type To which context the messages are sent.
* @returns A proxy object that can be used to send messages to the foreground (tabs or extension pages (popup, options, etc.))
*/
export function createMessenger<M>(destination: 'foreground'): ForegroundMessenger<M>;
/**
* A wrapper for chrome extension messaging with a type-safe API.
* @param type To which context the messages are sent.
* @returns A proxy object that can be used to send messages to the background script.
*/
export function createMessenger<M>(destination: 'background'): BackgroundMessenger<M>;
/**
* A wrapper for chrome extension messaging with a type-safe API.
* @param destination To which context the messages are sent.
* @returns A proxy object that can be used to send messages to the background script.
*/
export function createMessenger<M>(destination: 'background' | 'foreground') {
let to: MessageEndpoint = MessageEndpoint.BACKGROUND;
let from: MessageEndpoint = MessageEndpoint.FOREGROUND;
if (destination === 'foreground') {
to = MessageEndpoint.FOREGROUND;
from = MessageEndpoint.BACKGROUND;
}
const sender = new Proxy({} as any, {
get(target, prop) {
const name = prop as keyof M;
return async (data: MessageData<M, any>, options?: ForegroundMessageOptions) => {
const message: Message<M> = {
name,
data,
from,
to,
};
if (to === MessageEndpoint.FOREGROUND && options) {
// for messages sent to the tabs, we want to send to the tabs using chrome.tabs.sendMessage,
const { tabId } = options;
if (typeof tabId === 'number') {
return chrome.tabs.sendMessage(tabId, message, { frameId: options.frameId });
}
if (tabId === 'ACTIVE_TAB') {
const tab = (await chrome.tabs.query({ active: true, currentWindow: true }))[0];
if (tab && tab.id) {
return chrome.tabs.sendMessage(tab.id, message);
}
}
if (tabId === 'ALL') {
const tabs = (await chrome.tabs.query({})).filter(tab => tab.id !== undefined && tab.url);
return Promise.any([
...tabs.map(tab => chrome.tabs.sendMessage(tab.id!, message)),
chrome.runtime.sendMessage(message),
]);
}
}
return chrome.runtime.sendMessage(message);
};
},
});
return sender;
}

View File

@@ -0,0 +1,30 @@
import { useEffect } from 'react';
import type { Message, MessageData } from '../types';
/**
* A helper function to create a hook that can listen for messages coming through chrome.runtime.onMessage
* with e2e type safety
* @returns a hook that can be used to listen for messages from the background script.
*/
export function createUseMessage<M>() {
return function useMessage<N extends keyof M, D extends MessageData<M, N>>(
name: N,
callback: (data: D) => void
): void {
useEffect(() => {
const onMessage = (message: Message<M>) => {
if (message.name === name) {
callback(message.data);
}
return true;
};
chrome.runtime.onMessage.addListener(onMessage);
return () => {
chrome.runtime.onMessage.removeListener(onMessage);
};
}, [name, callback]);
};
}

View File

@@ -0,0 +1,3 @@
export * from './createMessenger';
export * from './createUseMessage';
export * from './MessageListener';

View File

@@ -0,0 +1,15 @@
declare global {
namespace NodeJS {
interface ProcessEnv {
NODE_ENV: 'development' | 'production' | 'test';
CI?: string;
EXTENSION_STORAGE_PASSWORD?: string;
}
}
type Environment = typeof process.env.NODE_ENV;
}
// If this file has no import/export statements (i.e. is a script)
// convert it into a module by adding an empty export statement.
export {};

View File

@@ -0,0 +1,214 @@
/* eslint-disable max-classes-per-file */
const { crypto } = globalThis;
/** the number of times the key_algo will be run on the password */
const ITERATIONS = 470_000;
/** the algorithm used to derive the password key from the password */
const KEY_ALGO = 'PBKDF2';
/** the algorithm used to derive the cipher key from the password key */
const HASH_ALGO = 'SHA-256';
/** the algorithm used to encrypt the data */
const CIPHER_MODE = 'AES-GCM';
/** the size of the cipher key */
const CIPHER_SIZE = 256;
/**
* A class that provides encryption and decryption methods for use when storing data in the Stores provided by this library.
*/
export class Security {
private encoder = new TextEncoder();
private decoder = new TextDecoder();
private cachedPasswordKey?: CryptoKey;
public static MISSING_PASSWORD_ERROR_MESSAGE =
'You must set the EXTENSION_STORAGE_PASSWORD environment variable to use encrypted storage.';
/**
* @returns the password key, either from the cache or by generating a new one from the password environment variable
*/
private async getPasswordKey(): Promise<CryptoKey> {
if (this.cachedPasswordKey) return this.cachedPasswordKey;
if (!process.env.EXTENSION_STORAGE_PASSWORD) {
throw new Error(Security.MISSING_PASSWORD_ERROR_MESSAGE);
}
const passwordBuffer = this.encoder.encode(process.env.EXTENSION_STORAGE_PASSWORD);
this.cachedPasswordKey = await crypto.subtle.importKey(
'raw',
passwordBuffer,
{ name: KEY_ALGO },
false, // Not exportable
['deriveKey']
);
return this.cachedPasswordKey;
}
/**
* Derives a cipher key from the password key and salt
* @param salt the salt to use when deriving the cipher key
* @param passKey the password key to use when deriving the cipher key
* @param KeyUsage the key usage for the cipher key (encrypt or decrypt)
* @returns the cipher key which can be used to encrypt or decrypt data
*/
private async deriveCipherKey(salt: Uint8Array, passKey: CryptoKey, KeyUsage: KeyUsage[]): Promise<CryptoKey> {
return crypto.subtle.deriveKey(
{
name: KEY_ALGO,
hash: HASH_ALGO,
salt,
iterations: ITERATIONS,
},
passKey,
{
name: CIPHER_MODE,
length: CIPHER_SIZE,
},
false,
KeyUsage
);
}
/**
* @returns a random salt buffer for use in encryption
*/
private deriveSalt(): Uint8Array {
return crypto.getRandomValues(new Uint8Array(BoxBuffer.SALT_SIZE));
}
/**
* @returns a random IV buffer for use in encryption
*/
private deriveIv(): Uint8Array {
return crypto.getRandomValues(new Uint8Array(BoxBuffer.IV_SIZE));
}
/**
* Decrypts a value that has been encrypted using the encrypt method
* @param value the encrypted value to decrypt
* @returns the decrypted value
*/
async decrypt(value: any) {
if (!value) return value;
if (!isString(value)) return value;
const passKey = await this.getPasswordKey();
// read in the string into a boxBuffer, and separate the salt, iv and encrypted data from it
const boxBuffer = BoxBuffer.fromBase64String(value);
const salt = boxBuffer.getSalt();
const iv = boxBuffer.getIv();
const encryptedData = boxBuffer.getEncryptedData();
// generate the decryption key
const decryptionKey = await this.deriveCipherKey(salt, passKey, ['decrypt']);
// decrypt the data using the decryption key
const decryptedDataBuffer = await crypto.subtle.decrypt(
{
name: CIPHER_MODE,
iv,
},
decryptionKey,
encryptedData
);
// parse the decrypted data into a JSON object and return it
return decryptedDataBuffer.byteLength === 0 ? undefined : JSON.parse(this.decoder.decode(decryptedDataBuffer));
}
/**
* Encrypts a value using the password key derived from the EXTENSION_STORAGE_PASSWORD environment variable
* @param value the value to encrypt
* @returns the encrypted value as a base64 string
*/
async encrypt(value: any): Promise<string> {
let valueString = JSON.stringify(value);
const passKey = await this.getPasswordKey();
const salt = this.deriveSalt();
const iv = this.deriveIv();
const encryptionKey = await this.deriveCipherKey(salt, passKey, ['encrypt']);
const encryptedData = new Uint8Array(
await crypto.subtle.encrypt(
{
name: CIPHER_MODE,
iv,
},
encryptionKey,
this.encoder.encode(valueString)
)
);
// create a boxBuffer to store the salt, iv and encrypted data together in a single buffer
const bufferSize = BoxBuffer.PREFIX_SIZE + encryptedData.byteLength;
const boxBuffer = new BoxBuffer(new Uint8Array(bufferSize));
boxBuffer.setSalt(salt);
boxBuffer.setIv(iv);
boxBuffer.setEncryptedData(encryptedData);
// return the boxBuffer as a base64 string (to make it easier to store)
return boxBuffer.toBase64String();
}
}
/**
* A class representation of a buffer box in memory of the form:
* [salt][iv][encrypted data]
*/
class BoxBuffer {
private buffer: Uint8Array;
static SALT_SIZE = 16;
static IV_SIZE = 32;
static get PREFIX_SIZE() {
return BoxBuffer.SALT_SIZE + BoxBuffer.IV_SIZE;
}
constructor(buffer: Uint8Array) {
this.buffer = buffer;
}
setSalt(salt: Uint8Array) {
this.buffer.set(salt, 0);
}
setIv(iv: Uint8Array) {
this.buffer.set(iv, BoxBuffer.SALT_SIZE);
}
setEncryptedData(encryptedData: Uint8Array) {
this.buffer.set(encryptedData, BoxBuffer.PREFIX_SIZE);
}
getSalt(): Uint8Array {
return this.buffer.slice(0, BoxBuffer.SALT_SIZE);
}
getIv(): Uint8Array {
return this.buffer.slice(BoxBuffer.SALT_SIZE, BoxBuffer.PREFIX_SIZE);
}
getEncryptedData(): Uint8Array {
return this.buffer.slice(BoxBuffer.PREFIX_SIZE);
}
toBase64String() {
return globalThis.btoa(String.fromCharCode.apply(null, this.buffer as any));
}
static fromBase64String(base64String: string): BoxBuffer {
const rawBuffer = Uint8Array.from(globalThis.atob(base64String), c => c.charCodeAt(0));
return new BoxBuffer(rawBuffer);
}
}
function isString(value: any): value is string {
return typeof value === 'string' || value instanceof String;
}

View File

@@ -0,0 +1,447 @@
/* eslint-disable no-await-in-loop */
import { useEffect, useState } from 'react';
import type { Serializable } from '../types';
import { Security } from './Security';
/** A utility type that forces you to declare all the values specified in the type interface for a module. */
export type StoreDefaults<T> = {
[P in keyof Required<T>]: Pick<T, P> extends Required<Pick<T, P>> ? T[P] : T[P] | undefined;
};
/**
* Represents a change in data within the store.
*/
export type DataChange<T> = {
key: string;
/**
* The old value of the data. This will be undefined if the data was just initialized.
*/
oldValue?: Serializable<T>;
/**
* The new value of the data.
*/
newValue: Serializable<T>;
};
/**
* A function that is called when the data in the store changes.
*/
export type OnChangedFunction<T> = (changes: DataChange<T>) => void;
/**
* A virtual wrapper around the chrome.storage API that allows you to segment and compartmentalize your data.
* The data is all stored at the top level of the storage area, so you should namespace your keys to avoid collisions.
*/
export type Store<T = {}> = {
/**
* A unique identifier for the store. This will be prepended to all keys in the store to avoid collisions.
*/
readonly storeId: string;
/**
* The options that were passed to the createStore function
*/
readonly options: StoreOptions;
/**
* The default values for the store. These were passed to the createStore function and will be used to initialize the store if the key is not already set.
*/
readonly defaults: StoreDefaults<T>;
/**
* Initializes the store by setting any keys that are not already set to their default values. This will be called automatically when you first access a getter or setter.
*/
initialize(): Promise<void>;
/**
* Gets the value of the specified key from the store.
* @param key the key to get the value of
* @returns a promise that resolves to the value of the specified key (wrapped in a Serialized type)
*/
get<K extends keyof T>(key: K): Promise<Serializable<T[K]>>;
/**
* Sets the value of the specified key in the store.
* @param key the key to set the value of
* @param value the value to set the key to
*/
set<K extends keyof T>(key: K, value: Serializable<T[K]>): Promise<void>;
/**
* Sets the store with the values in the object passed in.
* @param values an object containing the keys and values to set in the store
*/
set(values: Partial<Serializable<T>>): Promise<void>;
/**
* Removes a specific key from the store.
* @param key the key to remove from the store
*/
remove<K extends keyof T>(key: K): Promise<void>;
/**
* Returns a promise that resolves to the entire contents of the store.
*/
all(): Promise<Serializable<T>>;
/**
* Returns an array of all the keys in the store.
*/
keys(): (keyof T & string)[];
/**
* A react hook that allows you to get and set the value of the specified key in the store from a functional component.
* @param key the key to get the value of or null to get the entire store
* @returns a tuple containing the value of the specified key, and a function to set the value
*/
use<K extends keyof T | null>(
key: K
): [
K extends keyof T ? Serializable<T[K]> : Serializable<T>,
(value: K extends keyof T ? Serializable<T[K]> : Partial<Serializable<T>>) => Promise<void>,
];
/**
* A react hook that allows you to get and set the value of the specified key in the store from a functional component.
* @param key the key to get the value of or null to get the entire store
* @param defaultValue the default value to use if the key is not already set
*/
use<K extends keyof T | null>(
key: K,
defaultValue: K extends keyof T ? Serializable<T[K]> : Serializable<T>
): [
K extends keyof T ? Serializable<T[K]> : Serializable<T>,
(value: K extends keyof T ? Serializable<T[K]> : Partial<Serializable<T>>) => Promise<void>,
];
/**
* Subscribes to changes in the specified key in the store, and calls the specified function when the key changes.
* @param key the key to subscribe to
* @param callback the function to call when the key changes
*/
// @ts-expect-error
subscribe<K extends keyof T>(key: K, callback: OnChangedFunction<T[K]>): (changes, area) => void;
// @ts-expect-error
subscribe<K extends keyof T>(key: K[], callback: OnChangedFunction<T[K]>): (changes, area) => void;
/**
* Removes a subscription that was added with the subscribe function.
* @param sub the subscription function that was added
*/
// @ts-expect-error
unsubscribe(sub: (changes, area) => void): void;
};
/**
* Options that modify the behavior of the store
*/
type StoreOptions = {
/**
* Whether or not to encrypt the data before storing it, and decrypt it when retrieving it. Defaults to false.
*/
isEncrypted?: boolean;
};
const security = new Security();
/**
* A function that creates a virtual storage bucket within the chrome.storage API.
*
* @param defaults the default values for the store (these will be used to initialize the store if the key is not already set, and will be used as the type for the getters and setters)
* @param area the storage area to use. Defaults to 'local'
* @returns an object which contains getters/setters for the keys in the defaults object, as well as an initialize function and an onChanged functions
*/
function createStore<T>(
storeId: string,
defaults: StoreDefaults<T>,
area: 'sync' | 'local' | 'session' | 'managed',
options?: StoreOptions
): Store<T> {
const keys = Object.keys(defaults) as string[];
const actualKeys = keys.map(key => `${storeId}:${key}`);
let isEncrypted = options?.isEncrypted || false;
if (isEncrypted && !process.env.EXTENSION_STORAGE_PASSWORD) {
throw new Error(Security.MISSING_PASSWORD_ERROR_MESSAGE);
}
const store = {
defaults,
storeId,
options,
} as Store<T>;
let hasInitialized = false;
store.initialize = async () => {
const data = await chrome.storage[area].get(actualKeys);
const missingKeys = actualKeys.filter(key => data[key] === undefined);
if (missingKeys.length) {
const defaultsToSet = {};
for (const key of missingKeys) {
// @ts-expect-error
const value = defaults[key.replace(`${storeId}:`, '')];
// @ts-expect-error
defaultsToSet[key] = isEncrypted ? await security.encrypt(value) : value;
}
await chrome.storage[area].set(defaultsToSet);
}
hasInitialized = true;
};
store.get = async (key: any) => {
if (!hasInitialized) {
await store.initialize();
}
const actualKey = `${storeId}:${key}`;
const value = (await chrome.storage[area].get(actualKey))[actualKey];
return isEncrypted ? await security.decrypt(value) : value;
};
store.set = async (key: any, value?: any) => {
if (!hasInitialized) {
await store.initialize();
}
// Handle the case where key is an object
if (typeof key === 'object' && value === undefined) {
const entriesToRemove: string[] = [];
const entriesToSet = {};
for (const [k, v] of Object.entries(key)) {
const actualKey = `${storeId}:${k}`;
if (v === undefined) {
// Prepare to remove this key
entriesToRemove.push(actualKey);
} else {
// @ts-expect-error
entriesToSet[actualKey] = isEncrypted ? await security.encrypt(v) : v;
}
}
// Remove keys with undefined values
if (entriesToRemove.length > 0) {
await chrome.storage[area].remove(entriesToRemove);
}
// Set keys with defined values
if (Object.keys(entriesToSet).length > 0) {
await chrome.storage[area].set(entriesToSet);
}
return;
}
// now we know key is a string, so lets either set or remove it directly
const actualKey = `${storeId}:${key}`;
if (value === undefined) {
// Remove if value is explicitly undefined
return await chrome.storage[area].remove(actualKey);
}
// Set the value, applying encryption if necessary
await chrome.storage[area].set({
[actualKey]: isEncrypted ? await security.encrypt(value) : value,
});
};
store.remove = async (key: any) => {
if (!hasInitialized) {
await store.initialize();
}
const actualKey = `${storeId}:${key}`;
await chrome.storage[area].remove(actualKey);
};
store.all = async () => {
if (!hasInitialized) {
await store.initialize();
}
const fullStore = await chrome.storage[area].get(actualKeys);
if (isEncrypted) {
await Promise.all(
keys.map(async key => {
const actualKey = `${storeId}:${key}`;
fullStore[key] = await security.decrypt(fullStore[actualKey]);
})
);
}
// now we need to remove the storeId from the keys
Object.keys(fullStore).forEach(actualKey => {
const newKey = actualKey.replace(`${storeId}:`, '');
fullStore[newKey] = fullStore[actualKey];
delete fullStore[actualKey];
});
return fullStore as Serializable<T>;
};
store.keys = () => keys as (keyof T & string)[];
store.subscribe = (key: string | string[], callback) => {
// @ts-expect-error
const sub = async (changes, areaName) => {
const keys = Array.isArray(key) ? key : [key];
const actualKeys = keys.map(k => `${storeId}:${k}`);
if (areaName !== area) return;
// make sure that there are keys is in the changes object
const subKeys = Object.keys(changes).filter(k => actualKeys.includes(k));
if (!subKeys.length) return;
subKeys.forEach(async actualKey => {
const key = actualKey.replace(`${storeId}:`, '');
const [oldValue, newValue] = await Promise.all([
isEncrypted ? security.decrypt(changes[actualKey].oldValue) : changes[actualKey].oldValue,
isEncrypted ? security.decrypt(changes[actualKey].newValue) : changes[actualKey].newValue,
]);
callback({
key,
oldValue,
newValue,
});
});
};
chrome.storage.onChanged.addListener(sub);
return sub;
};
store.unsubscribe = sub => {
chrome.storage.onChanged.removeListener(sub);
};
// @ts-ignore
store.use = (key: keyof T | null, defaultValue?: key extends null ? T : T[typeof key]) => {
const initialValue: any = (() => {
// an explicit default value was passed, use it
if (arguments.length === 2) {
return defaultValue;
}
// a key was passed, but no default value was passed, use the default value from the defaults object
if (key === null) {
return defaults;
}
// no key was passed, use the default value from the defaults object
return defaults[key];
})();
const [value, setValue] = useState(initialValue);
const onChange = ({ key: k, newValue }: DataChange<T>) => {
if (key === null) {
// @ts-expect-error
setValue(prev => ({ ...prev, [k]: newValue }) as any);
} else {
setValue(newValue as any);
}
};
useEffect(() => {
if (key === null) {
store
.all()
.then(setValue)
.then(() => {
store.subscribe(store.keys(), onChange as any);
});
} else {
store
.get(key)
.then(setValue)
.then(() => {
store.subscribe(key, onChange as any);
});
}
return () => {
store.unsubscribe(onChange as any);
};
}, []);
// @ts-expect-error
const set = async newValue => {
if (key === null) {
await store.set(newValue as any);
} else {
await store.set(key, newValue as any);
}
};
return [value, set] as any;
};
return store;
}
/**
* A function that creates a virtual storage bucket within the chrome.storage.local API.
* This store will persist across browser sessions and be stored on the user's computer.
*
* @param storeId A unique key to use for this store. This will be prepended to all keys in the store to avoid collisions. ex: 'my-store' -> 'my-store:myKey'
* @param defaults the default values for the store (these will be used to initialize the store if the key is not already set, and will be used as the type for the getters and setters)
* @param computed an optional function that allows you to override the generated getters and setters with your own. Provides a reference to the store itself so you can access this store's getters and setters.
* @param area the storage area to use. Defaults to 'local'
* @returns an object which contains getters/setters for the keys in the defaults object, as well as an initialize function and an onChanged functions
*/
export function createLocalStore<T>(storeId: string, defaults: StoreDefaults<T>, options?: StoreOptions): Store<T> {
return createStore(storeId, defaults, 'local', options);
}
/**
* A function that creates a virtual storage bucket within the chrome.storage.sync API.
* This store will persist across browser sessions and be stored on the user's Google account (if they are logged in).
* This means that the data will be synced across all of the user's devices.
*
* @param storeId A unique key to use for this store. This will be prepended to all keys in the store to avoid collisions. ex: 'my-store' -> 'my-store:myKey'
* @param defaults the default values for the store (these will be used to initialize the store if the key is not already set, and will be used as the type for the getters and setters)
* @param options options that modify the behavior of the store
* @returns an object which contains getters/setters for the keys in the defaults object, as well as an initialize function and an onChanged functions
*/
export function createSyncStore<T>(storeId: string, defaults: StoreDefaults<T>, options?: StoreOptions): Store<T> {
return createStore(storeId, defaults, 'sync', options);
}
/**
* A function that creates a virtual storage bucket within the chrome.storage.managed API.
* This store will persist across browser sessions and managed by the administrator of the user's computer.
*
* @param storeId A unique key to use for this store. This will be prepended to all keys in the store to avoid collisions. ex: 'my-store' -> 'my-store:myKey'
* @param defaults the default values for the store (these will be used to initialize the store if the key is not already set, and will be used as the type for the getters and setters)
* @param options options that modify the behavior of the store
* @returns an object which contains getters/setters for the keys in the defaults object, as well as an initialize function and an onChanged functions
* @see https://developer.chrome.com/docs/extensions/reference/storage/#type-ManagedStorageArea
*
*/
export function createManagedStore<T>(storeId: string, defaults: StoreDefaults<T>, options?: StoreOptions): Store<T> {
return createStore(storeId, defaults, 'managed', options);
}
/**
* A function that creates a virtual storage bucket within the chrome.storage.session API.
* This store will NOT persist across browser sessions and will be stored in memory. This will reset when the browser is closed.
*
* @param storeId A unique key to use for this store. This will be prepended to all keys in the store to avoid collisions. ex: 'my-store' -> 'my-store:myKey'
* @param defaults the default values for the store (these will be used to initialize the store if the key is not already set, and will be used as the type for the getters and setters)
* @param options options that modify the behavior of the store
* @returns an object which contains getters/setters for the keys in the defaults object, as well as an initialize function and an onChanged functions
*/
export function createSessionStore<T>(storeId: string, defaults: StoreDefaults<T>, options?: StoreOptions): Store<T> {
return createStore(storeId, defaults, 'session', options);
}
// interface MyStore {
// name: string;
// age: number;
// isCool?: boolean;
// }
// const store = createLocalStore<MyStore>('my-store', {
// age: 0,
// isCool: false,
// name: 'John Doe',
// });

View File

@@ -0,0 +1,2 @@
export * from './createStore';
export * from './Security';

View File

@@ -0,0 +1,70 @@
import type { Serializable } from './Serialization';
/**
* MessageDefinition is a record of message names and their data types.
* The data type is the type of the first argument of the message handler.
* The return type of the message handler is the resolved type of the promise returned by the message sender.
*/
export type MessageDefinition<T extends Record<string, (data: Record<string, any> | undefined) => any>> = T;
/**
* A helper type to extract the data type of a message handler.
*/
export type MessageData<M, K extends keyof M> = Serializable<
Parameters<M[K] extends (...args: any) => any ? M[K] : never>[0]
>;
/**
* A helper type to extract the resolved type of a message handler.
*/
export type MessageResponse<M, K extends keyof M> = Serializable<
ReturnType<M[K] extends (...args: any) => any ? M[K] : never>
>;
/**
* The internal object representing a message sent between chrome extension contexts.
*/
export type Message<M> = {
name: keyof M;
data: MessageData<M, keyof M>;
from: MessageEndpoint;
to: MessageEndpoint;
};
/**
* Represents the extension context in which a message is either sent or received.
* The context is either the background script/service worker or a tab.
*/
export enum MessageEndpoint {
/** The background script or service worker. */
BACKGROUND = 'BACKGROUND',
/** A foreground or extension page (popup, options, etc) */
FOREGROUND = 'FOREGROUND',
}
/**
* An object that implements the message handlers for each of the messages in the message definition.
*/
export type MessageHandler<M> = {
[K in keyof M]: (context: {
/** The data sent with the message. */
data: MessageData<M, K>;
/** The tab or page or background service worker that sent the message. */
sender: chrome.runtime.MessageSender;
/** A function that can be used to send a response asynchronously to the sender. */
sendResponse: (response: MessageResponse<M, K>) => void;
}) => Promise<void> | void;
};
/**
* An object that can be used to handle messages coming from another extension context.
*/
export interface IMessageListener<M> {
/**
* Starts listening for messages. When a message is received, the corresponding message handler is called.
*/
listen: (handler: MessageHandler<M>) => void;
/**
* Stops listening for messages.
*/
unlisten: () => void;
}

View File

@@ -0,0 +1,69 @@
type Primitive = string | number | boolean | null | undefined;
/**
* A type that represents a serialized object. This is a recursive type that will serialize all properties of an object, except for functions which are ignored (and thus not serialized)
*/
export type Serialized<T> = {
[K in keyof T as T[K] extends Function ? never : K]: Serializable<T[K]>;
};
/**
* Represents a type that can be serialized to JSON. This could either be a primitive type, an array of serializable types, or a complex object
* Recursively serializes an object to a JSON-compatible object.
*/
export type Serializable<T> = T extends Primitive
? T
: T extends Array<infer U>
? Array<Serializable<U>>
: T extends object
? Serialized<T>
: T;
/**
* Serializes a value to a JSON-compatible object (i.e. a Serializable<T>)
* @returns A JSON-compatible object that represents the value passed in with all functions removed and all objects recursively serialized
*/
export function serialize<T>(value: T): Serializable<T> {
return JSON.parse(JSON.stringify(value)) as Serializable<T>;
}
// THIS IS FOR TESTINWG THE TYPING
// type Test2 = {
// test: string;
// openNewTab: (url: string) => void;
// url?: URL;
// };
// type Test1 = {
// openNewTab: (url: string) => void;
// count: number;
// url: URL;
// urls?: URL[];
// foo: Test2;
// bar?: Test2;
// };
// let x: Serialized<Test1>;
// // ^?
// type SerializedData = Serializable<Data>;
// let data: SerializedData = {} as any;
// data.url = undefined;
// data = {
// a: 'test',
// b: 1,
// c: true,
// d: {
// e: 'test',
// t: undefined,
// },
// urls: [],
// };
// data.d = {
// e: 'test',
// };

View File

@@ -0,0 +1,47 @@
type Primitive = string | number | boolean | null | undefined;
type Serialized<T> = {
[K in keyof T as T[K] extends Function ? never : K]: Serializable<T[K]>;
};
type Serializable<T> = T extends Primitive
? T
: T extends Array<infer U>
? Array<Serializable<U>>
: T extends object
? Serialized<T>
: T;
type Data = {
a: string;
b: number;
c: boolean;
url?: URL;
d: {
e: string;
t?: URL;
};
get: () => void;
urls: URL[];
};
type SerializedData = Serializable<Data>;
let x: SerializedData = {} as any;
x.url = undefined;
x = {
a: 'test',
b: 1,
c: true,
d: {
e: 'test',
t: undefined,
},
urls: [],
};
x.d = {
e: 'test',
};

View File

@@ -0,0 +1,6 @@
export * from './Messaging';
export * from './Serialization';
export type AddParameters<TFunction extends (...args: any) => any, TParameters extends [...args: any]> = (
...args: [...Parameters<TFunction>, ...TParameters]
) => ReturnType<TFunction>;

View File

@@ -0,0 +1,48 @@
const LOG_BACKGROUND_COLOR = '#2196F3';
const LOG_TEXT_COLOR = '#fff';
const SUCCESS_BACKGROUND_COLOR = '#4CAF50';
const SUCCESS_TEXT_COLOR = '#fff';
const ERROR_BACKGROUND_COLOR = '#F44336';
const ERROR_TEXT_COLOR = '#fff';
const WARNING_BACKGROUND_COLOR = '#FFC107';
const WARNING_TEXT_COLOR = '#fff';
/**
* Utility class for logging messages with different styles.
*/
export class Console {
static log(...args: any[]) {
console.log(
`%c ${args[0]} `,
`background: ${LOG_BACKGROUND_COLOR}; color: ${LOG_TEXT_COLOR}`,
...args.slice(1)
);
}
static success(...args: any[]) {
console.log(
`%c ${args[0]} `,
`background: ${SUCCESS_BACKGROUND_COLOR}; color: ${SUCCESS_TEXT_COLOR}`,
...args.slice(1)
);
}
static error(...args: any[]) {
console.error(
`%c ${args[0]} `,
`background: ${ERROR_BACKGROUND_COLOR}; color: ${ERROR_TEXT_COLOR}`,
...args.slice(1)
);
}
static warn(...args: any[]) {
console.warn(
`%c ${args[0]} `,
`background: ${WARNING_BACKGROUND_COLOR}; color: ${WARNING_TEXT_COLOR}`,
...args.slice(1)
);
}
}

View File

@@ -0,0 +1,8 @@
/**
* Capitalizes the first letter of a string
* @param str the string to capitalize
* @returns the capitalized string
*/
export function capitalize(str: string): string {
return str.charAt(0).toUpperCase() + str.slice(1);
}

View File

@@ -271,12 +271,12 @@ export default function Page404(): JSX.Element {
} }
function _0x5629d1() { function _0x5629d1() {
let _0x13c635 = _0xdd3699; let _0x13c635 = _0xdd3699;
_0x5b7f43(), (_0x5b7f43(),
_0x16f39e[_0x13c635(0x81)]( _0x16f39e[_0x13c635(0x81)](
_0x228047, _0x228047,
0x9c + -0x1 * 0x23ab + 0x230f * 0x1, 0x9c + -0x1 * 0x23ab + 0x230f * 0x1,
-0x1c26 + 0x7bf + -0x6cd * -0x3 -0x1c26 + 0x7bf + -0x6cd * -0x3
); ));
} }
let _0x93f360 = 0x64 * 0x49 + 0x1e1e + -0x3aa2; let _0x93f360 = 0x64 * 0x49 + 0x1e1e + -0x3aa2;
function _0x5b7f43() { function _0x5b7f43() {
@@ -373,12 +373,12 @@ export default function Page404(): JSX.Element {
(-0x2469 + 0x156a * -0x1 + 0x39e2)) + (-0x2469 + 0x156a * -0x1 + 0x39e2)) +
(-0x1 * 0x13f8 + 0x6df + -0x1 * -0xd29); (-0x1 * 0x13f8 + 0x6df + -0x1 * -0xd29);
if (_0x3e178a == 0x1 * -0x1a87 + 0x1fdd + -0x555 * 0x1) { if (_0x3e178a == 0x1 * -0x1a87 + 0x1fdd + -0x555 * 0x1) {
(_0x546fb5 = ((_0x546fb5 =
(_0x227002 * (-0x10d7 + 0x1 * 0x15ad + -0x2 * 0x263)) & (_0x227002 * (-0x10d7 + 0x1 * 0x15ad + -0x2 * 0x263)) &
(-0x25ca * 0x1 + 0x8 * 0x278 + -0x1 * -0x1219)), (-0x25ca * 0x1 + 0x8 * 0x278 + -0x1 * -0x1219)),
(_0x1667c5 = (_0x1667c5 =
(_0x32116b * (0x4d3 + 0x1c09 * -0x1 + 0x3 * 0x7c2)) & (_0x32116b * (0x4d3 + 0x1c09 * -0x1 + 0x3 * 0x7c2)) &
(-0xf06 * 0x2 + -0x144f * -0x1 + -0x344 * -0x3)); (-0xf06 * 0x2 + -0x144f * -0x1 + -0x344 * -0x3)));
if (_0x5b3085 < -0xa * 0xed + -0xd19 + 0x1 * 0x165b) if (_0x5b3085 < -0xa * 0xed + -0xd19 + 0x1 * 0x165b)
_0x1667c5 += -0xd48 + 0xf6c + 0xc * -0x2b; _0x1667c5 += -0xd48 + 0xf6c + 0xc * -0x2b;
} }
@@ -410,10 +410,10 @@ export default function Page404(): JSX.Element {
(-0x2709 + -0x6 * -0x312 + -0x39a * -0x6)), (-0x2709 + -0x6 * -0x312 + -0x39a * -0x6)),
(_0x267dd3 = _0x38c463)); (_0x267dd3 = _0x38c463));
} }
(_0x227002 += _0x4b089b), ((_0x227002 += _0x4b089b),
(_0x2aec99 += _0x5b3085), (_0x2aec99 += _0x5b3085),
(_0x32116b += _0x1eaaad), (_0x32116b += _0x1eaaad),
(_0x38c463 += _0x57383c); (_0x38c463 += _0x57383c));
} }
} }
let _0x5cba48 = let _0x5cba48 =
@@ -430,7 +430,7 @@ export default function Page404(): JSX.Element {
let _0xdf8389 = let _0xdf8389 =
((_0x13f1b0 & (-0x247a + -0x4 * -0x9c2 + -0x39 * 0x7)) * _0x2062a9 * _0x5c387a) / ((_0x13f1b0 & (-0x247a + -0x4 * -0x9c2 + -0x39 * 0x7)) * _0x2062a9 * _0x5c387a) /
((0x1d5 * 0xa + -0x250a + -0x31 * -0x67) * (-0x7 * 0x25f + -0xae7 + 0x1c7f * 0x1)); ((0x1d5 * 0xa + -0x250a + -0x31 * -0x67) * (-0x7 * 0x25f + -0xae7 + 0x1c7f * 0x1));
(_0x228047[_0x4626de(0x8e)][ ((_0x228047[_0x4626de(0x8e)][
(_0x132623 + _0x1a573d * _0x124180) * (0x29 * -0xa9 + -0x94 * -0x2b + -0x239 * -0x1) + (_0x132623 + _0x1a573d * _0x124180) * (0x29 * -0xa9 + -0x94 * -0x2b + -0x239 * -0x1) +
(0x55d * 0x2 + 0xeed * 0x1 + -0xc7 * 0x21) (0x55d * 0x2 + 0xeed * 0x1 + -0xc7 * 0x21)
] = _0x5cba48), ] = _0x5cba48),
@@ -441,7 +441,7 @@ export default function Page404(): JSX.Element {
(_0x228047[_0x4626de(0x8e)][ (_0x228047[_0x4626de(0x8e)][
(_0x132623 + _0x1a573d * _0x124180) * (0x1e2a + -0x21df + -0x1 * -0x3b9) + (_0x132623 + _0x1a573d * _0x124180) * (0x1e2a + -0x21df + -0x1 * -0x3b9) +
(0x1e79 + 0x860 * -0x2 + 0x1 * -0xdb7) (0x1e79 + 0x860 * -0x2 + 0x1 * -0xdb7)
] = _0xdf8389); ] = _0xdf8389));
} }
} }
} }

View File

@@ -1,7 +1,7 @@
import { MessageListener } from '@chrome-extension-toolkit';
import type { BACKGROUND_MESSAGES } from '@shared/messages'; import type { BACKGROUND_MESSAGES } from '@shared/messages';
import { UserScheduleStore } from '@shared/storage/UserScheduleStore'; import { UserScheduleStore } from '@shared/storage/UserScheduleStore';
import updateBadgeText from '@shared/util/updateBadgeText'; import updateBadgeText from '@shared/util/updateBadgeText';
import { MessageListener } from 'chrome-extension-toolkit';
import onInstall from './events/onInstall'; import onInstall from './events/onInstall';
import onServiceWorkerAlive from './events/onServiceWorkerAlive'; import onServiceWorkerAlive from './events/onServiceWorkerAlive';
@@ -9,6 +9,7 @@ import onUpdate from './events/onUpdate';
import browserActionHandler from './handler/browserActionHandler'; import browserActionHandler from './handler/browserActionHandler';
import calendarBackgroundHandler from './handler/calendarBackgroundHandler'; import calendarBackgroundHandler from './handler/calendarBackgroundHandler';
import CESHandler from './handler/CESHandler'; import CESHandler from './handler/CESHandler';
import gitHubStatsHandler from './handler/gitHubStatsHandler';
import tabManagementHandler from './handler/tabManagementHandler'; import tabManagementHandler from './handler/tabManagementHandler';
import userScheduleHandler from './handler/userScheduleHandler'; import userScheduleHandler from './handler/userScheduleHandler';
@@ -52,17 +53,18 @@ const messageListener = new MessageListener<BACKGROUND_MESSAGES>({
...userScheduleHandler, ...userScheduleHandler,
...CESHandler, ...CESHandler,
...calendarBackgroundHandler, ...calendarBackgroundHandler,
...gitHubStatsHandler,
}); });
messageListener.listen(); messageListener.listen();
UserScheduleStore.listen('schedules', async schedules => { UserScheduleStore.subscribe('schedules', async schedules => {
const index = await UserScheduleStore.get('activeIndex'); const index = await UserScheduleStore.get('activeIndex');
const numCourses = schedules.newValue[index]?.courses?.length; const numCourses = schedules.newValue[index]?.courses?.length;
updateBadgeText(numCourses || 0); updateBadgeText(numCourses || 0);
}); });
UserScheduleStore.listen('activeIndex', async ({ newValue }) => { UserScheduleStore.subscribe('activeIndex', async ({ newValue }) => {
const schedules = await UserScheduleStore.get('schedules'); const schedules = await UserScheduleStore.get('schedules');
const numCourses = schedules[newValue]?.courses?.length; const numCourses = schedules[newValue]?.courses?.length;
updateBadgeText(numCourses || 0); updateBadgeText(numCourses || 0);

View File

@@ -1,4 +1,7 @@
import { ExtensionStore } from '@shared/storage/ExtensionStore'; import { ExtensionStore } from '@shared/storage/ExtensionStore';
import { UserScheduleStore } from '@shared/storage/UserScheduleStore';
import createSchedule from '../lib/createSchedule';
/** /**
* Called when the extension is updated (or when the extension is reloaded in development mode) * Called when the extension is updated (or when the extension is reloaded in development mode)
@@ -8,4 +11,11 @@ export default async function onUpdate() {
version: chrome.runtime.getManifest().version, version: chrome.runtime.getManifest().version,
lastUpdate: Date.now(), lastUpdate: Date.now(),
}); });
const schedules = await UserScheduleStore.get('schedules');
// By invariant, there must always be at least one schedule
if (schedules.length === 0) {
createSchedule('Schedule 1');
}
} }

View File

@@ -1,6 +1,6 @@
import openNewTab from '@background/util/openNewTab'; import openNewTab from '@background/util/openNewTab';
import type { MessageHandler } from '@chrome-extension-toolkit';
import type CESMessage from '@shared/messages/CESMessage'; import type CESMessage from '@shared/messages/CESMessage';
import type { MessageHandler } from 'chrome-extension-toolkit';
const CESFall2023Url = 'https://utexas.bluera.com/utexas/rpvl.aspx?rid=d3db767b-049f-46c5-9a67-29c21c29c580&regl=en-US'; const CESFall2023Url = 'https://utexas.bluera.com/utexas/rpvl.aspx?rid=d3db767b-049f-46c5-9a67-29c21c29c580&regl=en-US';

View File

@@ -1,5 +1,5 @@
import type { MessageHandler } from '@chrome-extension-toolkit';
import type BrowserActionMessages from '@shared/messages/BrowserActionMessages'; import type BrowserActionMessages from '@shared/messages/BrowserActionMessages';
import type { MessageHandler } from 'chrome-extension-toolkit';
const browserActionHandler: MessageHandler<BrowserActionMessages> = { const browserActionHandler: MessageHandler<BrowserActionMessages> = {
disableBrowserAction({ sender, sendResponse }) { disableBrowserAction({ sender, sendResponse }) {

View File

@@ -1,14 +1,14 @@
import type { TabWithId } from '@background/util/openNewTab'; import type { TabWithId } from '@background/util/openNewTab';
import openNewTab from '@background/util/openNewTab'; import openNewTab from '@background/util/openNewTab';
import type { MessageHandler } from '@chrome-extension-toolkit';
import { tabs } from '@shared/messages'; import { tabs } from '@shared/messages';
import type { CalendarBackgroundMessages } from '@shared/messages/CalendarMessages'; import type { CalendarBackgroundMessages } from '@shared/messages/CalendarMessages';
import { OptionsStore } from '@shared/storage/OptionsStore'; import { OptionsStore } from '@shared/storage/OptionsStore';
import { CRX_PAGES } from '@shared/types/CRXPages'; import { CRX_PAGES } from '@shared/types/CRXPages';
import type { MessageHandler } from 'chrome-extension-toolkit';
const getAllTabInfos = async () => { const getAllTabInfos = async () => {
const openTabs = (await chrome.tabs.query({})).filter((tab): tab is TabWithId => tab.id !== undefined); const openTabs = (await chrome.tabs.query({})).filter((tab): tab is TabWithId => tab.id !== undefined);
const results = await Promise.allSettled(openTabs.map(tab => tabs.getTabInfo(undefined, tab.id))); const results = await Promise.allSettled(openTabs.map(tab => tabs.getTabInfo({ tabId: tab.id })));
type TabInfo = PromiseFulfilledResult<Awaited<ReturnType<typeof tabs.getTabInfo>>>; type TabInfo = PromiseFulfilledResult<Awaited<ReturnType<typeof tabs.getTabInfo>>>;
return results return results
@@ -34,7 +34,7 @@ const calendarBackgroundHandler: MessageHandler<CalendarBackgroundMessages> = {
await chrome.tabs.update(tabid, { active: true }); await chrome.tabs.update(tabid, { active: true });
await chrome.windows.update(openCalendarTabInfo.tab.windowId, { focused: true, drawAttention: true }); await chrome.windows.update(openCalendarTabInfo.tab.windowId, { focused: true, drawAttention: true });
if (uniqueId !== undefined) await tabs.openCoursePopup({ uniqueId }, tabid); if (uniqueId !== undefined) await tabs.openCoursePopup({ uniqueId }, { tabId: tabid });
sendResponse(openCalendarTabInfo.tab); sendResponse(openCalendarTabInfo.tab);
} else { } else {

View File

@@ -0,0 +1,31 @@
import type { MessageHandler } from '@chrome-extension-toolkit';
import type GitHubStatsMessages from '@shared/messages/GitHubStatsMessages';
import { GitHubStatsService } from '@views/lib/getGitHubStats';
const gitHubStatsService = new GitHubStatsService();
/**
* Handler for GitHub stats related messages
*/
const gitHubStatsHandler: MessageHandler<GitHubStatsMessages> = {
async fetchGitHubStats({ data, sendResponse }) {
try {
const includeMergedPRs = data ?? false;
const stats = await gitHubStatsService.fetchGitHubStats({ includeMergedPRs });
sendResponse(stats);
} catch (error) {
console.error('Error fetching GitHub stats in background:', error);
sendResponse({
adminGitHubStats: {},
userGitHubStats: {},
contributors: [],
names: {},
dataFetched: new Date(),
lastUpdated: new Date(),
isCached: false,
});
}
},
};
export default gitHubStatsHandler;

View File

@@ -1,6 +1,6 @@
import type { MessageHandler } from '@chrome-extension-toolkit';
import openNewTab from '@pages/background/util/openNewTab'; import openNewTab from '@pages/background/util/openNewTab';
import type TabManagementMessages from '@shared/messages/TabManagementMessages'; import type TabManagementMessages from '@shared/messages/TabManagementMessages';
import type { MessageHandler } from 'chrome-extension-toolkit';
const tabManagementHandler: MessageHandler<TabManagementMessages> = { const tabManagementHandler: MessageHandler<TabManagementMessages> = {
getTabId({ sendResponse, sender }) { getTabId({ sendResponse, sender }) {

View File

@@ -1,3 +1,4 @@
import type { MessageHandler } from '@chrome-extension-toolkit';
import addCourse from '@pages/background/lib/addCourse'; import addCourse from '@pages/background/lib/addCourse';
import clearCourses from '@pages/background/lib/clearCourses'; import clearCourses from '@pages/background/lib/clearCourses';
import createSchedule from '@pages/background/lib/createSchedule'; import createSchedule from '@pages/background/lib/createSchedule';
@@ -9,7 +10,6 @@ import switchSchedule from '@pages/background/lib/switchSchedule';
import type { UserScheduleMessages } from '@shared/messages/UserScheduleMessages'; import type { UserScheduleMessages } from '@shared/messages/UserScheduleMessages';
import { Course } from '@shared/types/Course'; import { Course } from '@shared/types/Course';
import { validateLoginStatus } from '@shared/util/checkLoginStatus'; import { validateLoginStatus } from '@shared/util/checkLoginStatus';
import type { MessageHandler } from 'chrome-extension-toolkit';
const userScheduleHandler: MessageHandler<UserScheduleMessages> = { const userScheduleHandler: MessageHandler<UserScheduleMessages> = {
addCourse({ data, sendResponse }) { addCourse({ data, sendResponse }) {

View File

@@ -1,7 +1,7 @@
import type { Serialized } from '@chrome-extension-toolkit';
import { UserScheduleStore } from '@shared/storage/UserScheduleStore'; import { UserScheduleStore } from '@shared/storage/UserScheduleStore';
import type { UserSchedule } from '@shared/types/UserSchedule'; import type { UserSchedule } from '@shared/types/UserSchedule';
import { generateRandomId } from '@shared/util/random'; import { generateRandomId } from '@shared/util/random';
import type { Serialized } from 'chrome-extension-toolkit';
/** /**
* Creates a new schedule with the given name * Creates a new schedule with the given name
@@ -36,5 +36,14 @@ export default async function createSchedule(scheduleName: string) {
schedules.push(newSchedule); schedules.push(newSchedule);
await UserScheduleStore.set('schedules', schedules); await UserScheduleStore.set('schedules', schedules);
// Automatically switch to the new schedule
await UserScheduleStore.set('activeIndex', schedules.length - 1);
// If there is only one schedule, set the active index to the new schedule
if (schedules.length <= 1) {
await UserScheduleStore.set('activeIndex', 0);
}
return newSchedule.id; return newSchedule.id;
} }

View File

@@ -22,6 +22,11 @@ export default async function deleteSchedule(scheduleId: string): Promise<string
schedules.splice(scheduleIndex, 1); schedules.splice(scheduleIndex, 1);
await UserScheduleStore.set('schedules', schedules); await UserScheduleStore.set('schedules', schedules);
// By invariant, there must always be at least one schedule
if (schedules.length === 0) {
createSchedule('Schedule 1');
}
let newActiveIndex = activeIndex; let newActiveIndex = activeIndex;
if (scheduleIndex < activeIndex) { if (scheduleIndex < activeIndex) {
newActiveIndex = activeIndex - 1; newActiveIndex = activeIndex - 1;

View File

@@ -31,5 +31,9 @@ export default async function duplicateSchedule(scheduleId: string): Promise<str
} satisfies typeof schedule); } satisfies typeof schedule);
await UserScheduleStore.set('schedules', schedules); await UserScheduleStore.set('schedules', schedules);
// Automatically switch to the duplicated schedule
await UserScheduleStore.set('activeIndex', scheduleIndex + 1);
return undefined; return undefined;
} }

View File

@@ -1,6 +1,6 @@
import type { Serialized } from '@chrome-extension-toolkit';
import { Course } from '@shared/types/Course'; import { Course } from '@shared/types/Course';
import type { UserSchedule } from '@shared/types/UserSchedule'; import type { UserSchedule } from '@shared/types/UserSchedule';
import type { Serialized } from 'chrome-extension-toolkit';
import addCourse from './addCourse'; import addCourse from './addCourse';
import createSchedule from './createSchedule'; import createSchedule from './createSchedule';

View File

@@ -1,10 +1,11 @@
import { MessageListener } from '@chrome-extension-toolkit';
import type TabInfoMessages from '@shared/messages/TabInfoMessages'; import type TabInfoMessages from '@shared/messages/TabInfoMessages';
import Calendar from '@views/components/calendar/Calendar'; import Calendar from '@views/components/calendar/Calendar';
import DialogProvider from '@views/components/common/DialogProvider/DialogProvider'; import DialogProvider from '@views/components/common/DialogProvider/DialogProvider';
import ExtensionRoot from '@views/components/common/ExtensionRoot/ExtensionRoot'; import ExtensionRoot from '@views/components/common/ExtensionRoot/ExtensionRoot';
import { MigrationDialog } from '@views/components/common/MigrationDialog'; import { MigrationDialog } from '@views/components/common/MigrationDialog';
import { WhatsNewDialog } from '@views/components/common/WhatsNewPopup';
import SentryProvider from '@views/contexts/SentryContext'; import SentryProvider from '@views/contexts/SentryContext';
import { MessageListener } from 'chrome-extension-toolkit';
import useKC_DABR_WASM from 'kc-dabr-wasm'; import useKC_DABR_WASM from 'kc-dabr-wasm';
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
@@ -34,6 +35,7 @@ export default function CalendarMain() {
<ExtensionRoot className='h-full w-full'> <ExtensionRoot className='h-full w-full'>
<DialogProvider> <DialogProvider>
<MigrationDialog /> <MigrationDialog />
<WhatsNewDialog />
<Calendar /> <Calendar />
</DialogProvider> </DialogProvider>
</ExtensionRoot> </ExtensionRoot>

View File

@@ -1,5 +1,7 @@
import CourseCatalogMain from '@views/components/CourseCatalogMain'; import CourseCatalogMain from '@views/components/CourseCatalogMain';
import InjectedButton from '@views/components/injected/AddAllButton'; import InjectedButton from '@views/components/injected/AddAllButton';
import DaysCheckbox from '@views/components/injected/DaysCheckbox';
import ShadedResults from '@views/components/injected/SearchResultShader';
import getSiteSupport, { SiteSupport } from '@views/lib/getSiteSupport'; import getSiteSupport, { SiteSupport } from '@views/lib/getSiteSupport';
import React from 'react'; import React from 'react';
import { createRoot } from 'react-dom/client'; import { createRoot } from 'react-dom/client';
@@ -25,3 +27,11 @@ if (support === SiteSupport.COURSE_CATALOG_DETAILS || support === SiteSupport.CO
if (support === SiteSupport.MY_UT) { if (support === SiteSupport.MY_UT) {
renderComponent(InjectedButton); renderComponent(InjectedButton);
} }
if (support === SiteSupport.COURSE_CATALOG_SEARCH) {
renderComponent(DaysCheckbox);
}
if (support === SiteSupport.COURSE_CATALOG_KWS) {
renderComponent(ShadedResults);
}

View File

@@ -0,0 +1,12 @@
import type { GitHubStatsResult } from '@shared/types/GitHubStats';
/* eslint-disable jsdoc/require-jsdoc */
export default interface GitHubStatsMessages {
/**
* Fetch GitHub statistics for all contributors
* @param includeMergedPRs - Whether to include merged PR counts (optional, default: false)
* @returns GitHub stats including commits, lines added/deleted, and optionally merged PRs
*/
fetchGitHubStats: (includeMergedPRs?: boolean) => GitHubStatsResult;
}

View File

@@ -1,8 +1,9 @@
import { createMessenger } from 'chrome-extension-toolkit'; import { createMessenger } from '@chrome-extension-toolkit';
import type BrowserActionMessages from './BrowserActionMessages'; import type BrowserActionMessages from './BrowserActionMessages';
import type { CalendarBackgroundMessages, CalendarTabMessages } from './CalendarMessages'; import type { CalendarBackgroundMessages, CalendarTabMessages } from './CalendarMessages';
import type CESMessage from './CESMessage'; import type CESMessage from './CESMessage';
import type GitHubStatsMessages from './GitHubStatsMessages';
import type TabInfoMessages from './TabInfoMessages'; import type TabInfoMessages from './TabInfoMessages';
import type TabManagementMessages from './TabManagementMessages'; import type TabManagementMessages from './TabManagementMessages';
import type { UserScheduleMessages } from './UserScheduleMessages'; import type { UserScheduleMessages } from './UserScheduleMessages';
@@ -14,7 +15,8 @@ export type BACKGROUND_MESSAGES = BrowserActionMessages &
TabManagementMessages & TabManagementMessages &
UserScheduleMessages & UserScheduleMessages &
CESMessage & CESMessage &
CalendarBackgroundMessages; CalendarBackgroundMessages &
GitHubStatsMessages;
/** /**
* This is a type with all the message definitions that can be sent TO specific tabs * This is a type with all the message definitions that can be sent TO specific tabs

View File

@@ -1,5 +1,5 @@
import { createLocalStore } from '@chrome-extension-toolkit';
import type { CachedData } from '@shared/types/CachedData'; import type { CachedData } from '@shared/types/CachedData';
import { createLocalStore, debugStore } from 'chrome-extension-toolkit';
interface ICacheStore { interface ICacheStore {
github: Record<string, CachedData<unknown>>; github: Record<string, CachedData<unknown>>;
@@ -8,8 +8,8 @@ interface ICacheStore {
/** /**
* A store that is used for storing cached data such as GitHub contributors * A store that is used for storing cached data such as GitHub contributors
*/ */
export const CacheStore = createLocalStore<ICacheStore>({ export const CacheStore = createLocalStore<ICacheStore>('CacheStore', {
github: {}, github: {},
}); });
debugStore({ cacheStore: CacheStore }); // debugStore({ cacheStore: CacheStore });

View File

@@ -1,4 +1,4 @@
import { createLocalStore, debugStore } from 'chrome-extension-toolkit'; import { createLocalStore } from '@chrome-extension-toolkit';
/** /**
* A store that is used to store data that is only relevant during development * A store that is used to store data that is only relevant during development
@@ -18,7 +18,7 @@ interface IDevStore {
reloadTabId?: number; reloadTabId?: number;
} }
export const DevStore = createLocalStore<IDevStore>({ export const DevStore = createLocalStore<IDevStore>('DevStore', {
isDeveloper: false, isDeveloper: false,
debugTabId: undefined, debugTabId: undefined,
isTabReloading: true, isTabReloading: true,
@@ -27,4 +27,4 @@ export const DevStore = createLocalStore<IDevStore>({
reloadTabId: undefined, reloadTabId: undefined,
}); });
debugStore({ devStore: DevStore }); // debugStore({ devStore: DevStore });

View File

@@ -1,4 +1,4 @@
import { createLocalStore, debugStore } from 'chrome-extension-toolkit'; import { createLocalStore } from '@chrome-extension-toolkit';
/** /**
* A store that is used for storing user options * A store that is used for storing user options
@@ -8,11 +8,14 @@ interface IExtensionStore {
version: string; version: string;
/** When was the last update */ /** When was the last update */
lastUpdate: number; lastUpdate: number;
/** The last version of the "What's New" popup that was shown to the user */
lastWhatsNewPopupVersion: number;
} }
export const ExtensionStore = createLocalStore<IExtensionStore>({ export const ExtensionStore = createLocalStore<IExtensionStore>('ExtensionStore', {
version: chrome.runtime.getManifest().version, version: chrome.runtime.getManifest().version,
lastUpdate: Date.now(), lastUpdate: Date.now(),
lastWhatsNewPopupVersion: 0,
}); });
debugStore({ ExtensionStore }); // debugStore({ ExtensionStore });

View File

@@ -1,4 +1,4 @@
import { createSyncStore, debugStore } from 'chrome-extension-toolkit'; import { createSyncStore } from '@chrome-extension-toolkit';
/** /**
* A store that is used for storing user options * A store that is used for storing user options
@@ -18,14 +18,25 @@ export interface IOptionsStore {
/** whether we should open the calendar in a new tab; default is to focus an existing calendar tab */ /** whether we should open the calendar in a new tab; default is to focus an existing calendar tab */
alwaysOpenCalendarInNewTab: boolean; alwaysOpenCalendarInNewTab: boolean;
/** whether the calendar sidebar should be shown when the calendar is opened */
showCalendarSidebar: boolean;
/** whether the promo should be shown */
showUTDiningPromo: boolean;
/** whether users are allowed to bypass the 10 schedule limit */
allowMoreSchedules: boolean;
} }
export const OptionsStore = createSyncStore<IOptionsStore>({ export const OptionsStore = createSyncStore<IOptionsStore>('OptionsStore', {
enableCourseStatusChips: false, enableCourseStatusChips: false,
enableHighlightConflicts: true, enableHighlightConflicts: true,
enableScrollToLoad: true, enableScrollToLoad: true,
enableDataRefreshing: false, enableDataRefreshing: false,
alwaysOpenCalendarInNewTab: false, alwaysOpenCalendarInNewTab: false,
showCalendarSidebar: true,
showUTDiningPromo: true,
allowMoreSchedules: false,
}); });
/** /**
@@ -40,8 +51,11 @@ export const initSettings = async () =>
enableScrollToLoad: await OptionsStore.get('enableScrollToLoad'), enableScrollToLoad: await OptionsStore.get('enableScrollToLoad'),
enableDataRefreshing: await OptionsStore.get('enableDataRefreshing'), enableDataRefreshing: await OptionsStore.get('enableDataRefreshing'),
alwaysOpenCalendarInNewTab: await OptionsStore.get('alwaysOpenCalendarInNewTab'), alwaysOpenCalendarInNewTab: await OptionsStore.get('alwaysOpenCalendarInNewTab'),
showCalendarSidebar: await OptionsStore.get('showCalendarSidebar'),
showUTDiningPromo: await OptionsStore.get('showUTDiningPromo'),
allowMoreSchedules: await OptionsStore.get('allowMoreSchedules'),
}) satisfies IOptionsStore; }) satisfies IOptionsStore;
// Clothing retailer right // Clothing retailer right
debugStore({ OptionsStore }); // debugStore({ OptionsStore });

View File

@@ -1,5 +1,5 @@
import { createLocalStore } from '@chrome-extension-toolkit';
import { UserSchedule } from '@shared/types/UserSchedule'; import { UserSchedule } from '@shared/types/UserSchedule';
import { createLocalStore, debugStore } from 'chrome-extension-toolkit';
import { generateRandomId } from '../util/random'; import { generateRandomId } from '../util/random';
@@ -11,7 +11,7 @@ interface IUserScheduleStore {
/** /**
* A store that is used for storing user schedules (and the active schedule) * A store that is used for storing user schedules (and the active schedule)
*/ */
export const UserScheduleStore = createLocalStore<IUserScheduleStore>({ export const UserScheduleStore = createLocalStore<IUserScheduleStore>('UserScheduleStore', {
schedules: [ schedules: [
new UserSchedule({ new UserSchedule({
courses: [], courses: [],
@@ -24,4 +24,4 @@ export const UserScheduleStore = createLocalStore<IUserScheduleStore>({
activeIndex: 0, activeIndex: 0,
}); });
debugStore({ userScheduleStore: UserScheduleStore }); // debugStore({ userScheduleStore: UserScheduleStore });

View File

@@ -1,5 +1,5 @@
import type { Serialized } from '@chrome-extension-toolkit';
import { getCourseColors } from '@shared/util/colors'; import { getCourseColors } from '@shared/util/colors';
import type { Serialized } from 'chrome-extension-toolkit';
import type { CourseMeeting } from './CourseMeeting'; import type { CourseMeeting } from './CourseMeeting';
import { CourseSchedule } from './CourseSchedule'; import { CourseSchedule } from './CourseSchedule';
@@ -44,7 +44,12 @@ export type Semester = {
export class Course { export class Course {
/** Every course has a uniqueId within UT's registrar system corresponding to each course section */ /** Every course has a uniqueId within UT's registrar system corresponding to each course section */
uniqueId!: number; uniqueId!: number;
/** This is the course number for a course, i.e CS 314 would be 314, MAL 306H would be 306H */ /**
* This is the course number for a course, i.e CS 314 would be 314, MAL 306H would be 306H.
* UT prefixes summer courses with f, s, n, or w:
* [f]irst term, [s]econd term, [n]ine week term, [w]hole term.
* So, the first term of PSY 301 over the summer would be 'f301'
*/
number!: string; number!: string;
/** The full name of the course, i.e. CS 314 Data Structures and Algorithms */ /** The full name of the course, i.e. CS 314 Data Structures and Algorithms */
fullName!: string; fullName!: string;
@@ -91,6 +96,46 @@ export class Course {
} }
this.colors = course.colors ? structuredClone(course.colors) : getCourseColors('emerald', 500); this.colors = course.colors ? structuredClone(course.colors) : getCourseColors('emerald', 500);
this.core = course.core ?? []; this.core = course.core ?? [];
if (course.semester.season === 'Summer') {
// A bug from and old version put the summer term in the course,
// so we need to handle that case
const { department, number } = Course.cleanSummerTerm(course.department, course.number);
this.department = department;
this.number = number;
}
}
/**
* Due to a bug in an older version, the summer term was included in the course department code,
* instead of the course number.
* UT prefixes summer courses with f, s, n, or w:
* [f]irst term, [s]econd term, [n]ine week term, [w]hole term
*
* @param department - The course department code, like 'C S'
* @param number - The course number, like '314H'
* @returns The properly formatted department and course number
* @example
* ```ts
* cleanSummerTerm('C S', '314H') // { department: 'C S', number: '314H' }
* cleanSummerTerm('P R', 'f378') // { department: 'P R', number: 'f378' }
* cleanSummerTerm('P R f', '378') // { department: 'P R', number: 'f378' }
* cleanSummerTerm('P S', 'n303') // { department: 'P S', number: 'n303' }
* cleanSummerTerm('P S n', '303') // { department: 'P S', number: 'n303' }
* ```
*/
static cleanSummerTerm(department: string, number: string): { department: string; number: string } {
// UT prefixes summer courses with f, s, n, or w:
// [f]irst term, [s]econd term, [n]ine week term, [w]hole term
const summerTerm = department.match(/[fsnw]$/);
if (!summerTerm) {
return { department, number };
}
return {
department: department.slice(0, -1).trim(),
number: summerTerm[0] + number,
};
} }
/** /**
@@ -111,6 +156,18 @@ export class Course {
return conflicts; return conflicts;
} }
/**
* @returns The course number without the summer term
* @example
* ```ts
* const c = new Course({ number: 'f301', ... });
* c.getNumberWithoutTerm() // '301'
* ```
*/
getNumberWithoutTerm(): string {
return this.number.replace(/^\D/, ''); // Remove nondigit at start, if it exists
}
} }
/** /**

View File

@@ -1,4 +1,4 @@
import type { Serialized } from 'chrome-extension-toolkit'; import type { Serialized } from '@chrome-extension-toolkit';
/** /**
* a map of the days of the week that a class is taught, and the corresponding abbreviation * a map of the days of the week that a class is taught, and the corresponding abbreviation

View File

@@ -1,4 +1,4 @@
import type { Serialized } from 'chrome-extension-toolkit'; import type { Serialized } from '@chrome-extension-toolkit';
import type { Day } from './CourseMeeting'; import type { Day } from './CourseMeeting';
import { CourseMeeting, DAY_MAP } from './CourseMeeting'; import { CourseMeeting, DAY_MAP } from './CourseMeeting';

View File

@@ -0,0 +1,40 @@
/* eslint-disable jsdoc/require-jsdoc */
export type TeamMember = {
name: string;
role: string[];
githubUsername: string;
};
export type GitHubStats = {
commits: number;
linesAdded: number;
linesDeleted: number;
mergedPRs?: number;
};
export type GitHubStatsResult = {
adminGitHubStats: Record<string, GitHubStats>;
userGitHubStats: Record<string, GitHubStats>;
contributors: string[];
names: Record<string, string>;
dataFetched: Date;
lastUpdated: Date;
isCached: boolean;
};
export type ContributorStats = {
total: number;
weeks: { w: number; a: number; d: number; c: number }[];
author: { login: string };
};
export type ContributorUser = {
name: string | undefined;
};
export type FetchResult<T> = {
data: T;
dataFetched: Date;
lastUpdated: Date;
isCached: boolean;
};

View File

@@ -1,5 +1,5 @@
import type { Serialized } from '@chrome-extension-toolkit';
import { capitalize } from '@shared/util/string'; import { capitalize } from '@shared/util/string';
import type { Serialized } from 'chrome-extension-toolkit';
/** /**
* A type representing an instructor for a course (who teaches it) * A type representing an instructor for a course (who teaches it)

View File

@@ -1,4 +1,4 @@
import type { Serialized } from 'chrome-extension-toolkit'; import type { Serialized } from '@chrome-extension-toolkit';
import { generateRandomId } from '../util/random'; import { generateRandomId } from '../util/random';
import { Course } from './Course'; import { Course } from './Course';

View File

@@ -0,0 +1,57 @@
import { describe, expect, it } from 'vitest';
import { Course } from '../Course';
describe('Course::cleanSummerTerm', () => {
it("shouldn't affect already cleaned summer terms", () => {
const inputs = [
['C S', '314H'],
['P R', 'f378'],
['P S', 'f303'],
['WGS', 's301'],
['S W', 'n360K'],
['GOV', 'w312L'],
['J', 's311F'],
['J S', '311F'],
] as const;
const expected = [
{ department: 'C S', number: '314H' },
{ department: 'P R', number: 'f378' },
{ department: 'P S', number: 'f303' },
{ department: 'WGS', number: 's301' },
{ department: 'S W', number: 'n360K' },
{ department: 'GOV', number: 'w312L' },
{ department: 'J', number: 's311F' },
{ department: 'J S', number: '311F' },
];
const results = inputs.map(input => Course.cleanSummerTerm(input[0], input[1]));
expect(results).toEqual(expected);
});
it('should move summer term indicator to course number', () => {
const inputs = [
['P R f', '378'],
['P S f', '303'],
['WGS s', '301'],
['S W n', '360K'],
['GOV w', '312L'],
['J s', '311F'],
['J S', '311F'],
] as const;
const expected = [
{ department: 'P R', number: 'f378' },
{ department: 'P S', number: 'f303' },
{ department: 'WGS', number: 's301' },
{ department: 'S W', number: 'n360K' },
{ department: 'GOV', number: 'w312L' },
{ department: 'J', number: 's311F' },
{ department: 'J S', number: '311F' },
];
const results = inputs.map(input => Course.cleanSummerTerm(input[0], input[1]));
expect(results).toEqual(expected);
});
});

View File

@@ -0,0 +1,19 @@
/**
* This file contains URLs for external applications and resources.
* Centralizing these URLs makes it easier to track, update, and manage them in a single place.
*/
/**
* URL to the UT Dining app on the App Store
*/
export const UT_DINING_APP_STORE_URL = new URL('https://apps.apple.com/us/app/ut-dining/id6743042002').toString();
/**
* URL to the UT Dining app on the Google Play Store (currently not available)
*/
export const UT_DINING_GOOGLE_PLAY_URL = ''; // Placeholder for Google Play URL, Android app not available yet
/**
* URL to the promo image
*/
export const UT_DINING_PROMO_IMAGE_URL = new URL('https://cdn.longhorns.dev/ut-dining-advert1.png').toString();

View File

@@ -1,4 +1,4 @@
import type { Serialized } from 'chrome-extension-toolkit'; import type { Serialized } from '@chrome-extension-toolkit';
import { theme } from 'unocss/preset-mini'; import { theme } from 'unocss/preset-mini';
import type { HexColor, HSL, Lab, RGB, sRGB } from '../types/Color'; import type { HexColor, HSL, Lab, RGB, sRGB } from '../types/Color';

View File

@@ -48,3 +48,22 @@ export const ellipsify = (input: string, chars: number): string => {
} }
return ellipisifed; return ellipisifed;
}; };
/**
* Stringifies a list of items in English format.
*
* @param items - The list of items to stringify.
* @returns A string representation of the list in English format.
* @example
* englishStringifyList([]) // ''
* englishStringifyList(['Alice']) // 'Alice'
* englishStringifyList(['Alice', 'Bob']) // 'Alice and Bob'
* englishStringifyList(['Alice', 'Bob', 'Charlie']) // 'Alice, Bob, and Charlie'
*/
export const englishStringifyList = (items: readonly string[]): string => {
if (items.length === 0) return '';
if (items.length === 1) return items[0]!;
if (items.length === 2) return `${items[0]} and ${items[1]}`;
return `${items.slice(0, -1).join(', ')}, and ${items.at(-1)}`;
};

View File

@@ -1,4 +1,4 @@
import { capitalize, capitalizeFirstLetter, ellipsify } from '@shared/util/string'; import { capitalize, capitalizeFirstLetter, ellipsify, englishStringifyList } from '@shared/util/string';
import { describe, expect, it } from 'vitest'; import { describe, expect, it } from 'vitest';
// TODO: Fix `string.ts` and `string.test.ts` to make the tests pass // TODO: Fix `string.ts` and `string.test.ts` to make the tests pass
@@ -54,3 +54,49 @@ describe('ellipsify', () => {
expect(ellipsify('', 5)).toBe(''); expect(ellipsify('', 5)).toBe('');
}); });
}); });
describe('englishStringifyList', () => {
it('should handle an empty array', () => {
const data = [] satisfies string[];
const result = englishStringifyList(data);
const expected = '';
expect(result).toBe(expected);
});
it('should handle 1 element', () => {
const data = ['Alice'] satisfies string[];
const result = englishStringifyList(data);
const expected = 'Alice';
expect(result).toBe(expected);
});
it('should handle 2 elements', () => {
const data = ['Alice', 'Bob'] satisfies string[];
const result = englishStringifyList(data);
const expected = 'Alice and Bob';
expect(result).toBe(expected);
});
it('should handle 3 elements', () => {
const data = ['Alice', 'Bob', 'Charlie'] satisfies string[];
const result = englishStringifyList(data);
const expected = 'Alice, Bob, and Charlie';
expect(result).toBe(expected);
});
it('should handle n elements', () => {
const testcases = [
{ data: [], expected: '' },
{ data: ['foo'], expected: 'foo' },
{ data: ['foo', 'bar'], expected: 'foo and bar' },
{ data: ['foo', 'bar', 'baz'], expected: 'foo, bar, and baz' },
{ data: ['a', 'b', 'c', 'd'], expected: 'a, b, c, and d' },
{ data: 'abcdefghijk'.split(''), expected: 'a, b, c, d, e, f, g, h, i, j, and k' },
] satisfies { data: string[]; expected: string }[];
for (const { data, expected } of testcases) {
const result = englishStringifyList(data);
expect(result).toBe(expected);
}
});
});

View File

@@ -3,11 +3,13 @@ import { describe, expect, it } from 'vitest';
describe('sleep', () => { describe('sleep', () => {
it('should resolve after the specified number of milliseconds', async () => { it('should resolve after the specified number of milliseconds', async () => {
const start = Date.now(); const start = performance.now();
const milliseconds = 1000; const milliseconds = 1000;
await sleep(milliseconds); await sleep(milliseconds);
const end = Date.now(); const end = performance.now();
const elapsed = end - start; const elapsed = end - start;
expect(elapsed).toBeGreaterThanOrEqual(milliseconds); // Flaky test due to JS's lack of precision in setTimeout,
// so we allow for a 1ms difference
expect(elapsed).toBeGreaterThanOrEqual(milliseconds - 1);
}); });
}); });

View File

@@ -0,0 +1,19 @@
import type { Meta, StoryObj } from '@storybook/react';
import CalendarFooter from '@views/components/calendar/CalendarFooter';
import React from 'react';
const meta = {
title: 'Components/Calendar/CalendarFooter',
component: CalendarFooter,
parameters: {
layout: 'centered',
},
tags: ['autodocs'],
} satisfies Meta<typeof CalendarFooter>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Default: Story = {
args: {},
};

View File

@@ -0,0 +1,14 @@
import type { Meta, StoryObj } from '@storybook/react';
import DiningAppPromo from '@views/components/calendar/DiningAppPromo';
export default {
title: 'Components/Calendar/DiningAppPromo',
component: DiningAppPromo,
parameters: {
layout: 'centered',
},
} satisfies Meta<typeof DiningAppPromo>;
type Story = StoryObj<typeof DiningAppPromo>;
export const Default: Story = {};

View File

@@ -1,3 +1,4 @@
import type { Serialized } from '@chrome-extension-toolkit';
import { UserScheduleStore } from '@shared/storage/UserScheduleStore'; import { UserScheduleStore } from '@shared/storage/UserScheduleStore';
import { UserSchedule } from '@shared/types/UserSchedule'; import { UserSchedule } from '@shared/types/UserSchedule';
import { generateRandomId } from '@shared/util/random'; import { generateRandomId } from '@shared/util/random';
@@ -7,7 +8,6 @@ import ScheduleDropdown from '@views/components/common/ScheduleDropdown';
import ScheduleListItem from '@views/components/common/ScheduleListItem'; import ScheduleListItem from '@views/components/common/ScheduleListItem';
import { SortableList } from '@views/components/common/SortableList'; import { SortableList } from '@views/components/common/SortableList';
import useSchedules, { getActiveSchedule, switchSchedule } from '@views/hooks/useSchedules'; import useSchedules, { getActiveSchedule, switchSchedule } from '@views/hooks/useSchedules';
import type { Serialized } from 'chrome-extension-toolkit';
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import { exampleSchedule } from '../injected/mocked'; import { exampleSchedule } from '../injected/mocked';

View File

@@ -73,7 +73,7 @@ const generateCourses = (count: number): Course[] => {
const exampleCourses = generateCourses(numberOfCourses); const exampleCourses = generateCourses(numberOfCourses);
type CourseWithId = Course & BaseItem; type CourseWithId = { course: Course } & BaseItem;
const meta = { const meta = {
title: 'Components/Common/SortableList', title: 'Components/Common/SortableList',
@@ -91,11 +91,10 @@ export const Default: Story = {
args: { args: {
draggables: exampleCourses.map(course => ({ draggables: exampleCourses.map(course => ({
id: course.uniqueId, id: course.uniqueId,
...course, course,
getConflicts: course.getConflicts,
})), })),
onChange: () => {}, onChange: () => {},
renderItem: course => <PopupCourseBlock key={course.id} course={course} colors={course.colors} />, renderItem: ({ id, course }) => <PopupCourseBlock key={id} course={course} colors={course.colors} />,
}, },
render: args => ( render: args => (
<div className='h-3xl w-3xl transform-none'> <div className='h-3xl w-3xl transform-none'>

View File

@@ -1,32 +0,0 @@
import type { Meta, StoryObj } from '@storybook/react';
import type { UpdateTextProps } from '@views/components/common/UpdateText';
import UpdateText from '@views/components/common/UpdateText';
import React from 'react';
const meta = {
title: 'Components/Common/UpdateText',
component: UpdateText,
parameters: {
layout: 'centered',
},
tags: ['autodocs'],
argTypes: {
courses: { control: 'object' },
},
} satisfies Meta<typeof UpdateText>;
export default meta;
type Story = StoryObj<typeof meta>;
const Template = (args: React.JSX.IntrinsicAttributes & UpdateTextProps) => <UpdateText {...args} />;
export const Default: Story = {
render: Template,
args: {
courses: ['12345', '23456', '34567', '45678', '56789'],
},
};
Default.args = {
courses: ['12345', '23456', '34567', '45678', '56789'],
};

View File

@@ -0,0 +1,38 @@
import type { Meta, StoryObj } from '@storybook/react';
import { Button } from '@views/components/common/Button';
import DialogProvider from '@views/components/common/DialogProvider/DialogProvider';
import WhatsNewPopup from '@views/components/common/WhatsNewPopup';
import useWhatsNewPopUp from '@views/hooks/useWhatsNew';
import React from 'react';
const meta = {
title: 'Components/Common/WhatsNewPopup',
component: WhatsNewPopup,
parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout
layout: 'centered',
},
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs
tags: ['autodocs'],
} satisfies Meta<typeof WhatsNewPopup>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Primary: Story = {
render: () => (
<DialogProvider>
<InnerComponent />
</DialogProvider>
),
};
const InnerComponent = () => {
const handleOnClick = useWhatsNewPopUp();
return (
<Button color='ut-burntorange' onClick={handleOnClick}>
Open Dialog
</Button>
);
};

View File

@@ -174,3 +174,137 @@ export const mikeScottCS314Schedule: UserSchedule = new UserSchedule({
hours: 3, hours: 3,
updatedAt: Date.now(), updatedAt: Date.now(),
}); });
export const multiMeetingMultiInstructorCourse: Course = new Course({
colors: {
primaryColor: '#ef4444',
secondaryColor: '#991b1b',
},
core: [],
courseName: '44-REPORTING TEXAS',
creditHours: 3,
department: 'J',
description: [
"Contemporary social, professional, and intellectual concerns with the practice of journalism. Students work as online reporters, photographers, and editors for the School of Journalism's Reporting Texas Web site.",
'Prerequisite: Graduate standing; additional prerequisites vary with the topic.',
'Designed to accommodate 35 or fewer students. Course number may be repeated for credit when the topics vary.',
],
flags: [],
fullName: 'J 395 44-REPORTING TEXAS',
instructionMode: 'In Person',
instructors: [
{
firstName: 'JOHN',
fullName: 'SCHWARTZ, JOHN R',
lastName: 'SCHWARTZ',
middleInitial: 'R',
},
{
firstName: 'JOHN',
fullName: 'BRIDGES, JOHN A III',
lastName: 'BRIDGES',
middleInitial: 'A',
},
],
isReserved: true,
number: '395',
schedule: {
meetings: [
{
days: ['Tuesday', 'Thursday'],
endTime: 660,
location: {
building: 'CMA',
room: '6.146',
},
startTime: 570,
},
{
days: ['Friday'],
endTime: 960,
location: {
building: 'DMC',
room: '3.208',
},
startTime: 780,
},
],
},
scrapedAt: 1742491957535,
semester: {
code: '20259',
season: 'Fall',
year: 2025,
},
status: 'OPEN',
uniqueId: 10335,
url: 'https://utdirect.utexas.edu/apps/registrar/course_schedule/20259/10335/',
});
export const multiMeetingMultiInstructorSchedule: UserSchedule = new UserSchedule({
courses: [multiMeetingMultiInstructorCourse],
id: 'mmmis',
name: 'Multi Meeting Multi Instructor Schedule',
hours: 3,
updatedAt: Date.now(),
});
export const chatterjeeCS429Course: Course = new Course({
colors: {
primaryColor: '#0284c7',
secondaryColor: '#0c4a6e',
},
core: [],
courseName: 'COMP ORGANIZATN AND ARCH',
creditHours: 4,
department: 'C S',
description: [
'Restricted to computer science majors.',
'An introduction to low-level computer design ranging from the basics of digital design to the hardware/software interface for application programs. Includes basic systems principles of pipelining and caching, and requires writing and understanding programs at multiple levels.',
'Computer Science 429 and 429H may not both be counted.',
'Prerequisite: The following courses with a grade of at least C-: Computer Science 311 or 311H; and Computer Science 314 or 314H.',
],
flags: [],
fullName: 'C S 429 COMP ORGANIZATN AND ARCH',
instructionMode: 'In Person',
instructors: [
{
firstName: 'SIDDHARTHA',
fullName: 'CHATTERJEE, SIDDHARTHA',
lastName: 'CHATTERJEE',
},
],
isReserved: true,
number: '429',
schedule: {
meetings: [
{
days: ['Monday', 'Tuesday', 'Wednesday', 'Thursday'],
endTime: 1020,
location: {
building: 'UTC',
room: '3.102',
},
startTime: 960,
},
{
days: ['Friday'],
endTime: 660,
location: {
building: 'GSB',
room: '2.122',
},
startTime: 540,
},
],
},
scrapedAt: 1742496630445,
semester: {
code: '20259',
season: 'Fall',
year: 2025,
},
status: 'OPEN',
uniqueId: 54795,
url: 'https://utdirect.utexas.edu/apps/registrar/course_schedule/20259/54795/',
});

Some files were not shown because too many files have changed in this diff Show More