From cdf2ab9f66f2533845973ac5373960cb5ab14a47 Mon Sep 17 00:00:00 2001 From: laryhills Date: Sun, 22 Feb 2026 14:38:23 +0100 Subject: [PATCH 1/3] chore: :lock: enforce type checks in ci --- .github/workflows/ci.yml | 49 +++++++++++++++++++++++++++++++++++++--- tsconfig.json | 5 +++- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7bd0200..53eec40 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,9 +7,25 @@ on: branches: [main, develop] jobs: - build: + type-check: runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: "npm" + + - name: Install dependencies + run: npm ci + + - name: Run Type Check + run: npm run type-check + lint: + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -25,11 +41,38 @@ jobs: - name: Run Lint run: npm run lint - - name: Run Type Check - run: npm run type-check + build: + runs-on: ubuntu-latest + needs: [type-check, lint] + steps: + - uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: "npm" + + - name: Install dependencies + run: npm ci - name: Run Build run: npm run build + test: + runs-on: ubuntu-latest + needs: [build] + steps: + - uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: "npm" + + - name: Install dependencies + run: npm ci + - name: Run Tests run: npm run test diff --git a/tsconfig.json b/tsconfig.json index c724881..5d7b55d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -28,7 +28,10 @@ "name": "next" } ], - "strictNullChecks": true + "strictNullChecks": true, + "noImplicitReturns": true, + "noUncheckedIndexedAccess": true, + "exactOptionalPropertyTypes": true }, "include": [ "next-env.d.ts", From bd067d2d228c100a976b1d5cf13351754439c09d Mon Sep 17 00:00:00 2001 From: laryhills Date: Mon, 23 Feb 2026 09:43:49 +0100 Subject: [PATCH 2/3] chore: update ESLint configuration and package dependencies; refine type definitions across components --- .eslintrc.json | 16 +- package-lock.json | 207 +++++++++++++----- package.json | 2 + src/app/api/courses/[id]/lessons/route.ts | 5 +- src/app/api/courses/[id]/route.ts | 7 +- src/app/api/lessons/[id]/progress/route.ts | 5 +- src/app/components/App.tsx | 2 +- src/app/components/auth/AnimatedButton.tsx | 10 + src/app/components/auth/AuthLayout.tsx | 1 + src/app/components/auth/FormInput.tsx | 7 +- .../components/dashboard/DashboardGrid.tsx | 8 +- .../widgets/LearningStreakWidget.tsx | 22 +- .../widgets/ProgressSummaryWidget.tsx | 8 +- .../widgets/RecentActivityWidget.tsx | 15 +- .../dashboard/widgets/RecentSalesWidget.tsx | 12 +- .../widgets/RecommendedCoursesWidget.tsx | 11 +- .../widgets/UpcomingDeadlinesWidget.tsx | 18 +- .../components/messaging/MessageComposer.tsx | 1 - .../notifications/NotificationCenter.tsx | 2 +- .../components/offline/DownloadManager.tsx | 12 +- src/app/components/offline/StorageManager.tsx | 14 +- .../components/profile/ProfileEditForm.tsx | 6 +- src/app/components/quizzes/QuestionCard.tsx | 3 +- src/app/components/quizzes/QuizContainer.tsx | 5 +- .../question-types/CodeChallengeQuestion.tsx | 7 +- .../question-types/MultipleChoiceQuestion.tsx | 5 +- .../question-types/TrueFalseQuestion.tsx | 3 +- .../social/GroupDiscussionThread.tsx | 9 +- .../social/SharedResourceLibrary.tsx | 8 +- .../__tests__/SharedResourceLibrary.test.tsx | 1 - src/app/components/video/BookmarkManager.tsx | 8 +- src/app/components/video/NotesTaker.tsx | 9 +- src/app/components/video/TranscriptView.tsx | 3 +- src/app/components/video/VideoPlayer.tsx | 8 +- src/app/context/OfflineModeContext.tsx | 2 +- src/app/courses/[courseId]/page.tsx | 8 +- src/app/dashboard/page.tsx | 3 - .../hooks/__tests__/useOfflineMode.test.tsx | 4 +- src/app/hooks/useDashboardWidgets.tsx | 6 +- src/app/hooks/useOfflineMode.tsx | 43 ++-- src/app/hooks/useSearchFilters.ts | 16 +- src/app/hooks/useVideoPlayer.tsx | 23 +- src/app/messages/page.tsx | 6 +- .../components/MobileLearningInterface.tsx | 12 +- .../components/MobileProgressTracker.tsx | 10 +- .../components/OfflineContentManager.tsx | 10 +- .../components/TouchOptimizedControls.tsx | 15 -- src/app/mobile/hooks/useAnalytics.tsx | 4 +- src/app/mobile/services/api.ts | 2 +- src/app/services/offlineSync.ts | 4 +- src/app/store/messagingStore.ts | 5 +- .../animations/TransitionManager.tsx | 2 +- .../errors/UserFriendlyErrorDisplay.tsx | 2 + .../i18n/InternationalizationEngine.tsx | 4 +- src/eslint.config.mjs | 14 ++ .../examples/configuration-parser-example.ts | 2 +- .../state/form-state-manager.ts | 2 +- src/form-management/types/core.ts | 14 +- src/form-management/types/interfaces.ts | 6 +- .../utils/configuration-parser.test.ts | 2 +- .../utils/configuration-parser.ts | 24 +- .../validation/validation-system-example.ts | 4 +- src/hooks/useAdvancedForms.tsx | 1 + src/hooks/useErrorHandling.tsx | 1 + src/hooks/useSearchFilters.tsx | 16 +- src/locales/translationManager.ts | 1 + src/services/errorReporting.ts | 1 + src/services/offlineSync.ts | 6 +- src/store/devTools.ts | 33 +-- src/utils/animationUtils.ts | 2 +- src/utils/errorUtils.ts | 5 +- src/utils/formUtils.ts | 1 + tsconfig.json | 9 +- 73 files changed, 456 insertions(+), 329 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index e74f007..152dc55 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,6 +1,10 @@ -{ - "extends": [ - "next/core-web-vitals", - "next/typescript" - ] -} +{ + "extends": [ + "next/core-web-vitals", + "next/typescript" + ], + "rules": { + "@typescript-eslint/no-unused-vars": "off", + "@typescript-eslint/no-explicit-any": "off" + } +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 18c74de..fd92cdb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@dnd-kit/utilities": "^3.2.2", "@hello-pangea/dnd": "^18.0.1", "@hookform/resolvers": "^3.10.0", + "@monaco-editor/react": "^4.7.0", "@tiptap/extension-image": "^3.20.0", "@tiptap/extension-link": "^3.20.0", "@tiptap/extension-placeholder": "^3.20.0", @@ -28,6 +29,7 @@ "next": "15.3.1", "next-themes": "^0.4.6", "react": "^18.3.1", + "react-countdown": "^2.3.6", "react-dom": "^18.3.1", "react-hook-form": "^7.60.0", "react-hot-toast": "^2.6.0", @@ -128,7 +130,6 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", @@ -1689,7 +1690,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" }, @@ -1713,7 +1713,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" } @@ -1735,7 +1734,6 @@ "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.3.1.tgz", "integrity": "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==", "license": "MIT", - "peer": true, "dependencies": { "@dnd-kit/accessibility": "^3.1.1", "@dnd-kit/utilities": "^3.2.2", @@ -2350,6 +2348,17 @@ "@floating-ui/utils": "^0.2.10" } }, + "node_modules/@floating-ui/dom": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.5.tgz", + "integrity": "sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg==", + "license": "MIT", + "optional": true, + "dependencies": { + "@floating-ui/core": "^1.7.4", + "@floating-ui/utils": "^0.2.10" + } + }, "node_modules/@floating-ui/utils": { "version": "0.2.10", "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", @@ -2994,6 +3003,29 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@monaco-editor/loader": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.7.0.tgz", + "integrity": "sha512-gIwR1HrJrrx+vfyOhYmCZ0/JcWqG5kbfG7+d3f/C1LXk2EvzAbHSg3MQ5lO2sMlo9izoAZ04shohfKLVT6crVA==", + "license": "MIT", + "dependencies": { + "state-local": "^1.0.6" + } + }, + "node_modules/@monaco-editor/react": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.7.0.tgz", + "integrity": "sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA==", + "license": "MIT", + "dependencies": { + "@monaco-editor/loader": "^1.5.0" + }, + "peerDependencies": { + "monaco-editor": ">= 0.25.0 < 1", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/@napi-rs/wasm-runtime": { "version": "0.2.12", "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", @@ -4832,7 +4864,6 @@ "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.20.0.tgz", "integrity": "sha512-aC9aROgia/SpJqhsXFiX9TsligL8d+oeoI8W3u00WI45s0VfsqjgeKQLDLF7Tu7hC+7F02teC84SAHuup003VQ==", "license": "MIT", - "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -5068,7 +5099,6 @@ "resolved": "https://registry.npmjs.org/@tiptap/extension-list/-/extension-list-3.20.0.tgz", "integrity": "sha512-+V0/gsVWAv+7vcY0MAe6D52LYTIicMSHw00wz3ISZgprSb2yQhJ4+4gurOnUrQ4Du3AnRQvxPROaofwxIQ66WQ==", "license": "MIT", - "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -5200,7 +5230,6 @@ "resolved": "https://registry.npmjs.org/@tiptap/extensions/-/extensions-3.20.0.tgz", "integrity": "sha512-HIsXX942w3nbxEQBlMAAR/aa6qiMBEP7CsSMxaxmTIVAmW35p6yUASw6GdV1u0o3lCZjXq2OSRMTskzIqi5uLg==", "license": "MIT", - "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -5215,7 +5244,6 @@ "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-3.20.0.tgz", "integrity": "sha512-jn+2KnQZn+b+VXr8EFOJKsnjVNaA4diAEr6FOazupMt8W8ro1hfpYtZ25JL87Kao/WbMze55sd8M8BDXLUKu1A==", "license": "MIT", - "peer": true, "dependencies": { "prosemirror-changeset": "^2.3.0", "prosemirror-collab": "^1.3.1", @@ -5320,7 +5348,8 @@ "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@types/chai": { "version": "5.2.3", @@ -5408,6 +5437,7 @@ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", "license": "MIT", + "peer": true, "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -5418,6 +5448,7 @@ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", "license": "MIT", + "peer": true, "dependencies": { "@types/eslint": "*", "@types/estree": "*" @@ -5484,7 +5515,6 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.27.tgz", "integrity": "sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==", "license": "MIT", - "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.2.2" @@ -5495,7 +5525,6 @@ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", "license": "MIT", - "peer": true, "peerDependencies": { "@types/react": "^18.0.0" } @@ -5570,7 +5599,6 @@ "integrity": "sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.54.0", "@typescript-eslint/types": "8.54.0", @@ -6183,6 +6211,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "license": "MIT", + "peer": true, "dependencies": { "@webassemblyjs/helper-numbers": "1.13.2", "@webassemblyjs/helper-wasm-bytecode": "1.13.2" @@ -6192,25 +6221,29 @@ "version": "1.13.2", "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@webassemblyjs/helper-api-error": { "version": "1.13.2", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@webassemblyjs/helper-buffer": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@webassemblyjs/helper-numbers": { "version": "1.13.2", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", "license": "MIT", + "peer": true, "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.13.2", "@webassemblyjs/helper-api-error": "1.13.2", @@ -6221,13 +6254,15 @@ "version": "1.13.2", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", "license": "MIT", + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-buffer": "1.14.1", @@ -6240,6 +6275,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", "license": "MIT", + "peer": true, "dependencies": { "@xtuc/ieee754": "^1.2.0" } @@ -6249,6 +6285,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@xtuc/long": "4.2.2" } @@ -6257,13 +6294,15 @@ "version": "1.13.2", "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@webassemblyjs/wasm-edit": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "license": "MIT", + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-buffer": "1.14.1", @@ -6280,6 +6319,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", "license": "MIT", + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-wasm-bytecode": "1.13.2", @@ -6293,6 +6333,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", "license": "MIT", + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-buffer": "1.14.1", @@ -6305,6 +6346,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", "license": "MIT", + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-api-error": "1.13.2", @@ -6319,6 +6361,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "license": "MIT", + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.14.1", "@xtuc/long": "4.2.2" @@ -6328,20 +6371,21 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "peer": true }, "node_modules/@xtuc/long": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "license": "Apache-2.0" + "license": "Apache-2.0", + "peer": true }, "node_modules/acorn": { "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -6354,6 +6398,7 @@ "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=10.13.0" }, @@ -6403,6 +6448,7 @@ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", "license": "MIT", + "peer": true, "dependencies": { "ajv": "^8.0.0" }, @@ -6420,6 +6466,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -6435,7 +6482,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/ansi-regex": { "version": "5.0.1", @@ -6817,7 +6865,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -6985,6 +7032,7 @@ "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=6.0" } @@ -7138,8 +7186,7 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/d3-array": { "version": "3.2.4", @@ -7472,7 +7519,8 @@ "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/dom-helpers": { "version": "5.2.1", @@ -7484,6 +7532,16 @@ "csstype": "^3.0.2" } }, + "node_modules/dompurify": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.7.tgz", + "integrity": "sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==", + "license": "(MPL-2.0 OR Apache-2.0)", + "peer": true, + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -7844,7 +7902,6 @@ "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -8018,7 +8075,6 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -8293,6 +8349,7 @@ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.8.x" } @@ -8764,7 +8821,8 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "license": "BSD-2-Clause" + "license": "BSD-2-Clause", + "peer": true }, "node_modules/glob/node_modules/minimatch": { "version": "10.1.1", @@ -9553,6 +9611,7 @@ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "license": "MIT", + "peer": true, "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -9567,6 +9626,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "license": "MIT", + "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -9612,7 +9672,6 @@ "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "cssstyle": "^4.2.1", "data-urls": "^5.0.0", @@ -9670,7 +9729,8 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/json-schema": { "version": "0.4.0", @@ -10076,6 +10136,7 @@ "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", "license": "MIT", + "peer": true, "engines": { "node": ">=6.11.5" }, @@ -10166,6 +10227,7 @@ "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", "dev": true, "license": "MIT", + "peer": true, "bin": { "lz-string": "bin/bin.js" } @@ -10209,6 +10271,19 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/marked": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-14.0.0.tgz", + "integrity": "sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==", + "license": "MIT", + "peer": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -10228,7 +10303,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/merge2": { "version": "1.4.1", @@ -10259,6 +10335,7 @@ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "license": "MIT", + "peer": true, "engines": { "node": ">= 0.6" } @@ -10268,6 +10345,7 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "license": "MIT", + "peer": true, "dependencies": { "mime-db": "1.52.0" }, @@ -10317,6 +10395,17 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/monaco-editor": { + "version": "0.55.1", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.55.1.tgz", + "integrity": "sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A==", + "license": "MIT", + "peer": true, + "dependencies": { + "dompurify": "3.2.7", + "marked": "14.0.0" + } + }, "node_modules/motion-dom": { "version": "12.29.2", "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.29.2.tgz", @@ -10383,7 +10472,8 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/next": { "version": "15.3.1", @@ -10875,6 +10965,7 @@ "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", @@ -10890,6 +10981,7 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=10" }, @@ -11026,7 +11118,6 @@ "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.4.tgz", "integrity": "sha512-PIM7E43PBxKce8OQeezAs9j4TP+5yDpZVbuurd1h5phUxEKIu+G2a+EUZzIC5nS1mJktDJWzbqS23n1tsAf5QA==", "license": "MIT", - "peer": true, "dependencies": { "orderedmap": "^2.0.0" } @@ -11056,7 +11147,6 @@ "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.4.tgz", "integrity": "sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==", "license": "MIT", - "peer": true, "dependencies": { "prosemirror-model": "^1.0.0", "prosemirror-transform": "^1.0.0", @@ -11105,7 +11195,6 @@ "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.41.6.tgz", "integrity": "sha512-mxpcDG4hNQa/CPtzxjdlir5bJFDlm0/x5nGBbStB2BWX+XOQ9M8ekEG+ojqB5BcVu2Rc80/jssCMZzSstJuSYg==", "license": "MIT", - "peer": true, "dependencies": { "prosemirror-model": "^1.20.0", "prosemirror-state": "^1.0.0", @@ -11188,7 +11277,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -11196,12 +11284,24 @@ "node": ">=0.10.0" } }, + "node_modules/react-countdown": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/react-countdown/-/react-countdown-2.3.6.tgz", + "integrity": "sha512-ZfX6S08Hb6x6W6eCn1hMDvxPICI/T30fd+gaeVTCR/2cGZ2WJ3f26e4ImNIMX1fHkopJrUdnRpWXP13/D39+gg==", + "license": "MIT", + "dependencies": { + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": ">= 15", + "react-dom": ">= 15" + } + }, "node_modules/react-dom": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -11215,7 +11315,6 @@ "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.71.1.tgz", "integrity": "sha512-9SUJKCGKo8HUSsCO+y0CtqkqI5nNuaDqTxyqPsZPqIwudpj4rCrAz/jZV+jn57bx5gtZKOh3neQu94DXMc+w5w==", "license": "MIT", - "peer": true, "engines": { "node": ">=18.0.0" }, @@ -11273,7 +11372,8 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/react-redux": { "version": "9.2.0", @@ -11385,8 +11485,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/reflect.getprototypeof": { "version": "1.0.10", @@ -11549,7 +11648,6 @@ "integrity": "sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A==", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -11732,6 +11830,7 @@ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", "license": "MIT", + "peer": true, "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -11768,6 +11867,7 @@ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3" }, @@ -11779,7 +11879,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/semver": { "version": "7.7.3", @@ -12095,6 +12196,12 @@ "dev": true, "license": "MIT" }, + "node_modules/state-local": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz", + "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==", + "license": "MIT" + }, "node_modules/std-env": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", @@ -12516,6 +12623,7 @@ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz", "integrity": "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==", "license": "MIT", + "peer": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", @@ -12606,7 +12714,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -12840,7 +12947,6 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -13062,7 +13168,6 @@ "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", @@ -13230,6 +13335,7 @@ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", "license": "MIT", + "peer": true, "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -13253,6 +13359,7 @@ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.105.2.tgz", "integrity": "sha512-dRXm0a2qcHPUBEzVk8uph0xWSjV/xZxenQQbLwnwP7caQCYpqG1qddwlyEkIDkYn0K8tvmcrZ+bOrzoQ3HxCDw==", "license": "MIT", + "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", @@ -13301,6 +13408,7 @@ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.4.tgz", "integrity": "sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==", "license": "MIT", + "peer": true, "engines": { "node": ">=10.13.0" } @@ -13309,13 +13417,15 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/webpack/node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "license": "BSD-2-Clause", + "peer": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -13329,6 +13439,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "license": "BSD-2-Clause", + "peer": true, "engines": { "node": ">=4.0" } @@ -13652,7 +13763,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -13690,7 +13800,6 @@ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz", "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", "license": "MIT", - "peer": true, "bin": { "rollup": "dist/bin/rollup" }, diff --git a/package.json b/package.json index 88ef18c..44f94c8 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "@dnd-kit/utilities": "^3.2.2", "@hello-pangea/dnd": "^18.0.1", "@hookform/resolvers": "^3.10.0", + "@monaco-editor/react": "^4.7.0", "@tiptap/extension-image": "^3.20.0", "@tiptap/extension-link": "^3.20.0", "@tiptap/extension-placeholder": "^3.20.0", @@ -34,6 +35,7 @@ "next": "15.3.1", "next-themes": "^0.4.6", "react": "^18.3.1", + "react-countdown": "^2.3.6", "react-dom": "^18.3.1", "react-hook-form": "^7.60.0", "react-hot-toast": "^2.6.0", diff --git a/src/app/api/courses/[id]/lessons/route.ts b/src/app/api/courses/[id]/lessons/route.ts index 6e332cb..9d6d313 100644 --- a/src/app/api/courses/[id]/lessons/route.ts +++ b/src/app/api/courses/[id]/lessons/route.ts @@ -1,9 +1,10 @@ import { NextResponse } from 'next/server'; export async function GET( - request: Request, - { params }: { params: { id: string } } + _request: Request, + { params }: { params: Promise<{ id: string }> } ) { + await params; // Mock lessons data const lessons = [ { diff --git a/src/app/api/courses/[id]/route.ts b/src/app/api/courses/[id]/route.ts index 97cc6fd..18c5d16 100644 --- a/src/app/api/courses/[id]/route.ts +++ b/src/app/api/courses/[id]/route.ts @@ -1,12 +1,13 @@ import { NextResponse } from 'next/server'; export async function GET( - request: Request, - { params }: { params: { id: string } } + _request: Request, + { params }: { params: Promise<{ id: string }> } ) { + const { id } = await params; // Mock single course data const course = { - id: params.id, + id, title: 'Web3 UX Design Principles', description: 'Create intuitive interfaces for decentralized applications', instructor: 'Sarah Johnson', diff --git a/src/app/api/lessons/[id]/progress/route.ts b/src/app/api/lessons/[id]/progress/route.ts index 871005a..c3cb48a 100644 --- a/src/app/api/lessons/[id]/progress/route.ts +++ b/src/app/api/lessons/[id]/progress/route.ts @@ -2,8 +2,9 @@ import { NextResponse } from 'next/server'; export async function PATCH( request: Request, - { params }: { params: { id: string } } + { params }: { params: Promise<{ id: string }> } ) { + const { id } = await params; const body = await request.json(); // Mock progress update @@ -11,7 +12,7 @@ export async function PATCH( success: true, message: 'Lesson progress updated successfully', data: { - lessonId: params.id, + lessonId: id, completed: body.completed, updatedAt: new Date().toISOString() } diff --git a/src/app/components/App.tsx b/src/app/components/App.tsx index 36042b8..0e2b742 100644 --- a/src/app/components/App.tsx +++ b/src/app/components/App.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { DashboardGrid } from './components/dashboard/DashboardGrid'; +import { DashboardGrid } from './dashboard/DashboardGrid'; function App() { return ( diff --git a/src/app/components/auth/AnimatedButton.tsx b/src/app/components/auth/AnimatedButton.tsx index db01430..d2056d8 100644 --- a/src/app/components/auth/AnimatedButton.tsx +++ b/src/app/components/auth/AnimatedButton.tsx @@ -15,8 +15,18 @@ export const AnimatedButton = ({ children, variant = 'primary', disabled, + onDrag, + onDragStart, + onDragEnd, + onAnimationStart, + onAnimationEnd, ...props }: AnimatedButtonProps) => { + void onDrag; + void onDragStart; + void onDragEnd; + void onAnimationStart; + void onAnimationEnd; const variantStyles = { primary: 'bg-gradient-to-r from-cyan-500 to-blue-600 text-white hover:from-cyan-600 hover:to-blue-700', diff --git a/src/app/components/auth/AuthLayout.tsx b/src/app/components/auth/AuthLayout.tsx index 99e1118..4754d93 100644 --- a/src/app/components/auth/AuthLayout.tsx +++ b/src/app/components/auth/AuthLayout.tsx @@ -16,6 +16,7 @@ export const AuthLayout = ({ heroSubtitle, heroImage = '/hero-image.jpg', }: AuthLayoutProps) => { + void heroImage; // Reserved for future hero image display return (
{/* Left side - Form */} diff --git a/src/app/components/auth/FormInput.tsx b/src/app/components/auth/FormInput.tsx index 4360150..bb4ac5c 100644 --- a/src/app/components/auth/FormInput.tsx +++ b/src/app/components/auth/FormInput.tsx @@ -11,7 +11,12 @@ interface FormInputProps extends InputHTMLAttributes { } export const FormInput = forwardRef( - ({ label, error, icon, type, ...props }, ref) => { + ({ label, error, icon, type, onDrag, onDragStart, onDragEnd, onAnimationStart, onAnimationEnd, ...props }, ref) => { + void onDrag; + void onDragStart; + void onDragEnd; + void onAnimationStart; + void onAnimationEnd; const [showPassword, setShowPassword] = useState(false); const [isFocused, setIsFocused] = useState(false); diff --git a/src/app/components/dashboard/DashboardGrid.tsx b/src/app/components/dashboard/DashboardGrid.tsx index b922e90..8861dfa 100644 --- a/src/app/components/dashboard/DashboardGrid.tsx +++ b/src/app/components/dashboard/DashboardGrid.tsx @@ -35,7 +35,7 @@ interface Widget { size: 'small' | 'medium' | 'large'; position: number; isCollapsed: boolean; - settings: Record; + settings: Record; } interface DashboardGridProps { @@ -67,7 +67,7 @@ export const DashboardGrid: React.FC = ({ const [showSettings, setShowSettings] = useState(false); const [showAddWidget, setShowAddWidget] = useState(false); const [activeTab, setActiveTab] = useState('overview'); - const [dateRange, setDateRange] = useState('Last 30 days'); + const [dateRange] = useState('Last 30 days'); const sensors = useSensors( useSensor(PointerSensor), @@ -130,7 +130,7 @@ export const DashboardGrid: React.FC = ({ )); }; - const updateWidgetSettings = (widgetId: string, settings: Record) => { + const updateWidgetSettings = (widgetId: string, settings: Record) => { setWidgets(prev => prev.map(widget => widget.id === widgetId ? { ...widget, settings: { ...widget.settings, ...settings } } @@ -186,7 +186,7 @@ export const DashboardGrid: React.FC = ({ isCollapsed: widget.isCollapsed, settings: widget.settings, onToggleCollapse: () => toggleWidgetCollapse(widget.id), - onUpdateSettings: (settings: Record) => updateWidgetSettings(widget.id, settings), + onUpdateSettings: (settings: Record) => updateWidgetSettings(widget.id, settings), onRemove: () => removeWidget(widget.id), size: widget.size as 'small' | 'medium' | 'large', onChangeSize: (size: 'small' | 'medium' | 'large') => changeWidgetSize(widget.id, size), diff --git a/src/app/components/dashboard/widgets/LearningStreakWidget.tsx b/src/app/components/dashboard/widgets/LearningStreakWidget.tsx index 71248a3..cee5290 100644 --- a/src/app/components/dashboard/widgets/LearningStreakWidget.tsx +++ b/src/app/components/dashboard/widgets/LearningStreakWidget.tsx @@ -1,14 +1,14 @@ import React, { useEffect, useState } from 'react'; import { motion } from 'framer-motion'; -import { Flame, Calendar, Trophy, Target, Settings } from 'lucide-react'; +import { Flame, Trophy, Target, Settings } from 'lucide-react'; interface LearningStreakWidgetProps { id: string; title: string; isCollapsed: boolean; - settings: Record; + settings: Record; onToggleCollapse: () => void; - onUpdateSettings: (settings: Record) => void; + onUpdateSettings: (settings: Record) => void; onRemove: () => void; size: 'small' | 'medium' | 'large'; onChangeSize: (size: 'small' | 'medium' | 'large') => void; @@ -49,7 +49,7 @@ export const LearningStreakWidget: React.FC = ({ try { await new Promise((r) => setTimeout(r, 150)); if (cancelled) return; - } catch (e) { + } catch { if (!cancelled) setError('Failed to load streak data'); } finally { if (!cancelled) setIsLoading(false); @@ -137,7 +137,7 @@ export const LearningStreakWidget: React.FC = ({ = ({ initial={{ opacity: 0, scale: 0.8 }} animate={{ opacity: 1, scale: 1 }} transition={{ delay: index * 0.02 }} - className={`w-4 h-4 rounded-sm ${ - day.studied - ? day.hours >= 2 - ? 'bg-green-500' + className={`w-4 h-4 rounded-sm ${day.studied + ? day.hours >= 2 + ? 'bg-green-500' : 'bg-green-300' : 'bg-gray-200' - }`} + }`} title={`${day.date.toLocaleDateString()}: ${day.hours}h`} /> ))} @@ -241,7 +241,7 @@ export const LearningStreakWidget: React.FC = ({

Keep the fire burning!

-

You're on a great streak. Don't break it!

+

You're on a great streak. Don't break it!

diff --git a/src/app/components/dashboard/widgets/ProgressSummaryWidget.tsx b/src/app/components/dashboard/widgets/ProgressSummaryWidget.tsx index d79fb04..0a98ef5 100644 --- a/src/app/components/dashboard/widgets/ProgressSummaryWidget.tsx +++ b/src/app/components/dashboard/widgets/ProgressSummaryWidget.tsx @@ -8,9 +8,9 @@ interface ProgressSummaryWidgetProps { id: string; title: string; isCollapsed: boolean; - settings: Record; + settings: Record; onToggleCollapse: () => void; - onUpdateSettings: (settings: Record) => void; + onUpdateSettings: (settings: Record) => void; onRemove: () => void; size: 'small' | 'medium' | 'large'; onChangeSize: (size: 'small' | 'medium' | 'large') => void; @@ -118,7 +118,7 @@ export const ProgressSummaryWidget: React.FC = ({ try { await new Promise((res) => setTimeout(res, 150)); if (cancelled) return; - } catch (e: any) { + } catch { if (!cancelled) setError('Failed to load progress data'); } finally { if (!cancelled) setIsLoading(false); @@ -283,7 +283,7 @@ export const ProgressSummaryWidget: React.FC = ({ onChangeSize(e.target.value as any)} + onChange={(e) => onChangeSize(e.target.value as 'small' | 'medium' | 'large')} className="w-full px-2 py-1 border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-50" > @@ -218,6 +218,7 @@ export const RecentActivityWidget: React.FC = ({
onChangeSize(e.target.value as any)} + onChange={(e) => onChangeSize(e.target.value as 'small' | 'medium' | 'large')} className="w-full px-2 py-1 border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-50" > @@ -204,6 +203,7 @@ export const RecentSalesWidget: React.FC = ({
onChangeSize(e.target.value as any)} + onChange={(e) => onChangeSize(e.target.value as 'small' | 'medium' | 'large')} className="w-full px-2 py-1 border border-gray-300 rounded" > @@ -198,6 +198,7 @@ export const RecommendedCoursesWidget: React.FC =
onUpdateSettings({ category: e.target.value })} className="w-full px-2 py-1 border border-gray-300 rounded" @@ -233,7 +234,7 @@ export const RecommendedCoursesWidget: React.FC = {course.title}

{course.instructor}

- +
diff --git a/src/app/components/dashboard/widgets/UpcomingDeadlinesWidget.tsx b/src/app/components/dashboard/widgets/UpcomingDeadlinesWidget.tsx index 40ed0a7..e98b1a9 100644 --- a/src/app/components/dashboard/widgets/UpcomingDeadlinesWidget.tsx +++ b/src/app/components/dashboard/widgets/UpcomingDeadlinesWidget.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react'; import { motion } from 'framer-motion'; -import { Clock, Users, FileText, Settings, Calendar } from 'lucide-react'; +import { Clock, Users, FileText, Settings } from 'lucide-react'; import { format, isToday, isTomorrow, addDays } from 'date-fns'; interface ScheduleEvent { @@ -11,16 +11,16 @@ interface ScheduleEvent { subtitle: string; date: Date; type: 'qa' | 'mentoring' | 'workshop'; - icon: any; + icon: React.ComponentType<{ size?: number; className?: string }>; } interface UpcomingDeadlinesWidgetProps { id: string; title: string; isCollapsed: boolean; - settings: Record; + settings: Record; onToggleCollapse: () => void; - onUpdateSettings: (settings: Record) => void; + onUpdateSettings: (settings: Record) => void; onRemove: () => void; size: 'small' | 'medium' | 'large'; onChangeSize: (size: 'small' | 'medium' | 'large') => void; @@ -56,7 +56,7 @@ export const UpcomingDeadlinesWidget: React.FC = ( try { await new Promise((r) => setTimeout(r, 150)); if (cancelled) return; - } catch (e) { + } catch { if (!cancelled) setError('Failed to load schedule data'); } finally { if (!cancelled) setIsLoading(false); @@ -73,7 +73,7 @@ export const UpcomingDeadlinesWidget: React.FC = ( subtitle: 'Intro to Starknet Course', date: new Date(new Date().setHours(14, 0, 0, 0)), // Today, 2:00 PM type: 'qa', - icon: Clock + icon: Clock as React.ComponentType<{ size?: number; className?: string }> }, { id: '2', @@ -81,7 +81,7 @@ export const UpcomingDeadlinesWidget: React.FC = ( subtitle: 'With John Smith', date: new Date(addDays(new Date(), 1).setHours(10, 0, 0, 0)), // Tomorrow, 10:00 AM type: 'mentoring', - icon: Users + icon: Users as React.ComponentType<{ size?: number; className?: string }> }, { id: '3', @@ -89,7 +89,7 @@ export const UpcomingDeadlinesWidget: React.FC = ( subtitle: 'Smart Contract Security', date: new Date(addDays(new Date(), 3).setHours(15, 30, 0, 0)), // Fri, 15, 3:30 PM type: 'workshop', - icon: FileText + icon: FileText as React.ComponentType<{ size?: number; className?: string }> } ]; @@ -181,7 +181,7 @@ export const UpcomingDeadlinesWidget: React.FC = ( setSortBy(e.target.value as any)} + onChange={(e) => setSortBy((e.target.value as 'name' | 'size' | 'date' | 'accessed'))} className="text-xs border border-gray-300 rounded px-2 py-1" > @@ -276,7 +270,7 @@ export const StorageManager: React.FC = ({ className = '' }