Merge branch 'main' into derek/settingsPageLag
This commit is contained in:
@@ -8,5 +8,5 @@ trim_trailing_whitespace = true
|
|||||||
indent_size = 4
|
indent_size = 4
|
||||||
indent_style = space
|
indent_style = space
|
||||||
|
|
||||||
[*.nix]
|
[*.{nix,yaml,yml}]
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|||||||
23
.github/ISSUE_TEMPLATE/bug_report.md
vendored
23
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,21 +1,20 @@
|
|||||||
---
|
---
|
||||||
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: ''
|
labels: ''
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Pre-submission Checklist**
|
**Pre-submission Checklist**
|
||||||
|
|
||||||
<!-- Please check all applicable boxes before submitting your issue -->
|
<!-- Please check all applicable boxes before submitting your issue -->
|
||||||
|
|
||||||
- [ ] I have searched existing issues to make sure this is not a duplicate
|
- [ ] I have searched existing issues to make sure this is not a duplicate
|
||||||
- [ ] I have cleared my browser cache and confirmed the issue persists
|
- [ ] I have cleared my browser cache and confirmed the issue persists
|
||||||
- [ ] I have checked this issue affects the latest version of the extension
|
- [ ] I have checked this issue affects the latest version of the extension
|
||||||
- [ ] I have disabled other extensions to ensure this isn't a conflict issue
|
- [ ] I have disabled other extensions to ensure this isn't a conflict issue
|
||||||
- [ ] I have included all the information requested below
|
- [ ] I have included all the information requested below
|
||||||
|
|
||||||
**Bug Description**
|
**Bug Description**
|
||||||
|
|
||||||
@@ -30,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**
|
||||||
|
|
||||||
@@ -42,9 +41,9 @@ assignees: ''
|
|||||||
|
|
||||||
**Debug Information**
|
**Debug Information**
|
||||||
|
|
||||||
- UTRP Extension Version: [e.g. 1.2.0]
|
- UTRP Extension Version: [e.g. 1.2.0]
|
||||||
- Browser Info: [e.g. Chrome 120.0.0]
|
- Browser Info: [e.g. Chrome 120.0.0]
|
||||||
- OS: [e.g. Windows 11, macOS Sonoma]
|
- OS: [e.g. Windows 11, macOS Sonoma]
|
||||||
|
|
||||||
**Console Logs**
|
**Console Logs**
|
||||||
|
|
||||||
|
|||||||
27
.github/ISSUE_TEMPLATE/feature_request.md
vendored
27
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,34 +1,29 @@
|
|||||||
---
|
---
|
||||||
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: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Pre-submission Checklist**
|
**Pre-submission Checklist**
|
||||||
|
|
||||||
<!-- Please check all applicable boxes before submitting your feature request -->
|
<!-- Please check all applicable boxes before submitting your feature request -->
|
||||||
|
|
||||||
- [ ] I have searched existing issues to ensure this feature hasn't been requested
|
- [ ] I have searched existing issues to ensure this feature hasn't been requested
|
||||||
- [ ] I have searched closed issues to check if this was previously rejected/implemented
|
- [ ] I have searched closed issues to check if this was previously rejected/implemented
|
||||||
- [ ] I have checked the project roadmap (if available) for planned similar features
|
- [ ] I have checked the project roadmap (if available) for planned similar features
|
||||||
- [ ] 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! -->
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ about: Updating Build Dependencies
|
|||||||
title: ''
|
title: ''
|
||||||
labels: build, dependencies
|
labels: build, dependencies
|
||||||
assignees: doprz, Razboy20
|
assignees: doprz, Razboy20
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
- [ ] Updated Nix Flake
|
- [ ] Updated Nix Flake
|
||||||
|
|||||||
37
.github/dependabot.yml
vendored
37
.github/dependabot.yml
vendored
@@ -1,21 +1,20 @@
|
|||||||
version: 2
|
version: 2
|
||||||
updates:
|
updates:
|
||||||
- package-ecosystem: 'npm'
|
- package-ecosystem: 'npm'
|
||||||
directory: '/'
|
directory: '/'
|
||||||
schedule:
|
schedule:
|
||||||
interval: 'weekly'
|
interval: 'weekly'
|
||||||
day: 'monday'
|
day: 'monday'
|
||||||
time: '09:00'
|
time: '09:00'
|
||||||
timezone: 'America/Chicago'
|
timezone: 'America/Chicago'
|
||||||
groups:
|
groups:
|
||||||
minor-and-patch-updates:
|
minor-and-patch-updates:
|
||||||
update-types:
|
update-types:
|
||||||
- 'minor'
|
- 'minor'
|
||||||
- 'patch'
|
- 'patch'
|
||||||
major-updates:
|
major-updates:
|
||||||
update-types:
|
update-types:
|
||||||
- 'major'
|
- 'major'
|
||||||
|
ignore:
|
||||||
ignore:
|
- dependency-name: '@crxjs/vite-plugin'
|
||||||
- dependency-name: '@crxjs/vite-plugin'
|
- dependency-name: '@unocss/vite'
|
||||||
- dependency-name: '@unocss/vite'
|
|
||||||
|
|||||||
70
.github/workflows/best-practices.yml
vendored
70
.github/workflows/best-practices.yml
vendored
@@ -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
|
||||||
|
uses: pnpm/action-setup@v4
|
||||||
- name: Setup pnpm
|
with:
|
||||||
uses: pnpm/action-setup@v4
|
version: 10
|
||||||
with:
|
- name: Install dependencies
|
||||||
version: 10
|
run: pnpm install
|
||||||
|
- name: Run ESLint
|
||||||
- name: Install dependencies
|
run: pnpm run lint
|
||||||
run: pnpm install
|
format:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
- name: Run ESLint
|
steps:
|
||||||
run: pnpm run lint
|
- name: Checkout code
|
||||||
format:
|
uses: actions/checkout@v4
|
||||||
runs-on: ubuntu-latest
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
steps:
|
- name: Setup pnpm
|
||||||
- name: Checkout code
|
uses: pnpm/action-setup@v4
|
||||||
uses: actions/checkout@v4
|
with:
|
||||||
with:
|
version: 10
|
||||||
fetch-depth: 0
|
- name: Install dependencies
|
||||||
|
run: pnpm install
|
||||||
- name: Setup pnpm
|
- name: Run Prettier
|
||||||
uses: pnpm/action-setup@v4
|
run: pnpm run prettier
|
||||||
with:
|
|
||||||
version: 10
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: pnpm install
|
|
||||||
|
|
||||||
- name: Run Prettier
|
|
||||||
run: pnpm run prettier
|
|
||||||
|
|||||||
36
.github/workflows/check-types.yml
vendored
36
.github/workflows/check-types.yml
vendored
@@ -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
|
||||||
|
uses: pnpm/action-setup@v4
|
||||||
- name: Setup pnpm
|
with:
|
||||||
uses: pnpm/action-setup@v4
|
version: 10
|
||||||
with:
|
- name: Install dependencies
|
||||||
version: 10
|
run: pnpm install
|
||||||
|
- name: Run tests
|
||||||
- name: Install dependencies
|
run: pnpm run check-types
|
||||||
run: pnpm install
|
|
||||||
|
|
||||||
- name: Run tests
|
|
||||||
run: pnpm run check-types
|
|
||||||
|
|||||||
42
.github/workflows/chromatic.yml
vendored
42
.github/workflows/chromatic.yml
vendored
@@ -1,26 +1,22 @@
|
|||||||
name: 'Chromatic'
|
name: 'Chromatic'
|
||||||
|
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
chromatic:
|
chromatic:
|
||||||
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: Publish to Chromatic
|
||||||
|
uses: chromaui/action@latest
|
||||||
- name: Publish to Chromatic
|
with:
|
||||||
uses: chromaui/action@latest
|
projectToken: chpt_e8bd07b0b27d8eb
|
||||||
with:
|
exitZeroOnChanges: true
|
||||||
projectToken: chpt_e8bd07b0b27d8eb
|
autoAcceptChanges: 'main'
|
||||||
exitZeroOnChanges: true
|
|
||||||
autoAcceptChanges: 'main'
|
|
||||||
|
|||||||
43
.github/workflows/release.yml
vendored
43
.github/workflows/release.yml
vendored
@@ -1,25 +1,24 @@
|
|||||||
name: Create Release
|
name: Create Release
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- production
|
- production
|
||||||
- preview
|
- preview
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: build extension & create release
|
name: build extension & create release
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.ref }}
|
group: ${{ github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
steps:
|
steps:
|
||||||
- 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
|
id: semantic-release
|
||||||
id: semantic-release
|
run: npx --no-install semantic-release
|
||||||
run: npx --no-install semantic-release
|
env:
|
||||||
env:
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|||||||
36
.github/workflows/tests.yml
vendored
36
.github/workflows/tests.yml
vendored
@@ -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
|
||||||
|
uses: pnpm/action-setup@v4
|
||||||
- name: Setup pnpm
|
with:
|
||||||
uses: pnpm/action-setup@v4
|
version: 10
|
||||||
with:
|
- name: Install dependencies
|
||||||
version: 10
|
run: pnpm install
|
||||||
|
- name: Run tests
|
||||||
- name: Install dependencies
|
run: pnpm test
|
||||||
run: pnpm install
|
|
||||||
|
|
||||||
- name: Run tests
|
|
||||||
run: pnpm test
|
|
||||||
|
|||||||
73
.github/workflows/validate-pr.yml
vendored
73
.github/workflows/validate-pr.yml
vendored
@@ -1,43 +1,40 @@
|
|||||||
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:
|
||||||
- opened
|
- opened
|
||||||
- reopened
|
- reopened
|
||||||
- edited
|
- edited
|
||||||
- synchronize
|
- synchronize
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
main:
|
main:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: amannn/action-semantic-pull-request@v3.2.6
|
- uses: amannn/action-semantic-pull-request@v3.2.6
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
- name: Post Conventional Commit Comment (on failure)
|
- name: Post Conventional Commit Comment (on failure)
|
||||||
uses: jungwinter/comment@v1
|
uses: jungwinter/comment@v1
|
||||||
id: conventional-commit-help
|
id: conventional-commit-help
|
||||||
with:
|
with:
|
||||||
type: create
|
type: create
|
||||||
issue_number: ${{ github.event.pull_request.number }}
|
issue_number: ${{ github.event.pull_request.number }}
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
body: |
|
body: |
|
||||||
Your pull request title did not conform to [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) standards. Our upcoming automated release pipeline will automatically determine
|
Your pull request title did not conform to [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) standards. Our upcoming automated release pipeline will automatically determine
|
||||||
the proper release version based on your pull request title.
|
the proper release version based on your pull request title.
|
||||||
**Cheat Sheet**
|
**Cheat Sheet**
|
||||||
- feat: A new feature
|
- feat: A new feature
|
||||||
- fix: A bug fix
|
- fix: A bug fix
|
||||||
- docs: Documentation only changes
|
- docs: Documentation only changes
|
||||||
- style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
|
- style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
|
||||||
- refactor: A code change that neither fixes a bug nor adds a feature
|
- refactor: A code change that neither fixes a bug nor adds a feature
|
||||||
- perf: A code change that improves performance
|
- perf: A code change that improves performance
|
||||||
- test: Adding missing tests or correcting existing tests
|
- test: Adding missing tests or correcting existing tests
|
||||||
- build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
|
- build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
|
||||||
- ci: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
|
- ci: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
|
||||||
- chore: Other changes that don't modify src or test files
|
- chore: Other changes that don't modify src or test files
|
||||||
- revert: Reverts a previous commit
|
- revert: Reverts a previous commit
|
||||||
if: ${{ failure() }}
|
if: ${{ failure() }}
|
||||||
|
|||||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -212,4 +212,9 @@ package-lock.json
|
|||||||
storybook-static/
|
storybook-static/
|
||||||
package/
|
package/
|
||||||
|
|
||||||
.direnv/
|
# Nix
|
||||||
|
result
|
||||||
|
result-*
|
||||||
|
|
||||||
|
# direnv
|
||||||
|
.direnv
|
||||||
|
|||||||
8
.vscode/launch.json
vendored
8
.vscode/launch.json
vendored
@@ -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>/**"
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@@ -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"
|
||||||
}
|
}
|
||||||
|
|||||||
16
CHANGELOG.md
16
CHANGELOG.md
@@ -1,3 +1,18 @@
|
|||||||
|
## [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)
|
## [2.2.2](https://github.com/Longhorn-Developers/UT-Registration-Plus/compare/v2.2.1...v2.2.2) (2025-10-13)
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
@@ -6,6 +21,7 @@
|
|||||||
* 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))
|
* 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))
|
* **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))
|
* 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))
|
* 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))
|
* 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))
|
* 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))
|
||||||
|
|||||||
@@ -15,14 +15,14 @@ If you believe someone is violating the code of conduct, we ask that you report
|
|||||||
- **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 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. It’s 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 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. It’s 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:
|
- **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.
|
- Violent threats or language directed against another person.
|
||||||
- Discriminatory jokes and language.
|
- Discriminatory jokes and language.
|
||||||
- Posting sexually explicit or violent material.
|
- Posting sexually explicit or violent material.
|
||||||
- Posting (or threatening to post) other people's personally identifying information ("doxing").
|
- Posting (or threatening to post) other people's personally identifying information ("doxing").
|
||||||
- Personal insults, especially those using racist or sexist terms.
|
- Personal insults, especially those using racist or sexist terms.
|
||||||
- Unwelcome sexual attention.
|
- Unwelcome sexual attention.
|
||||||
- Advocating for, or encouraging, any of the above behavior.
|
- Advocating for, or encouraging, any of the above behavior.
|
||||||
- Repeated harassment of others. In general, if someone asks you to stop, then stop.
|
- 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 we’re 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 doesn’t mean that they’re wrong. Don’t forget that it is human to err and blaming each other doesn’t get us anywhere. Instead, focus on helping to resolve issues and learning from mistakes.
|
- **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 we’re 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 doesn’t mean that they’re wrong. Don’t forget that it is human to err and blaming each other doesn’t 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).
|
Original text courtesy of the [Speak Up! project](http://web.archive.org/web/20141109123859/http://speakup.io/coc.html).
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
- Docker installed on your machine
|
- Docker installed on your machine
|
||||||
- Git (to clone the repository)
|
- Git (to clone the repository)
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
@@ -70,9 +70,9 @@ docker run -it --rm -v $(pwd)/dist:/extension/dist -p 5173:5173 -e BUILD_MODE=de
|
|||||||
|
|
||||||
## Accessing the Built Extension
|
## Accessing the Built Extension
|
||||||
|
|
||||||
- For build mode, the extension files will be in the `dist` directory on your host machine.
|
- For build mode, the extension files will be in the `dist` directory on your host machine.
|
||||||
- For zip mode, the zipped extension will be in the `package` directory on your host machine.
|
- For zip mode, the zipped extension will be in the `package` directory on your host machine.
|
||||||
- For dev mode, the extension will be continuously built in the `dist` directory, and you can load it as an unpacked extension in Chrome.
|
- For dev mode, the extension will be continuously built in the `dist` directory, and you can load it as an unpacked extension in Chrome.
|
||||||
|
|
||||||
## Docker Development Workflow
|
## Docker Development Workflow
|
||||||
|
|
||||||
@@ -85,5 +85,5 @@ When working on the extension:
|
|||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
- If you encounter permission issues with the output directories, ensure that the directories exist on your host machine and have the correct permissions.
|
- If you encounter permission issues with the output directories, ensure that the directories exist on your host machine and have the correct permissions.
|
||||||
- For any other issues, please check the Docker logs or open an issue in the GitHub repository.
|
- For any other issues, please check the Docker logs or open an issue in the GitHub repository.
|
||||||
|
|||||||
118
README.md
118
README.md
@@ -14,37 +14,37 @@
|
|||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- **Quick Access to Class Info**: For each class in the UT Course Schedule, UTRP provides a "breakdown" popup with direct links to RateMyProfessor, Course Evaluation Surveys (CES), and past syllabi.
|
- **Quick Access to Class Info**: For each class in the UT Course Schedule, UTRP provides a "breakdown" popup with direct links to RateMyProfessor, Course Evaluation Surveys (CES), and past syllabi.
|
||||||
- **Prerequisite & Restriction Highlights**: Displays course descriptions with highlighted details on prerequisites, restrictions, and other important info.
|
- **Prerequisite & Restriction Highlights**: Displays course descriptions with highlighted details on prerequisites, restrictions, and other important info.
|
||||||
- **Grade Distribution Graphs**: View an aggregate and semester-specific graph of grade distributions for each course.
|
- **Grade Distribution Graphs**: View an aggregate and semester-specific graph of grade distributions for each course.
|
||||||
- **Saved Courses List**: Easily add courses to a list and view them in the extension popup. Copy unique numbers with a single click.
|
- **Saved Courses List**: Easily add courses to a list and view them in the extension popup. Copy unique numbers with a single click.
|
||||||
- **Conflict Detection**: Automatically highlights and strikes out courses that conflict with your saved courses in the UT Course Catalog.
|
- **Conflict Detection**: Automatically highlights and strikes out courses that conflict with your saved courses in the UT Course Catalog.
|
||||||
- **Weekly Schedule View**: Displays your saved courses in a weekly schedule format for easier planning.
|
- **Weekly Schedule View**: Displays your saved courses in a weekly schedule format for easier planning.
|
||||||
- **Multiple Schedule Support**: Create multiple schedules to plan for different registration scenarios.
|
- **Multiple Schedule Support**: Create multiple schedules to plan for different registration scenarios.
|
||||||
- **And much more!**
|
- **And much more!**
|
||||||
|
|
||||||
## Toolchain
|
## Toolchain
|
||||||
|
|
||||||
- React v20.9.0 (LTS)
|
- React v20.9.0 (LTS)
|
||||||
- TypeScript v5.x
|
- TypeScript v5.x
|
||||||
- Vite v5.x
|
- Vite v5.x
|
||||||
- pnpm v10.x
|
- pnpm v10.x
|
||||||
- UnoCSS
|
- UnoCSS
|
||||||
- ESLint
|
- ESLint
|
||||||
- Prettier
|
- Prettier
|
||||||
- Storybook
|
- Storybook
|
||||||
- Figma
|
- Figma
|
||||||
- Semantic-Release
|
- Semantic-Release
|
||||||
- Custom Messaging & Storage Wrappers
|
- Custom Messaging & Storage Wrappers
|
||||||
|
|
||||||
## VSCode Extensions
|
## VSCode Extensions
|
||||||
|
|
||||||
We recommend using the following VSCode extensions to improve your development experience:
|
We recommend using the following VSCode extensions to improve your development experience:
|
||||||
|
|
||||||
- **[ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)**: For identifying and fixing linting issues.
|
- **[ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)**: For identifying and fixing linting issues.
|
||||||
- **[Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)**: For automatic code formatting.
|
- **[Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)**: For automatic code formatting.
|
||||||
- **[Tailwind CSS IntelliSense](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss)**: For Tailwind CSS class autocomplete and IntelliSense.
|
- **[Tailwind CSS IntelliSense](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss)**: For Tailwind CSS class autocomplete and IntelliSense.
|
||||||
- **[UnoCSS](https://marketplace.visualstudio.com/items?itemName=antfu.unocss)**: For better support with UnoCSS utilities.
|
- **[UnoCSS](https://marketplace.visualstudio.com/items?itemName=antfu.unocss)**: For better support with UnoCSS utilities.
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ Once set up, the extension can be built to the `dist/` directory using the follo
|
|||||||
|
|
||||||
### Development Builds
|
### Development Builds
|
||||||
|
|
||||||
- Run the development server:
|
- Run the development server:
|
||||||
```bash
|
```bash
|
||||||
pnpm dev
|
pnpm dev
|
||||||
```
|
```
|
||||||
@@ -92,7 +92,7 @@ Once set up, the extension can be built to the `dist/` directory using the follo
|
|||||||
|
|
||||||
### Production Builds
|
### Production Builds
|
||||||
|
|
||||||
- To generate production builds:
|
- To generate production builds:
|
||||||
```bash
|
```bash
|
||||||
pnpm build
|
pnpm build
|
||||||
```
|
```
|
||||||
@@ -121,10 +121,10 @@ To load the extension manually in Chrome:
|
|||||||
|
|
||||||
If you encounter bugs or issues, please report them in the [Issues](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues) section, including:
|
If you encounter bugs or issues, please report them in the [Issues](https://github.com/Longhorn-Developers/UT-Registration-Plus/issues) section, including:
|
||||||
|
|
||||||
- A clear, descriptive title
|
- A clear, descriptive title
|
||||||
- Steps to reproduce the issue
|
- Steps to reproduce the issue
|
||||||
- Expected behavior
|
- Expected behavior
|
||||||
- Screenshots or logs (if applicable)
|
- Screenshots or logs (if applicable)
|
||||||
|
|
||||||
We aim to address issues promptly.
|
We aim to address issues promptly.
|
||||||
|
|
||||||
@@ -142,14 +142,14 @@ Follow this structure for commit messages:
|
|||||||
|
|
||||||
Where:
|
Where:
|
||||||
|
|
||||||
- **type**: One of the following:
|
- **type**: One of the following:
|
||||||
- `feat`: A new feature
|
- `feat`: A new feature
|
||||||
- `fix`: A bug fix
|
- `fix`: A bug fix
|
||||||
- `docs`: Documentation updates
|
- `docs`: Documentation updates
|
||||||
- `style`: Code formatting changes (whitespace, semicolons, etc.)
|
- `style`: Code formatting changes (whitespace, semicolons, etc.)
|
||||||
- `refactor`: Code restructuring (without adding features or fixing bugs)
|
- `refactor`: Code restructuring (without adding features or fixing bugs)
|
||||||
- `test`: Adding or modifying tests
|
- `test`: Adding or modifying tests
|
||||||
- `chore`: Maintenance tasks or build process changes
|
- `chore`: Maintenance tasks or build process changes
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@@ -168,9 +168,9 @@ Branch names should follow the format:
|
|||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
- `feat/user-login`
|
- `feat/user-login`
|
||||||
- `fix/navbar-layout`
|
- `fix/navbar-layout`
|
||||||
- `docs/update-readme`
|
- `docs/update-readme`
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
@@ -184,28 +184,28 @@ 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 v5.x
|
- TypeScript v5.x
|
||||||
- Vite v5.x
|
- Vite v5.x
|
||||||
- pnpm v10.x
|
- pnpm v10.x
|
||||||
- UnoCSS
|
- UnoCSS
|
||||||
- ESLint
|
- ESLint
|
||||||
- Prettier
|
- Prettier
|
||||||
- Storybook
|
- Storybook
|
||||||
- Figma
|
- Figma
|
||||||
- Semantic-Release
|
- Semantic-Release
|
||||||
- [chrome-extension-toolkit](https://github.com/sghsri/chrome-extension-toolkit)
|
- [chrome-extension-toolkit](https://github.com/sghsri/chrome-extension-toolkit)
|
||||||
- [UT_Grade_Parser](https://github.com/doprz/UT_Grade_Parser)
|
- [UT_Grade_Parser](https://github.com/doprz/UT_Grade_Parser)
|
||||||
- [eslint-plugin-import-essentials](https://github.com/doprz/eslint-plugin-import-essentials)
|
- [eslint-plugin-import-essentials](https://github.com/doprz/eslint-plugin-import-essentials)
|
||||||
- [UT Registration Plus v1.2.2.7](https://github.com/Longhorn-Developers/UT-Registration-Plus/tree/legacy) by @sghsri
|
- [UT Registration Plus v1.2.2.7](https://github.com/Longhorn-Developers/UT-Registration-Plus/tree/legacy) by @sghsri
|
||||||
- [UT Registration Planner](https://github.com/doprz/UT-Registration-Planner) by @doprz
|
- [UT Registration Planner](https://github.com/doprz/UT-Registration-Planner) by @doprz
|
||||||
- [Figma Designs](https://www.figma.com/design/8tsCay2FRqctrdcZ3r9Ahw/UTRP) by @IsaDavRod
|
- [Figma Designs](https://www.figma.com/design/8tsCay2FRqctrdcZ3r9Ahw/UTRP) by @IsaDavRod
|
||||||
- [Longhorn Developers](https://github.com/Longhorn-Developers) - established in 2024
|
- [Longhorn Developers](https://github.com/Longhorn-Developers) - established in 2024
|
||||||
- The UTRP devs, beta testers, and all supporters of the project!
|
- The UTRP devs, beta testers, and all supporters of the project!
|
||||||
|
|
||||||
## Activity
|
## Activity
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Star History
|
## Star History
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"onlyChanged": true,
|
"onlyChanged": true,
|
||||||
"projectId": "Project:65c5172964f36dcf207985bf",
|
"projectId": "Project:65c5172964f36dcf207985bf",
|
||||||
"zip": true
|
"zip": true
|
||||||
}
|
}
|
||||||
|
|||||||
10
default.nix
Normal file
10
default.nix
Normal 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
|
||||||
@@ -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
|
||||||
|
|||||||
87
flake.lock
generated
87
flake.lock
generated
@@ -1,30 +1,30 @@
|
|||||||
{
|
{
|
||||||
"nodes": {
|
"nodes": {
|
||||||
"flake-utils": {
|
"flake-parts": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"systems": "systems"
|
"nixpkgs-lib": "nixpkgs-lib"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1731533236,
|
"lastModified": 1767609335,
|
||||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
"narHash": "sha256-feveD98mQpptwrAEggBQKJTYbvwwglSbOv53uCfH9PY=",
|
||||||
"owner": "numtide",
|
"owner": "hercules-ci",
|
||||||
"repo": "flake-utils",
|
"repo": "flake-parts",
|
||||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
"rev": "250481aafeb741edfe23d29195671c19b36b6dca",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "numtide",
|
"owner": "hercules-ci",
|
||||||
"repo": "flake-utils",
|
"repo": "flake-parts",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1759831965,
|
"lastModified": 1767640445,
|
||||||
"narHash": "sha256-vgPm2xjOmKdZ0xKA6yLXPJpjOtQPHfaZDRtH+47XEBo=",
|
"narHash": "sha256-UWYqmD7JFBEDBHWYcqE6s6c77pWdcU/i+bwD6XxMb8A=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "c9b6fb798541223bbb396d287d16f43520250518",
|
"rev": "9f0c42f8bc7151b8e7e5840fb3bd454ad850d8c5",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -34,24 +34,59 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root": {
|
"nixpkgs-lib": {
|
||||||
"inputs": {
|
|
||||||
"flake-utils": "flake-utils",
|
|
||||||
"nixpkgs": "nixpkgs"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"systems": {
|
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1681028828,
|
"lastModified": 1765674936,
|
||||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
"narHash": "sha256-k00uTP4JNfmejrCLJOwdObYC9jHRrr/5M/a/8L2EIdo=",
|
||||||
"owner": "nix-systems",
|
"owner": "nix-community",
|
||||||
"repo": "default",
|
"repo": "nixpkgs.lib",
|
||||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
"rev": "2075416fcb47225d9b68ac469a5c4801a9c4dd85",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "nix-systems",
|
"owner": "nix-community",
|
||||||
"repo": "default",
|
"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"
|
"type": "github"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
56
flake.nix
56
flake.nix
@@ -1,43 +1,33 @@
|
|||||||
{
|
{
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
flake-utils.url = "github:numtide/flake-utils";
|
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||||
|
treefmt-nix.url = "github:numtide/treefmt-nix";
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs =
|
outputs =
|
||||||
{
|
inputs@{ flake-parts, ... }:
|
||||||
self,
|
flake-parts.lib.mkFlake { inherit inputs; } {
|
||||||
nixpkgs,
|
systems = inputs.nixpkgs.lib.systems.flakeExposed;
|
||||||
flake-utils,
|
|
||||||
}:
|
|
||||||
flake-utils.lib.eachDefaultSystem (
|
|
||||||
system:
|
|
||||||
let
|
|
||||||
pkgs = (import nixpkgs { inherit system; });
|
|
||||||
|
|
||||||
commonPackages = with pkgs; [
|
imports = [
|
||||||
nodejs_20 # v20.19.5
|
./nix/packages.nix
|
||||||
pnpm_10 # v10.18.0
|
./nix/devShells.nix
|
||||||
];
|
./nix/treefmt.nix
|
||||||
|
];
|
||||||
|
|
||||||
additionalPackages = with pkgs; [
|
perSystem =
|
||||||
bun
|
{ system, ... }:
|
||||||
nodePackages.conventional-changelog-cli
|
{
|
||||||
sentry-cli
|
_module.args.pkgs = import inputs.nixpkgs {
|
||||||
];
|
inherit system;
|
||||||
in
|
overlays = [
|
||||||
{
|
(final: prev: {
|
||||||
formatter = pkgs.nixfmt-rfc-style;
|
nodejs = prev.nodejs_20; # v20.19.5
|
||||||
|
})
|
||||||
devShells.default = pkgs.mkShell {
|
];
|
||||||
name = "utrp-dev";
|
config = { };
|
||||||
buildInputs = commonPackages;
|
};
|
||||||
};
|
};
|
||||||
|
};
|
||||||
devShells.full = pkgs.mkShell {
|
|
||||||
name = "utrp-dev-full";
|
|
||||||
buildInputs = commonPackages ++ additionalPackages;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
30
nix/devShells.nix
Normal file
30
nix/devShells.nix
Normal 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
51
nix/package.nix
Normal 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
40
nix/packages.nix
Normal 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
63
nix/treefmt.nix
Normal 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
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
12
package.json
12
package.json
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "ut-registration-plus",
|
"name": "ut-registration-plus",
|
||||||
"displayName": "UT Registration Plus",
|
"displayName": "UT Registration Plus",
|
||||||
"version": "2.2.2",
|
"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",
|
||||||
@@ -39,6 +39,9 @@
|
|||||||
"@phosphor-icons/react": "^2.1.7",
|
"@phosphor-icons/react": "^2.1.7",
|
||||||
"@sentry/react": "^8.55.0",
|
"@sentry/react": "^8.55.0",
|
||||||
"@tanstack/react-query": "^5.69.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": "^4.3.4",
|
||||||
"chrome-extension-toolkit": "^0.0.54",
|
"chrome-extension-toolkit": "^0.0.54",
|
||||||
@@ -136,7 +139,7 @@
|
|||||||
"gulp-zip": "^6.1.0",
|
"gulp-zip": "^6.1.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": "^24.2.3",
|
||||||
"storybook": "^8.6.0",
|
"storybook": "^8.6.0",
|
||||||
@@ -159,7 +162,10 @@
|
|||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"es-module-lexer": "^1.5.4"
|
"es-module-lexer": "^1.5.4"
|
||||||
}
|
},
|
||||||
|
"onlyBuiltDependencies": [
|
||||||
|
"@tsparticles/engine"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"volta": {
|
"volta": {
|
||||||
"node": "20.19.4",
|
"node": "20.19.4",
|
||||||
|
|||||||
496
pnpm-lock.yaml
generated
496
pnpm-lock.yaml
generated
@@ -49,6 +49,15 @@ importers:
|
|||||||
'@tanstack/react-query':
|
'@tanstack/react-query':
|
||||||
specifier: ^5.69.0
|
specifier: ^5.69.0
|
||||||
version: 5.69.0(react@18.3.1)
|
version: 5.69.0(react@18.3.1)
|
||||||
|
'@tsparticles/engine':
|
||||||
|
specifier: ^3.9.1
|
||||||
|
version: 3.9.1
|
||||||
|
'@tsparticles/react':
|
||||||
|
specifier: ^3.0.0
|
||||||
|
version: 3.0.0(@tsparticles/engine@3.9.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
|
'@tsparticles/slim':
|
||||||
|
specifier: ^3.9.1
|
||||||
|
version: 3.9.1
|
||||||
'@unocss/vite':
|
'@unocss/vite':
|
||||||
specifier: ^0.63.6
|
specifier: ^0.63.6
|
||||||
version: 0.63.6(patch_hash=9e2d2732a6e057a2ca90fba199730f252d8b4db8631b2c6ee0854fce7771bc95)(rollup@4.52.4)(typescript@5.7.3)(vite@5.4.20(@types/node@22.13.5)(sass@1.85.1)(terser@5.44.0))
|
version: 0.63.6(patch_hash=9e2d2732a6e057a2ca90fba199730f252d8b4db8631b2c6ee0854fce7771bc95)(rollup@4.52.4)(typescript@5.7.3)(vite@5.4.20(@types/node@22.13.5)(sass@1.85.1)(terser@5.44.0))
|
||||||
@@ -154,25 +163,25 @@ importers:
|
|||||||
version: 8.55.0
|
version: 8.55.0
|
||||||
'@storybook/addon-designs':
|
'@storybook/addon-designs':
|
||||||
specifier: ^8.2.0
|
specifier: ^8.2.0
|
||||||
version: 8.2.0(@storybook/blocks@8.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.6.0(prettier@3.5.2)))(@storybook/components@8.6.0(storybook@8.6.0(prettier@3.5.2)))(@storybook/theming@8.6.0(storybook@8.6.0(prettier@3.5.2)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
version: 8.2.0(@storybook/blocks@8.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.6.0(prettier@3.6.2)))(@storybook/components@8.6.0(storybook@8.6.0(prettier@3.6.2)))(@storybook/theming@8.6.0(storybook@8.6.0(prettier@3.6.2)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
'@storybook/addon-essentials':
|
'@storybook/addon-essentials':
|
||||||
specifier: ^8.6.0
|
specifier: ^8.6.0
|
||||||
version: 8.6.0(@types/react@18.3.18)(storybook@8.6.0(prettier@3.5.2))
|
version: 8.6.0(@types/react@18.3.18)(storybook@8.6.0(prettier@3.6.2))
|
||||||
'@storybook/addon-links':
|
'@storybook/addon-links':
|
||||||
specifier: ^8.6.0
|
specifier: ^8.6.0
|
||||||
version: 8.6.0(react@18.3.1)(storybook@8.6.0(prettier@3.5.2))
|
version: 8.6.0(react@18.3.1)(storybook@8.6.0(prettier@3.6.2))
|
||||||
'@storybook/blocks':
|
'@storybook/blocks':
|
||||||
specifier: ^8.6.0
|
specifier: ^8.6.0
|
||||||
version: 8.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.6.0(prettier@3.5.2))
|
version: 8.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.6.0(prettier@3.6.2))
|
||||||
'@storybook/react':
|
'@storybook/react':
|
||||||
specifier: ^8.6.0
|
specifier: ^8.6.0
|
||||||
version: 8.6.0(@storybook/test@8.6.0(storybook@8.6.0(prettier@3.5.2)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.6.0(prettier@3.5.2))(typescript@5.7.3)
|
version: 8.6.0(@storybook/test@8.6.0(storybook@8.6.0(prettier@3.6.2)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.6.0(prettier@3.6.2))(typescript@5.7.3)
|
||||||
'@storybook/react-vite':
|
'@storybook/react-vite':
|
||||||
specifier: ^8.6.0
|
specifier: ^8.6.0
|
||||||
version: 8.6.0(@storybook/test@8.6.0(storybook@8.6.0(prettier@3.5.2)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.52.4)(storybook@8.6.0(prettier@3.5.2))(typescript@5.7.3)(vite@5.4.20(@types/node@22.13.5)(sass@1.85.1)(terser@5.44.0))
|
version: 8.6.0(@storybook/test@8.6.0(storybook@8.6.0(prettier@3.6.2)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.52.4)(storybook@8.6.0(prettier@3.6.2))(typescript@5.7.3)(vite@5.4.20(@types/node@22.13.5)(sass@1.85.1)(terser@5.44.0))
|
||||||
'@storybook/test':
|
'@storybook/test':
|
||||||
specifier: ^8.6.0
|
specifier: ^8.6.0
|
||||||
version: 8.6.0(storybook@8.6.0(prettier@3.5.2))
|
version: 8.6.0(storybook@8.6.0(prettier@3.6.2))
|
||||||
'@svgr/core':
|
'@svgr/core':
|
||||||
specifier: ^8.1.0
|
specifier: ^8.1.0
|
||||||
version: 8.1.0(typescript@5.7.3)
|
version: 8.1.0(typescript@5.7.3)
|
||||||
@@ -298,7 +307,7 @@ importers:
|
|||||||
version: 50.6.3(eslint@8.57.1)
|
version: 50.6.3(eslint@8.57.1)
|
||||||
eslint-plugin-prettier:
|
eslint-plugin-prettier:
|
||||||
specifier: ^5.2.3
|
specifier: ^5.2.3
|
||||||
version: 5.2.3(@types/eslint@9.6.1)(eslint-config-prettier@9.1.0(eslint@8.57.1))(eslint@8.57.1)(prettier@3.5.2)
|
version: 5.2.3(@types/eslint@9.6.1)(eslint-config-prettier@9.1.0(eslint@8.57.1))(eslint@8.57.1)(prettier@3.6.2)
|
||||||
eslint-plugin-react:
|
eslint-plugin-react:
|
||||||
specifier: ^7.37.4
|
specifier: ^7.37.4
|
||||||
version: 7.37.4(eslint@8.57.1)
|
version: 7.37.4(eslint@8.57.1)
|
||||||
@@ -336,8 +345,8 @@ importers:
|
|||||||
specifier: ^8.5.3
|
specifier: ^8.5.3
|
||||||
version: 8.5.3
|
version: 8.5.3
|
||||||
prettier:
|
prettier:
|
||||||
specifier: ^3.5.2
|
specifier: 3.6.2
|
||||||
version: 3.5.2
|
version: 3.6.2
|
||||||
react-dev-utils:
|
react-dev-utils:
|
||||||
specifier: ^12.0.1
|
specifier: ^12.0.1
|
||||||
version: 12.0.1(eslint@8.57.1)(typescript@5.7.3)(webpack@5.97.1(esbuild@0.25.10))
|
version: 12.0.1(eslint@8.57.1)(typescript@5.7.3)(webpack@5.97.1(esbuild@0.25.10))
|
||||||
@@ -346,7 +355,7 @@ importers:
|
|||||||
version: 24.2.3(typescript@5.7.3)
|
version: 24.2.3(typescript@5.7.3)
|
||||||
storybook:
|
storybook:
|
||||||
specifier: ^8.6.0
|
specifier: ^8.6.0
|
||||||
version: 8.6.0(prettier@3.5.2)
|
version: 8.6.0(prettier@3.6.2)
|
||||||
typescript:
|
typescript:
|
||||||
specifier: ^5.7.3
|
specifier: ^5.7.3
|
||||||
version: 5.7.3
|
version: 5.7.3
|
||||||
@@ -2075,6 +2084,121 @@ packages:
|
|||||||
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
|
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
|
||||||
engines: {node: '>=10.13.0'}
|
engines: {node: '>=10.13.0'}
|
||||||
|
|
||||||
|
'@tsparticles/basic@3.9.1':
|
||||||
|
resolution: {integrity: sha512-ijr2dHMx0IQHqhKW3qA8tfwrR2XYbbWYdaJMQuBo2CkwBVIhZ76U+H20Y492j/NXpd1FUnt2aC0l4CEVGVGdeQ==}
|
||||||
|
|
||||||
|
'@tsparticles/engine@3.9.1':
|
||||||
|
resolution: {integrity: sha512-DpdgAhWMZ3Eh2gyxik8FXS6BKZ8vyea+Eu5BC4epsahqTGY9V3JGGJcXC6lRJx6cPMAx1A0FaQAojPF3v6rkmQ==}
|
||||||
|
|
||||||
|
'@tsparticles/interaction-external-attract@3.9.1':
|
||||||
|
resolution: {integrity: sha512-5AJGmhzM9o4AVFV24WH5vSqMBzOXEOzIdGLIr+QJf4fRh9ZK62snsusv/ozKgs2KteRYQx+L7c5V3TqcDy2upg==}
|
||||||
|
|
||||||
|
'@tsparticles/interaction-external-bounce@3.9.1':
|
||||||
|
resolution: {integrity: sha512-bv05+h70UIHOTWeTsTI1AeAmX6R3s8nnY74Ea6p6AbQjERzPYIa0XY19nq/hA7+Nrg+EissP5zgoYYeSphr85A==}
|
||||||
|
|
||||||
|
'@tsparticles/interaction-external-bubble@3.9.1':
|
||||||
|
resolution: {integrity: sha512-tbd8ox/1GPl+zr+KyHQVV1bW88GE7OM6i4zql801YIlCDrl9wgTDdDFGIy9X7/cwTvTrCePhrfvdkUamXIribQ==}
|
||||||
|
|
||||||
|
'@tsparticles/interaction-external-connect@3.9.1':
|
||||||
|
resolution: {integrity: sha512-sq8YfUNsIORjXHzzW7/AJQtfi/qDqLnYG2qOSE1WOsog39MD30RzmiOloejOkfNeUdcGUcfsDgpUuL3UhzFUOA==}
|
||||||
|
|
||||||
|
'@tsparticles/interaction-external-grab@3.9.1':
|
||||||
|
resolution: {integrity: sha512-QwXza+sMMWDaMiFxd8y2tJwUK6c+nNw554+/9+tEZeTTk2fCbB0IJ7p/TH6ZGWDL0vo2muK54Njv2fEey191ow==}
|
||||||
|
|
||||||
|
'@tsparticles/interaction-external-pause@3.9.1':
|
||||||
|
resolution: {integrity: sha512-Gzv4/FeNir0U/tVM9zQCqV1k+IAgaFjDU3T30M1AeAsNGh/rCITV2wnT7TOGFkbcla27m4Yxa+Fuab8+8pzm+g==}
|
||||||
|
|
||||||
|
'@tsparticles/interaction-external-push@3.9.1':
|
||||||
|
resolution: {integrity: sha512-GvnWF9Qy4YkZdx+WJL2iy9IcgLvzOIu3K7aLYJFsQPaxT8d9TF8WlpoMlWKnJID6H5q4JqQuMRKRyWH8aAKyQw==}
|
||||||
|
|
||||||
|
'@tsparticles/interaction-external-remove@3.9.1':
|
||||||
|
resolution: {integrity: sha512-yPThm4UDWejDOWW5Qc8KnnS2EfSo5VFcJUQDWc1+Wcj17xe7vdSoiwwOORM0PmNBzdDpSKQrte/gUnoqaUMwOA==}
|
||||||
|
|
||||||
|
'@tsparticles/interaction-external-repulse@3.9.1':
|
||||||
|
resolution: {integrity: sha512-/LBppXkrMdvLHlEKWC7IykFhzrz+9nebT2fwSSFXK4plEBxDlIwnkDxd3FbVOAbnBvx4+L8+fbrEx+RvC8diAw==}
|
||||||
|
|
||||||
|
'@tsparticles/interaction-external-slow@3.9.1':
|
||||||
|
resolution: {integrity: sha512-1ZYIR/udBwA9MdSCfgADsbDXKSFS0FMWuPWz7bm79g3sUxcYkihn+/hDhc6GXvNNR46V1ocJjrj0u6pAynS1KQ==}
|
||||||
|
|
||||||
|
'@tsparticles/interaction-particles-attract@3.9.1':
|
||||||
|
resolution: {integrity: sha512-CYYYowJuGwRLUixQcSU/48PTKM8fCUYThe0hXwQ+yRMLAn053VHzL7NNZzKqEIeEyt5oJoy9KcvubjKWbzMBLQ==}
|
||||||
|
|
||||||
|
'@tsparticles/interaction-particles-collisions@3.9.1':
|
||||||
|
resolution: {integrity: sha512-ggGyjW/3v1yxvYW1IF1EMT15M6w31y5zfNNUPkqd/IXRNPYvm0Z0ayhp+FKmz70M5p0UxxPIQHTvAv9Jqnuj8w==}
|
||||||
|
|
||||||
|
'@tsparticles/interaction-particles-links@3.9.1':
|
||||||
|
resolution: {integrity: sha512-MsLbMjy1vY5M5/hu/oa5OSRZAUz49H3+9EBMTIOThiX+a+vpl3sxc9AqNd9gMsPbM4WJlub8T6VBZdyvzez1Vg==}
|
||||||
|
|
||||||
|
'@tsparticles/move-base@3.9.1':
|
||||||
|
resolution: {integrity: sha512-X4huBS27d8srpxwOxliWPUt+NtCwY+8q/cx1DvQxyqmTA8VFCGpcHNwtqiN+9JicgzOvSuaORVqUgwlsc7h4pQ==}
|
||||||
|
|
||||||
|
'@tsparticles/move-parallax@3.9.1':
|
||||||
|
resolution: {integrity: sha512-whlOR0bVeyh6J/hvxf/QM3DqvNnITMiAQ0kro6saqSDItAVqg4pYxBfEsSOKq7EhjxNvfhhqR+pFMhp06zoCVA==}
|
||||||
|
|
||||||
|
'@tsparticles/plugin-easing-quad@3.9.1':
|
||||||
|
resolution: {integrity: sha512-C2UJOca5MTDXKUTBXj30Kiqr5UyID+xrY/LxicVWWZPczQW2bBxbIbfq9ULvzGDwBTxE2rdvIB8YFKmDYO45qw==}
|
||||||
|
|
||||||
|
'@tsparticles/plugin-hex-color@3.9.1':
|
||||||
|
resolution: {integrity: sha512-vZgZ12AjUicJvk7AX4K2eAmKEQX/D1VEjEPFhyjbgI7A65eX72M465vVKIgNA6QArLZ1DLs7Z787LOE6GOBWsg==}
|
||||||
|
|
||||||
|
'@tsparticles/plugin-hsl-color@3.9.1':
|
||||||
|
resolution: {integrity: sha512-jJd1iGgRwX6eeNjc1zUXiJivaqC5UE+SC2A3/NtHwwoQrkfxGWmRHOsVyLnOBRcCPgBp/FpdDe6DIDjCMO715w==}
|
||||||
|
|
||||||
|
'@tsparticles/plugin-rgb-color@3.9.1':
|
||||||
|
resolution: {integrity: sha512-SBxk7f1KBfXeTnnklbE2Hx4jBgh6I6HOtxb+Os1gTp0oaghZOkWcCD2dP4QbUu7fVNCMOcApPoMNC8RTFcy9wQ==}
|
||||||
|
|
||||||
|
'@tsparticles/react@3.0.0':
|
||||||
|
resolution: {integrity: sha512-hjGEtTT1cwv6BcjL+GcVgH++KYs52bIuQGW3PWv7z3tMa8g0bd6RI/vWSLj7p//NZ3uTjEIeilYIUPBh7Jfq/Q==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tsparticles/engine': ^3.0.2
|
||||||
|
react: '>=16.8.0'
|
||||||
|
react-dom: '>=16.8.0'
|
||||||
|
|
||||||
|
'@tsparticles/shape-circle@3.9.1':
|
||||||
|
resolution: {integrity: sha512-DqZFLjbuhVn99WJ+A9ajz9YON72RtCcvubzq6qfjFmtwAK7frvQeb6iDTp6Ze9FUipluxVZWVRG4vWTxi2B+/g==}
|
||||||
|
|
||||||
|
'@tsparticles/shape-emoji@3.9.1':
|
||||||
|
resolution: {integrity: sha512-ifvY63usuT+hipgVHb8gelBHSeF6ryPnMxAAEC1RGHhhXfpSRWMtE6ybr+pSsYU52M3G9+TF84v91pSwNrb9ZQ==}
|
||||||
|
|
||||||
|
'@tsparticles/shape-image@3.9.1':
|
||||||
|
resolution: {integrity: sha512-fCA5eme8VF3oX8yNVUA0l2SLDKuiZObkijb0z3Ky0qj1HUEVlAuEMhhNDNB9E2iELTrWEix9z7BFMePp2CC7AA==}
|
||||||
|
|
||||||
|
'@tsparticles/shape-line@3.9.1':
|
||||||
|
resolution: {integrity: sha512-wT8NSp0N9HURyV05f371cHKcNTNqr0/cwUu6WhBzbshkYGy1KZUP9CpRIh5FCrBpTev34mEQfOXDycgfG0KiLQ==}
|
||||||
|
|
||||||
|
'@tsparticles/shape-polygon@3.9.1':
|
||||||
|
resolution: {integrity: sha512-dA77PgZdoLwxnliH6XQM/zF0r4jhT01pw5y7XTeTqws++hg4rTLV9255k6R6eUqKq0FPSW1/WBsBIl7q/MmrqQ==}
|
||||||
|
|
||||||
|
'@tsparticles/shape-square@3.9.1':
|
||||||
|
resolution: {integrity: sha512-DKGkDnRyZrAm7T2ipqNezJahSWs6xd9O5LQLe5vjrYm1qGwrFxJiQaAdlb00UNrexz1/SA7bEoIg4XKaFa7qhQ==}
|
||||||
|
|
||||||
|
'@tsparticles/shape-star@3.9.1':
|
||||||
|
resolution: {integrity: sha512-kdMJpi8cdeb6vGrZVSxTG0JIjCwIenggqk0EYeKAwtOGZFBgL7eHhF2F6uu1oq8cJAbXPujEoabnLsz6mW8XaA==}
|
||||||
|
|
||||||
|
'@tsparticles/slim@3.9.1':
|
||||||
|
resolution: {integrity: sha512-CL5cDmADU7sDjRli0So+hY61VMbdroqbArmR9Av+c1Fisa5ytr6QD7Jv62iwU2S6rvgicEe9OyRmSy5GIefwZw==}
|
||||||
|
|
||||||
|
'@tsparticles/updater-color@3.9.1':
|
||||||
|
resolution: {integrity: sha512-XGWdscrgEMA8L5E7exsE0f8/2zHKIqnTrZymcyuFBw2DCB6BIV+5z6qaNStpxrhq3DbIxxhqqcybqeOo7+Alpg==}
|
||||||
|
|
||||||
|
'@tsparticles/updater-life@3.9.1':
|
||||||
|
resolution: {integrity: sha512-Oi8aF2RIwMMsjssUkCB6t3PRpENHjdZf6cX92WNfAuqXtQphr3OMAkYFJFWkvyPFK22AVy3p/cFt6KE5zXxwAA==}
|
||||||
|
|
||||||
|
'@tsparticles/updater-opacity@3.9.1':
|
||||||
|
resolution: {integrity: sha512-w778LQuRZJ+IoWzeRdrGykPYSSaTeWfBvLZ2XwYEkh/Ss961InOxZKIpcS6i5Kp/Zfw0fS1ZAuqeHwuj///Osw==}
|
||||||
|
|
||||||
|
'@tsparticles/updater-out-modes@3.9.1':
|
||||||
|
resolution: {integrity: sha512-cKQEkAwbru+hhKF+GTsfbOvuBbx2DSB25CxOdhtW2wRvDBoCnngNdLw91rs+0Cex4tgEeibkebrIKFDDE6kELg==}
|
||||||
|
|
||||||
|
'@tsparticles/updater-rotate@3.9.1':
|
||||||
|
resolution: {integrity: sha512-9BfKaGfp28JN82MF2qs6Ae/lJr9EColMfMTHqSKljblwbpVDHte4umuwKl3VjbRt87WD9MGtla66NTUYl+WxuQ==}
|
||||||
|
|
||||||
|
'@tsparticles/updater-size@3.9.1':
|
||||||
|
resolution: {integrity: sha512-3NSVs0O2ApNKZXfd+y/zNhTXSFeG1Pw4peI8e6z/q5+XLbmue9oiEwoPy/tQLaark3oNj3JU7Q903ZijPyXSzw==}
|
||||||
|
|
||||||
|
'@tsparticles/updater-stroke-color@3.9.1':
|
||||||
|
resolution: {integrity: sha512-3x14+C2is9pZYTg9T2TiA/aM1YMq4wLdYaZDcHm3qO30DZu5oeQq0rm/6w+QOGKYY1Z3Htg9rlSUZkhTHn7eDA==}
|
||||||
|
|
||||||
'@types/aria-query@5.0.4':
|
'@types/aria-query@5.0.4':
|
||||||
resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==}
|
resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==}
|
||||||
|
|
||||||
@@ -5907,8 +6031,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==}
|
resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==}
|
||||||
engines: {node: '>=6.0.0'}
|
engines: {node: '>=6.0.0'}
|
||||||
|
|
||||||
prettier@3.5.2:
|
prettier@3.6.2:
|
||||||
resolution: {integrity: sha512-lc6npv5PH7hVqozBR7lkBNOGXV9vMwROAPlumdBkX0wTbbzPu/U1hk5yL8p2pt4Xoc+2mkT8t/sow2YrV/M5qg==}
|
resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
@@ -8425,126 +8549,126 @@ snapshots:
|
|||||||
|
|
||||||
'@sindresorhus/merge-streams@4.0.0': {}
|
'@sindresorhus/merge-streams@4.0.0': {}
|
||||||
|
|
||||||
'@storybook/addon-actions@8.6.0(storybook@8.6.0(prettier@3.5.2))':
|
'@storybook/addon-actions@8.6.0(storybook@8.6.0(prettier@3.6.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@storybook/global': 5.0.0
|
'@storybook/global': 5.0.0
|
||||||
'@types/uuid': 9.0.8
|
'@types/uuid': 9.0.8
|
||||||
dequal: 2.0.3
|
dequal: 2.0.3
|
||||||
polished: 4.3.1
|
polished: 4.3.1
|
||||||
storybook: 8.6.0(prettier@3.5.2)
|
storybook: 8.6.0(prettier@3.6.2)
|
||||||
uuid: 9.0.1
|
uuid: 9.0.1
|
||||||
|
|
||||||
'@storybook/addon-backgrounds@8.6.0(storybook@8.6.0(prettier@3.5.2))':
|
'@storybook/addon-backgrounds@8.6.0(storybook@8.6.0(prettier@3.6.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@storybook/global': 5.0.0
|
'@storybook/global': 5.0.0
|
||||||
memoizerific: 1.11.3
|
memoizerific: 1.11.3
|
||||||
storybook: 8.6.0(prettier@3.5.2)
|
storybook: 8.6.0(prettier@3.6.2)
|
||||||
ts-dedent: 2.2.0
|
ts-dedent: 2.2.0
|
||||||
|
|
||||||
'@storybook/addon-controls@8.6.0(storybook@8.6.0(prettier@3.5.2))':
|
'@storybook/addon-controls@8.6.0(storybook@8.6.0(prettier@3.6.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@storybook/global': 5.0.0
|
'@storybook/global': 5.0.0
|
||||||
dequal: 2.0.3
|
dequal: 2.0.3
|
||||||
storybook: 8.6.0(prettier@3.5.2)
|
storybook: 8.6.0(prettier@3.6.2)
|
||||||
ts-dedent: 2.2.0
|
ts-dedent: 2.2.0
|
||||||
|
|
||||||
'@storybook/addon-designs@8.2.0(@storybook/blocks@8.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.6.0(prettier@3.5.2)))(@storybook/components@8.6.0(storybook@8.6.0(prettier@3.5.2)))(@storybook/theming@8.6.0(storybook@8.6.0(prettier@3.5.2)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
'@storybook/addon-designs@8.2.0(@storybook/blocks@8.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.6.0(prettier@3.6.2)))(@storybook/components@8.6.0(storybook@8.6.0(prettier@3.6.2)))(@storybook/theming@8.6.0(storybook@8.6.0(prettier@3.6.2)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@figspec/react': 1.0.3(react@18.3.1)
|
'@figspec/react': 1.0.3(react@18.3.1)
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@storybook/blocks': 8.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.6.0(prettier@3.5.2))
|
'@storybook/blocks': 8.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.6.0(prettier@3.6.2))
|
||||||
'@storybook/components': 8.6.0(storybook@8.6.0(prettier@3.5.2))
|
'@storybook/components': 8.6.0(storybook@8.6.0(prettier@3.6.2))
|
||||||
'@storybook/theming': 8.6.0(storybook@8.6.0(prettier@3.5.2))
|
'@storybook/theming': 8.6.0(storybook@8.6.0(prettier@3.6.2))
|
||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
react-dom: 18.3.1(react@18.3.1)
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
|
|
||||||
'@storybook/addon-docs@8.6.0(@types/react@18.3.18)(storybook@8.6.0(prettier@3.5.2))':
|
'@storybook/addon-docs@8.6.0(@types/react@18.3.18)(storybook@8.6.0(prettier@3.6.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@mdx-js/react': 3.1.0(@types/react@18.3.18)(react@18.3.1)
|
'@mdx-js/react': 3.1.0(@types/react@18.3.18)(react@18.3.1)
|
||||||
'@storybook/blocks': 8.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.6.0(prettier@3.5.2))
|
'@storybook/blocks': 8.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.6.0(prettier@3.6.2))
|
||||||
'@storybook/csf-plugin': 8.6.0(storybook@8.6.0(prettier@3.5.2))
|
'@storybook/csf-plugin': 8.6.0(storybook@8.6.0(prettier@3.6.2))
|
||||||
'@storybook/react-dom-shim': 8.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.6.0(prettier@3.5.2))
|
'@storybook/react-dom-shim': 8.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.6.0(prettier@3.6.2))
|
||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
react-dom: 18.3.1(react@18.3.1)
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
storybook: 8.6.0(prettier@3.5.2)
|
storybook: 8.6.0(prettier@3.6.2)
|
||||||
ts-dedent: 2.2.0
|
ts-dedent: 2.2.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@types/react'
|
- '@types/react'
|
||||||
|
|
||||||
'@storybook/addon-essentials@8.6.0(@types/react@18.3.18)(storybook@8.6.0(prettier@3.5.2))':
|
'@storybook/addon-essentials@8.6.0(@types/react@18.3.18)(storybook@8.6.0(prettier@3.6.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@storybook/addon-actions': 8.6.0(storybook@8.6.0(prettier@3.5.2))
|
'@storybook/addon-actions': 8.6.0(storybook@8.6.0(prettier@3.6.2))
|
||||||
'@storybook/addon-backgrounds': 8.6.0(storybook@8.6.0(prettier@3.5.2))
|
'@storybook/addon-backgrounds': 8.6.0(storybook@8.6.0(prettier@3.6.2))
|
||||||
'@storybook/addon-controls': 8.6.0(storybook@8.6.0(prettier@3.5.2))
|
'@storybook/addon-controls': 8.6.0(storybook@8.6.0(prettier@3.6.2))
|
||||||
'@storybook/addon-docs': 8.6.0(@types/react@18.3.18)(storybook@8.6.0(prettier@3.5.2))
|
'@storybook/addon-docs': 8.6.0(@types/react@18.3.18)(storybook@8.6.0(prettier@3.6.2))
|
||||||
'@storybook/addon-highlight': 8.6.0(storybook@8.6.0(prettier@3.5.2))
|
'@storybook/addon-highlight': 8.6.0(storybook@8.6.0(prettier@3.6.2))
|
||||||
'@storybook/addon-measure': 8.6.0(storybook@8.6.0(prettier@3.5.2))
|
'@storybook/addon-measure': 8.6.0(storybook@8.6.0(prettier@3.6.2))
|
||||||
'@storybook/addon-outline': 8.6.0(storybook@8.6.0(prettier@3.5.2))
|
'@storybook/addon-outline': 8.6.0(storybook@8.6.0(prettier@3.6.2))
|
||||||
'@storybook/addon-toolbars': 8.6.0(storybook@8.6.0(prettier@3.5.2))
|
'@storybook/addon-toolbars': 8.6.0(storybook@8.6.0(prettier@3.6.2))
|
||||||
'@storybook/addon-viewport': 8.6.0(storybook@8.6.0(prettier@3.5.2))
|
'@storybook/addon-viewport': 8.6.0(storybook@8.6.0(prettier@3.6.2))
|
||||||
storybook: 8.6.0(prettier@3.5.2)
|
storybook: 8.6.0(prettier@3.6.2)
|
||||||
ts-dedent: 2.2.0
|
ts-dedent: 2.2.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@types/react'
|
- '@types/react'
|
||||||
|
|
||||||
'@storybook/addon-highlight@8.6.0(storybook@8.6.0(prettier@3.5.2))':
|
'@storybook/addon-highlight@8.6.0(storybook@8.6.0(prettier@3.6.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@storybook/global': 5.0.0
|
'@storybook/global': 5.0.0
|
||||||
storybook: 8.6.0(prettier@3.5.2)
|
storybook: 8.6.0(prettier@3.6.2)
|
||||||
|
|
||||||
'@storybook/addon-links@8.6.0(react@18.3.1)(storybook@8.6.0(prettier@3.5.2))':
|
'@storybook/addon-links@8.6.0(react@18.3.1)(storybook@8.6.0(prettier@3.6.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@storybook/global': 5.0.0
|
'@storybook/global': 5.0.0
|
||||||
storybook: 8.6.0(prettier@3.5.2)
|
storybook: 8.6.0(prettier@3.6.2)
|
||||||
ts-dedent: 2.2.0
|
ts-dedent: 2.2.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
|
|
||||||
'@storybook/addon-measure@8.6.0(storybook@8.6.0(prettier@3.5.2))':
|
'@storybook/addon-measure@8.6.0(storybook@8.6.0(prettier@3.6.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@storybook/global': 5.0.0
|
'@storybook/global': 5.0.0
|
||||||
storybook: 8.6.0(prettier@3.5.2)
|
storybook: 8.6.0(prettier@3.6.2)
|
||||||
tiny-invariant: 1.3.3
|
tiny-invariant: 1.3.3
|
||||||
|
|
||||||
'@storybook/addon-outline@8.6.0(storybook@8.6.0(prettier@3.5.2))':
|
'@storybook/addon-outline@8.6.0(storybook@8.6.0(prettier@3.6.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@storybook/global': 5.0.0
|
'@storybook/global': 5.0.0
|
||||||
storybook: 8.6.0(prettier@3.5.2)
|
storybook: 8.6.0(prettier@3.6.2)
|
||||||
ts-dedent: 2.2.0
|
ts-dedent: 2.2.0
|
||||||
|
|
||||||
'@storybook/addon-toolbars@8.6.0(storybook@8.6.0(prettier@3.5.2))':
|
'@storybook/addon-toolbars@8.6.0(storybook@8.6.0(prettier@3.6.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
storybook: 8.6.0(prettier@3.5.2)
|
storybook: 8.6.0(prettier@3.6.2)
|
||||||
|
|
||||||
'@storybook/addon-viewport@8.6.0(storybook@8.6.0(prettier@3.5.2))':
|
'@storybook/addon-viewport@8.6.0(storybook@8.6.0(prettier@3.6.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
memoizerific: 1.11.3
|
memoizerific: 1.11.3
|
||||||
storybook: 8.6.0(prettier@3.5.2)
|
storybook: 8.6.0(prettier@3.6.2)
|
||||||
|
|
||||||
'@storybook/blocks@8.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.6.0(prettier@3.5.2))':
|
'@storybook/blocks@8.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.6.0(prettier@3.6.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@storybook/icons': 1.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
'@storybook/icons': 1.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
storybook: 8.6.0(prettier@3.5.2)
|
storybook: 8.6.0(prettier@3.6.2)
|
||||||
ts-dedent: 2.2.0
|
ts-dedent: 2.2.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
react-dom: 18.3.1(react@18.3.1)
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
|
|
||||||
'@storybook/builder-vite@8.6.0(storybook@8.6.0(prettier@3.5.2))(vite@5.4.20(@types/node@22.13.5)(sass@1.85.1)(terser@5.44.0))':
|
'@storybook/builder-vite@8.6.0(storybook@8.6.0(prettier@3.6.2))(vite@5.4.20(@types/node@22.13.5)(sass@1.85.1)(terser@5.44.0))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@storybook/csf-plugin': 8.6.0(storybook@8.6.0(prettier@3.5.2))
|
'@storybook/csf-plugin': 8.6.0(storybook@8.6.0(prettier@3.6.2))
|
||||||
browser-assert: 1.2.1
|
browser-assert: 1.2.1
|
||||||
storybook: 8.6.0(prettier@3.5.2)
|
storybook: 8.6.0(prettier@3.6.2)
|
||||||
ts-dedent: 2.2.0
|
ts-dedent: 2.2.0
|
||||||
vite: 5.4.20(@types/node@22.13.5)(sass@1.85.1)(terser@5.44.0)
|
vite: 5.4.20(@types/node@22.13.5)(sass@1.85.1)(terser@5.44.0)
|
||||||
|
|
||||||
'@storybook/components@8.6.0(storybook@8.6.0(prettier@3.5.2))':
|
'@storybook/components@8.6.0(storybook@8.6.0(prettier@3.6.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
storybook: 8.6.0(prettier@3.5.2)
|
storybook: 8.6.0(prettier@3.6.2)
|
||||||
|
|
||||||
'@storybook/core@8.6.0(prettier@3.5.2)(storybook@8.6.0(prettier@3.5.2))':
|
'@storybook/core@8.6.0(prettier@3.6.2)(storybook@8.6.0(prettier@3.6.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@storybook/theming': 8.6.0(storybook@8.6.0(prettier@3.5.2))
|
'@storybook/theming': 8.6.0(storybook@8.6.0(prettier@3.6.2))
|
||||||
better-opn: 3.0.2
|
better-opn: 3.0.2
|
||||||
browser-assert: 1.2.1
|
browser-assert: 1.2.1
|
||||||
esbuild: 0.25.10
|
esbuild: 0.25.10
|
||||||
@@ -8556,16 +8680,16 @@ snapshots:
|
|||||||
util: 0.12.5
|
util: 0.12.5
|
||||||
ws: 8.18.1
|
ws: 8.18.1
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
prettier: 3.5.2
|
prettier: 3.6.2
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- bufferutil
|
- bufferutil
|
||||||
- storybook
|
- storybook
|
||||||
- supports-color
|
- supports-color
|
||||||
- utf-8-validate
|
- utf-8-validate
|
||||||
|
|
||||||
'@storybook/csf-plugin@8.6.0(storybook@8.6.0(prettier@3.5.2))':
|
'@storybook/csf-plugin@8.6.0(storybook@8.6.0(prettier@3.6.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
storybook: 8.6.0(prettier@3.5.2)
|
storybook: 8.6.0(prettier@3.6.2)
|
||||||
unplugin: 1.16.1
|
unplugin: 1.16.1
|
||||||
|
|
||||||
'@storybook/csf@0.0.1':
|
'@storybook/csf@0.0.1':
|
||||||
@@ -8579,77 +8703,77 @@ snapshots:
|
|||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
react-dom: 18.3.1(react@18.3.1)
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
|
|
||||||
'@storybook/instrumenter@8.6.0(storybook@8.6.0(prettier@3.5.2))':
|
'@storybook/instrumenter@8.6.0(storybook@8.6.0(prettier@3.6.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@storybook/global': 5.0.0
|
'@storybook/global': 5.0.0
|
||||||
'@vitest/utils': 2.1.9
|
'@vitest/utils': 2.1.9
|
||||||
storybook: 8.6.0(prettier@3.5.2)
|
storybook: 8.6.0(prettier@3.6.2)
|
||||||
|
|
||||||
'@storybook/manager-api@8.6.0(storybook@8.6.0(prettier@3.5.2))':
|
'@storybook/manager-api@8.6.0(storybook@8.6.0(prettier@3.6.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
storybook: 8.6.0(prettier@3.5.2)
|
storybook: 8.6.0(prettier@3.6.2)
|
||||||
|
|
||||||
'@storybook/preview-api@8.6.0(storybook@8.6.0(prettier@3.5.2))':
|
'@storybook/preview-api@8.6.0(storybook@8.6.0(prettier@3.6.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
storybook: 8.6.0(prettier@3.5.2)
|
storybook: 8.6.0(prettier@3.6.2)
|
||||||
|
|
||||||
'@storybook/react-dom-shim@8.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.6.0(prettier@3.5.2))':
|
'@storybook/react-dom-shim@8.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.6.0(prettier@3.6.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
react-dom: 18.3.1(react@18.3.1)
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
storybook: 8.6.0(prettier@3.5.2)
|
storybook: 8.6.0(prettier@3.6.2)
|
||||||
|
|
||||||
'@storybook/react-vite@8.6.0(@storybook/test@8.6.0(storybook@8.6.0(prettier@3.5.2)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.52.4)(storybook@8.6.0(prettier@3.5.2))(typescript@5.7.3)(vite@5.4.20(@types/node@22.13.5)(sass@1.85.1)(terser@5.44.0))':
|
'@storybook/react-vite@8.6.0(@storybook/test@8.6.0(storybook@8.6.0(prettier@3.6.2)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.52.4)(storybook@8.6.0(prettier@3.6.2))(typescript@5.7.3)(vite@5.4.20(@types/node@22.13.5)(sass@1.85.1)(terser@5.44.0))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@joshwooding/vite-plugin-react-docgen-typescript': 0.5.0(typescript@5.7.3)(vite@5.4.20(@types/node@22.13.5)(sass@1.85.1)(terser@5.44.0))
|
'@joshwooding/vite-plugin-react-docgen-typescript': 0.5.0(typescript@5.7.3)(vite@5.4.20(@types/node@22.13.5)(sass@1.85.1)(terser@5.44.0))
|
||||||
'@rollup/pluginutils': 5.1.4(rollup@4.52.4)
|
'@rollup/pluginutils': 5.1.4(rollup@4.52.4)
|
||||||
'@storybook/builder-vite': 8.6.0(storybook@8.6.0(prettier@3.5.2))(vite@5.4.20(@types/node@22.13.5)(sass@1.85.1)(terser@5.44.0))
|
'@storybook/builder-vite': 8.6.0(storybook@8.6.0(prettier@3.6.2))(vite@5.4.20(@types/node@22.13.5)(sass@1.85.1)(terser@5.44.0))
|
||||||
'@storybook/react': 8.6.0(@storybook/test@8.6.0(storybook@8.6.0(prettier@3.5.2)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.6.0(prettier@3.5.2))(typescript@5.7.3)
|
'@storybook/react': 8.6.0(@storybook/test@8.6.0(storybook@8.6.0(prettier@3.6.2)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.6.0(prettier@3.6.2))(typescript@5.7.3)
|
||||||
find-up: 5.0.0
|
find-up: 5.0.0
|
||||||
magic-string: 0.30.17
|
magic-string: 0.30.17
|
||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
react-docgen: 7.1.1
|
react-docgen: 7.1.1
|
||||||
react-dom: 18.3.1(react@18.3.1)
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
resolve: 1.22.10
|
resolve: 1.22.10
|
||||||
storybook: 8.6.0(prettier@3.5.2)
|
storybook: 8.6.0(prettier@3.6.2)
|
||||||
tsconfig-paths: 4.2.0
|
tsconfig-paths: 4.2.0
|
||||||
vite: 5.4.20(@types/node@22.13.5)(sass@1.85.1)(terser@5.44.0)
|
vite: 5.4.20(@types/node@22.13.5)(sass@1.85.1)(terser@5.44.0)
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@storybook/test': 8.6.0(storybook@8.6.0(prettier@3.5.2))
|
'@storybook/test': 8.6.0(storybook@8.6.0(prettier@3.6.2))
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- rollup
|
- rollup
|
||||||
- supports-color
|
- supports-color
|
||||||
- typescript
|
- typescript
|
||||||
|
|
||||||
'@storybook/react@8.6.0(@storybook/test@8.6.0(storybook@8.6.0(prettier@3.5.2)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.6.0(prettier@3.5.2))(typescript@5.7.3)':
|
'@storybook/react@8.6.0(@storybook/test@8.6.0(storybook@8.6.0(prettier@3.6.2)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.6.0(prettier@3.6.2))(typescript@5.7.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@storybook/components': 8.6.0(storybook@8.6.0(prettier@3.5.2))
|
'@storybook/components': 8.6.0(storybook@8.6.0(prettier@3.6.2))
|
||||||
'@storybook/global': 5.0.0
|
'@storybook/global': 5.0.0
|
||||||
'@storybook/manager-api': 8.6.0(storybook@8.6.0(prettier@3.5.2))
|
'@storybook/manager-api': 8.6.0(storybook@8.6.0(prettier@3.6.2))
|
||||||
'@storybook/preview-api': 8.6.0(storybook@8.6.0(prettier@3.5.2))
|
'@storybook/preview-api': 8.6.0(storybook@8.6.0(prettier@3.6.2))
|
||||||
'@storybook/react-dom-shim': 8.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.6.0(prettier@3.5.2))
|
'@storybook/react-dom-shim': 8.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.6.0(prettier@3.6.2))
|
||||||
'@storybook/theming': 8.6.0(storybook@8.6.0(prettier@3.5.2))
|
'@storybook/theming': 8.6.0(storybook@8.6.0(prettier@3.6.2))
|
||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
react-dom: 18.3.1(react@18.3.1)
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
storybook: 8.6.0(prettier@3.5.2)
|
storybook: 8.6.0(prettier@3.6.2)
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@storybook/test': 8.6.0(storybook@8.6.0(prettier@3.5.2))
|
'@storybook/test': 8.6.0(storybook@8.6.0(prettier@3.6.2))
|
||||||
typescript: 5.7.3
|
typescript: 5.7.3
|
||||||
|
|
||||||
'@storybook/test@8.6.0(storybook@8.6.0(prettier@3.5.2))':
|
'@storybook/test@8.6.0(storybook@8.6.0(prettier@3.6.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@storybook/global': 5.0.0
|
'@storybook/global': 5.0.0
|
||||||
'@storybook/instrumenter': 8.6.0(storybook@8.6.0(prettier@3.5.2))
|
'@storybook/instrumenter': 8.6.0(storybook@8.6.0(prettier@3.6.2))
|
||||||
'@testing-library/dom': 10.4.0
|
'@testing-library/dom': 10.4.0
|
||||||
'@testing-library/jest-dom': 6.5.0
|
'@testing-library/jest-dom': 6.5.0
|
||||||
'@testing-library/user-event': 14.5.2(@testing-library/dom@10.4.0)
|
'@testing-library/user-event': 14.5.2(@testing-library/dom@10.4.0)
|
||||||
'@vitest/expect': 2.0.5
|
'@vitest/expect': 2.0.5
|
||||||
'@vitest/spy': 2.0.5
|
'@vitest/spy': 2.0.5
|
||||||
storybook: 8.6.0(prettier@3.5.2)
|
storybook: 8.6.0(prettier@3.6.2)
|
||||||
|
|
||||||
'@storybook/theming@8.6.0(storybook@8.6.0(prettier@3.5.2))':
|
'@storybook/theming@8.6.0(storybook@8.6.0(prettier@3.6.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
storybook: 8.6.0(prettier@3.5.2)
|
storybook: 8.6.0(prettier@3.6.2)
|
||||||
|
|
||||||
'@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.26.9)':
|
'@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.26.9)':
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -8820,6 +8944,188 @@ snapshots:
|
|||||||
|
|
||||||
'@trysound/sax@0.2.0': {}
|
'@trysound/sax@0.2.0': {}
|
||||||
|
|
||||||
|
'@tsparticles/basic@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
'@tsparticles/move-base': 3.9.1
|
||||||
|
'@tsparticles/plugin-hex-color': 3.9.1
|
||||||
|
'@tsparticles/plugin-hsl-color': 3.9.1
|
||||||
|
'@tsparticles/plugin-rgb-color': 3.9.1
|
||||||
|
'@tsparticles/shape-circle': 3.9.1
|
||||||
|
'@tsparticles/updater-color': 3.9.1
|
||||||
|
'@tsparticles/updater-opacity': 3.9.1
|
||||||
|
'@tsparticles/updater-out-modes': 3.9.1
|
||||||
|
'@tsparticles/updater-size': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/engine@3.9.1': {}
|
||||||
|
|
||||||
|
'@tsparticles/interaction-external-attract@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/interaction-external-bounce@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/interaction-external-bubble@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/interaction-external-connect@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/interaction-external-grab@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/interaction-external-pause@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/interaction-external-push@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/interaction-external-remove@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/interaction-external-repulse@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/interaction-external-slow@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/interaction-particles-attract@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/interaction-particles-collisions@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/interaction-particles-links@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/move-base@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/move-parallax@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/plugin-easing-quad@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/plugin-hex-color@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/plugin-hsl-color@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/plugin-rgb-color@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/react@3.0.0(@tsparticles/engine@3.9.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
react: 18.3.1
|
||||||
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
|
|
||||||
|
'@tsparticles/shape-circle@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/shape-emoji@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/shape-image@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/shape-line@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/shape-polygon@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/shape-square@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/shape-star@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/slim@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/basic': 3.9.1
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
'@tsparticles/interaction-external-attract': 3.9.1
|
||||||
|
'@tsparticles/interaction-external-bounce': 3.9.1
|
||||||
|
'@tsparticles/interaction-external-bubble': 3.9.1
|
||||||
|
'@tsparticles/interaction-external-connect': 3.9.1
|
||||||
|
'@tsparticles/interaction-external-grab': 3.9.1
|
||||||
|
'@tsparticles/interaction-external-pause': 3.9.1
|
||||||
|
'@tsparticles/interaction-external-push': 3.9.1
|
||||||
|
'@tsparticles/interaction-external-remove': 3.9.1
|
||||||
|
'@tsparticles/interaction-external-repulse': 3.9.1
|
||||||
|
'@tsparticles/interaction-external-slow': 3.9.1
|
||||||
|
'@tsparticles/interaction-particles-attract': 3.9.1
|
||||||
|
'@tsparticles/interaction-particles-collisions': 3.9.1
|
||||||
|
'@tsparticles/interaction-particles-links': 3.9.1
|
||||||
|
'@tsparticles/move-parallax': 3.9.1
|
||||||
|
'@tsparticles/plugin-easing-quad': 3.9.1
|
||||||
|
'@tsparticles/shape-emoji': 3.9.1
|
||||||
|
'@tsparticles/shape-image': 3.9.1
|
||||||
|
'@tsparticles/shape-line': 3.9.1
|
||||||
|
'@tsparticles/shape-polygon': 3.9.1
|
||||||
|
'@tsparticles/shape-square': 3.9.1
|
||||||
|
'@tsparticles/shape-star': 3.9.1
|
||||||
|
'@tsparticles/updater-life': 3.9.1
|
||||||
|
'@tsparticles/updater-rotate': 3.9.1
|
||||||
|
'@tsparticles/updater-stroke-color': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/updater-color@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/updater-life@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/updater-opacity@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/updater-out-modes@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/updater-rotate@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/updater-size@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
|
'@tsparticles/updater-stroke-color@3.9.1':
|
||||||
|
dependencies:
|
||||||
|
'@tsparticles/engine': 3.9.1
|
||||||
|
|
||||||
'@types/aria-query@5.0.4': {}
|
'@types/aria-query@5.0.4': {}
|
||||||
|
|
||||||
'@types/babel__core@7.20.5':
|
'@types/babel__core@7.20.5':
|
||||||
@@ -11010,10 +11316,10 @@ snapshots:
|
|||||||
safe-regex-test: 1.1.0
|
safe-regex-test: 1.1.0
|
||||||
string.prototype.includes: 2.0.1
|
string.prototype.includes: 2.0.1
|
||||||
|
|
||||||
eslint-plugin-prettier@5.2.3(@types/eslint@9.6.1)(eslint-config-prettier@9.1.0(eslint@8.57.1))(eslint@8.57.1)(prettier@3.5.2):
|
eslint-plugin-prettier@5.2.3(@types/eslint@9.6.1)(eslint-config-prettier@9.1.0(eslint@8.57.1))(eslint@8.57.1)(prettier@3.6.2):
|
||||||
dependencies:
|
dependencies:
|
||||||
eslint: 8.57.1
|
eslint: 8.57.1
|
||||||
prettier: 3.5.2
|
prettier: 3.6.2
|
||||||
prettier-linter-helpers: 1.0.0
|
prettier-linter-helpers: 1.0.0
|
||||||
synckit: 0.9.2
|
synckit: 0.9.2
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
@@ -13381,7 +13687,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
fast-diff: 1.3.0
|
fast-diff: 1.3.0
|
||||||
|
|
||||||
prettier@3.5.2: {}
|
prettier@3.6.2: {}
|
||||||
|
|
||||||
pretty-format@27.5.1:
|
pretty-format@27.5.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -14038,11 +14344,11 @@ snapshots:
|
|||||||
es-errors: 1.3.0
|
es-errors: 1.3.0
|
||||||
internal-slot: 1.1.0
|
internal-slot: 1.1.0
|
||||||
|
|
||||||
storybook@8.6.0(prettier@3.5.2):
|
storybook@8.6.0(prettier@3.6.2):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@storybook/core': 8.6.0(prettier@3.5.2)(storybook@8.6.0(prettier@3.5.2))
|
'@storybook/core': 8.6.0(prettier@3.6.2)(storybook@8.6.0(prettier@3.6.2))
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
prettier: 3.5.2
|
prettier: 3.6.2
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- bufferutil
|
- bufferutil
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|||||||
10
shell.nix
Normal file
10
shell.nix
Normal 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
|
||||||
@@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
19
src/stories/components/CalendarFooter.stories.tsx
Normal file
19
src/stories/components/CalendarFooter.stories.tsx
Normal 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: {},
|
||||||
|
};
|
||||||
@@ -114,11 +114,12 @@ export default function Calendar(): ReactNode {
|
|||||||
<LargeLogo />
|
<LargeLogo />
|
||||||
<Button
|
<Button
|
||||||
variant='minimal'
|
variant='minimal'
|
||||||
|
size='small'
|
||||||
color='theme-black'
|
color='theme-black'
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setShowSidebar(!showSidebar);
|
setShowSidebar(!showSidebar);
|
||||||
}}
|
}}
|
||||||
className='h-fit screenshot:hidden !p-0'
|
className='screenshot:hidden'
|
||||||
icon={Sidebar}
|
icon={Sidebar}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -124,17 +124,15 @@ export default function CourseCellColorPicker({ defaultColor }: CourseCellColorP
|
|||||||
<>
|
<>
|
||||||
<Divider orientation='horizontal' size='100%' className='my-1' />
|
<Divider orientation='horizontal' size='100%' className='my-1' />
|
||||||
<div className='grid grid-cols-6 gap-1'>
|
<div className='grid grid-cols-6 gap-1'>
|
||||||
{colorPatchColors
|
{colorPatchColors.get(selectedBaseColor)?.map(shadeColor => (
|
||||||
.get(selectedBaseColor)
|
<ColorPatch
|
||||||
?.map(shadeColor => (
|
key={shadeColor}
|
||||||
<ColorPatch
|
color={shadeColor}
|
||||||
key={shadeColor}
|
isSelected={shadeColor === hexCodeWithHash}
|
||||||
color={shadeColor}
|
handleSelectColorPatch={handleSelectColorPatch}
|
||||||
isSelected={shadeColor === hexCodeWithHash}
|
defaultColor={defaultColor}
|
||||||
handleSelectColorPatch={handleSelectColorPatch}
|
/>
|
||||||
defaultColor={defaultColor}
|
))}
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -58,13 +58,7 @@ export default function CalendarFooter(): JSX.Element {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Button
|
<Button variant='minimal' size='small' icon={GearSix} color='ut-black' onClick={handleOpenOptions} />
|
||||||
className='h-fit w-fit !p-0'
|
|
||||||
variant='minimal'
|
|
||||||
icon={GearSix}
|
|
||||||
color='ut-black'
|
|
||||||
onClick={handleOpenOptions}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -28,14 +28,15 @@ export default function CalendarHeader({ sidebarOpen, onSidebarToggle }: Calenda
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{ scrollbarGutter: 'stable' }}
|
style={{ scrollbarGutter: 'stable' }}
|
||||||
className='sticky left-0 right-0 top-0 z-10 min-h-[85px] flex items-center gap-5 overflow-x-scroll overflow-y-hidden bg-white pl-spacing-7 pt-spacing-5'
|
className='sticky left-0 right-0 top-0 z-10 min-h-[85px] flex items-center gap-5 overflow-x-auto overflow-y-hidden bg-white pl-spacing-7 pt-spacing-5'
|
||||||
>
|
>
|
||||||
{!sidebarOpen && (
|
{!sidebarOpen && (
|
||||||
<Button
|
<Button
|
||||||
variant='minimal'
|
variant='minimal'
|
||||||
|
size='small'
|
||||||
color='theme-black'
|
color='theme-black'
|
||||||
onClick={onSidebarToggle}
|
onClick={onSidebarToggle}
|
||||||
className='h-fit w-fit screenshot:hidden !p-0'
|
className='screenshot:hidden'
|
||||||
icon={Sidebar}
|
icon={Sidebar}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -26,15 +26,16 @@ export function CalendarSchedules() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='min-w-full w-0 flex flex-col items-center gap-y-spacing-3'>
|
<div className='min-w-full w-0 flex flex-col items-center gap-y-spacing-2'>
|
||||||
<div className='m0 w-full flex justify-between'>
|
<div className='m0 w-full flex items-center justify-between'>
|
||||||
<Text variant='h3' className='text-nowrap text-theme-black'>
|
<Text variant='h3' className='text-nowrap text-theme-black'>
|
||||||
MY SCHEDULES
|
MY SCHEDULES
|
||||||
</Text>
|
</Text>
|
||||||
<Button
|
<Button
|
||||||
variant='minimal'
|
variant='minimal'
|
||||||
|
size='small'
|
||||||
color='theme-black'
|
color='theme-black'
|
||||||
className='h-fit w-fit !p-0 btn'
|
className='!p-0 btn'
|
||||||
onClick={handleAddSchedule}
|
onClick={handleAddSchedule}
|
||||||
icon={Plus}
|
icon={Plus}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -444,7 +444,8 @@ export const calculateCourseCellColumns = (dayCells: CalendarGridCourse[]) => {
|
|||||||
typeof cell.calendarGridPoint.startIndex === 'number' &&
|
typeof cell.calendarGridPoint.startIndex === 'number' &&
|
||||||
cell.calendarGridPoint.startIndex >= 0
|
cell.calendarGridPoint.startIndex >= 0
|
||||||
)
|
)
|
||||||
.toSorted((a, b) => a.calendarGridPoint.startIndex - b.calendarGridPoint.startIndex);
|
.slice()
|
||||||
|
.sort((a, b) => a.calendarGridPoint.startIndex - b.calendarGridPoint.startIndex);
|
||||||
|
|
||||||
// Initialize metadata
|
// Initialize metadata
|
||||||
for (const cell of cells) {
|
for (const cell of cells) {
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ export default function Link(props: PropsWithChildren<Props>): JSX.Element {
|
|||||||
tabIndex={isDisabled ? -1 : 0}
|
tabIndex={isDisabled ? -1 : 0}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
{
|
{
|
||||||
'underline cursor-pointer': !isDisabled,
|
'underline cursor-pointer p-2': !isDisabled,
|
||||||
'cursor-not-allowed color-ut-gray': isDisabled,
|
'cursor-not-allowed color-ut-gray': isDisabled,
|
||||||
},
|
},
|
||||||
className
|
className
|
||||||
|
|||||||
197
src/views/components/settings/AdvancedSettings.tsx
Normal file
197
src/views/components/settings/AdvancedSettings.tsx
Normal file
@@ -0,0 +1,197 @@
|
|||||||
|
import { Trash } from '@phosphor-icons/react';
|
||||||
|
import { OptionsStore } from '@shared/storage/OptionsStore';
|
||||||
|
import MIMEType from '@shared/types/MIMEType';
|
||||||
|
import type { UserSchedule } from '@shared/types/UserSchedule';
|
||||||
|
import { handleExportJson } from '@views/components/calendar/utils';
|
||||||
|
import { Button } from '@views/components/common/Button';
|
||||||
|
import Divider from '@views/components/common/Divider';
|
||||||
|
import SwitchButton from '@views/components/common/SwitchButton';
|
||||||
|
import Text from '@views/components/common/Text/Text';
|
||||||
|
import clsx from 'clsx';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import FileUpload from '../common/FileUpload';
|
||||||
|
import { DISPLAY_PREVIEWS, PREVIEW_SECTION_DIV_CLASSNAME } from './constants';
|
||||||
|
import Preview from './Preview';
|
||||||
|
|
||||||
|
interface AdvancedSettingsProps {
|
||||||
|
highlightConflicts: boolean;
|
||||||
|
setHighlightConflicts: (value: boolean) => void;
|
||||||
|
loadAllCourses: boolean;
|
||||||
|
setLoadAllCourses: (value: boolean) => void;
|
||||||
|
increaseScheduleLimit: boolean;
|
||||||
|
setIncreaseScheduleLimit: (value: boolean) => void;
|
||||||
|
calendarNewTab: boolean;
|
||||||
|
setCalendarNewTab: (value: boolean) => void;
|
||||||
|
activeSchedule: UserSchedule;
|
||||||
|
handleEraseAll: () => void;
|
||||||
|
handleImportClick: (event: React.ChangeEvent<HTMLInputElement>) => Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Settings section component for advanced settings
|
||||||
|
*/
|
||||||
|
export const AdvancedSettings: React.FC<AdvancedSettingsProps> = ({
|
||||||
|
highlightConflicts,
|
||||||
|
setHighlightConflicts,
|
||||||
|
loadAllCourses,
|
||||||
|
setLoadAllCourses,
|
||||||
|
increaseScheduleLimit,
|
||||||
|
setIncreaseScheduleLimit,
|
||||||
|
calendarNewTab,
|
||||||
|
setCalendarNewTab,
|
||||||
|
activeSchedule,
|
||||||
|
handleEraseAll,
|
||||||
|
handleImportClick,
|
||||||
|
}) => (
|
||||||
|
<section className='mb-8'>
|
||||||
|
<h2 className='mb-4 text-xl text-ut-black font-semibold'>ADVANCED SETTINGS</h2>
|
||||||
|
<div className='flex space-x-4'>
|
||||||
|
<div className={PREVIEW_SECTION_DIV_CLASSNAME}>
|
||||||
|
<div className='flex items-center justify-between'>
|
||||||
|
<div className='max-w-xs'>
|
||||||
|
<Text variant='h4' className='text-ut-burntorange font-semibold'>
|
||||||
|
Export Current Schedule
|
||||||
|
</Text>
|
||||||
|
<p className='text-sm text-gray-600'>Backup your active schedule to a portable file</p>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
variant='outline'
|
||||||
|
color='ut-burntorange'
|
||||||
|
onClick={() => handleExportJson(activeSchedule.id)}
|
||||||
|
>
|
||||||
|
Export
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Divider size='auto' orientation='horizontal' />
|
||||||
|
|
||||||
|
<div className='flex items-center justify-between'>
|
||||||
|
<div className='max-w-xs'>
|
||||||
|
<Text variant='h4' className='text-ut-burntorange font-semibold'>
|
||||||
|
Import Schedule
|
||||||
|
</Text>
|
||||||
|
<p className='text-sm text-gray-600'>Import from a schedule file</p>
|
||||||
|
</div>
|
||||||
|
<FileUpload
|
||||||
|
variant='filled'
|
||||||
|
color='ut-burntorange'
|
||||||
|
onChange={handleImportClick}
|
||||||
|
accept={MIMEType.JSON}
|
||||||
|
>
|
||||||
|
Import Schedule
|
||||||
|
</FileUpload>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Divider size='auto' orientation='horizontal' />
|
||||||
|
|
||||||
|
<div className='flex items-center justify-between'>
|
||||||
|
<div className='max-w-xs'>
|
||||||
|
<Text variant='h4' className='text-ut-burntorange font-semibold'>
|
||||||
|
Course Conflict Highlight
|
||||||
|
</Text>
|
||||||
|
<p className='text-sm text-gray-600'>
|
||||||
|
Adds a red strikethrough to courses that have conflicting times.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<SwitchButton
|
||||||
|
isChecked={highlightConflicts}
|
||||||
|
onChange={() => {
|
||||||
|
setHighlightConflicts(!highlightConflicts);
|
||||||
|
OptionsStore.set('enableHighlightConflicts', !highlightConflicts);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Divider size='auto' orientation='horizontal' />
|
||||||
|
|
||||||
|
<div className='flex items-center justify-between'>
|
||||||
|
<div className='max-w-xs'>
|
||||||
|
<Text variant='h4' className='text-ut-burntorange font-semibold'>
|
||||||
|
Load All Courses in Course Schedule
|
||||||
|
</Text>
|
||||||
|
<p className='text-sm text-gray-600'>
|
||||||
|
Loads all courses in the Course Schedule site by scrolling, instead of using next/prev page
|
||||||
|
buttons.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<SwitchButton
|
||||||
|
isChecked={loadAllCourses}
|
||||||
|
onChange={() => {
|
||||||
|
setLoadAllCourses(!loadAllCourses);
|
||||||
|
OptionsStore.set('enableScrollToLoad', !loadAllCourses);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Divider size='auto' orientation='horizontal' />
|
||||||
|
|
||||||
|
<div className='flex items-center justify-between'>
|
||||||
|
<div className='max-w-xs'>
|
||||||
|
<Text variant='h4' className='text-ut-burntorange font-semibold'>
|
||||||
|
Allow more than 10 schedules
|
||||||
|
</Text>
|
||||||
|
<p className='text-sm text-gray-600'>
|
||||||
|
Allow bypassing the 10-schedule limit. Intended for advisors or staff who need to create
|
||||||
|
many schedules on behalf of students.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<SwitchButton
|
||||||
|
isChecked={increaseScheduleLimit}
|
||||||
|
onChange={() => {
|
||||||
|
setIncreaseScheduleLimit(!increaseScheduleLimit);
|
||||||
|
OptionsStore.set('allowMoreSchedules', !increaseScheduleLimit);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Divider size='auto' orientation='horizontal' />
|
||||||
|
|
||||||
|
<div className='flex items-center justify-between'>
|
||||||
|
<div className='max-w-xs'>
|
||||||
|
<Text variant='h4' className='text-ut-burntorange font-semibold'>
|
||||||
|
Always Open Calendar in New Tab
|
||||||
|
</Text>
|
||||||
|
<p className='text-sm text-gray-600'>
|
||||||
|
Always opens the calendar view in a new tab when navigating to the calendar page. May
|
||||||
|
prevent issues where the calendar refuses to open.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<SwitchButton
|
||||||
|
isChecked={calendarNewTab}
|
||||||
|
onChange={() => {
|
||||||
|
setCalendarNewTab(!calendarNewTab);
|
||||||
|
OptionsStore.set('alwaysOpenCalendarInNewTab', !calendarNewTab);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Divider size='auto' orientation='horizontal' />
|
||||||
|
|
||||||
|
<div className='flex items-center justify-between'>
|
||||||
|
<div className='max-w-xs'>
|
||||||
|
<Text variant='h4' className='text-ut-burntorange font-semibold'>
|
||||||
|
Reset All Data
|
||||||
|
</Text>
|
||||||
|
<p className='text-sm text-gray-600'>Erases all schedules and courses you have.</p>
|
||||||
|
</div>
|
||||||
|
<Button variant='outline' color='theme-red' icon={Trash} onClick={handleEraseAll}>
|
||||||
|
Erase All
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{DISPLAY_PREVIEWS && (
|
||||||
|
<Preview>
|
||||||
|
<Text
|
||||||
|
variant='h2-course'
|
||||||
|
className={clsx('text-center text-theme-red font-normal', {
|
||||||
|
'line-through': highlightConflicts,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
01234 MWF 10:00 AM - 11:00 AM UTC 1.234
|
||||||
|
</Text>
|
||||||
|
</Preview>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
54
src/views/components/settings/ContributorCard.tsx
Normal file
54
src/views/components/settings/ContributorCard.tsx
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import Text from '@views/components/common/Text/Text';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
interface ContributorCardProps {
|
||||||
|
name: string;
|
||||||
|
githubUsername: string;
|
||||||
|
roles: string[];
|
||||||
|
stats?: {
|
||||||
|
commits: number;
|
||||||
|
linesAdded: number;
|
||||||
|
linesDeleted: number;
|
||||||
|
mergedPRs?: number;
|
||||||
|
};
|
||||||
|
showStats: boolean;
|
||||||
|
includeMergedPRs: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GitHub contributor card component
|
||||||
|
*/
|
||||||
|
export const ContributorCard: React.FC<ContributorCardProps> = ({
|
||||||
|
name,
|
||||||
|
githubUsername,
|
||||||
|
roles,
|
||||||
|
stats,
|
||||||
|
showStats,
|
||||||
|
includeMergedPRs,
|
||||||
|
}) => (
|
||||||
|
<div className='border border-gray-300 rounded bg-ut-gray/10 p-4'>
|
||||||
|
<Text
|
||||||
|
variant='p'
|
||||||
|
className='text-ut-burntorange font-semibold hover:cursor-pointer'
|
||||||
|
onClick={() => window.open(`https://github.com/${githubUsername}`, '_blank')}
|
||||||
|
>
|
||||||
|
{name}
|
||||||
|
</Text>
|
||||||
|
{roles.map(role => (
|
||||||
|
<p key={`${githubUsername}-${role}`} className='text-sm text-gray-600'>
|
||||||
|
{role}
|
||||||
|
</p>
|
||||||
|
))}
|
||||||
|
{showStats && stats && (
|
||||||
|
<div className='mt-2'>
|
||||||
|
<p className='text-xs text-gray-500'>GitHub Stats (UTRP repo):</p>
|
||||||
|
{includeMergedPRs && stats.mergedPRs !== undefined && (
|
||||||
|
<p className='text-xs'>Merged PRs: {stats.mergedPRs}</p>
|
||||||
|
)}
|
||||||
|
<p className='text-xs'>Commits: {stats.commits}</p>
|
||||||
|
<p className='text-xs text-ut-green'>{stats.linesAdded}++</p>
|
||||||
|
<p className='text-xs text-theme-red'>{stats.linesDeleted}--</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
@@ -1,115 +1,68 @@
|
|||||||
// import addCourse from '@pages/background/lib/addCourse';
|
// Pages
|
||||||
import { addCourseByURL } from '@pages/background/lib/addCourseByURL';
|
import { addCourseByURL } from '@pages/background/lib/addCourseByURL';
|
||||||
import { deleteAllSchedules } from '@pages/background/lib/deleteSchedule';
|
import { deleteAllSchedules } from '@pages/background/lib/deleteSchedule';
|
||||||
import importSchedule from '@pages/background/lib/importSchedule';
|
import importSchedule from '@pages/background/lib/importSchedule';
|
||||||
import { CalendarDots, Trash } from '@phosphor-icons/react';
|
import { CalendarDots } from '@phosphor-icons/react';
|
||||||
|
// Shared
|
||||||
import { background } from '@shared/messages';
|
import { background } from '@shared/messages';
|
||||||
import { DevStore } from '@shared/storage/DevStore';
|
import { DevStore } from '@shared/storage/DevStore';
|
||||||
import { initSettings, OptionsStore } from '@shared/storage/OptionsStore';
|
import { initSettings, OptionsStore } from '@shared/storage/OptionsStore';
|
||||||
import { CRX_PAGES } from '@shared/types/CRXPages';
|
import { CRX_PAGES } from '@shared/types/CRXPages';
|
||||||
import MIMEType from '@shared/types/MIMEType';
|
import Particles from '@tsparticles/react';
|
||||||
// import { addCourseByUrl } from '@shared/util/courseUtils';
|
|
||||||
// import { getCourseColors } from '@shared/util/colors';
|
|
||||||
// import CalendarCourseCell from '@views/components/calendar/CalendarCourseCell';
|
|
||||||
import { Button } from '@views/components/common/Button';
|
import { Button } from '@views/components/common/Button';
|
||||||
import { usePrompt } from '@views/components/common/DialogProvider/DialogProvider';
|
import { usePrompt } from '@views/components/common/DialogProvider/DialogProvider';
|
||||||
|
// Views
|
||||||
import Divider from '@views/components/common/Divider';
|
import Divider from '@views/components/common/Divider';
|
||||||
import { LargeLogo } from '@views/components/common/LogoIcon';
|
import { LargeLogo } from '@views/components/common/LogoIcon';
|
||||||
// import PopupCourseBlock from '@views/components/common/PopupCourseBlock';
|
|
||||||
import SwitchButton from '@views/components/common/SwitchButton';
|
|
||||||
import Text from '@views/components/common/Text/Text';
|
import Text from '@views/components/common/Text/Text';
|
||||||
|
// Hooks
|
||||||
import useChangelog from '@views/hooks/useChangelog';
|
import useChangelog from '@views/hooks/useChangelog';
|
||||||
import useSchedules from '@views/hooks/useSchedules';
|
import useSchedules from '@views/hooks/useSchedules';
|
||||||
// import { CourseCatalogScraper } from '@views/lib/CourseCatalogScraper';
|
|
||||||
// import getCourseTableRows from '@views/lib/getCourseTableRows';
|
|
||||||
import { GitHubStatsService, LONGHORN_DEVELOPERS_ADMINS, LONGHORN_DEVELOPERS_SWE } from '@views/lib/getGitHubStats';
|
import { GitHubStatsService, LONGHORN_DEVELOPERS_ADMINS, LONGHORN_DEVELOPERS_SWE } from '@views/lib/getGitHubStats';
|
||||||
// import { SiteSupport } from '@views/lib/getSiteSupport';
|
// Misc
|
||||||
import clsx from 'clsx';
|
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import React, { useCallback, useEffect, useState } from 'react';
|
|
||||||
|
|
||||||
|
// Icons
|
||||||
import IconoirGitFork from '~icons/iconoir/git-fork';
|
import IconoirGitFork from '~icons/iconoir/git-fork';
|
||||||
|
|
||||||
import { handleExportJson } from '../calendar/utils';
|
|
||||||
// import { ExampleCourse } from 'src/stories/components/ConflictsWithWarning.stories';;
|
|
||||||
import FileUpload from '../common/FileUpload';
|
|
||||||
import { useMigrationDialog } from '../common/MigrationDialog';
|
import { useMigrationDialog } from '../common/MigrationDialog';
|
||||||
// import RefreshIcon from '~icons/material-symbols/refresh';
|
import { AdvancedSettings } from './AdvancedSettings';
|
||||||
|
import { DEV_MODE_CLICK_TARGET, INCLUDE_MERGED_PRS, STATS_TOGGLE_KEY } from './constants';
|
||||||
|
import { ContributorCard } from './ContributorCard';
|
||||||
import DevMode from './DevMode';
|
import DevMode from './DevMode';
|
||||||
import Preview from './Preview';
|
import { useBirthdayCelebration } from './useBirthdayCelebration';
|
||||||
|
import { useDevMode } from './useDevMode';
|
||||||
|
|
||||||
const manifest = chrome.runtime.getManifest();
|
const manifest = chrome.runtime.getManifest();
|
||||||
|
|
||||||
const gitHubStatsService = new GitHubStatsService();
|
|
||||||
const includeMergedPRs = false;
|
|
||||||
|
|
||||||
const DISPLAY_PREVIEWS = false;
|
|
||||||
const PREVIEW_SECTION_DIV_CLASSNAME = DISPLAY_PREVIEWS ? 'w-1/2 space-y-4' : 'flex-grow space-y-4';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom hook for enabling developer mode.
|
* Main Settings Component for managing user settings and preferences.
|
||||||
*
|
|
||||||
* @param targetCount - The target count to activate developer mode.
|
|
||||||
* @returns A tuple containing a boolean indicating if developer mode is active and a function to increment the count.
|
|
||||||
*/
|
|
||||||
const useDevMode = (targetCount: number): [boolean, () => void] => {
|
|
||||||
const [count, setCount] = useState(0);
|
|
||||||
const [active, setActive] = useState(false);
|
|
||||||
const [lastClick, setLastClick] = useState(0);
|
|
||||||
|
|
||||||
const incrementCount = useCallback(() => {
|
|
||||||
const now = Date.now();
|
|
||||||
if (now - lastClick < 500) {
|
|
||||||
setCount(prevCount => {
|
|
||||||
const newCount = prevCount + 1;
|
|
||||||
if (newCount === targetCount) {
|
|
||||||
setActive(true);
|
|
||||||
}
|
|
||||||
return newCount;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
setCount(1);
|
|
||||||
}
|
|
||||||
setLastClick(now);
|
|
||||||
}, [lastClick, targetCount]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const timer = setTimeout(() => setCount(0), 3000);
|
|
||||||
return () => clearTimeout(timer);
|
|
||||||
}, [count]);
|
|
||||||
|
|
||||||
return [active, incrementCount];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Component for managing user settings and preferences.
|
|
||||||
*
|
*
|
||||||
* @returns The Settings component.
|
* @returns The Settings component.
|
||||||
*/
|
*/
|
||||||
export default function Settings(): JSX.Element {
|
export default function Settings(): JSX.Element {
|
||||||
const [_enableCourseStatusChips, setEnableCourseStatusChips] = useState<boolean>(false);
|
const gitHubStatsService = useMemo(() => new GitHubStatsService(), []);
|
||||||
// const [_showTimeLocation, setShowTimeLocation] = useState<boolean>(false);
|
|
||||||
const [highlightConflicts, setHighlightConflicts] = useState<boolean>(false);
|
|
||||||
const [loadAllCourses, setLoadAllCourses] = useState<boolean>(false);
|
|
||||||
const [_enableDataRefreshing, setEnableDataRefreshing] = useState<boolean>(false);
|
|
||||||
const [calendarNewTab, setCalendarNewTab] = useState<boolean>(false);
|
|
||||||
const [increaseScheduleLimit, setIncreaseScheduleLimit] = useState<boolean>(false);
|
|
||||||
|
|
||||||
const showMigrationDialog = useMigrationDialog();
|
// State
|
||||||
|
const [highlightConflicts, setHighlightConflicts] = useState(false);
|
||||||
// Toggle GitHub stats when the user presses the 'S' key
|
const [loadAllCourses, setLoadAllCourses] = useState(false);
|
||||||
const [showGitHubStats, setShowGitHubStats] = useState<boolean>(false);
|
const [calendarNewTab, setCalendarNewTab] = useState(false);
|
||||||
|
const [increaseScheduleLimit, setIncreaseScheduleLimit] = useState(false);
|
||||||
|
const [showGitHubStats, setShowGitHubStats] = useState(false);
|
||||||
const [githubStats, setGitHubStats] = useState<Awaited<
|
const [githubStats, setGitHubStats] = useState<Awaited<
|
||||||
ReturnType<typeof gitHubStatsService.fetchGitHubStats>
|
ReturnType<typeof gitHubStatsService.fetchGitHubStats>
|
||||||
> | null>(null);
|
> | null>(null);
|
||||||
|
const [isDeveloper, setIsDeveloper] = useState(false);
|
||||||
|
|
||||||
const [activeSchedule] = useSchedules();
|
const [activeSchedule] = useSchedules();
|
||||||
// const [isRefreshing, setIsRefreshing] = useState<boolean>(false);
|
|
||||||
|
|
||||||
const [isDeveloper, setIsDeveloper] = useState<boolean>(false);
|
|
||||||
|
|
||||||
const showDialog = usePrompt();
|
const showDialog = usePrompt();
|
||||||
const handleChangelogOnClick = useChangelog();
|
const handleChangelogOnClick = useChangelog();
|
||||||
|
const showMigrationDialog = useMigrationDialog();
|
||||||
|
|
||||||
|
const [devMode, toggleDevMode] = useDevMode(DEV_MODE_CLICK_TARGET);
|
||||||
|
const { showParticles, particlesInit, particlesOptions, triggerCelebration, isBirthday } = useBirthdayCelebration();
|
||||||
|
|
||||||
|
// Initialize settings and listeners
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchGitHubStats = async () => {
|
const fetchGitHubStats = async () => {
|
||||||
try {
|
try {
|
||||||
@@ -121,19 +74,10 @@ export default function Settings(): JSX.Element {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const initAndSetSettings = async () => {
|
const initAndSetSettings = async () => {
|
||||||
const {
|
const { enableHighlightConflicts, enableScrollToLoad, alwaysOpenCalendarInNewTab, allowMoreSchedules } =
|
||||||
enableCourseStatusChips,
|
await initSettings();
|
||||||
enableHighlightConflicts,
|
|
||||||
enableScrollToLoad,
|
|
||||||
enableDataRefreshing,
|
|
||||||
alwaysOpenCalendarInNewTab,
|
|
||||||
allowMoreSchedules,
|
|
||||||
} = await initSettings();
|
|
||||||
setEnableCourseStatusChips(enableCourseStatusChips);
|
|
||||||
// setShowTimeLocation(enableTimeAndLocationInPopup);
|
|
||||||
setHighlightConflicts(enableHighlightConflicts);
|
setHighlightConflicts(enableHighlightConflicts);
|
||||||
setLoadAllCourses(enableScrollToLoad);
|
setLoadAllCourses(enableScrollToLoad);
|
||||||
setEnableDataRefreshing(enableDataRefreshing);
|
|
||||||
setCalendarNewTab(alwaysOpenCalendarInNewTab);
|
setCalendarNewTab(alwaysOpenCalendarInNewTab);
|
||||||
setIncreaseScheduleLimit(allowMoreSchedules);
|
setIncreaseScheduleLimit(allowMoreSchedules);
|
||||||
};
|
};
|
||||||
@@ -143,79 +87,50 @@ export default function Settings(): JSX.Element {
|
|||||||
setIsDeveloper(isDev);
|
setIsDeveloper(isDev);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleKeyPress = (event: KeyboardEvent) => {
|
||||||
|
if (event.key === STATS_TOGGLE_KEY || event.key === STATS_TOGGLE_KEY.toUpperCase()) {
|
||||||
|
setShowGitHubStats(prev => !prev);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Listeners
|
||||||
const ds_l1 = DevStore.listen('isDeveloper', async ({ newValue }) => {
|
const ds_l1 = DevStore.listen('isDeveloper', async ({ newValue }) => {
|
||||||
setIsDeveloper(newValue);
|
setIsDeveloper(newValue);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const l1 = OptionsStore.listen('enableHighlightConflicts', async ({ newValue }) => {
|
||||||
|
setHighlightConflicts(newValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
const l2 = OptionsStore.listen('enableScrollToLoad', async ({ newValue }) => {
|
||||||
|
setLoadAllCourses(newValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
const l3 = OptionsStore.listen('alwaysOpenCalendarInNewTab', async ({ newValue }) => {
|
||||||
|
setCalendarNewTab(newValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
const l4 = OptionsStore.listen('allowMoreSchedules', async ({ newValue }) => {
|
||||||
|
setIncreaseScheduleLimit(newValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener('keydown', handleKeyPress);
|
||||||
|
|
||||||
initDS();
|
initDS();
|
||||||
fetchGitHubStats();
|
fetchGitHubStats();
|
||||||
initAndSetSettings();
|
initAndSetSettings();
|
||||||
|
|
||||||
const handleKeyPress = (event: KeyboardEvent) => {
|
|
||||||
if (event.key === 'S' || event.key === 's') {
|
|
||||||
setShowGitHubStats(prev => !prev);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
window.addEventListener('keydown', handleKeyPress);
|
|
||||||
|
|
||||||
// Listen for changes in the settings
|
|
||||||
const l1 = OptionsStore.listen('enableCourseStatusChips', async ({ newValue }) => {
|
|
||||||
setEnableCourseStatusChips(newValue);
|
|
||||||
// console.log('enableCourseStatusChips', newValue);
|
|
||||||
});
|
|
||||||
|
|
||||||
// const l2 = OptionsStore.listen('enableTimeAndLocationInPopup', async ({ newValue }) => {
|
|
||||||
// setShowTimeLocation(newValue);
|
|
||||||
// // console.log('enableTimeAndLocationInPopup', newValue);
|
|
||||||
// });
|
|
||||||
|
|
||||||
const l2 = OptionsStore.listen('enableHighlightConflicts', async ({ newValue }) => {
|
|
||||||
setHighlightConflicts(newValue);
|
|
||||||
// console.log('enableHighlightConflicts', newValue);
|
|
||||||
});
|
|
||||||
|
|
||||||
const l3 = OptionsStore.listen('enableScrollToLoad', async ({ newValue }) => {
|
|
||||||
setLoadAllCourses(newValue);
|
|
||||||
// console.log('enableScrollToLoad', newValue);
|
|
||||||
});
|
|
||||||
|
|
||||||
const l4 = OptionsStore.listen('enableDataRefreshing', async ({ newValue }) => {
|
|
||||||
setEnableDataRefreshing(newValue);
|
|
||||||
// console.log('enableDataRefreshing', newValue);
|
|
||||||
});
|
|
||||||
|
|
||||||
const l5 = OptionsStore.listen('alwaysOpenCalendarInNewTab', async ({ newValue }) => {
|
|
||||||
setCalendarNewTab(newValue);
|
|
||||||
// console.log('alwaysOpenCalendarInNewTab', newValue);
|
|
||||||
});
|
|
||||||
|
|
||||||
const l6 = OptionsStore.listen('alwaysOpenCalendarInNewTab', async ({ newValue }) => {
|
|
||||||
setCalendarNewTab(newValue);
|
|
||||||
// console.log('alwaysOpenCalendarInNewTab', newValue);
|
|
||||||
});
|
|
||||||
|
|
||||||
const l7 = OptionsStore.listen('allowMoreSchedules', async ({ newValue }) => {
|
|
||||||
setIncreaseScheduleLimit(newValue);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Remove listeners when the component is unmounted
|
|
||||||
return () => {
|
return () => {
|
||||||
OptionsStore.removeListener(l1);
|
OptionsStore.removeListener(l1);
|
||||||
OptionsStore.removeListener(l2);
|
OptionsStore.removeListener(l2);
|
||||||
OptionsStore.removeListener(l3);
|
OptionsStore.removeListener(l3);
|
||||||
OptionsStore.removeListener(l4);
|
OptionsStore.removeListener(l4);
|
||||||
OptionsStore.removeListener(l5);
|
|
||||||
OptionsStore.removeListener(l6);
|
|
||||||
OptionsStore.removeListener(l7);
|
|
||||||
|
|
||||||
DevStore.removeListener(ds_l1);
|
DevStore.removeListener(ds_l1);
|
||||||
|
|
||||||
window.removeEventListener('keydown', handleKeyPress);
|
window.removeEventListener('keydown', handleKeyPress);
|
||||||
};
|
};
|
||||||
}, []);
|
}, [gitHubStatsService]);
|
||||||
|
|
||||||
const handleEraseAll = () => {
|
const handleEraseAll = useCallback(() => {
|
||||||
showDialog({
|
showDialog({
|
||||||
title: 'Erase All Course/Schedule Data',
|
title: 'Erase All Course/Schedule Data',
|
||||||
description: (
|
description: (
|
||||||
@@ -242,9 +157,9 @@ export default function Settings(): JSX.Element {
|
|||||||
</Button>
|
</Button>
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
};
|
}, [showDialog]);
|
||||||
|
|
||||||
const handleImportClick = async (event: React.ChangeEvent<HTMLInputElement>) => {
|
const handleImportClick = useCallback(async (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const file = event.target.files?.[0];
|
const file = event.target.files?.[0];
|
||||||
if (!file) return;
|
if (!file) return;
|
||||||
|
|
||||||
@@ -257,16 +172,30 @@ export default function Settings(): JSX.Element {
|
|||||||
console.error('Error importing schedule:', error);
|
console.error('Error importing schedule:', error);
|
||||||
alert('Failed to import schedule. Make sure the file is a valid .json format.');
|
alert('Failed to import schedule. Make sure the file is a valid .json format.');
|
||||||
}
|
}
|
||||||
};
|
}, []);
|
||||||
// const handleAddCourseByLink = async () => {
|
|
||||||
// // todo: Use a proper modal instead of a prompt
|
|
||||||
// const link: string | null = prompt('Enter course link');
|
|
||||||
// // Exit if the user cancels the prompt
|
|
||||||
// if (link === null) return;
|
|
||||||
// await addCourseByUrl(link, activeSchedule);
|
|
||||||
// };
|
|
||||||
|
|
||||||
const [devMode, toggleDevMode] = useDevMode(10);
|
const sortedContributors = useMemo(() => {
|
||||||
|
if (!githubStats) return LONGHORN_DEVELOPERS_SWE;
|
||||||
|
return [...LONGHORN_DEVELOPERS_SWE].sort(
|
||||||
|
(a, b) =>
|
||||||
|
(githubStats.userGitHubStats[b.githubUsername]?.commits ?? 0) -
|
||||||
|
(githubStats.userGitHubStats[a.githubUsername]?.commits ?? 0)
|
||||||
|
);
|
||||||
|
}, [githubStats]);
|
||||||
|
|
||||||
|
const additionalContributors = useMemo(() => {
|
||||||
|
if (!githubStats) return [];
|
||||||
|
return Object.keys(githubStats.userGitHubStats)
|
||||||
|
.filter(
|
||||||
|
username =>
|
||||||
|
!LONGHORN_DEVELOPERS_ADMINS.some(admin => admin.githubUsername === username) &&
|
||||||
|
!LONGHORN_DEVELOPERS_SWE.some(swe => swe.githubUsername === username)
|
||||||
|
)
|
||||||
|
.sort(
|
||||||
|
(a, b) =>
|
||||||
|
(githubStats.userGitHubStats[b]?.commits ?? 0) - (githubStats.userGitHubStats[a]?.commits ?? 0)
|
||||||
|
);
|
||||||
|
}, [githubStats]);
|
||||||
|
|
||||||
if (devMode) {
|
if (devMode) {
|
||||||
DevStore.set('isDeveloper', true);
|
DevStore.set('isDeveloper', true);
|
||||||
@@ -274,13 +203,32 @@ export default function Settings(): JSX.Element {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className='relative'>
|
||||||
|
{particlesInit && showParticles && (
|
||||||
|
<Particles
|
||||||
|
id='birthday-particles'
|
||||||
|
options={particlesOptions}
|
||||||
|
className='pointer-events-none absolute inset-0 z-50'
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
<header className='flex items-center gap-5 overflow-x-auto overflow-y-hidden border-b border-ut-offwhite px-7 py-4 md:overflow-x-hidden'>
|
<header className='flex items-center gap-5 overflow-x-auto overflow-y-hidden border-b border-ut-offwhite px-7 py-4 md:overflow-x-hidden'>
|
||||||
<LargeLogo />
|
<LargeLogo />
|
||||||
<Divider className='mx-2 self-center md:mx-4' size='2.5rem' orientation='vertical' />
|
<Divider className='mx-2 self-center md:mx-4' size='2.5rem' orientation='vertical' />
|
||||||
<Text variant='h1' className='flex-1 text-ut-burntorange normal-case!'>
|
<div className='flex flex-1 items-center gap-2'>
|
||||||
Settings and Credits
|
<Text variant='h1' className='text-ut-burntorange normal-case'>
|
||||||
</Text>
|
Settings and Credits
|
||||||
|
</Text>
|
||||||
|
{isBirthday && (
|
||||||
|
<span
|
||||||
|
onClick={triggerCelebration}
|
||||||
|
className='cursor-pointer px-4 text-sm text-ut-burntorange transition-transform hover:scale-110'
|
||||||
|
title='Click to celebrate!'
|
||||||
|
>
|
||||||
|
🎉 Happy Birthday LHD! 🎉
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
<div className='hidden flex-row items-center justify-end gap-6 screenshot:hidden lg:flex'>
|
<div className='hidden flex-row items-center justify-end gap-6 screenshot:hidden lg:flex'>
|
||||||
<Button variant='minimal' color='theme-black' onClick={handleChangelogOnClick}>
|
<Button variant='minimal' color='theme-black' onClick={handleChangelogOnClick}>
|
||||||
<IconoirGitFork className='h-6 w-6 text-ut-gray' />
|
<IconoirGitFork className='h-6 w-6 text-ut-gray' />
|
||||||
@@ -301,238 +249,19 @@ export default function Settings(): JSX.Element {
|
|||||||
|
|
||||||
<div className='p-6 lg:flex'>
|
<div className='p-6 lg:flex'>
|
||||||
<div className='mr-4 lg:w-1/2 xl:w-xl'>
|
<div className='mr-4 lg:w-1/2 xl:w-xl'>
|
||||||
{/* <section className='mb-8'>
|
<AdvancedSettings
|
||||||
<h2 className='mb-4 text-xl text-ut-black font-semibold'>CUSTOMIZATION OPTIONS</h2>
|
highlightConflicts={highlightConflicts}
|
||||||
<div className='flex space-x-4'>
|
setHighlightConflicts={setHighlightConflicts}
|
||||||
<div className='w-1/2 space-y-4'>
|
loadAllCourses={loadAllCourses}
|
||||||
<div className='flex items-center justify-between'>
|
setLoadAllCourses={setLoadAllCourses}
|
||||||
<div className='max-w-xs'>
|
increaseScheduleLimit={increaseScheduleLimit}
|
||||||
<h3 className='text-ut-burntorange font-semibold'>Show Course Status</h3>
|
setIncreaseScheduleLimit={setIncreaseScheduleLimit}
|
||||||
<p className='text-sm text-gray-600'>
|
calendarNewTab={calendarNewTab}
|
||||||
Shows an indicator for waitlisted, cancelled, and closed courses.
|
setCalendarNewTab={setCalendarNewTab}
|
||||||
</p>
|
activeSchedule={activeSchedule}
|
||||||
</div>
|
handleEraseAll={handleEraseAll}
|
||||||
<SwitchButton
|
handleImportClick={handleImportClick}
|
||||||
isChecked={enableCourseStatusChips}
|
/>
|
||||||
onChange={() => {
|
|
||||||
setEnableCourseStatusChips(!enableCourseStatusChips);
|
|
||||||
OptionsStore.set('enableCourseStatusChips', !enableCourseStatusChips);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Divider size='auto' orientation='horizontal' />
|
|
||||||
|
|
||||||
<div className='flex items-center justify-between'>
|
|
||||||
<div className='max-w-xs'>
|
|
||||||
<h3 className='text-ut-burntorange font-semibold'>
|
|
||||||
Show Time & Location in Popup
|
|
||||||
</h3>
|
|
||||||
<p className='text-sm text-gray-600'>
|
|
||||||
Shows the course's time and location in the extension's popup.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<SwitchButton
|
|
||||||
isChecked={showTimeLocation}
|
|
||||||
onChange={() => {
|
|
||||||
setShowTimeLocation(!showTimeLocation);
|
|
||||||
OptionsStore.set('enableTimeAndLocationInPopup', !showTimeLocation);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{DISPLAY_PREVIEWS && (
|
|
||||||
<Preview>
|
|
||||||
<CalendarCourseCell
|
|
||||||
colors={getCourseColors('orange')}
|
|
||||||
courseDeptAndInstr={ExampleCourse.department}
|
|
||||||
className={ExampleCourse.number}
|
|
||||||
status={ExampleCourse.status}
|
|
||||||
timeAndLocation={ExampleCourse.schedule.meetings[0]!.getTimeString({
|
|
||||||
separator: '-',
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
<PopupCourseBlock colors={getCourseColors('orange')} course={ExampleCourse} />
|
|
||||||
</Preview>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<Divider size='auto' orientation='horizontal' /> */}
|
|
||||||
|
|
||||||
<section className='mb-8'>
|
|
||||||
<h2 className='mb-4 text-xl text-ut-black font-semibold'>ADVANCED SETTINGS</h2>
|
|
||||||
<div className='flex space-x-4'>
|
|
||||||
<div className={PREVIEW_SECTION_DIV_CLASSNAME}>
|
|
||||||
{/* <div className='flex items-center justify-between'>
|
|
||||||
<div className='max-w-xs'>
|
|
||||||
<h3 className='text-ut-burntorange font-semibold'>Refresh Data</h3>
|
|
||||||
<p className='text-sm text-gray-600'>
|
|
||||||
Refreshes waitlist, course status, and other info with the latest data from
|
|
||||||
UT's site.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<Button
|
|
||||||
variant='outline'
|
|
||||||
color='ut-black'
|
|
||||||
icon={RefreshIcon}
|
|
||||||
onClick={() => console.log('Refresh clicked')}
|
|
||||||
disabled={!enableDataRefreshing}
|
|
||||||
>
|
|
||||||
Refresh
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Divider size='auto' orientation='horizontal' /> */}
|
|
||||||
|
|
||||||
<div className='flex items-center justify-between'>
|
|
||||||
<div className='max-w-xs'>
|
|
||||||
<Text variant='h4' className='text-ut-burntorange font-semibold'>
|
|
||||||
Export Current Schedule
|
|
||||||
</Text>
|
|
||||||
<p className='text-sm text-gray-600'>
|
|
||||||
Backup your active schedule to a portable file
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<Button
|
|
||||||
variant='outline'
|
|
||||||
color='ut-burntorange'
|
|
||||||
onClick={() => handleExportJson(activeSchedule.id)}
|
|
||||||
>
|
|
||||||
Export
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Divider size='auto' orientation='horizontal' />
|
|
||||||
|
|
||||||
<div className='flex items-center justify-between'>
|
|
||||||
<div className='max-w-xs'>
|
|
||||||
<Text variant='h4' className='text-ut-burntorange font-semibold'>
|
|
||||||
Import Schedule
|
|
||||||
</Text>
|
|
||||||
<p className='text-sm text-gray-600'>Import from a schedule file</p>
|
|
||||||
</div>
|
|
||||||
<FileUpload
|
|
||||||
variant='filled'
|
|
||||||
color='ut-burntorange'
|
|
||||||
onChange={handleImportClick}
|
|
||||||
accept={MIMEType.JSON}
|
|
||||||
>
|
|
||||||
Import Schedule
|
|
||||||
</FileUpload>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Divider size='auto' orientation='horizontal' />
|
|
||||||
|
|
||||||
<div className='flex items-center justify-between'>
|
|
||||||
<div className='max-w-xs'>
|
|
||||||
<Text variant='h4' className='text-ut-burntorange font-semibold'>
|
|
||||||
Course Conflict Highlight
|
|
||||||
</Text>
|
|
||||||
<p className='text-sm text-gray-600'>
|
|
||||||
Adds a red strikethrough to courses that have conflicting times.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<SwitchButton
|
|
||||||
isChecked={highlightConflicts}
|
|
||||||
onChange={() => {
|
|
||||||
setHighlightConflicts(!highlightConflicts);
|
|
||||||
OptionsStore.set('enableHighlightConflicts', !highlightConflicts);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Divider size='auto' orientation='horizontal' />
|
|
||||||
|
|
||||||
<div className='flex items-center justify-between'>
|
|
||||||
<div className='max-w-xs'>
|
|
||||||
<Text variant='h4' className='text-ut-burntorange font-semibold'>
|
|
||||||
Load All Courses in Course Schedule
|
|
||||||
</Text>
|
|
||||||
<p className='text-sm text-gray-600'>
|
|
||||||
Loads all courses in the Course Schedule site by scrolling, instead of using
|
|
||||||
next/prev page buttons.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<SwitchButton
|
|
||||||
isChecked={loadAllCourses}
|
|
||||||
onChange={() => {
|
|
||||||
setLoadAllCourses(!loadAllCourses);
|
|
||||||
OptionsStore.set('enableScrollToLoad', !loadAllCourses);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className='flex items-center justify-between'>
|
|
||||||
<div className='max-w-xs'>
|
|
||||||
<Text variant='h4' className='text-ut-burntorange font-semibold'>
|
|
||||||
Allow more than 10 schedules
|
|
||||||
</Text>
|
|
||||||
<p className='text-sm text-gray-600'>
|
|
||||||
Allow bypassing the 10-schedule limit. Intended for advisors or staff who
|
|
||||||
need to create many schedules on behalf of students.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<SwitchButton
|
|
||||||
isChecked={increaseScheduleLimit}
|
|
||||||
onChange={() => {
|
|
||||||
setIncreaseScheduleLimit(!increaseScheduleLimit);
|
|
||||||
OptionsStore.set('allowMoreSchedules', !increaseScheduleLimit);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Divider size='auto' orientation='horizontal' />
|
|
||||||
|
|
||||||
<div className='flex items-center justify-between'>
|
|
||||||
<div className='max-w-xs'>
|
|
||||||
<Text variant='h4' className='text-ut-burntorange font-semibold'>
|
|
||||||
Always Open Calendar in New Tab
|
|
||||||
</Text>
|
|
||||||
<p className='text-sm text-gray-600'>
|
|
||||||
Always opens the calendar view in a new tab when navigating to the calendar
|
|
||||||
page. May prevent issues where the calendar refuses to open.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<SwitchButton
|
|
||||||
isChecked={calendarNewTab}
|
|
||||||
onChange={() => {
|
|
||||||
setCalendarNewTab(!calendarNewTab);
|
|
||||||
OptionsStore.set('alwaysOpenCalendarInNewTab', !calendarNewTab);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Divider size='auto' orientation='horizontal' />
|
|
||||||
|
|
||||||
<div className='flex items-center justify-between'>
|
|
||||||
<div className='max-w-xs'>
|
|
||||||
<Text variant='h4' className='text-ut-burntorange font-semibold'>
|
|
||||||
Reset All Data
|
|
||||||
</Text>
|
|
||||||
<p className='text-sm text-gray-600'>
|
|
||||||
Erases all schedules and courses you have.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<Button variant='outline' color='theme-red' icon={Trash} onClick={handleEraseAll}>
|
|
||||||
Erase All
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{DISPLAY_PREVIEWS && (
|
|
||||||
<Preview>
|
|
||||||
<Text
|
|
||||||
variant='h2-course'
|
|
||||||
className={clsx('text-center text-theme-red !font-normal', {
|
|
||||||
'line-through': highlightConflicts,
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
01234 MWF 10:00 AM - 11:00 AM UTC 1.234
|
|
||||||
</Text>
|
|
||||||
</Preview>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<Divider size='auto' orientation='horizontal' />
|
<Divider size='auto' orientation='horizontal' />
|
||||||
|
|
||||||
@@ -593,17 +322,21 @@ export default function Settings(): JSX.Element {
|
|||||||
Open Debug Page
|
Open Debug Page
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<Divider size='auto' orientation='horizontal' />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
variant='filled'
|
||||||
|
color='ut-black'
|
||||||
|
onClick={() => addCourseByURL(activeSchedule)}
|
||||||
|
>
|
||||||
|
Add course by link
|
||||||
|
</Button>
|
||||||
|
<Button variant='filled' color='ut-burntorange' onClick={showMigrationDialog}>
|
||||||
|
Show Migration Dialog
|
||||||
|
</Button>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Divider size='auto' orientation='horizontal' />
|
|
||||||
|
|
||||||
<Button variant='filled' color='ut-black' onClick={() => addCourseByURL(activeSchedule)}>
|
|
||||||
Add course by link
|
|
||||||
</Button>
|
|
||||||
<Button variant='filled' color='ut-burntorange' onClick={showMigrationDialog}>
|
|
||||||
Show Migration Dialog
|
|
||||||
</Button>
|
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -616,144 +349,44 @@ export default function Settings(): JSX.Element {
|
|||||||
</h2>
|
</h2>
|
||||||
<div className='grid grid-cols-2 gap-4 2xl:grid-cols-4 md:grid-cols-3'>
|
<div className='grid grid-cols-2 gap-4 2xl:grid-cols-4 md:grid-cols-3'>
|
||||||
{LONGHORN_DEVELOPERS_ADMINS.map(admin => (
|
{LONGHORN_DEVELOPERS_ADMINS.map(admin => (
|
||||||
<div
|
<ContributorCard
|
||||||
key={admin.githubUsername}
|
key={admin.githubUsername}
|
||||||
className='border border-gray-300 rounded bg-ut-gray/10 p-4'
|
name={admin.name}
|
||||||
>
|
githubUsername={admin.githubUsername}
|
||||||
<Text
|
roles={admin.role}
|
||||||
variant='p'
|
stats={githubStats?.adminGitHubStats[admin.githubUsername]}
|
||||||
className='text-ut-burntorange font-semibold hover:cursor-pointer'
|
showStats={showGitHubStats}
|
||||||
onClick={() =>
|
includeMergedPRs={INCLUDE_MERGED_PRS}
|
||||||
window.open(`https://github.com/${admin.githubUsername}`, '_blank')
|
/>
|
||||||
}
|
|
||||||
>
|
|
||||||
{admin.name}
|
|
||||||
</Text>
|
|
||||||
{admin.role.map(role => (
|
|
||||||
<p key={admin.githubUsername} className='text-sm text-gray-600'>
|
|
||||||
{role}
|
|
||||||
</p>
|
|
||||||
))}
|
|
||||||
{showGitHubStats && githubStats && (
|
|
||||||
<div className='mt-2'>
|
|
||||||
<p className='text-xs text-gray-500'>GitHub Stats (UTRP repo):</p>
|
|
||||||
{includeMergedPRs && (
|
|
||||||
<p className='text-xs'>
|
|
||||||
Merged PRS:{' '}
|
|
||||||
{githubStats.adminGitHubStats[admin.githubUsername]?.mergedPRs}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
<p className='text-xs'>
|
|
||||||
Commits: {githubStats.adminGitHubStats[admin.githubUsername]?.commits}
|
|
||||||
</p>
|
|
||||||
<p className='text-xs text-ut-green'>
|
|
||||||
{githubStats.adminGitHubStats[admin.githubUsername]?.linesAdded} ++
|
|
||||||
</p>
|
|
||||||
<p className='text-xs text-theme-red'>
|
|
||||||
{githubStats.adminGitHubStats[admin.githubUsername]?.linesDeleted} --
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section className='my-8'>
|
<section className='my-8'>
|
||||||
<h2 className='mb-4 text-xl text-ut-black font-semibold'>UTRP CONTRIBUTORS</h2>
|
<h2 className='mb-4 text-xl text-ut-black font-semibold'>UTRP CONTRIBUTORS</h2>
|
||||||
<div className='grid grid-cols-2 gap-4 2xl:grid-cols-4 md:grid-cols-3 xl:grid-cols-3'>
|
<div className='grid grid-cols-2 gap-4 2xl:grid-cols-4 md:grid-cols-3 xl:grid-cols-3'>
|
||||||
{LONGHORN_DEVELOPERS_SWE.sort(
|
{sortedContributors.map(swe => (
|
||||||
(a, b) =>
|
<ContributorCard
|
||||||
(githubStats?.userGitHubStats[b.githubUsername]?.commits ?? 0) -
|
|
||||||
(githubStats?.userGitHubStats[a.githubUsername]?.commits ?? 0)
|
|
||||||
).map(swe => (
|
|
||||||
<div
|
|
||||||
key={swe.githubUsername}
|
key={swe.githubUsername}
|
||||||
className='border border-gray-300 rounded bg-ut-gray/10 p-4'
|
name={swe.name}
|
||||||
>
|
githubUsername={swe.githubUsername}
|
||||||
<Text
|
roles={swe.role}
|
||||||
variant='p'
|
stats={githubStats?.userGitHubStats[swe.githubUsername]}
|
||||||
className='text-ut-burntorange font-semibold hover:cursor-pointer'
|
showStats={showGitHubStats}
|
||||||
onClick={() =>
|
includeMergedPRs={INCLUDE_MERGED_PRS}
|
||||||
window.open(`https://github.com/${swe.githubUsername}`, '_blank')
|
/>
|
||||||
}
|
))}
|
||||||
>
|
{additionalContributors.map(username => (
|
||||||
{swe.name}
|
<ContributorCard
|
||||||
</Text>
|
key={username}
|
||||||
{swe.role.map(role => (
|
name={githubStats!.names[username] || username}
|
||||||
<p key={swe.githubUsername} className='text-sm text-gray-600'>
|
githubUsername={username}
|
||||||
{role}
|
roles={['Contributor']}
|
||||||
</p>
|
stats={githubStats!.userGitHubStats[username]}
|
||||||
))}
|
showStats={showGitHubStats}
|
||||||
{showGitHubStats && githubStats && (
|
includeMergedPRs={INCLUDE_MERGED_PRS}
|
||||||
<div className='mt-2'>
|
/>
|
||||||
<p className='text-xs text-gray-500'>GitHub Stats (UTRP repo):</p>
|
|
||||||
{includeMergedPRs && (
|
|
||||||
<p className='text-xs'>
|
|
||||||
Merged PRS:{' '}
|
|
||||||
{githubStats.userGitHubStats[swe.githubUsername]?.mergedPRs}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
<p className='text-xs'>
|
|
||||||
Commits: {githubStats.userGitHubStats[swe.githubUsername]?.commits}
|
|
||||||
</p>
|
|
||||||
<p className='text-xs text-ut-green'>
|
|
||||||
{githubStats.userGitHubStats[swe.githubUsername]?.linesAdded} ++
|
|
||||||
</p>
|
|
||||||
<p className='text-xs text-theme-red'>
|
|
||||||
{githubStats.userGitHubStats[swe.githubUsername]?.linesDeleted} --
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
))}
|
))}
|
||||||
{githubStats &&
|
|
||||||
Object.keys(githubStats.userGitHubStats)
|
|
||||||
.filter(
|
|
||||||
username =>
|
|
||||||
!LONGHORN_DEVELOPERS_ADMINS.some(
|
|
||||||
admin => admin.githubUsername === username
|
|
||||||
) && !LONGHORN_DEVELOPERS_SWE.some(swe => swe.githubUsername === username)
|
|
||||||
)
|
|
||||||
.sort(
|
|
||||||
(a, b) =>
|
|
||||||
(githubStats.userGitHubStats[b]?.commits ?? 0) -
|
|
||||||
(githubStats.userGitHubStats[a]?.commits ?? 0)
|
|
||||||
)
|
|
||||||
.map(username => (
|
|
||||||
<div
|
|
||||||
key={username}
|
|
||||||
className='overflow-clip border border-gray-300 rounded bg-ut-gray/10 p-4'
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
variant='p'
|
|
||||||
className='text-ut-burntorange font-semibold hover:cursor-pointer'
|
|
||||||
onClick={() => window.open(`https://github.com/${username}`, '_blank')}
|
|
||||||
>
|
|
||||||
{githubStats.names[username]}
|
|
||||||
</Text>
|
|
||||||
<p className='text-sm text-gray-600'>Contributor</p>
|
|
||||||
{showGitHubStats && (
|
|
||||||
<div className='mt-2'>
|
|
||||||
<p className='text-xs text-gray-500'>GitHub Stats (UTRP repo):</p>
|
|
||||||
{includeMergedPRs && (
|
|
||||||
<p className='text-xs'>
|
|
||||||
Merged PRs:{' '}
|
|
||||||
{githubStats.userGitHubStats[username]?.mergedPRs}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
<p className='text-xs'>
|
|
||||||
Commits: {githubStats.userGitHubStats[username]?.commits}
|
|
||||||
</p>
|
|
||||||
<p className='text-xs text-ut-green'>
|
|
||||||
{githubStats.userGitHubStats[username]?.linesAdded} ++
|
|
||||||
</p>
|
|
||||||
<p className='text-xs text-theme-red'>
|
|
||||||
{githubStats.userGitHubStats[username]?.linesDeleted} --
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
13
src/views/components/settings/constants.ts
Normal file
13
src/views/components/settings/constants.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
export const DISPLAY_PREVIEWS = false;
|
||||||
|
export const PREVIEW_SECTION_DIV_CLASSNAME = DISPLAY_PREVIEWS ? 'w-1/2 space-y-4' : 'flex-grow space-y-4';
|
||||||
|
|
||||||
|
export const STATS_TOGGLE_KEY = 's';
|
||||||
|
export const INCLUDE_MERGED_PRS = false;
|
||||||
|
export const DEV_MODE_CLICK_TARGET = 5;
|
||||||
|
export const DEV_MODE_CLICK_TIMEOUT = 5000;
|
||||||
|
export const DEV_MODE_CLICK_INTERVAL = 500;
|
||||||
|
|
||||||
|
// LHD Birthday: January 9th, 2025
|
||||||
|
export const LHD_BIRTHDAY = { month: 0, day: 9 };
|
||||||
|
export const BIRTHDAY_CELEBRATION_DURATION = 5000;
|
||||||
|
export const BIRTHDAY_CELEBRATION_DEBOUNCE = 2000;
|
||||||
140
src/views/components/settings/useBirthdayCelebration.ts
Normal file
140
src/views/components/settings/useBirthdayCelebration.ts
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
import type { Engine, ISourceOptions } from '@tsparticles/engine';
|
||||||
|
import { initParticlesEngine } from '@tsparticles/react';
|
||||||
|
import { loadSlim } from '@tsparticles/slim';
|
||||||
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
|
|
||||||
|
import { BIRTHDAY_CELEBRATION_DEBOUNCE, BIRTHDAY_CELEBRATION_DURATION, LHD_BIRTHDAY } from './constants';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom hook for birthday celebration particles
|
||||||
|
*/
|
||||||
|
export const useBirthdayCelebration = () => {
|
||||||
|
const [showParticles, setShowParticles] = useState(false);
|
||||||
|
const [particlesInit, setParticlesInit] = useState(false);
|
||||||
|
const [lastCelebration, setLastCelebration] = useState(0);
|
||||||
|
|
||||||
|
const isBirthday = useMemo(() => {
|
||||||
|
const today = new Date();
|
||||||
|
return today.getMonth() === LHD_BIRTHDAY.month && today.getDate() === LHD_BIRTHDAY.day;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
initParticlesEngine(async (engine: Engine) => {
|
||||||
|
await loadSlim(engine);
|
||||||
|
}).then(() => {
|
||||||
|
setParticlesInit(true);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const triggerCelebration = useCallback(() => {
|
||||||
|
if (!isBirthday) return;
|
||||||
|
|
||||||
|
const now = Date.now();
|
||||||
|
// Debounce: prevent triggering again within BIRTHDAY_CELEBRATION_DEBOUNCE ms
|
||||||
|
if (now - lastCelebration < BIRTHDAY_CELEBRATION_DEBOUNCE) return;
|
||||||
|
|
||||||
|
setLastCelebration(now);
|
||||||
|
setShowParticles(true);
|
||||||
|
setTimeout(() => setShowParticles(false), BIRTHDAY_CELEBRATION_DURATION);
|
||||||
|
}, [isBirthday, lastCelebration]);
|
||||||
|
|
||||||
|
const particlesOptions: ISourceOptions = useMemo(
|
||||||
|
() => ({
|
||||||
|
fullScreen: { enable: true, zIndex: 1 },
|
||||||
|
particles: {
|
||||||
|
color: { value: ['#BF5700', '#333F48', '#FFFFFF'] }, // UT colors
|
||||||
|
move: {
|
||||||
|
direction: 'bottom',
|
||||||
|
enable: true,
|
||||||
|
outModes: {
|
||||||
|
default: 'out',
|
||||||
|
},
|
||||||
|
size: true,
|
||||||
|
speed: {
|
||||||
|
min: 1,
|
||||||
|
max: 3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
number: {
|
||||||
|
value: 500,
|
||||||
|
density: {
|
||||||
|
enable: true,
|
||||||
|
area: 800,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
opacity: {
|
||||||
|
value: 1,
|
||||||
|
animation: {
|
||||||
|
enable: false,
|
||||||
|
startValue: 'max',
|
||||||
|
destroy: 'min',
|
||||||
|
speed: 0.3,
|
||||||
|
sync: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rotate: {
|
||||||
|
value: {
|
||||||
|
min: 0,
|
||||||
|
max: 360,
|
||||||
|
},
|
||||||
|
direction: 'random',
|
||||||
|
move: true,
|
||||||
|
animation: {
|
||||||
|
enable: true,
|
||||||
|
speed: 60,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
tilt: {
|
||||||
|
direction: 'random',
|
||||||
|
enable: true,
|
||||||
|
move: true,
|
||||||
|
value: {
|
||||||
|
min: 0,
|
||||||
|
max: 360,
|
||||||
|
},
|
||||||
|
animation: {
|
||||||
|
enable: true,
|
||||||
|
speed: 60,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
shape: {
|
||||||
|
type: ['circle', 'square'],
|
||||||
|
options: {},
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
value: {
|
||||||
|
min: 2,
|
||||||
|
max: 4,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
roll: {
|
||||||
|
darken: {
|
||||||
|
enable: true,
|
||||||
|
value: 30,
|
||||||
|
},
|
||||||
|
enlighten: {
|
||||||
|
enable: true,
|
||||||
|
value: 30,
|
||||||
|
},
|
||||||
|
enable: true,
|
||||||
|
speed: {
|
||||||
|
min: 15,
|
||||||
|
max: 25,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wobble: {
|
||||||
|
distance: 30,
|
||||||
|
enable: true,
|
||||||
|
move: true,
|
||||||
|
speed: {
|
||||||
|
min: -15,
|
||||||
|
max: 15,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
return { showParticles, particlesInit, particlesOptions, triggerCelebration, isBirthday };
|
||||||
|
};
|
||||||
35
src/views/components/settings/useDevMode.ts
Normal file
35
src/views/components/settings/useDevMode.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
import { DEV_MODE_CLICK_INTERVAL, DEV_MODE_CLICK_TIMEOUT } from './constants';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom hook for enabling developer mode via rapid clicking
|
||||||
|
*/
|
||||||
|
export const useDevMode = (targetCount: number): [boolean, () => void] => {
|
||||||
|
const [count, setCount] = useState(0);
|
||||||
|
const [active, setActive] = useState(false);
|
||||||
|
const [lastClick, setLastClick] = useState(0);
|
||||||
|
|
||||||
|
const incrementCount = useCallback(() => {
|
||||||
|
const now = Date.now();
|
||||||
|
if (now - lastClick < DEV_MODE_CLICK_INTERVAL) {
|
||||||
|
setCount(prevCount => {
|
||||||
|
const newCount = prevCount + 1;
|
||||||
|
if (newCount === targetCount) {
|
||||||
|
setActive(true);
|
||||||
|
}
|
||||||
|
return newCount;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setCount(1);
|
||||||
|
}
|
||||||
|
setLastClick(now);
|
||||||
|
}, [lastClick, targetCount]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const timer = setTimeout(() => setCount(0), DEV_MODE_CLICK_TIMEOUT);
|
||||||
|
return () => clearTimeout(timer);
|
||||||
|
}, [count]);
|
||||||
|
|
||||||
|
return [active, incrementCount];
|
||||||
|
};
|
||||||
@@ -88,6 +88,31 @@ const fixManifestOptionsPage = (): Plugin => ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function getGitInfo() {
|
||||||
|
// Try environment variables first (for Nix builds)
|
||||||
|
if (process.env.VITE_GIT_BRANCH && process.env.VITE_GIT_COMMIT) {
|
||||||
|
return {
|
||||||
|
gitBranch: process.env.VITE_GIT_BRANCH,
|
||||||
|
gitCommit: process.env.VITE_GIT_COMMIT,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fall back to git commands (for local development)
|
||||||
|
try {
|
||||||
|
return {
|
||||||
|
gitBranch: execSync('git rev-parse --abbrev-ref HEAD').toString().trim(),
|
||||||
|
gitCommit: execSync('git rev-parse --short HEAD').toString().trim(),
|
||||||
|
};
|
||||||
|
} catch {
|
||||||
|
return {
|
||||||
|
gitBranch: 'unknown',
|
||||||
|
gitCommit: 'unknown',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const gitInfo = getGitInfo();
|
||||||
|
|
||||||
let config: ResolvedConfig;
|
let config: ResolvedConfig;
|
||||||
let server: ViteDevServer;
|
let server: ViteDevServer;
|
||||||
|
|
||||||
@@ -180,12 +205,14 @@ export default defineConfig({
|
|||||||
'PROD',
|
'PROD',
|
||||||
'VITE_SENTRY_ENVIRONMENT',
|
'VITE_SENTRY_ENVIRONMENT',
|
||||||
'VITE_BETA_BUILD',
|
'VITE_BETA_BUILD',
|
||||||
|
'VITE_GIT_BRANCH',
|
||||||
|
'VITE_GIT_COMMIT',
|
||||||
],
|
],
|
||||||
includeTimestamp: true,
|
includeTimestamp: true,
|
||||||
includeBuildTime: true,
|
includeBuildTime: true,
|
||||||
customMetadata: {
|
customMetadata: {
|
||||||
gitBranch: () => execSync('git rev-parse --abbrev-ref HEAD').toString().trim(),
|
gitBranch: () => gitInfo.gitBranch,
|
||||||
gitCommit: () => execSync('git rev-parse --short HEAD').toString().trim(),
|
gitCommit: () => gitInfo.gitCommit,
|
||||||
nodeVersion: () => process.version,
|
nodeVersion: () => process.version,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|||||||
Reference in New Issue
Block a user