From b96d91cd7c25e64db46e12e11a8ca7450c9f2538 Mon Sep 17 00:00:00 2001 From: Rotimi Best Date: Sat, 1 Nov 2025 15:49:29 +0100 Subject: [PATCH] feat: setup drizzle (#594) * chore: migration to SvelteKit 2 * stage 1: migrate to svelte 5 and fix rerendering issues * stage 2: fix more $: reactivity across dashboard * fix merge conflicts * chore: migrate code in main to svelte 5 * chore: update preventDefault * chore: simplify tsconfig and remove unused mobileMenuRef in MobileMenu.svelte * chore: enforce .ts across dashboard * rename from classroomio-com to website * stage-3: Replace carbon icon svelte with lucide icon * update lock file * chore: finish icon replacement * fix: settings and setup page multiple rerender * stage 3: More icon and rerendering fixes * feat: setup drizzle and better auth * fix: onboarding validation error showing translation key #586 (#593) * fix: onboarding validation error showing translation key #586 * fix: remove debug log for profile update errors * chore: add a clean command * fix: remove message from email verification response --- .editorconfig | 15 - .gitpod.yml | 46 - .npmrc | 2 - .prettierrc | 7 +- .vscode/settings.json | 2 +- CONTRIBUTING.md | 2 +- README.md | 18 +- apps/api/.env.example | 2 + apps/api/package.json | 4 - apps/api/src/app.ts | 6 +- apps/api/src/constants/index.ts | 2 +- apps/api/src/index.ts | 6 +- apps/api/src/middlewares/auth.ts | 2 +- apps/api/src/middlewares/rate-limiter.ts | 4 +- apps/api/src/routes/course/course.ts | 16 +- apps/api/src/routes/course/lesson.ts | 4 +- apps/api/src/routes/course/presign.ts | 14 +- apps/api/src/routes/mail.ts | 6 +- apps/api/src/services/mail.ts | 8 +- apps/api/src/types/course/index.ts | 2 +- apps/api/src/utils/certificate.ts | 4 +- apps/api/src/utils/cloudflare.ts | 2 +- apps/api/src/utils/course.ts | 4 +- apps/api/src/utils/email.ts | 2 +- apps/api/src/utils/lesson.ts | 2 +- apps/api/src/utils/openapi/index.ts | 2 +- apps/api/src/utils/redis/key-generators.ts | 2 +- apps/api/src/utils/redis/limiter.ts | 2 +- apps/api/src/utils/redis/redis.ts | 2 +- apps/api/src/utils/s3.ts | 2 +- apps/api/src/utils/supabase.ts | 2 +- apps/api/tsconfig.json | 3 +- apps/dashboard/.eslintrc.cjs | 6 - apps/dashboard/.prettierignore | 7 + apps/dashboard/eslint.config.js | 53 + apps/dashboard/package.json | 32 +- apps/dashboard/scripts/translate.cjs | 4 +- apps/dashboard/src/app.html | 49 +- apps/dashboard/src/app.postcss | 14 +- apps/dashboard/src/error.html | 5 +- apps/dashboard/src/hooks.server.ts | 9 +- .../AI/AIButton/CustomPromptBtn.svelte | 142 +- .../components/Analytics/ActivityCard.svelte | 14 +- .../Analytics/HeroProfileCard.svelte | 16 +- .../Apps/components/Notes/index.svelte | 12 - .../components/Poll/components/Avatar.svelte | 7 - .../Poll/components/CreatePollForm.svelte | 126 - .../components/Poll/components/Label.svelte | 5 - .../components/Poll/components/Poll.svelte | 215 - .../components/Poll/components/Tabs.svelte | 34 - .../Apps/components/Poll/index.svelte | 290 - .../Apps/components/Poll/service.ts | 141 - .../components/Apps/components/Poll/store.ts | 4 - .../components/Apps/components/Poll/types.ts | 69 - .../components/Apps/components/Poll/utils.ts | 31 - .../Apps/components/QandA/index.svelte | 135 - .../src/lib/components/Apps/constants.js | 8 - .../src/lib/components/Apps/index.svelte | 237 - .../src/lib/components/Apps/store.ts | 11 - .../src/lib/components/AuthUI/index.svelte | 54 +- .../src/lib/components/Avatar/index.svelte | 25 +- .../src/lib/components/Backdrop/index.svelte | 16 +- .../src/lib/components/Box/index.svelte | 13 +- .../lib/components/Buttons/Close/index.svelte | 31 +- .../src/lib/components/Buttons/Close/index.ts | 1 + .../components/Buttons/Delete/index.svelte | 10 +- .../lib/components/Buttons/Send/index.svelte | 10 +- .../components/Buttons/VisitOrgSite.svelte | 10 +- .../src/lib/components/Chip/Plan.svelte | 12 +- .../src/lib/components/Chip/Text.svelte | 16 +- .../src/lib/components/Chip/index.svelte | 10 +- .../lib/components/CodeSnippet/index.svelte | 10 +- .../lib/components/ComingSoon/index.svelte | 8 +- .../src/lib/components/Confetti/index.svelte | 14 +- .../Confetti/{store.js => store.ts} | 0 .../components/Analytics/AnalyticsCard.svelte | 28 +- .../Analytics/AnalyticsGraph.svelte | 129 +- .../Analytics/AnalyticsSkeleton.svelte | 12 +- .../components/Analytics/EmptyState.svelte | 27 +- .../components/Analytics/StudentTable.svelte | 64 +- .../Analytics/icons/ExercisesIcon.svelte | 6 +- .../Analytics/icons/LessonsIcon.svelte | 6 +- .../Analytics/icons/ProgressIcon.svelte | 6 +- .../Analytics/icons/StudentsIcon.svelte | 10 +- .../components/Ceritficate/Design.svelte | 40 +- .../Ceritficate/IssueCertificateModal.svelte | 24 +- .../components/Ceritficate/Reports.svelte | 42 +- .../LockedCertificate.svelte | 6 +- .../UnlockedCertificate.svelte | 27 +- .../Ceritficate/{mockData.js => mockData.ts} | 0 .../templates/BlueBadgePattern.svelte | 48 +- .../templates/BlueProfessionalBadge.svelte | 34 +- .../Ceritficate/templates/Plain.svelte | 30 +- .../Ceritficate/templates/Professional.svelte | 34 +- .../templates/PurpleBadgePattern.svelte | 48 +- .../templates/PurpleProfessionalBadge.svelte | 34 +- .../Lesson/ActivateSectionsModal.svelte | 12 +- .../Lesson/DeleteLessonConfirmation.svelte | 10 +- .../Lesson/Exercise/DeleteConfirmation.svelte | 5 +- .../Lesson/Exercise/EditMode.svelte | 315 +- .../Lesson/Exercise/MarkExerciseModal.svelte | 296 +- .../Lesson/Exercise/OrderModal.svelte | 39 +- .../components/Lesson/Exercise/Preview.svelte | 34 +- .../Exercise/Submissions/Individual.svelte | 37 +- .../Exercise/Submissions/Summary.svelte | 63 +- .../Lesson/Exercise/Submissions/index.svelte | 54 +- .../Lesson/Exercise/UpdateDescription.svelte | 19 +- .../Lesson/Exercise/ViewMode.svelte | 118 +- .../Exercise/{constants.js => constants.ts} | 2 - .../components/Lesson/Exercise/functions.ts | 10 +- .../components/Lesson/Exercise/index.svelte | 79 +- .../Lesson/Exercises/NewExerciseModal.svelte | 244 +- .../components/Lesson/Exercises/index.svelte | 163 +- .../components/Lesson/LessonList.svelte | 53 +- .../Lesson/LessonSectionList.svelte | 65 +- .../Lesson/LessonVersionHistory.svelte | 124 +- .../Document/AddDocumentToLesson.svelte | 76 +- .../Materials/Document/DocumentList.svelte | 95 +- .../Materials/Video/AddVideoToLesson.svelte | 22 +- .../Lesson/Materials/Video/EmbedLink.svelte | 12 +- .../Lesson/Materials/Video/Index.svelte | 22 +- .../Lesson/Materials/Video/UploadVideo.svelte | 62 +- .../Materials/Video/YoutubeVideo.svelte | 18 +- .../Lesson/Materials/Video/constants.ts | 13 +- .../Materials/components/Comments.svelte | 55 +- .../components/ComponentDocument.svelte | 68 +- .../Materials/components/ComponentNote.svelte | 31 +- .../components/ComponentSlide.svelte | 10 +- .../components/ComponentVideo.svelte | 19 +- .../components/Lesson/Materials/constants.ts | 20 +- .../components/Lesson/Materials/index.svelte | 555 +- .../components/Lesson/NewLessonModal.svelte | 18 +- .../Course/components/Lesson/functions.ts | 5 +- .../Lesson/store/{answers.js => answers.ts} | 0 .../Lesson/store/{exercise.js => exercise.ts} | 93 +- .../Course/components/Lesson/store/lessons.ts | 93 +- .../Navigation/NavExpandable.svelte | 94 +- .../components/Navigation/NavIcons.svelte | 52 +- .../Course/components/Navigation/index.svelte | 353 +- .../NewsFeed/DeleteFeedConfirmation.svelte | 24 +- .../components/NewsFeed/NewFeedModal.svelte | 54 +- .../components/NewsFeed/NewsFeedCard.svelte | 115 +- .../components/NewsFeed/NewsFeedLoader.svelte | 4 +- .../People/DeleteConfirmation.svelte | 5 +- .../components/People/InvitationModal.svelte | 158 +- .../components/People/ShareQRImage.svelte | 30 +- .../components/People/{store.js => store.ts} | 0 .../components/Settings/DragAndDrop.svelte | 12 +- .../Course/components/Settings/index.svelte | 95 +- .../Settings/{store.js => store.ts} | 0 .../components/Course/components/readme.js | 26 - .../Course/{constants.js => constants.ts} | 0 .../src/lib/components/Course/store.ts | 62 +- .../src/lib/components/Course/types.ts | 28 + .../components/CourseContainer/index.svelte | 110 +- .../lib/components/CourseContainer/index.ts | 1 + .../components/Editor/CertificateForm.svelte | 74 +- .../components/Editor/Container.svelte | 14 +- .../components/Editor/DescriptionForm.svelte | 31 +- .../components/Editor/GoalsForm.svelte | 31 +- .../components/Editor/HeaderForm.svelte | 6 +- .../components/Editor/InstructorForm.svelte | 73 +- .../components/Editor/PricingForm.svelte | 69 +- .../components/Editor/RequirementForm.svelte | 31 +- .../components/Editor/ReviewFormEditor.svelte | 43 +- .../components/Editor/ReviewsForm.svelte | 68 +- .../components/Editor/index.svelte | 89 +- ...ionObserver.js => IntersectionObserver.ts} | 0 .../components/PaymentModal.svelte | 46 +- .../components/PricingSection.svelte | 50 +- .../components/SectionsDisplay.svelte | 32 +- .../components/CourseLandingPage/index.svelte | 169 +- .../CourseLandingPage/{store.js => store.ts} | 0 .../Courses/components/Card/Loader.svelte | 6 +- .../Courses/components/Card/index.svelte | 150 +- .../components/CopyCourseModal/index.svelte | 13 +- .../Courses/components/List/Loader.svelte | 2 +- .../Courses/components/List/index.svelte | 55 +- .../components/NewCourseModal/index.svelte | 40 +- .../Courses/{constants.js => constants.ts} | 0 .../Courses/{functions.js => functions.ts} | 2 - .../src/lib/components/Courses/index.svelte | 18 +- .../src/lib/components/Dropdown/index.svelte | 36 +- .../lib/components/ErrorMessage/index.svelte | 4 +- .../lib/components/Expandable/index.svelte | 53 +- .../src/lib/components/Footer/index.svelte | 8 +- .../components/Form/AutoGrowTextField.svelte | 67 +- .../src/lib/components/Form/Checkbox.svelte | 55 +- .../src/lib/components/Form/Date.svelte | 22 +- .../src/lib/components/Form/DateTime.svelte | 25 +- .../src/lib/components/Form/RadioItem.svelte | 63 +- .../src/lib/components/Form/Select.svelte | 39 +- .../src/lib/components/Form/TextArea.svelte | 78 +- .../src/lib/components/Form/TextField.svelte | 94 +- .../components/HTMLRender/HTMLRender.svelte | 13 +- .../src/lib/components/HashTags/index.svelte | 8 +- .../src/lib/components/Hoverable/index.svelte | 13 +- .../lib/components/IconButton/index.svelte | 71 +- .../src/lib/components/IconButton/index.ts | 1 + .../components/Icons/AudienceEmptyIcon.svelte | 56 +- .../lib/components/Icons/AudienceIcon.svelte | 21 - .../components/Icons/CircleCheckIcon.svelte | 53 + .../lib/components/Icons/CommunityIcon.svelte | 19 - .../lib/components/Icons/CourseIcon.svelte | 21 +- .../components/Icons/CoursesEmptyIcon.svelte | 86 +- .../lib/components/Icons/EmailSentIcon.svelte | 35 +- .../src/lib/components/Icons/ErrorIcon.svelte | 281 +- .../components/Icons/ErrorIconDarkMode.svelte | 280 +- .../lib/components/Icons/ExerciseIcon.svelte | 49 +- .../components/Icons/GoogleIconColored.svelte | 8 +- .../src/lib/components/Icons/HomeIcon.svelte | 19 - .../lib/components/Icons/PasswordEye.svelte | 26 +- .../src/lib/components/Icons/QuizIcon.svelte | 13 - .../lib/components/Icons/ReviewsIcon.svelte | 17 +- .../components/Icons/SiteSettingsIcon.svelte | 15 - .../components/Icons/UserProfileIcon.svelte | 8 +- .../src/lib/components/LMS/SideBar.svelte | 154 +- .../components/LMS/components/Learning.svelte | 24 +- .../components/LMS/components/Profile.svelte | 16 +- .../components/MarkdownEditor/index.svelte | 27 +- .../lib/components/Modal/DeleteModal.svelte | 15 +- .../src/lib/components/Modal/index.svelte | 56 +- .../components/Navigation/AuthButtons.svelte | 17 +- .../components/Navigation/CustomLinks.svelte | 12 +- .../src/lib/components/Navigation/Logo.svelte | 8 +- .../components/Navigation/MobileMenu.svelte | 52 +- .../src/lib/components/Navigation/app.svelte | 64 +- .../lib/components/Navigation/index.svelte | 41 +- .../src/lib/components/Navigation/lms.svelte | 47 +- .../Org/AddOrgModal/AddOrgModal.svelte | 25 +- .../Org/Audience/AudienceList.svelte | 21 +- .../lib/components/Org/Audience/index.svelte | 25 +- .../Org/Community/DeleteModal.svelte | 22 +- .../components/Org/Community/Loader.svelte | 10 +- .../lib/components/Org/Community/index.svelte | 121 +- .../Org/LandingPage/PageHeader.svelte | 15 +- .../Org/LandingPage/PageLoader.svelte | 12 +- .../components/Org/LandingPage/index.svelte | 163 +- .../components/Org/ProfileMenu/Menu.svelte | 61 +- .../components/Org/Quiz/DeleteModal.svelte | 12 +- .../src/lib/components/Org/Quiz/Loader.svelte | 4 +- .../components/Org/Quiz/NewQuizModal.svelte | 26 +- .../Org/Quiz/Play/ConnectToPlay.svelte | 50 +- .../components/Org/Quiz/Play/Container.svelte | 26 +- .../Org/Quiz/Play/Header/Answer.svelte | 8 +- .../Org/Quiz/Play/Header/CircleContent.svelte | 14 +- .../Org/Quiz/Play/Header/Timer.svelte | 16 +- .../Org/Quiz/Play/Header/index.svelte | 12 +- .../components/Org/Quiz/Play/Podium.svelte | 2 +- .../components/Org/Quiz/Play/Preview.svelte | 79 +- .../components/Org/Quiz/Play/Question.svelte | 2 +- .../Org/Quiz/Play/Scoreboard.svelte | 2 +- .../lib/components/Org/Quiz/Play/index.svelte | 8 +- .../lib/components/Org/Quiz/QuizCard.svelte | 19 +- .../components/Org/Quiz/QuizQuestion.svelte | 45 +- .../lib/components/Org/Quiz/Quizzes.svelte | 11 +- .../components/Org/ResizeableSidebar.svelte | 80 - .../lib/components/Org/SectionTitle.svelte | 12 +- .../components/Org/Settings/Billing.svelte | 8 +- .../Org/Settings/CustomizeLms.svelte | 87 +- .../components/Org/Settings/Domains.svelte | 96 +- .../Org/Settings/Integrations.svelte | 29 +- .../Org/Settings/LandingpageSettings.svelte | 92 +- .../Org/Settings/LanguagePicker.svelte | 15 +- .../Org/Settings/OrgSettings.svelte | 102 +- .../components/Org/Settings/Profile.svelte | 32 +- .../Org/Settings/TeamMembers.svelte | 37 +- .../lib/components/Org/Settings/index.svelte | 97 +- .../src/lib/components/Org/Settings/store.ts | 83 +- .../src/lib/components/Org/SideBar.svelte | 84 +- .../Org/VerifyEmail/VerifyEmailModal.svelte | 32 +- .../components/OrgSelector/OrgSelector.svelte | 49 +- .../OrgSelector/OrgSelectorItem.svelte | 54 +- .../src/lib/components/Page/Body.svelte | 41 +- .../src/lib/components/Page/Nav.svelte | 58 +- .../src/lib/components/Page/NotFound.svelte | 17 +- .../src/lib/components/Page/Restricted.svelte | 19 +- .../lib/components/Page/Unauthorized.svelte | 8 +- .../{constants.js => constants.ts} | 9 +- .../lib/components/PrimaryButton/index.svelte | 68 +- .../Progress/PageLoadProgressBar.svelte | 172 +- .../src/lib/components/Progress/index.svelte | 14 +- .../Question/CheckboxQuestion/index.svelte | 84 +- .../src/lib/components/Question/Grade.svelte | 22 +- .../components/Question/QuestionTitle.svelte | 8 +- .../Question/RadioQuestion/index.svelte | 91 +- .../lib/components/Question/ReasonBox.svelte | 20 +- .../Question/TextareaQuestion/index.svelte | 84 +- .../components/QuestionContainer/index.svelte | 61 +- .../components/RoleBasedSecurity/index.svelte | 44 +- .../src/lib/components/Senja/Embed.svelte | 8 +- .../src/lib/components/Snackbar/index.svelte | 18 +- .../Snackbar/{store.js => store.ts} | 0 .../lib/components/TabContent/index.svelte | 7 +- .../src/lib/components/Tabs/index.svelte | 35 +- .../TextEditor/TinymceSvelte/index.svelte | 60 +- .../lib/components/TextEditor/index.svelte | 49 +- .../src/lib/components/ToolTip/index.svelte | 15 +- .../components/UnsavedChanges/index.svelte | 11 +- .../src/lib/components/Upgrade/Banner.svelte | 21 +- .../src/lib/components/Upgrade/Modal.svelte | 82 +- .../lib/components/Upgrade/PoweredBy.svelte | 14 +- .../lib/components/UploadImage/index.svelte | 104 +- .../lib/components/UploadWidget/index.svelte | 183 +- .../src/lib/components/Vote/index.svelte | 16 +- .../WelcomeModal/WelcomeModal.svelte | 21 +- .../WelcomeModal/{store.js => store.ts} | 0 apps/dashboard/src/lib/config.ts | 7 +- .../src/lib/mocks/css/002_css_selectors.ts | 3 +- .../src/lib/mocks/css/005_css_colors.ts | 3 +- .../src/lib/mocks/css/006_css_backgrounds.ts | 3 +- .../src/lib/mocks/css/007_css_borders.ts | 3 +- .../src/lib/mocks/css/009_css_padding.ts | 6 +- .../src/lib/mocks/css/010_css_dimentions.ts | 6 +- .../src/lib/mocks/css/015_css_icons.ts | 3 +- .../src/lib/mocks/css/017_css_lists.ts | 3 +- .../src/lib/mocks/css/019_css_display.ts | 9 +- .../src/lib/mocks/git/007_git_pull.ts | 3 +- .../src/lib/mocks/git/014_git_githubFork.ts | 6 +- .../src/lib/mocks/git/015_git_clone.ts | 6 +- .../src/lib/mocks/git/016_git_pullRequest.ts | 6 +- .../src/lib/mocks/git/017_git_ignore.ts | 3 +- .../dashboard/src/lib/mocks/git/018_gitSsh.ts | 6 +- .../src/lib/mocks/git/020_git_reset.ts | 3 +- .../src/lib/mocks/html/011_html_links.ts | 3 +- .../src/lib/mocks/html/012_html_images.ts | 3 +- .../src/lib/mocks/js/001_js_statements.ts | 3 +- .../src/lib/mocks/js/002_js_syntax.ts | 3 +- .../src/lib/mocks/js/003_js_comments.ts | 3 +- .../src/lib/mocks/js/013_js_events.ts | 3 +- .../src/lib/mocks/js/015_js_stringMethods.ts | 6 +- .../src/lib/mocks/js/016_stringSearch.ts | 15 +- .../lib/mocks/js/017_js_stringTemplates.ts | 12 +- .../src/lib/mocks/js/020_js_numberMethods.ts | 6 +- .../src/lib/mocks/node/002_node_httpModule.ts | 3 +- .../src/lib/mocks/node/003_node_fileSystem.ts | 6 +- .../src/lib/mocks/node/004_node_urlModule.ts | 3 +- .../src/lib/mocks/node/006_node_events.ts | 6 +- .../lib/mocks/node/007_node_uploadFiles.ts | 3 +- .../src/lib/mocks/node/008_node_email.ts | 3 +- .../lib/mocks/node/009_node_sqlDatabase.ts | 3 +- .../lib/mocks/node/011_node_sqlInsertInto.ts | 12 +- .../lib/mocks/node/012_node_sqlSelectForm.ts | 6 +- .../src/lib/mocks/node/013_node_sqlWhere.ts | 3 +- .../src/lib/mocks/node/014_node_sqlOrderBy.ts | 3 +- .../src/lib/mocks/node/018_node_sqlLimit.ts | 6 +- .../src/lib/mocks/node/019_node_sqlJoin.ts | 9 +- .../mocks/node/020_node_mongodbDatabase.ts | 6 +- apps/dashboard/src/lib/mocks/node/index.ts | 3 +- .../src/lib/mocks/php/004_php_echo.ts | 3 +- .../src/lib/mocks/php/006_php_string.ts | 6 +- .../src/lib/mocks/php/009_php_constants.ts | 3 +- .../src/lib/mocks/php/011_php_conditionals.ts | 3 +- .../src/lib/mocks/php/012_php_switch.ts | 3 +- .../src/lib/mocks/php/013_php_loops.ts | 6 +- .../src/lib/mocks/php/016_php_superGlobal.ts | 3 +- .../src/lib/mocks/php/017_php_regex.ts | 3 +- .../lib/mocks/python/002_python_comments.ts | 3 +- .../lib/mocks/python/007_python_strings.ts | 3 +- .../lib/mocks/python/015_python_whileLoops.ts | 3 +- .../lib/mocks/python/016_python_forLoops.ts | 3 +- .../lib/mocks/python/020_python_classes.ts | 3 +- .../react/002_react_es6ArrowFunctions.ts | 3 +- .../mocks/react/004_react_es6ArrayMethods.ts | 9 +- .../lib/mocks/react/007_react_es6Modules.ts | 3 +- .../react/008_react_es6TenaryOperator.ts | 6 +- .../src/lib/mocks/react/009_react_jsx.ts | 3 +- .../lib/mocks/react/010_react_components.ts | 9 +- .../mocks/react/011_react_classComponents.ts | 12 +- .../lib/mocks/react/014_react_conditionals.ts | 6 +- .../src/lib/mocks/react/015_react_lists.ts | 6 +- .../src/lib/mocks/react/016_react_forms.ts | 3 +- .../react/021_react_importingAndExporting.ts | 9 +- .../react/022_react_extractingStateLogic.ts | 15 +- .../lib/mocks/react/023_react_sharingState.ts | 6 +- .../mocks/react/024_react_updatingObjects.ts | 12 +- .../mocks/react/025_react_updatingArrays.ts | 9 +- .../lib/mocks/react/027_react_useContext.ts | 3 +- .../lib/mocks/react/028_react_useEffect.ts | 9 +- .../lib/mocks/react/029_react_useReducer.ts | 6 +- .../lib/mocks/react/031_react_useCallBack.ts | 9 +- .../src/lib/mocks/react/033_react_useMemo.ts | 9 +- apps/dashboard/src/lib/mocks/react/index.ts | 30 +- .../mocks/typescript/001_ts_simpleTypes.ts | 3 +- .../mocks/typescript/002_ts_specialTypes.ts | 6 +- .../src/lib/mocks/typescript/003_ts_arrays.ts | 6 +- .../src/lib/mocks/typescript/004_ts_tuples.ts | 6 +- .../mocks/typescript/005_ts_objectTypes.ts | 15 +- .../src/lib/mocks/typescript/006_ts_enums.ts | 3 +- .../lib/mocks/typescript/007_ts_interfaces.ts | 3 +- .../lib/mocks/typescript/008_ts_unionTypes.ts | 3 +- .../lib/mocks/typescript/009_ts_functions.ts | 15 +- .../lib/mocks/typescript/011_ts_classes.ts | 3 +- .../mocks/typescript/013_ts_utilityTypes.ts | 9 +- .../src/lib/mocks/typescript/014_ts_keyOf.ts | 3 +- .../src/lib/mocks/typescript/015_ts_null.ts | 9 +- .../typescript/016_ts_definitelyTyped.ts | 21 +- .../src/lib/mocks/typescript/index.ts | 3 +- .../src/lib/mocks/vue/004_vue_vShow.ts | 9 +- .../src/lib/mocks/vue/015_vue_templates.ts | 3 +- apps/dashboard/src/lib/mocks/vue/index.ts | 6 +- apps/dashboard/src/lib/utils/constants/app.ts | 42 +- .../{authentication.js => authentication.ts} | 0 .../lib/utils/constants/{quiz.js => quiz.ts} | 8 +- .../{reusableClass.js => reusableClass.ts} | 0 .../utils/constants/{roles.js => roles.ts} | 0 .../utils/functions/IsSubmissionEarly.spec.js | 30 - .../lib/utils/functions/{api.js => api.ts} | 0 .../lib/utils/functions/{app.js => app.ts} | 0 .../src/lib/utils/functions/appSetup.ts | 2 +- .../src/lib/utils/functions/course.spec.ts | 18 - .../src/lib/utils/functions/date.spec.ts | 36 - .../{formatDate.js => formatDate.ts} | 0 .../functions/formatYoutubeVideo.spec.ts | 46 - .../lib/utils/functions/genUniqueId.spec.js | 25 - .../{genUniqueId.js => genUniqueId.ts} | 0 .../lib/utils/functions/generateSlug.spec.js | 17 - .../{generateSlug.js => generateSlug.ts} | 0 .../lib/utils/functions/generateUUID.spec.ts | 26 - .../src/lib/utils/functions/generateUUID.ts | 6 +- .../functions/getCurrencyFormatter.spec.ts | 27 - .../src/lib/utils/functions/isObject.spec.ts | 23 - .../lib/utils/functions/isSubmissionEarly.js | 3 - .../lib/utils/functions/isSubmissionEarly.ts | 3 + .../src/lib/utils/functions/isUUID.ts | 2 +- .../src/lib/utils/functions/org.spec.ts | 60 - apps/dashboard/src/lib/utils/functions/org.ts | 4 +- .../utils/functions/removeDuplicate.spec.js | 38 - ...{removeDuplicate.js => removeDuplicate.ts} | 0 .../{isPublicRoute.js => isPublicRoute.ts} | 0 .../utils/functions/showAppsSideBar.spec.js | 26 - ...{showAppsSideBar.js => showAppsSideBar.ts} | 0 .../src/lib/utils/functions/string.spec.ts | 28 - .../lib/utils/functions/supabase.server.ts | 16 +- .../src/lib/utils/functions/svelte.ts | 29 + .../lib/utils/functions/tinymce/plugins.ts | 14 +- .../src/lib/utils/functions/translations.ts | 11 +- .../lib/utils/functions/validateEmail.spec.js | 28 - .../{validateEmail.js => validateEmail.ts} | 0 .../src/lib/utils/functions/validator.ts | 244 +- .../src/lib/utils/services/api/index.ts | 32 +- .../src/lib/utils/services/api/utils.ts | 19 +- .../attendance/{index.js => index.ts} | 0 .../src/lib/utils/services/courses/index.ts | 50 +- .../src/lib/utils/services/courses/presign.ts | 9 +- .../src/lib/utils/services/lms/exercises.ts | 5 +- .../services/marks/{index.js => index.ts} | 0 .../src/lib/utils/services/newsfeed/index.ts | 18 +- .../services/notification/notification.ts | 3 +- .../src/lib/utils/services/org/domain.ts | 14 +- .../src/lib/utils/services/org/index.ts | 5 +- .../utils/services/org/{quiz.js => quiz.ts} | 0 .../src/lib/utils/services/posthog/index.ts | 6 +- .../lib/utils/services/submissions/index.ts | 12 +- apps/dashboard/src/lib/utils/store/org.ts | 2 +- .../store/{useMobile.js => useMobile.ts} | 0 apps/dashboard/src/lib/utils/store/user.ts | 2 +- .../src/lib/utils/translations/da.json | 3 +- .../src/lib/utils/translations/de.json | 3 +- .../src/lib/utils/translations/en.json | 1 + .../src/lib/utils/translations/es.json | 3 +- .../src/lib/utils/translations/fr.json | 3 +- .../src/lib/utils/translations/hi.json | 3 +- .../src/lib/utils/translations/pl.json | 3 +- .../src/lib/utils/translations/pt.json | 3 +- .../src/lib/utils/translations/ru.json | 3 +- .../src/lib/utils/translations/vi.json | 3 +- apps/dashboard/src/lib/utils/types/dom.ts | 5 + apps/dashboard/src/lib/utils/types/index.ts | 5 +- apps/dashboard/src/lib/utils/types/org.ts | 80 +- apps/dashboard/src/mail/sendEmail.ts | 5 +- apps/dashboard/src/routes/+error.svelte | 31 +- apps/dashboard/src/routes/+layout.server.ts | 8 +- apps/dashboard/src/routes/+layout.svelte | 32 +- apps/dashboard/src/routes/+page.svelte | 41 +- apps/dashboard/src/routes/404/+page.svelte | 6 +- .../routes/api/analytics/course/+server.ts | 36 +- .../src/routes/api/analytics/user/+server.ts | 36 +- .../api/completion/gradingprompt/+server.ts | 3 +- .../src/routes/api/domain/+server.ts | 11 +- .../api/email/course/newsfeed/+server.ts | 7 +- .../course/student_prove_payment/+server.ts | 9 +- .../teacher_student_buycourse/+server.ts | 8 +- .../src/routes/api/email/invite/+server.ts | 5 +- .../routes/api/email/verify_email/+server.ts | 7 +- .../src/routes/api/polar/webhook/+server.ts | 7 +- .../src/routes/api/unsplash/+server.ts | 5 +- .../api/verify/{+server.js => +server.ts} | 4 +- .../src/routes/course/[slug]/+page.svelte | 14 +- .../src/routes/courses/[id]/+layout.svelte | 33 +- .../src/routes/courses/[id]/+page.svelte | 79 +- .../courses/[id]/{+page.js => +page.ts} | 0 .../courses/[id]/analytics/+page.svelte | 18 +- .../courses/[id]/attendance/+page.svelte | 57 +- .../[id]/attendance/{+page.js => +page.ts} | 0 .../courses/[id]/certificates/+page.svelte | 28 +- .../[id]/certificates/{+page.js => +page.ts} | 0 .../courses/[id]/landingpage/+page.svelte | 39 +- .../[id]/landingpage/{+page.js => +page.ts} | 0 .../routes/courses/[id]/lessons/+page.svelte | 88 +- .../[id]/lessons/{+page.js => +page.ts} | 0 .../{+page.server.js => +page.server.ts} | 2 +- .../lessons/[...lessonParams]/+page.svelte | 278 +- .../routes/courses/[id]/marks/+page.svelte | 72 +- .../courses/[id]/marks/{+page.js => +page.ts} | 0 .../routes/courses/[id]/people/+layout.svelte | 34 +- .../routes/courses/[id]/people/+page.svelte | 57 +- .../[id]/people/{+page.js => +page.ts} | 0 .../[id]/people/[personId]/+page.svelte | 66 +- .../routes/courses/[id]/settings/+page.svelte | 8 +- .../[id]/settings/{+page.js => +page.ts} | 0 .../courses/[id]/submissions/+page.svelte | 85 +- .../[id]/submissions/{+page.js => +page.ts} | 0 apps/dashboard/src/routes/forgot/+page.svelte | 37 +- .../routes/invite/s/[hash]/+layout.server.ts | 2 +- .../src/routes/invite/s/[hash]/+page.svelte | 20 +- .../routes/invite/t/[hash]/+layout.server.ts | 2 +- .../src/routes/invite/t/[hash]/+page.svelte | 53 +- apps/dashboard/src/routes/lms/+layout.svelte | 13 +- apps/dashboard/src/routes/lms/+page.svelte | 54 +- .../src/routes/lms/community/+page.svelte | 8 +- .../routes/lms/community/[slug]/+page.svelte | 143 +- .../community/[slug]/{+page.js => +page.ts} | 0 .../src/routes/lms/community/ask/+page.svelte | 39 +- .../src/routes/lms/exercises/+page.svelte | 57 +- .../src/routes/lms/explore/+page.svelte | 77 +- .../src/routes/lms/mylearning/+page.svelte | 87 +- .../src/routes/lms/settings/+page.svelte | 21 +- apps/dashboard/src/routes/login/+page.svelte | 10 +- apps/dashboard/src/routes/logout/+page.svelte | 2 +- .../src/routes/onboarding/+page.svelte | 87 +- .../src/routes/org/[slug]/+layout.svelte | 26 +- .../src/routes/org/[slug]/+page.svelte | 70 +- .../routes/org/[slug]/{+page.js => +page.ts} | 0 .../routes/org/[slug]/audience/+page.svelte | 19 +- .../[slug]/audience/[...params]/+page.svelte | 57 +- .../routes/org/[slug]/community/+page.svelte | 18 +- .../org/[slug]/community/[slug]/+page.svelte | 130 +- .../community/[slug]/{+page.js => +page.ts} | 0 .../org/[slug]/community/ask/+page.svelte | 34 +- .../routes/org/[slug]/courses/+page.svelte | 52 +- .../org/[slug]/courses/{+page.js => +page.ts} | 0 .../src/routes/org/[slug]/quiz/+page.svelte | 12 +- .../org/[slug]/quiz/[slug]/+page.svelte | 85 +- .../[slug]/quiz/[slug]/{+page.js => +page.ts} | 0 .../routes/org/[slug]/settings/+page.svelte | 8 +- .../settings/customize-lms/+page.svelte | 10 +- .../org/[slug]/settings/domains/+page.svelte | 10 +- .../org/[slug]/settings/teams/+page.svelte | 10 +- .../src/routes/org/[slug]/setup/+page.svelte | 49 +- .../src/routes/org/[slug]/setup/+page.ts | 10 +- .../src/routes/profile/[id]/+page.js | 5 - .../src/routes/profile/[id]/+page.svelte | 214 - apps/dashboard/src/routes/reset/+page.svelte | 48 +- apps/dashboard/src/routes/signup/+page.svelte | 35 +- apps/dashboard/svelte.config.js | 2 +- apps/dashboard/tsconfig.json | 8 +- apps/docs/pages/contributor-guides/_meta.json | 1 - apps/docs/pages/contributor-guides/gitpod.mdx | 28 - .../{classroomio-com => website}/.env.example | 0 apps/{classroomio-com => website}/.gitignore | 0 apps/{classroomio-com => website}/.npmrc | 0 apps/{classroomio-com => website}/.nvmrc | 0 apps/{classroomio-com => website}/.prettierrc | 0 apps/{classroomio-com => website}/README.md | 0 .../jsconfig.json | 0 .../{classroomio-com => website}/package.json | 4 +- .../postcss.config.js | 0 apps/{classroomio-com => website}/src/app.css | 0 .../{classroomio-com => website}/src/app.d.ts | 0 .../{classroomio-com => website}/src/app.html | 0 .../src/blog/brand-customisations.md | 0 ...assroomio-at-eduai-conference-at-unilag.md | 0 .../src/blog/custom-domain.md | 0 .../src/blog/free-tools.md | 0 .../src/blog/google-open-source-peer-bonus.md | 0 .../src/blog/launch-week-001.md | 0 .../src/blog/learn-from-the-best.md | 0 .../src/blog/multi-language.md | 0 .../src/blog/pranav-hits-100-students.md | 0 .../src/blog/self-host.md | 0 .../src/blog/students-analytics.md | 0 .../src/blog/teach-with-data.md | 0 .../src/lib/Blog/BlogListItem.svelte | 0 .../src/lib/Button/Button.svelte | 0 .../src/lib/Chip/Chip.svelte | 0 .../src/lib/Contact/FeedbackForm.svelte | 0 .../src/lib/Contact/HelpForm.svelte | 0 .../src/lib/Contact/Sucess.svelte | 0 .../src/lib/Footer/Footer.svelte | 0 .../src/lib/Home/CoreFeatureSection.svelte | 0 .../src/lib/Home/CoreFeatures.svelte | 0 .../src/lib/Home/Faq.svelte | 0 .../src/lib/Home/Hero.svelte | 0 .../src/lib/Home/MoreFeatures.svelte | 0 .../src/lib/Home/StudentDashboard.svelte | 0 .../src/lib/Home/Testimonial.svelte | 0 .../src/lib/Home/faqs.js | 0 .../src/lib/Icons/CourseIcon.svelte | 0 .../src/lib/Input/TextArea.svelte | 0 .../src/lib/Input/TextField.svelte | 0 .../src/lib/Modal/Modal.svelte | 0 .../src/lib/Navigation/Navigation.svelte | 0 .../src/lib/NotFound/NotFound.svelte | 0 .../src/lib/PageHeader/PageHeader.svelte | 0 .../src/lib/PageSignupCTA/index.svelte | 0 .../src/lib/Senja/Embed.svelte | 2 +- .../src/lib/Timeline/Timeline.svelte | 0 .../src/lib/ToolsHeader/ToolsHeader.svelte | 0 .../src/lib/UploadWidget/UploadWidget.svelte | 0 .../src/lib/custom/img.svelte | 0 .../src/lib/custom/index.ts | 0 .../src/lib/emojis/crossed-fingers.svg | 0 .../src/lib/emojis/folder.svg | 0 .../src/lib/emojis/globe.svg | 0 .../src/lib/emojis/index.js | 0 .../src/lib/emojis/left-fist.svg | 0 .../src/lib/emojis/printer.svg | 0 .../src/lib/emojis/right-fist.svg | 0 .../src/lib/emojis/robot-arm.svg | 0 .../src/lib/emojis/team.svg | 0 .../src/lib/emojis/thumbs-up.svg | 0 .../src/lib/types.ts | 0 .../src/lib/utils/constants/tools.ts | 0 .../src/lib/utils/formatDate.ts | 0 .../src/lib/utils/isFormValid.ts | 0 .../src/lib/utils/posthog/index.ts | 0 .../src/lib/utils/submitForm.ts | 0 .../src/mdsvex.svelte | 0 .../routes/(marketing)/bootcamps/+page.svelte | 0 .../customer-education/+page.svelte | 0 .../employee-training/+page.svelte | 0 .../routes/(redirects)/demo/+page.server.ts | 0 .../(redirects)/devanddesign/+page.server.ts | 0 .../(redirects)/discord/+page.server.ts | 0 .../routes/(redirects)/docs/+layout.svelte | 0 .../src/routes/(redirects)/docs/+page.svelte | 0 .../routes/(redirects)/github/+page.server.ts | 0 .../routes/(redirects)/learn/+page.server.ts | 0 .../routes/(redirects)/new/+page.server.ts | 0 .../src/routes/(redirects)/ph/+page.server.ts | 0 .../(redirects)/privacy/+page.server.ts | 0 .../routes/(redirects)/signup/+page.server.ts | 0 .../routes/(redirects)/tos/+page.server.ts | 0 .../routes/(redirects)/waec/+page.server.ts | 0 .../src/routes/+layout.svelte | 0 .../src/routes/+layout.ts | 0 .../src/routes/+page.svelte | 0 .../src/routes/api/blog/+server.ts | 0 .../src/routes/api/contact/+server.ts | 0 .../src/routes/blog/+page.svelte | 0 .../src/routes/blog/+page.ts | 0 .../src/routes/blog/[slug]/+page.svelte | 0 .../src/routes/blog/[slug]/+page.ts | 0 .../src/routes/contact/+layout.ts | 0 .../src/routes/contact/+page.svelte | 0 .../src/routes/oss-friends/+page.svelte | 0 .../src/routes/oss-friends/+page.ts | 0 .../src/routes/pricing/+layout.ts | 0 .../src/routes/pricing/+page.svelte | 9 +- .../src/routes/roadmap/+page.svelte | 0 .../src/routes/teach/+layout.ts | 0 .../src/routes/teach/+page.svelte | 0 .../src/routes/teach/register/+page.server.ts | 0 .../src/routes/tools/+layout.svelte | 0 .../src/routes/tools/+layout.ts | 0 .../src/routes/tools/+page.svelte | 0 .../src/routes/tools/name-picker/+page.svelte | 0 .../src/routes/tools/pomodoro/+page.svelte | 0 .../src/routes/tools/progress/+page.svelte | 0 .../tools/progress/components/Avatar.svelte | 0 .../progress/components/Background.svelte | 0 .../progress/components/DownloadButton.svelte | 0 .../tools/progress/components/FullView.svelte | 0 .../tools/progress/components/Mood.svelte | 0 .../tools/progress/components/Report.svelte | 0 .../routes/tools/progress/components/store.ts | 0 .../src/routes/tools/stopwatch/+page.svelte | 0 .../tools/stopwatch/components/Timer.svelte | 0 .../src/routes/tools/tic-tac-toe/+page.svelte | 0 .../tools/tic-tac-toe/components/Board.svelte | 0 .../tic-tac-toe/components/WinningLine.svelte | 0 .../tools/tic-tac-toe/components/board.ts | 0 .../tools/tic-tac-toe/components/store.ts | 0 .../src/routes/transition.svelte | 0 ...ytics-classroom-by-dalle3-classroomio.jpeg | Bin .../static/blog/best.jpg | Bin .../blog/google-os-peer-bonus-classroomio.png | Bin ...os-peer-bonus-award-letter-classroomio.jpg | Bin .../static/cio-hero.webp | Bin .../static/classroomio-courses.png | Bin .../static/classroomio-opengraph-image.png | Bin .../classroomio-opengraph-image_launch.png | Bin .../static/discord-blue.png | Bin .../static/download-pdf.png | Bin .../static/favicon.ico | Bin .../static/free-tools/activity-stopwatch.svg | 0 .../static/free-tools/jamb.svg | 0 .../static/free-tools/name-picker.svg | 0 .../static/free-tools/pomodoro.svg | 0 .../static/free-tools/pomodoro/add-icon.svg | 0 .../static/free-tools/pomodoro/done-icon.svg | 0 .../free-tools/pomodoro/list-play-icon.svg | 0 .../static/free-tools/pomodoro/menu-icon.svg | 0 .../static/free-tools/pomodoro/pause-icon.svg | 0 .../static/free-tools/pomodoro/pen-icon.svg | 0 .../free-tools/pomodoro/restart-icon.svg | 0 .../free-tools/pomodoro/settings-icon.svg | 0 .../free-tools/pomodoro/timer-play-icon.svg | 0 .../static/free-tools/progress-report.svg | 0 .../free-tools/progress-report/close-icon.svg | 0 .../progress-report/full-screen-icon.svg | 0 .../free-tools/progress-report/hide-icon.svg | 0 .../progress-report/hover-plus-icon.svg | 0 .../progress-report/preview-icon.svg | 0 .../progress-report/question-mark.svg | 0 .../progress-report/smiley-face-icon.svg | 0 .../free-tools/stopwatch/loading-timer.svg | 0 .../free-tools/stopwatch/no-speaker-icon.svg | 0 .../free-tools/stopwatch/pause-icon.svg | 0 .../static/free-tools/stopwatch/play-icon.svg | 0 .../free-tools/stopwatch/reset-icon.svg | 0 .../free-tools/stopwatch/speaker-icon.svg | 0 .../static/free-tools/tic-tac.svg | 0 .../free-tools/tic-tac/computer-icon.svg | 0 .../free-tools/tic-tac/restart-icon.svg | 0 .../static/free-tools/tic-tac/tic-tac-bg.svg | 0 .../static/free-tools/tic-tac/tic-tac-o.svg | 0 .../free-tools/tic-tac/tic-tac-start-icon.svg | 0 .../static/free-tools/tic-tac/tic-tac-x.svg | 0 .../free-tools/tic-tac/winner-star-icon.svg | 0 .../static/free-tools/waec.svg | 0 .../static/github-mark.png | Bin .../static/hero-1.svg | 0 .../static/hero-2.svg | 0 .../static/hero-3.svg | 0 .../static/hero-4.svg | 0 .../static/hero-5.svg | 0 .../static/hero-section.png | Bin .../static/landing-page-builder.webp | Bin .../static/logo-16.png | Bin .../static/logo-192.png | Bin .../static/logo-32.png | Bin .../static/logo-512.png | Bin .../static/manifest.json | 0 .../static/ng.png | Bin .../static/prime_twitter.svg | 0 .../static/roadmap-one.svg | 0 .../static/roadmap-two.svg | 0 .../static/robots.txt | 0 .../static/socials-avatar.png | Bin .../static/sort-icon.svg | 0 .../static/teach/get-paid.svg | 0 .../static/teach/inspire-learners.svg | 0 .../static/teach/star.svg | 0 .../static/teach/teach-from-anywhere.svg | 0 .../static/teach/teacher-banner.png | Bin .../static/teach/teacher-hero.png | Bin .../static/teach/thumbs-up.svg | 0 .../static/teach/user-profile.png | Bin .../static/team-management.png | Bin .../static/twitter.svg | 0 .../static/twitter_logo.png | Bin .../static/unsort-icon.svg | 0 .../static/video-transcription.png | Bin .../svelte.config.js | 0 .../tailwind.config.js | 0 .../vite.config.js | 0 cypress.config.js | 10 - docker/Dockerfile.api | 2 +- docker/Dockerfile.dashboard | 2 +- package.json | 13 +- packages/db/drizzle.config.ts | 12 + packages/db/existingAccounts.json | 1 + packages/db/package.json | 24 + packages/db/src/auth-schema.ts | 67 + packages/db/src/auth.ts | 25 + packages/db/src/drizzle.ts | 60 + .../db/src/migrations/0000_stale_storm.sql | 644 +++ .../migrations/0001_tranquil_thunderbolts.sql | 47 + .../db/src/migrations/meta/0000_snapshot.json | 4588 ++++++++++++++++ .../db/src/migrations/meta/0001_snapshot.json | 4881 +++++++++++++++++ packages/db/src/migrations/meta/_journal.json | 20 + packages/db/src/relations.ts | 424 ++ packages/db/src/schema.ts | 1439 +++++ .../db/src/scripts/supabase-to-betterauth.ts | 173 + packages/db/tsconfig.json | 11 + packages/db/users.json | 155 + packages/shared/package.json | 7 - packages/shared/tsconfig.json | 3 - packages/tsconfig/package.json | 2 +- packages/utils/package.json | 11 + .../{shared => utils}/src/plans/constants.ts | 0 .../{shared => utils}/src/plans/data.json | 0 packages/utils/src/plans/index.ts | 6 + packages/{shared => utils}/src/plans/types.ts | 0 packages/{shared => utils}/src/plans/utils.ts | 0 packages/{shared => utils}/src/senja/index.ts | 0 packages/utils/tsconfig.json | 6 + pnpm-lock.yaml | 2338 ++++++-- pnpm-workspace.yaml | 3 + 801 files changed, 22279 insertions(+), 10834 deletions(-) delete mode 100644 .editorconfig delete mode 100644 .gitpod.yml delete mode 100644 .npmrc delete mode 100644 apps/dashboard/.eslintrc.cjs create mode 100644 apps/dashboard/.prettierignore create mode 100644 apps/dashboard/eslint.config.js delete mode 100644 apps/dashboard/src/lib/components/Apps/components/Notes/index.svelte delete mode 100644 apps/dashboard/src/lib/components/Apps/components/Poll/components/Avatar.svelte delete mode 100644 apps/dashboard/src/lib/components/Apps/components/Poll/components/CreatePollForm.svelte delete mode 100644 apps/dashboard/src/lib/components/Apps/components/Poll/components/Label.svelte delete mode 100644 apps/dashboard/src/lib/components/Apps/components/Poll/components/Poll.svelte delete mode 100644 apps/dashboard/src/lib/components/Apps/components/Poll/components/Tabs.svelte delete mode 100644 apps/dashboard/src/lib/components/Apps/components/Poll/index.svelte delete mode 100644 apps/dashboard/src/lib/components/Apps/components/Poll/service.ts delete mode 100644 apps/dashboard/src/lib/components/Apps/components/Poll/store.ts delete mode 100644 apps/dashboard/src/lib/components/Apps/components/Poll/types.ts delete mode 100644 apps/dashboard/src/lib/components/Apps/components/Poll/utils.ts delete mode 100644 apps/dashboard/src/lib/components/Apps/components/QandA/index.svelte delete mode 100644 apps/dashboard/src/lib/components/Apps/constants.js delete mode 100644 apps/dashboard/src/lib/components/Apps/index.svelte delete mode 100644 apps/dashboard/src/lib/components/Apps/store.ts create mode 100644 apps/dashboard/src/lib/components/Buttons/Close/index.ts rename apps/dashboard/src/lib/components/Confetti/{store.js => store.ts} (100%) rename apps/dashboard/src/lib/components/Course/components/Ceritficate/{mockData.js => mockData.ts} (100%) rename apps/dashboard/src/lib/components/Course/components/Lesson/Exercise/{constants.js => constants.ts} (56%) rename apps/dashboard/src/lib/components/Course/components/Lesson/store/{answers.js => answers.ts} (100%) rename apps/dashboard/src/lib/components/Course/components/Lesson/store/{exercise.js => exercise.ts} (72%) rename apps/dashboard/src/lib/components/Course/components/People/{store.js => store.ts} (100%) rename apps/dashboard/src/lib/components/Course/components/Settings/{store.js => store.ts} (100%) delete mode 100644 apps/dashboard/src/lib/components/Course/components/readme.js rename apps/dashboard/src/lib/components/Course/{constants.js => constants.ts} (100%) create mode 100644 apps/dashboard/src/lib/components/Course/types.ts create mode 100644 apps/dashboard/src/lib/components/CourseContainer/index.ts rename apps/dashboard/src/lib/components/CourseLandingPage/components/{IntersectionObserver.js => IntersectionObserver.ts} (100%) rename apps/dashboard/src/lib/components/CourseLandingPage/{store.js => store.ts} (100%) rename apps/dashboard/src/lib/components/Courses/{constants.js => constants.ts} (100%) rename apps/dashboard/src/lib/components/Courses/{functions.js => functions.ts} (85%) create mode 100644 apps/dashboard/src/lib/components/IconButton/index.ts delete mode 100644 apps/dashboard/src/lib/components/Icons/AudienceIcon.svelte create mode 100644 apps/dashboard/src/lib/components/Icons/CircleCheckIcon.svelte delete mode 100644 apps/dashboard/src/lib/components/Icons/CommunityIcon.svelte delete mode 100644 apps/dashboard/src/lib/components/Icons/HomeIcon.svelte delete mode 100644 apps/dashboard/src/lib/components/Icons/QuizIcon.svelte delete mode 100644 apps/dashboard/src/lib/components/Icons/SiteSettingsIcon.svelte delete mode 100644 apps/dashboard/src/lib/components/Org/ResizeableSidebar.svelte rename apps/dashboard/src/lib/components/PrimaryButton/{constants.js => constants.ts} (79%) rename apps/dashboard/src/lib/components/Snackbar/{store.js => store.ts} (100%) rename apps/dashboard/src/lib/components/WelcomeModal/{store.js => store.ts} (100%) rename apps/dashboard/src/lib/utils/constants/{authentication.js => authentication.ts} (100%) rename apps/dashboard/src/lib/utils/constants/{quiz.js => quiz.ts} (89%) rename apps/dashboard/src/lib/utils/constants/{reusableClass.js => reusableClass.ts} (100%) rename apps/dashboard/src/lib/utils/constants/{roles.js => roles.ts} (100%) delete mode 100644 apps/dashboard/src/lib/utils/functions/IsSubmissionEarly.spec.js rename apps/dashboard/src/lib/utils/functions/{api.js => api.ts} (100%) rename apps/dashboard/src/lib/utils/functions/{app.js => app.ts} (100%) delete mode 100644 apps/dashboard/src/lib/utils/functions/course.spec.ts delete mode 100644 apps/dashboard/src/lib/utils/functions/date.spec.ts rename apps/dashboard/src/lib/utils/functions/{formatDate.js => formatDate.ts} (100%) delete mode 100644 apps/dashboard/src/lib/utils/functions/formatYoutubeVideo.spec.ts delete mode 100644 apps/dashboard/src/lib/utils/functions/genUniqueId.spec.js rename apps/dashboard/src/lib/utils/functions/{genUniqueId.js => genUniqueId.ts} (100%) delete mode 100644 apps/dashboard/src/lib/utils/functions/generateSlug.spec.js rename apps/dashboard/src/lib/utils/functions/{generateSlug.js => generateSlug.ts} (100%) delete mode 100644 apps/dashboard/src/lib/utils/functions/generateUUID.spec.ts delete mode 100644 apps/dashboard/src/lib/utils/functions/getCurrencyFormatter.spec.ts delete mode 100644 apps/dashboard/src/lib/utils/functions/isObject.spec.ts delete mode 100644 apps/dashboard/src/lib/utils/functions/isSubmissionEarly.js create mode 100644 apps/dashboard/src/lib/utils/functions/isSubmissionEarly.ts delete mode 100644 apps/dashboard/src/lib/utils/functions/org.spec.ts delete mode 100644 apps/dashboard/src/lib/utils/functions/removeDuplicate.spec.js rename apps/dashboard/src/lib/utils/functions/{removeDuplicate.js => removeDuplicate.ts} (100%) rename apps/dashboard/src/lib/utils/functions/routes/{isPublicRoute.js => isPublicRoute.ts} (100%) delete mode 100644 apps/dashboard/src/lib/utils/functions/showAppsSideBar.spec.js rename apps/dashboard/src/lib/utils/functions/{showAppsSideBar.js => showAppsSideBar.ts} (100%) delete mode 100644 apps/dashboard/src/lib/utils/functions/string.spec.ts create mode 100644 apps/dashboard/src/lib/utils/functions/svelte.ts delete mode 100644 apps/dashboard/src/lib/utils/functions/validateEmail.spec.js rename apps/dashboard/src/lib/utils/functions/{validateEmail.js => validateEmail.ts} (100%) rename apps/dashboard/src/lib/utils/services/attendance/{index.js => index.ts} (100%) rename apps/dashboard/src/lib/utils/services/marks/{index.js => index.ts} (100%) rename apps/dashboard/src/lib/utils/services/org/{quiz.js => quiz.ts} (100%) rename apps/dashboard/src/lib/utils/store/{useMobile.js => useMobile.ts} (100%) create mode 100644 apps/dashboard/src/lib/utils/types/dom.ts rename apps/dashboard/src/routes/api/verify/{+server.js => +server.ts} (89%) rename apps/dashboard/src/routes/courses/[id]/{+page.js => +page.ts} (100%) rename apps/dashboard/src/routes/courses/[id]/attendance/{+page.js => +page.ts} (100%) rename apps/dashboard/src/routes/courses/[id]/certificates/{+page.js => +page.ts} (100%) rename apps/dashboard/src/routes/courses/[id]/landingpage/{+page.js => +page.ts} (100%) rename apps/dashboard/src/routes/courses/[id]/lessons/{+page.js => +page.ts} (100%) rename apps/dashboard/src/routes/courses/[id]/lessons/[...lessonParams]/{+page.server.js => +page.server.ts} (85%) rename apps/dashboard/src/routes/courses/[id]/marks/{+page.js => +page.ts} (100%) rename apps/dashboard/src/routes/courses/[id]/people/{+page.js => +page.ts} (100%) rename apps/dashboard/src/routes/courses/[id]/settings/{+page.js => +page.ts} (100%) rename apps/dashboard/src/routes/courses/[id]/submissions/{+page.js => +page.ts} (100%) rename apps/dashboard/src/routes/lms/community/[slug]/{+page.js => +page.ts} (100%) rename apps/dashboard/src/routes/org/[slug]/{+page.js => +page.ts} (100%) rename apps/dashboard/src/routes/org/[slug]/community/[slug]/{+page.js => +page.ts} (100%) rename apps/dashboard/src/routes/org/[slug]/courses/{+page.js => +page.ts} (100%) rename apps/dashboard/src/routes/org/[slug]/quiz/[slug]/{+page.js => +page.ts} (100%) delete mode 100644 apps/dashboard/src/routes/profile/[id]/+page.js delete mode 100644 apps/dashboard/src/routes/profile/[id]/+page.svelte delete mode 100644 apps/docs/pages/contributor-guides/gitpod.mdx rename apps/{classroomio-com => website}/.env.example (100%) rename apps/{classroomio-com => website}/.gitignore (100%) rename apps/{classroomio-com => website}/.npmrc (100%) rename apps/{classroomio-com => website}/.nvmrc (100%) rename apps/{classroomio-com => website}/.prettierrc (100%) rename apps/{classroomio-com => website}/README.md (100%) rename apps/{classroomio-com => website}/jsconfig.json (100%) rename apps/{classroomio-com => website}/package.json (94%) rename apps/{classroomio-com => website}/postcss.config.js (100%) rename apps/{classroomio-com => website}/src/app.css (100%) rename apps/{classroomio-com => website}/src/app.d.ts (100%) rename apps/{classroomio-com => website}/src/app.html (100%) rename apps/{classroomio-com => website}/src/blog/brand-customisations.md (100%) rename apps/{classroomio-com => website}/src/blog/classroomio-at-eduai-conference-at-unilag.md (100%) rename apps/{classroomio-com => website}/src/blog/custom-domain.md (100%) rename apps/{classroomio-com => website}/src/blog/free-tools.md (100%) rename apps/{classroomio-com => website}/src/blog/google-open-source-peer-bonus.md (100%) rename apps/{classroomio-com => website}/src/blog/launch-week-001.md (100%) rename apps/{classroomio-com => website}/src/blog/learn-from-the-best.md (100%) rename apps/{classroomio-com => website}/src/blog/multi-language.md (100%) rename apps/{classroomio-com => website}/src/blog/pranav-hits-100-students.md (100%) rename apps/{classroomio-com => website}/src/blog/self-host.md (100%) rename apps/{classroomio-com => website}/src/blog/students-analytics.md (100%) rename apps/{classroomio-com => website}/src/blog/teach-with-data.md (100%) rename apps/{classroomio-com => website}/src/lib/Blog/BlogListItem.svelte (100%) rename apps/{classroomio-com => website}/src/lib/Button/Button.svelte (100%) rename apps/{classroomio-com => website}/src/lib/Chip/Chip.svelte (100%) rename apps/{classroomio-com => website}/src/lib/Contact/FeedbackForm.svelte (100%) rename apps/{classroomio-com => website}/src/lib/Contact/HelpForm.svelte (100%) rename apps/{classroomio-com => website}/src/lib/Contact/Sucess.svelte (100%) rename apps/{classroomio-com => website}/src/lib/Footer/Footer.svelte (100%) rename apps/{classroomio-com => website}/src/lib/Home/CoreFeatureSection.svelte (100%) rename apps/{classroomio-com => website}/src/lib/Home/CoreFeatures.svelte (100%) rename apps/{classroomio-com => website}/src/lib/Home/Faq.svelte (100%) rename apps/{classroomio-com => website}/src/lib/Home/Hero.svelte (100%) rename apps/{classroomio-com => website}/src/lib/Home/MoreFeatures.svelte (100%) rename apps/{classroomio-com => website}/src/lib/Home/StudentDashboard.svelte (100%) rename apps/{classroomio-com => website}/src/lib/Home/Testimonial.svelte (100%) rename apps/{classroomio-com => website}/src/lib/Home/faqs.js (100%) rename apps/{classroomio-com => website}/src/lib/Icons/CourseIcon.svelte (100%) rename apps/{classroomio-com => website}/src/lib/Input/TextArea.svelte (100%) rename apps/{classroomio-com => website}/src/lib/Input/TextField.svelte (100%) rename apps/{classroomio-com => website}/src/lib/Modal/Modal.svelte (100%) rename apps/{classroomio-com => website}/src/lib/Navigation/Navigation.svelte (100%) rename apps/{classroomio-com => website}/src/lib/NotFound/NotFound.svelte (100%) rename apps/{classroomio-com => website}/src/lib/PageHeader/PageHeader.svelte (100%) rename apps/{classroomio-com => website}/src/lib/PageSignupCTA/index.svelte (100%) rename apps/{classroomio-com => website}/src/lib/Senja/Embed.svelte (80%) rename apps/{classroomio-com => website}/src/lib/Timeline/Timeline.svelte (100%) rename apps/{classroomio-com => website}/src/lib/ToolsHeader/ToolsHeader.svelte (100%) rename apps/{classroomio-com => website}/src/lib/UploadWidget/UploadWidget.svelte (100%) rename apps/{classroomio-com => website}/src/lib/custom/img.svelte (100%) rename apps/{classroomio-com => website}/src/lib/custom/index.ts (100%) rename apps/{classroomio-com => website}/src/lib/emojis/crossed-fingers.svg (100%) rename apps/{classroomio-com => website}/src/lib/emojis/folder.svg (100%) rename apps/{classroomio-com => website}/src/lib/emojis/globe.svg (100%) rename apps/{classroomio-com => website}/src/lib/emojis/index.js (100%) rename apps/{classroomio-com => website}/src/lib/emojis/left-fist.svg (100%) rename apps/{classroomio-com => website}/src/lib/emojis/printer.svg (100%) rename apps/{classroomio-com => website}/src/lib/emojis/right-fist.svg (100%) rename apps/{classroomio-com => website}/src/lib/emojis/robot-arm.svg (100%) rename apps/{classroomio-com => website}/src/lib/emojis/team.svg (100%) rename apps/{classroomio-com => website}/src/lib/emojis/thumbs-up.svg (100%) rename apps/{classroomio-com => website}/src/lib/types.ts (100%) rename apps/{classroomio-com => website}/src/lib/utils/constants/tools.ts (100%) rename apps/{classroomio-com => website}/src/lib/utils/formatDate.ts (100%) rename apps/{classroomio-com => website}/src/lib/utils/isFormValid.ts (100%) rename apps/{classroomio-com => website}/src/lib/utils/posthog/index.ts (100%) rename apps/{classroomio-com => website}/src/lib/utils/submitForm.ts (100%) rename apps/{classroomio-com => website}/src/mdsvex.svelte (100%) rename apps/{classroomio-com => website}/src/routes/(marketing)/bootcamps/+page.svelte (100%) rename apps/{classroomio-com => website}/src/routes/(marketing)/customer-education/+page.svelte (100%) rename apps/{classroomio-com => website}/src/routes/(marketing)/employee-training/+page.svelte (100%) rename apps/{classroomio-com => website}/src/routes/(redirects)/demo/+page.server.ts (100%) rename apps/{classroomio-com => website}/src/routes/(redirects)/devanddesign/+page.server.ts (100%) rename apps/{classroomio-com => website}/src/routes/(redirects)/discord/+page.server.ts (100%) rename apps/{classroomio-com => website}/src/routes/(redirects)/docs/+layout.svelte (100%) rename apps/{classroomio-com => website}/src/routes/(redirects)/docs/+page.svelte (100%) rename apps/{classroomio-com => website}/src/routes/(redirects)/github/+page.server.ts (100%) rename apps/{classroomio-com => website}/src/routes/(redirects)/learn/+page.server.ts (100%) rename apps/{classroomio-com => website}/src/routes/(redirects)/new/+page.server.ts (100%) rename apps/{classroomio-com => website}/src/routes/(redirects)/ph/+page.server.ts (100%) rename apps/{classroomio-com => website}/src/routes/(redirects)/privacy/+page.server.ts (100%) rename apps/{classroomio-com => website}/src/routes/(redirects)/signup/+page.server.ts (100%) rename apps/{classroomio-com => website}/src/routes/(redirects)/tos/+page.server.ts (100%) rename apps/{classroomio-com => website}/src/routes/(redirects)/waec/+page.server.ts (100%) rename apps/{classroomio-com => website}/src/routes/+layout.svelte (100%) rename apps/{classroomio-com => website}/src/routes/+layout.ts (100%) rename apps/{classroomio-com => website}/src/routes/+page.svelte (100%) rename apps/{classroomio-com => website}/src/routes/api/blog/+server.ts (100%) rename apps/{classroomio-com => website}/src/routes/api/contact/+server.ts (100%) rename apps/{classroomio-com => website}/src/routes/blog/+page.svelte (100%) rename apps/{classroomio-com => website}/src/routes/blog/+page.ts (100%) rename apps/{classroomio-com => website}/src/routes/blog/[slug]/+page.svelte (100%) rename apps/{classroomio-com => website}/src/routes/blog/[slug]/+page.ts (100%) rename apps/{classroomio-com => website}/src/routes/contact/+layout.ts (100%) rename apps/{classroomio-com => website}/src/routes/contact/+page.svelte (100%) rename apps/{classroomio-com => website}/src/routes/oss-friends/+page.svelte (100%) rename apps/{classroomio-com => website}/src/routes/oss-friends/+page.ts (100%) rename apps/{classroomio-com => website}/src/routes/pricing/+layout.ts (100%) rename apps/{classroomio-com => website}/src/routes/pricing/+page.svelte (96%) rename apps/{classroomio-com => website}/src/routes/roadmap/+page.svelte (100%) rename apps/{classroomio-com => website}/src/routes/teach/+layout.ts (100%) rename apps/{classroomio-com => website}/src/routes/teach/+page.svelte (100%) rename apps/{classroomio-com => website}/src/routes/teach/register/+page.server.ts (100%) rename apps/{classroomio-com => website}/src/routes/tools/+layout.svelte (100%) rename apps/{classroomio-com => website}/src/routes/tools/+layout.ts (100%) rename apps/{classroomio-com => website}/src/routes/tools/+page.svelte (100%) rename apps/{classroomio-com => website}/src/routes/tools/name-picker/+page.svelte (100%) rename apps/{classroomio-com => website}/src/routes/tools/pomodoro/+page.svelte (100%) rename apps/{classroomio-com => website}/src/routes/tools/progress/+page.svelte (100%) rename apps/{classroomio-com => website}/src/routes/tools/progress/components/Avatar.svelte (100%) rename apps/{classroomio-com => website}/src/routes/tools/progress/components/Background.svelte (100%) rename apps/{classroomio-com => website}/src/routes/tools/progress/components/DownloadButton.svelte (100%) rename apps/{classroomio-com => website}/src/routes/tools/progress/components/FullView.svelte (100%) rename apps/{classroomio-com => website}/src/routes/tools/progress/components/Mood.svelte (100%) rename apps/{classroomio-com => website}/src/routes/tools/progress/components/Report.svelte (100%) rename apps/{classroomio-com => website}/src/routes/tools/progress/components/store.ts (100%) rename apps/{classroomio-com => website}/src/routes/tools/stopwatch/+page.svelte (100%) rename apps/{classroomio-com => website}/src/routes/tools/stopwatch/components/Timer.svelte (100%) rename apps/{classroomio-com => website}/src/routes/tools/tic-tac-toe/+page.svelte (100%) rename apps/{classroomio-com => website}/src/routes/tools/tic-tac-toe/components/Board.svelte (100%) rename apps/{classroomio-com => website}/src/routes/tools/tic-tac-toe/components/WinningLine.svelte (100%) rename apps/{classroomio-com => website}/src/routes/tools/tic-tac-toe/components/board.ts (100%) rename apps/{classroomio-com => website}/src/routes/tools/tic-tac-toe/components/store.ts (100%) rename apps/{classroomio-com => website}/src/routes/transition.svelte (100%) rename apps/{classroomio-com => website}/static/blog/analytics-classroom-by-dalle3-classroomio.jpeg (100%) rename apps/{classroomio-com => website}/static/blog/best.jpg (100%) rename apps/{classroomio-com => website}/static/blog/google-os-peer-bonus-classroomio.png (100%) rename apps/{classroomio-com => website}/static/blog/os-peer-bonus-award-letter-classroomio.jpg (100%) rename apps/{classroomio-com => website}/static/cio-hero.webp (100%) rename apps/{classroomio-com => website}/static/classroomio-courses.png (100%) rename apps/{classroomio-com => website}/static/classroomio-opengraph-image.png (100%) rename apps/{classroomio-com => website}/static/classroomio-opengraph-image_launch.png (100%) rename apps/{classroomio-com => website}/static/discord-blue.png (100%) rename apps/{classroomio-com => website}/static/download-pdf.png (100%) rename apps/{classroomio-com => website}/static/favicon.ico (100%) rename apps/{classroomio-com => website}/static/free-tools/activity-stopwatch.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/jamb.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/name-picker.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/pomodoro.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/pomodoro/add-icon.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/pomodoro/done-icon.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/pomodoro/list-play-icon.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/pomodoro/menu-icon.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/pomodoro/pause-icon.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/pomodoro/pen-icon.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/pomodoro/restart-icon.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/pomodoro/settings-icon.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/pomodoro/timer-play-icon.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/progress-report.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/progress-report/close-icon.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/progress-report/full-screen-icon.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/progress-report/hide-icon.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/progress-report/hover-plus-icon.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/progress-report/preview-icon.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/progress-report/question-mark.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/progress-report/smiley-face-icon.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/stopwatch/loading-timer.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/stopwatch/no-speaker-icon.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/stopwatch/pause-icon.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/stopwatch/play-icon.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/stopwatch/reset-icon.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/stopwatch/speaker-icon.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/tic-tac.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/tic-tac/computer-icon.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/tic-tac/restart-icon.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/tic-tac/tic-tac-bg.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/tic-tac/tic-tac-o.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/tic-tac/tic-tac-start-icon.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/tic-tac/tic-tac-x.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/tic-tac/winner-star-icon.svg (100%) rename apps/{classroomio-com => website}/static/free-tools/waec.svg (100%) rename apps/{classroomio-com => website}/static/github-mark.png (100%) rename apps/{classroomio-com => website}/static/hero-1.svg (100%) rename apps/{classroomio-com => website}/static/hero-2.svg (100%) rename apps/{classroomio-com => website}/static/hero-3.svg (100%) rename apps/{classroomio-com => website}/static/hero-4.svg (100%) rename apps/{classroomio-com => website}/static/hero-5.svg (100%) rename apps/{classroomio-com => website}/static/hero-section.png (100%) rename apps/{classroomio-com => website}/static/landing-page-builder.webp (100%) rename apps/{classroomio-com => website}/static/logo-16.png (100%) rename apps/{classroomio-com => website}/static/logo-192.png (100%) rename apps/{classroomio-com => website}/static/logo-32.png (100%) rename apps/{classroomio-com => website}/static/logo-512.png (100%) rename apps/{classroomio-com => website}/static/manifest.json (100%) rename apps/{classroomio-com => website}/static/ng.png (100%) rename apps/{classroomio-com => website}/static/prime_twitter.svg (100%) rename apps/{classroomio-com => website}/static/roadmap-one.svg (100%) rename apps/{classroomio-com => website}/static/roadmap-two.svg (100%) rename apps/{classroomio-com => website}/static/robots.txt (100%) rename apps/{classroomio-com => website}/static/socials-avatar.png (100%) rename apps/{classroomio-com => website}/static/sort-icon.svg (100%) rename apps/{classroomio-com => website}/static/teach/get-paid.svg (100%) rename apps/{classroomio-com => website}/static/teach/inspire-learners.svg (100%) rename apps/{classroomio-com => website}/static/teach/star.svg (100%) rename apps/{classroomio-com => website}/static/teach/teach-from-anywhere.svg (100%) rename apps/{classroomio-com => website}/static/teach/teacher-banner.png (100%) rename apps/{classroomio-com => website}/static/teach/teacher-hero.png (100%) rename apps/{classroomio-com => website}/static/teach/thumbs-up.svg (100%) rename apps/{classroomio-com => website}/static/teach/user-profile.png (100%) rename apps/{classroomio-com => website}/static/team-management.png (100%) rename apps/{classroomio-com => website}/static/twitter.svg (100%) rename apps/{classroomio-com => website}/static/twitter_logo.png (100%) rename apps/{classroomio-com => website}/static/unsort-icon.svg (100%) rename apps/{classroomio-com => website}/static/video-transcription.png (100%) rename apps/{classroomio-com => website}/svelte.config.js (100%) rename apps/{classroomio-com => website}/tailwind.config.js (100%) rename apps/{classroomio-com => website}/vite.config.js (100%) delete mode 100644 cypress.config.js create mode 100644 packages/db/drizzle.config.ts create mode 100644 packages/db/existingAccounts.json create mode 100644 packages/db/package.json create mode 100644 packages/db/src/auth-schema.ts create mode 100644 packages/db/src/auth.ts create mode 100644 packages/db/src/drizzle.ts create mode 100644 packages/db/src/migrations/0000_stale_storm.sql create mode 100644 packages/db/src/migrations/0001_tranquil_thunderbolts.sql create mode 100644 packages/db/src/migrations/meta/0000_snapshot.json create mode 100644 packages/db/src/migrations/meta/0001_snapshot.json create mode 100644 packages/db/src/migrations/meta/_journal.json create mode 100644 packages/db/src/relations.ts create mode 100644 packages/db/src/schema.ts create mode 100644 packages/db/src/scripts/supabase-to-betterauth.ts create mode 100644 packages/db/tsconfig.json create mode 100644 packages/db/users.json delete mode 100644 packages/shared/package.json delete mode 100644 packages/shared/tsconfig.json create mode 100644 packages/utils/package.json rename packages/{shared => utils}/src/plans/constants.ts (100%) rename packages/{shared => utils}/src/plans/data.json (100%) create mode 100644 packages/utils/src/plans/index.ts rename packages/{shared => utils}/src/plans/types.ts (100%) rename packages/{shared => utils}/src/plans/utils.ts (100%) rename packages/{shared => utils}/src/senja/index.ts (100%) create mode 100644 packages/utils/tsconfig.json diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index e95a1f65..00000000 --- a/.editorconfig +++ /dev/null @@ -1,15 +0,0 @@ -root = true - -[*] -indent_style = tab -tab_width = 2 -end_of_line = lf -charset = utf-8 -insert_final_newline = false -trim_trailing_whitespace = true - -[{.*rc,*.yml,*.md,*.json,*.svg}] -indent_style = space - -[*.md] -trim_trailing_whitespace = false \ No newline at end of file diff --git a/.gitpod.yml b/.gitpod.yml deleted file mode 100644 index c9e6d675..00000000 --- a/.gitpod.yml +++ /dev/null @@ -1,46 +0,0 @@ -image: gitpod/workspace-full - -tasks: - - name: Setup all projects - init: | - pnpm i && - cd apps/classroomio-com && - cp .env.example .env && - cd ../dashboard && - cp .env.example .env && - cd ../.. && - pnpx supabase start - command: | - SUPABASE_ANON_KEY=$(pnpx supabase status | grep "anon key" | awk '{print $3}' | tr -d '\\n') && - cd apps/dashboard && - sed -i "s/PUBLIC_SUPABASE_ANON_KEY=.*/PUBLIC_SUPABASE_ANON_KEY=$SUPABASE_ANON_KEY/g" .env && - sed -i "s/PRIVATE_SUPABASE_SERVICE_ROLE=.*/PRIVATE_SUPABASE_SERVICE_ROLE=$SUPABASE_SERVICE_ROLE/g" .env && - cd ../classroomio-com && - cd ../.. && - pnpm dev - -ports: - - port: 3000 - visibility: public - onOpen: open-browser - - port: 5173 - visibility: public - onOpen: open-browser - - port: 5174 - visibility: public - onOpen: open-browser - - port: 54321 - visibility: public - onOpen: ignore - - port: 54323 - visibility: public - onOpen: ignore - - port: 54324 - visibility: public - onOpen: ignore - -github: - prebuilds: - master: true - pullRequests: true - addComment: true diff --git a/.npmrc b/.npmrc deleted file mode 100644 index 7d8cde73..00000000 --- a/.npmrc +++ /dev/null @@ -1,2 +0,0 @@ -auto-install-peers = true -package-manager-strict=false \ No newline at end of file diff --git a/.prettierrc b/.prettierrc index 16b3fd86..023892d8 100644 --- a/.prettierrc +++ b/.prettierrc @@ -2,13 +2,16 @@ "useTabs": false, "singleQuote": true, "trailingComma": "none", - "printWidth": 100, + "printWidth": 120, "plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"], "overrides": [ { "files": "*.svelte", "options": { - "parser": "svelte" + "parser": "svelte", + "bracketSameLine": false, + "svelteAllowShorthand": true, + "svelteIndentScriptAndStyle": true } } ] diff --git a/.vscode/settings.json b/.vscode/settings.json index be9fd438..f3416c3a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -19,7 +19,7 @@ "deno.importMap": "./supabase/functions/import_map.json", "editor.formatOnSave": true, "[svelte]": { - "editor.defaultFormatter": "svelte.svelte-vscode" + "editor.defaultFormatter": "esbenp.prettier-vscode" }, "vitest.disableWorkspaceWarning": true } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 85e7993b..f9f15186 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,7 +14,7 @@ We invite innovative minds to contribute to the evolution of ClassroomIO. If you Ready to dive into the code and make a real impact? Here's your path: -1. **Fork the Repository:** Fork our repository or use [Gitpod](https://classroomio.com/docs/contributor-guides/gitpod) +1. **Fork the Repository:** Fork our repository 2. **Implementation:** Code it out, test it and apply your changes. diff --git a/README.md b/README.md index 1c19a3ad..5a04263f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ - ClassroomIO is a no-code tool that allows you build and scale your online bootcamp with ease. + ClassroomIO is a no-code tool that allows you build and scale your online bootcamp with ease.

ClassroomIO.com

The Open Source Learning Management System for Companies @@ -12,7 +12,7 @@ ## ✨ About ClassroomIO.com -ClassroomIO Courses page +ClassroomIO Courses page Streamline training for everyone with ClassroomIO.com. Our all-in-one platform empowers bootcamps, educators, and businesses to manage training programs easily. With our platform, anyone can run multiple classes and cohorts all from one UI. The application is mobile-first, which means that students can access your lesson materials from any device. @@ -71,21 +71,13 @@ Here is what you need to be able to run ClassroomIO.com This repo is a mono repo that consists of 3 projects: -1. `classroomio-com`: The landing page of ClassroomIO hosted [here](https://classroomio.com) +1. `website`: The landing page of ClassroomIO hosted [here](https://classroomio.com) 2. `api`: The api service that handles PDF, video processing, Emailing and Notifications. 3. `dashboard`: The web application that runs the learning management system hosted [here](https://app.classroomio.com). 4. `docs`: Official documentation of ClassroomIO hosted [here](https://classroomio.com/docs) ## Development -### Gitpod Setup - -1. Click the button below to open this project in Gitpod. - -2. This will open a fully configured workspace in your browser with all the necessary dependencies already installed. - -[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/classroomio/classroomio) - ### Local Setup 1. Fork the repo, then clone it using the following command (remember to replace the url with the url from your forked repo) @@ -173,14 +165,14 @@ To get the environmental variables for supabase continue to step(5) 4. All projects should start running - - `classroomio-com`: [http://localhost:5174](http://localhost:5174) + - `website`: [http://localhost:5174](http://localhost:5174) - `api`: [http://localhost:3002](http://localhost:3002) - `dashboard`: [http://localhost:5173](http://localhost:5173) - `docs`: [http://localhost:3000](http://localhost:3000) 5. Running a specific project - - **classroomio-com**: `pnpm dev --filter=@cio/classroomio-com` + - **website**: `pnpm dev --filter=@cio/website` - **api**: `pnpm dev --filter=@cio/api` - **dashboard**: `pnpm dev --filter=@cio/dashboard` - **docs**: `pnpm dev --filter=@cio/docs` diff --git a/apps/api/.env.example b/apps/api/.env.example index 4158bf20..9ff43a05 100644 --- a/apps/api/.env.example +++ b/apps/api/.env.example @@ -1,3 +1,5 @@ +DATABASE_URL= + ## Supabase - DB PUBLIC_SUPABASE_ANON_KEY= PUBLIC_SUPABASE_URL= diff --git a/apps/api/package.json b/apps/api/package.json index 5aed6318..a804e0e6 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -40,7 +40,6 @@ "@hono/standard-validator": "^0.1.5", "@hono/zod-validator": "^0.7.2", "@scalar/hono-api-reference": "^0.9.18", - "@sentry/node": "^7.110.1", "@sentry/profiling-node": "^7.110.1", "@supabase/supabase-js": "^2.32.0", "axios": "^1.4.0", @@ -72,8 +71,5 @@ "typescript": "^5.5.2", "vitest": "^1.2.2", "wrangler": "4.21.x" - }, - "_moduleAliases": { - "$src": "src" } } diff --git a/apps/api/src/app.ts b/apps/api/src/app.ts index 3e52486a..2025933e 100644 --- a/apps/api/src/app.ts +++ b/apps/api/src/app.ts @@ -2,11 +2,11 @@ import 'dotenv/config'; import { Hono } from 'hono'; import { cors } from 'hono/cors'; -import { courseRouter } from '$src/routes/course/course'; +import { courseRouter } from '@api/routes/course/course'; import { logger } from 'hono/logger'; -import { mailRouter } from '$src/routes/mail'; +import { mailRouter } from '@api/routes/mail'; import { prettyJSON } from 'hono/pretty-json'; -import { rateLimiterMiddleware } from '$src/middlewares/rate-limiter'; +import { rateLimiterMiddleware } from '@api/middlewares/rate-limiter'; import { secureHeaders } from 'hono/secure-headers'; // Create Hono app with chaining for RPC support diff --git a/apps/api/src/constants/index.ts b/apps/api/src/constants/index.ts index f719cb76..0dff0f1b 100644 --- a/apps/api/src/constants/index.ts +++ b/apps/api/src/constants/index.ts @@ -1,4 +1,4 @@ -import { env } from '$src/config/env'; +import { env } from '@api/config/env'; export * from './rate-limiter'; diff --git a/apps/api/src/index.ts b/apps/api/src/index.ts index 39abd795..81d75a1c 100644 --- a/apps/api/src/index.ts +++ b/apps/api/src/index.ts @@ -1,8 +1,8 @@ import 'dotenv/config'; -import { app } from '$src/app'; -import { configureOpenAPI } from '$src/utils/openapi'; -import { env } from '$src/config/env'; +import { app } from '@api/app'; +import { configureOpenAPI } from '@api/utils/openapi'; +import { env } from '@api/config/env'; import { serve } from '@hono/node-server'; import { showRoutes } from 'hono/dev'; diff --git a/apps/api/src/middlewares/auth.ts b/apps/api/src/middlewares/auth.ts index 4c6d9aa2..d47d663e 100644 --- a/apps/api/src/middlewares/auth.ts +++ b/apps/api/src/middlewares/auth.ts @@ -1,6 +1,6 @@ import { Context, Next } from 'hono'; -import { validateUser } from '$src/utils/auth/validate-user'; +import { validateUser } from '@api/utils/auth/validate-user'; export const authMiddleware = async (c: Context, next: Next) => { try { diff --git a/apps/api/src/middlewares/rate-limiter.ts b/apps/api/src/middlewares/rate-limiter.ts index e4efabb2..df3d6f96 100644 --- a/apps/api/src/middlewares/rate-limiter.ts +++ b/apps/api/src/middlewares/rate-limiter.ts @@ -3,10 +3,10 @@ import { ERROR_MESSAGES, HTTP_STATUS, RATE_LIMIT_HEADERS -} from '$src/constants/rate-limiter'; +} from '@api/constants/rate-limiter'; import type { MiddlewareHandler } from 'hono'; -import { rateLimiter } from '$src/utils/redis/limiter'; +import { rateLimiter } from '@api/utils/redis/limiter'; import { userKeyGenerator } from '../utils/redis/key-generators'; export interface RateLimiterOptions { diff --git a/apps/api/src/routes/course/course.ts b/apps/api/src/routes/course/course.ts index 869e284d..8662f03c 100644 --- a/apps/api/src/routes/course/course.ts +++ b/apps/api/src/routes/course/course.ts @@ -1,12 +1,12 @@ -import { TCourseClone,TCourseDownloadContent, TCertificateDownload, ZCertificateDownload, ZCourseDownloadContent } from '$src/types/course'; - import { Hono } from 'hono'; -import { generateCertificate } from '$src/utils/certificate'; -import { generateCoursePdf } from '$src/utils/course'; -import { katexRouter } from '$src/routes/course/katex'; -import { lessonRouter } from '$src/routes/course/lesson'; -import { presignRouter } from '$src/routes/course/presign'; -import { cloneRouter } from '$src/routes/course/clone'; +import { TCourseClone,TCourseDownloadContent, TCertificateDownload, ZCertificateDownload, ZCourseDownloadContent } from '@api/types/course'; + +import { generateCertificate } from '@api/utils/certificate'; +import { generateCoursePdf } from '@api/utils/course'; +import { katexRouter } from '@api/routes/course/katex'; +import { lessonRouter } from '@api/routes/course/lesson'; +import { presignRouter } from '@api/routes/course/presign'; +import { cloneRouter } from '@api/routes/course/clone'; import { zValidator } from '@hono/zod-validator'; export const courseRouter = new Hono() diff --git a/apps/api/src/routes/course/lesson.ts b/apps/api/src/routes/course/lesson.ts index 0307bccd..d33df431 100644 --- a/apps/api/src/routes/course/lesson.ts +++ b/apps/api/src/routes/course/lesson.ts @@ -1,6 +1,6 @@ import { Hono } from 'hono'; -import { TLessonDownloadContent, ZLessonDownloadContent } from '$src/types/course/lesson'; -import { generateLessonPdf } from '$src/utils/lesson'; +import { TLessonDownloadContent, ZLessonDownloadContent } from '@api/types/course/lesson'; +import { generateLessonPdf } from '@api/utils/lesson'; import { zValidator } from '@hono/zod-validator'; export const lessonRouter = new Hono().post( diff --git a/apps/api/src/routes/course/presign.ts b/apps/api/src/routes/course/presign.ts index 20519806..5c06b75f 100644 --- a/apps/api/src/routes/course/presign.ts +++ b/apps/api/src/routes/course/presign.ts @@ -3,17 +3,17 @@ import { ZCourseDocumentPresignUrlUpload, ZCourseDownloadPresignedUrl, ZCoursePresignUrlUpload -} from '$src/types/course'; +} from '@api/types/course'; import { describeRoute, validator } from 'hono-openapi'; -import { BUCKET_NAME } from '$src/constants/upload'; -import { CLOUDFLARE } from '$src/constants'; -import type { GetSignedUrlParameters } from '$src/utils/s3'; +import { BUCKET_NAME } from '@api/constants/upload'; +import { CLOUDFLARE } from '@api/constants'; +import type { GetSignedUrlParameters } from '@api/utils/s3'; import { Hono } from 'hono'; -import { authMiddleware } from '$src/middlewares/auth'; -import { generateFileKey } from '$src/utils/upload'; +import { authMiddleware } from '@api/middlewares/auth'; +import { generateFileKey } from '@api/utils/upload'; import { getSignedUrl } from '@aws-sdk/s3-request-presigner'; -import { s3Client } from '$src/utils/s3'; +import { s3Client } from '@api/utils/s3'; // Response schemas for OpenAPI documentation const PresignUploadResponse = { diff --git a/apps/api/src/routes/mail.ts b/apps/api/src/routes/mail.ts index 53deeb88..5c43c18c 100644 --- a/apps/api/src/routes/mail.ts +++ b/apps/api/src/routes/mail.ts @@ -1,8 +1,8 @@ -import { sendWithNodemailer, sendWithZoho } from '$src/services/mail'; +import { sendWithNodemailer, sendWithZoho } from '@api/services/mail'; import { Hono } from 'hono'; -import { ZSendEmailValidation } from '$src/types/mail'; -import { env } from '$src/config/env'; +import { ZSendEmailValidation } from '@api/types/mail'; +import { env } from '@api/config/env'; import { zValidator } from '@hono/zod-validator'; export const mailRouter = new Hono().post( diff --git a/apps/api/src/services/mail.ts b/apps/api/src/services/mail.ts index 2d46422e..42d54960 100644 --- a/apps/api/src/services/mail.ts +++ b/apps/api/src/services/mail.ts @@ -1,10 +1,10 @@ -import { extractNameAndEmail, withEmailTemplate } from '$src/utils/mail'; -import { nodemailerTransporter, zohoClient } from '$src/utils/email'; +import { extractNameAndEmail, withEmailTemplate } from '@api/utils/mail'; +import { nodemailerTransporter, zohoClient } from '@api/utils/email'; import { Hono } from 'hono'; -import type { TSendEmailValidation } from '$src/types/mail'; +import type { TSendEmailValidation } from '@api/types/mail'; import type { Transporter } from 'nodemailer'; -import { env } from '$src/config/env'; +import { env } from '@api/config/env'; export const mailRouter = new Hono(); diff --git a/apps/api/src/types/course/index.ts b/apps/api/src/types/course/index.ts index 574bffae..40ec48a9 100644 --- a/apps/api/src/types/course/index.ts +++ b/apps/api/src/types/course/index.ts @@ -1,4 +1,4 @@ -import { ALLOWED_CONTENT_TYPES, ALLOWED_DOCUMENT_TYPES } from '$src/constants/upload'; +import { ALLOWED_CONTENT_TYPES, ALLOWED_DOCUMENT_TYPES } from '@api/constants/upload'; import { z } from 'zod'; diff --git a/apps/api/src/utils/certificate.ts b/apps/api/src/utils/certificate.ts index b9a40eb9..c6dc4d20 100644 --- a/apps/api/src/utils/certificate.ts +++ b/apps/api/src/utils/certificate.ts @@ -1,5 +1,5 @@ -import type { TCertificateDownload } from '$src/types/course/lesson'; -import { getCloudflarePdfBuffer } from '$src/utils/cloudflare'; +import type { TCertificateDownload } from '@api/types/course/lesson'; +import { getCloudflarePdfBuffer } from '@api/utils/cloudflare'; export interface CertificateData { theme: string; diff --git a/apps/api/src/utils/cloudflare.ts b/apps/api/src/utils/cloudflare.ts index 6a1e55ed..a7fd47d8 100644 --- a/apps/api/src/utils/cloudflare.ts +++ b/apps/api/src/utils/cloudflare.ts @@ -1,4 +1,4 @@ -import { CLOUDFLARE } from '$src/constants'; +import { CLOUDFLARE } from '@api/constants'; export const getCloudflarePdfBuffer = async (html: string, styles?: string) => { console.log('Generating PDF with Cloudflare API...'); diff --git a/apps/api/src/utils/course.ts b/apps/api/src/utils/course.ts index 52edcd8a..387e4211 100644 --- a/apps/api/src/utils/course.ts +++ b/apps/api/src/utils/course.ts @@ -1,5 +1,5 @@ -import type { TCourseDownloadContent } from '$src/types/course'; -import { getCloudflarePdfBuffer } from '$src/utils/cloudflare'; +import type { TCourseDownloadContent } from '@api/types/course'; +import { getCloudflarePdfBuffer } from '@api/utils/cloudflare'; import { marked } from 'marked'; function getHtmlTemplate(body: string): string { diff --git a/apps/api/src/utils/email.ts b/apps/api/src/utils/email.ts index 3a52bf81..1c5a8af5 100644 --- a/apps/api/src/utils/email.ts +++ b/apps/api/src/utils/email.ts @@ -1,6 +1,6 @@ import { SendMailClient } from 'zeptomail'; import type { Transporter } from 'nodemailer'; -import { env } from '$src/config/env'; +import { env } from '@api/config/env'; import nodemailer from 'nodemailer'; export const zohoClient = new SendMailClient({ diff --git a/apps/api/src/utils/lesson.ts b/apps/api/src/utils/lesson.ts index 4f4c6241..fec11c79 100644 --- a/apps/api/src/utils/lesson.ts +++ b/apps/api/src/utils/lesson.ts @@ -1,4 +1,4 @@ -import type { TLessonDownloadContent } from '$src/types/course/lesson'; +import type { TLessonDownloadContent } from '@api/types/course/lesson'; import { marked } from 'marked'; function getHtmlTemplate(body: string): string { diff --git a/apps/api/src/utils/openapi/index.ts b/apps/api/src/utils/openapi/index.ts index 323a635a..9a784a34 100644 --- a/apps/api/src/utils/openapi/index.ts +++ b/apps/api/src/utils/openapi/index.ts @@ -1,6 +1,6 @@ import { Hono } from 'hono'; import { Scalar } from '@scalar/hono-api-reference'; -import { env } from '$src/config/env'; +import { env } from '@api/config/env'; export function configureOpenAPI(app: Hono) { if (env.OPENAPI_URL) { diff --git a/apps/api/src/utils/redis/key-generators.ts b/apps/api/src/utils/redis/key-generators.ts index c18669b7..f11584dc 100644 --- a/apps/api/src/utils/redis/key-generators.ts +++ b/apps/api/src/utils/redis/key-generators.ts @@ -4,7 +4,7 @@ */ import type { Context } from 'hono'; -import { supabase } from '$src/utils/supabase'; +import { supabase } from '@api/utils/supabase'; /** * Extract user ID from JWT token diff --git a/apps/api/src/utils/redis/limiter.ts b/apps/api/src/utils/redis/limiter.ts index 63c02c6f..fcc0c804 100644 --- a/apps/api/src/utils/redis/limiter.ts +++ b/apps/api/src/utils/redis/limiter.ts @@ -3,7 +3,7 @@ import { DEFAULT_WINDOW_MS, ERROR_MESSAGES, RATE_LIMIT_KEY_PREFIX -} from '$src/constants/rate-limiter'; +} from '@api/constants/rate-limiter'; import { Redis } from 'ioredis'; import { redis } from './redis'; diff --git a/apps/api/src/utils/redis/redis.ts b/apps/api/src/utils/redis/redis.ts index 785e4be6..f22d6ffd 100644 --- a/apps/api/src/utils/redis/redis.ts +++ b/apps/api/src/utils/redis/redis.ts @@ -1,4 +1,4 @@ import { Redis } from 'ioredis'; -import { env } from '$src/config/env'; +import { env } from '@api/config/env'; export const redis = new Redis(env.REDIS_URL); diff --git a/apps/api/src/utils/s3.ts b/apps/api/src/utils/s3.ts index 56b56d05..7269a0a1 100644 --- a/apps/api/src/utils/s3.ts +++ b/apps/api/src/utils/s3.ts @@ -8,7 +8,7 @@ import { S3Client } from '@aws-sdk/client-s3'; -import { CLOUDFLARE } from '$src/constants'; +import { CLOUDFLARE } from '@api/constants'; import { getSignedUrl } from '@aws-sdk/s3-request-presigner'; export type GetSignedUrlParameters = Parameters; diff --git a/apps/api/src/utils/supabase.ts b/apps/api/src/utils/supabase.ts index c8bc26e6..440e0101 100644 --- a/apps/api/src/utils/supabase.ts +++ b/apps/api/src/utils/supabase.ts @@ -1,6 +1,6 @@ import { SupabaseClient, createClient } from '@supabase/supabase-js'; -import { env } from '$src/config/env'; +import { env } from '@api/config/env'; const { PUBLIC_SUPABASE_ANON_KEY, PUBLIC_SUPABASE_URL, PRIVATE_SUPABASE_SERVICE_ROLE } = env; diff --git a/apps/api/tsconfig.json b/apps/api/tsconfig.json index 0dfe20e6..f7d94198 100644 --- a/apps/api/tsconfig.json +++ b/apps/api/tsconfig.json @@ -9,8 +9,7 @@ "moduleResolution": "Bundler", "outDir": "./dist", "paths": { - "$src": ["./src"], - "$src/*": ["./src/*"] + "@api/*": ["src/*"] }, "resolveJsonModule": false, "skipLibCheck": true, diff --git a/apps/dashboard/.eslintrc.cjs b/apps/dashboard/.eslintrc.cjs deleted file mode 100644 index ff8b2ff6..00000000 --- a/apps/dashboard/.eslintrc.cjs +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - extends: ['custom/svelte'], - rules: { - '@typescript-eslint/ban-ts-comment': 'off' - } -}; diff --git a/apps/dashboard/.prettierignore b/apps/dashboard/.prettierignore new file mode 100644 index 00000000..0e25ab8e --- /dev/null +++ b/apps/dashboard/.prettierignore @@ -0,0 +1,7 @@ +node_modules +dist +build +.vercel +.turbo +.svelte-kit +static \ No newline at end of file diff --git a/apps/dashboard/eslint.config.js b/apps/dashboard/eslint.config.js new file mode 100644 index 00000000..af36b091 --- /dev/null +++ b/apps/dashboard/eslint.config.js @@ -0,0 +1,53 @@ +import { defineConfig } from 'eslint/config'; +import { fileURLToPath } from 'node:url'; +import globals from 'globals'; +import { includeIgnoreFile } from '@eslint/compat'; +import js from '@eslint/js'; +import svelte from 'eslint-plugin-svelte'; +import svelteConfig from './svelte.config.js'; +import ts from 'typescript-eslint'; +import unusedImports from 'eslint-plugin-unused-imports'; + +const gitignorePath = fileURLToPath(new URL('./.gitignore', import.meta.url)); + +export default defineConfig( + includeIgnoreFile(gitignorePath), + js.configs.recommended, + ...ts.configs.recommended, + ...svelte.configs.recommended, + { + plugins: { + 'unused-imports': unusedImports + }, + languageOptions: { + globals: { ...globals.browser, ...globals.node } + }, + rules: { + // typescript-eslint strongly recommend that you do not use the no-undef lint rule on TypeScript projects. + // see: https://typescript-eslint.io/troubleshooting/faqs/eslint/#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors + 'no-undef': 'off', + 'no-unused-vars': 'off', + 'unused-imports/no-unused-imports': 'error', + 'unused-imports/no-unused-vars': [ + 'warn', + { + vars: 'all', + varsIgnorePattern: '^_', + args: 'after-used', + argsIgnorePattern: '^_' + } + ] + } + }, + { + files: ['**/*.svelte', '**/*.svelte.ts', '**/*.svelte.js'], + languageOptions: { + parserOptions: { + projectService: true, + extraFileExtensions: ['.svelte'], + parser: ts.parser, + svelteConfig + } + } + } +); diff --git a/apps/dashboard/package.json b/apps/dashboard/package.json index 4dc041ec..5930cf4c 100644 --- a/apps/dashboard/package.json +++ b/apps/dashboard/package.json @@ -8,6 +8,7 @@ "build": "vite build", "preview": "vite preview", "lint": "eslint ./src", + "lint:fix": "eslint ./src --fix", "clean": "rm -rf node_modules", "format": "prettier . --write .", "start": "node build", @@ -21,11 +22,12 @@ "@carbon/charts-svelte": "^1.13.6", "@cio/api": "workspace:*", "@lemonsqueezy/lemonsqueezy.js": "^2.2.0", + "@lucide/svelte": "^0.545.0", "@polar-sh/sveltekit": "^0.2.1", "@supabase/supabase-js": "^2.31.0", - "@sveltejs/adapter-auto": "^2.1.0", - "@sveltejs/adapter-node": "^1.3.1", - "@sveltejs/adapter-vercel": "^3.1.0", + "@sveltejs/adapter-auto": "^3.0.0", + "@sveltejs/adapter-node": "^2.0.0", + "@sveltejs/adapter-vercel": "^4.0.0", "@sveltekit-i18n/base": "^1.3.7", "@sveltekit-i18n/parser-icu": "^1.0.8", "@tailwindcss/forms": "^0.5.4", @@ -55,7 +57,7 @@ "papaparse": "^5.4.1", "pluralize": "^8.0.0", "posthog-js": "^1.180.1", - "shared": "workspace:*", + "@cio/utils": "workspace:*", "sirv": "^2.0.3", "stripe": "^14.22.0", "svelte-awesome-color-picker": "^3.1.4", @@ -74,37 +76,45 @@ "@babel/preset-env": "^7.22.9", "@babel/preset-typescript": "^7.23.3", "@babel/runtime": "^7.22.6", - "@sveltejs/kit": "^1.29.0", + "@eslint/compat": "^1.4.0", + "@eslint/js": "^9.36.0", + "@sveltejs/kit": "^2.5.27", + "@sveltejs/vite-plugin-svelte": "^4.0.0", "@tailwindcss/typography": "^0.5.9", "@testing-library/jest-dom": "^6.1.5", "@testing-library/svelte": "^4.0.5", "@types/jest": "^29.5.10", "@types/lodash": "^4.14.196", + "@types/node": "^20", "all-object-keys": "^2.2.0", "autoprefixer": "^10.4.14", "babel-jest": "^29.7.0", "carbon-components-svelte": "^0.79.0", - "carbon-icons-svelte": "^12.1.0", "diff": "^5.2.0", "dotenv": "^16.3.1", + "eslint": "^9.36.0", + "eslint-plugin-svelte": "^3.12.4", + "eslint-plugin-unused-imports": "^4.2.0", + "globals": "^16.4.0", "jessy": "^3.1.1", "jest": "^29.7.0", "postcss": "^8.4.24", "postcss-load-config": "^4.0.1", "qrcode": "^1.5.3", "sass": "^1.64.2", - "svelte": "^4.1.2", + "svelte": "^5.0.0", "svelte-dnd-action": "^0.9.24", "svelte-jester": "^3.0.0", "svelte-loading-spinners": "^0.3.4", - "svelte-preprocess": "^5.0.4", + "svelte-preprocess": "^6.0.0", "tailwindcss": "^3.3.2", "ts-jest": "^29.1.1", "ts-node": "^10.9.2", - "tsconfig": "workspace:*", + "@cio/tsconfig": "workspace:*", "tslib": "^2.6.1", - "typescript": "^5.1.6", - "vite": "^4.4.8" + "typescript": "^5.5.0", + "typescript-eslint": "^8.44.1", + "vite": "^5.4.4" }, "type": "module", "engines": { diff --git a/apps/dashboard/scripts/translate.cjs b/apps/dashboard/scripts/translate.cjs index 21697eab..cda5ce91 100644 --- a/apps/dashboard/scripts/translate.cjs +++ b/apps/dashboard/scripts/translate.cjs @@ -50,9 +50,7 @@ const getMissingTranslations = async (toLanguage, outputFilePath) => { // Check if there are missing translations, if not, stop the process if (!missingKeysWithDetails) { - console.log( - `No missing translations for ${toLanguage.toUpperCase()}. Stopping translation process.` - ); + console.log(`No missing translations for ${toLanguage.toUpperCase()}. Stopping translation process.`); return; } diff --git a/apps/dashboard/src/app.html b/apps/dashboard/src/app.html index 55344eec..baba87df 100644 --- a/apps/dashboard/src/app.html +++ b/apps/dashboard/src/app.html @@ -1,32 +1,33 @@ + + + + - - - - + + + + - - - - + + + + + - - - - - + - + - + %sveltekit.head% + - %sveltekit.head% - - - -

%sveltekit.body%
- - - \ No newline at end of file + +
%sveltekit.body%
+ + diff --git a/apps/dashboard/src/app.postcss b/apps/dashboard/src/app.postcss index ce2f08d0..bad4aa4d 100644 --- a/apps/dashboard/src/app.postcss +++ b/apps/dashboard/src/app.postcss @@ -115,22 +115,28 @@ code { white-space: pre-wrap; } -[aria-current] :global(svg.carbon-icon), +/* [aria-current] :global(svg.carbon-icon), .active :global(svg.carbon-icon) { fill: var(--main-primary-color); -} +} */ .prose a { color: var(--main-primary-color); } -.success :global(svg.carbon-icon) { +svg.lucide-icon:not(.custom) { + color: #666666; +} +.dark svg.lucide-icon:not(.custom) { + color: #fff; +} +/* .success :global(svg.carbon-icon) { fill: green; } :global(svg.carbon-icon.error) { fill: red; -} +} */ .org-root { height: calc(100vh - 48px); diff --git a/apps/dashboard/src/error.html b/apps/dashboard/src/error.html index 115380f7..7e8b1db3 100644 --- a/apps/dashboard/src/error.html +++ b/apps/dashboard/src/error.html @@ -3,9 +3,8 @@

Something unexpected occured.

- Don't worry, your learning is safe. It isn't your fault, it is ours. We have gotten the error - notification and will push a fix ASAP. In the meantime, take a short break and come back a bit - later. + Don't worry, your learning is safe. It isn't your fault, it is ours. We have gotten the error notification and + will push a fix ASAP. In the meantime, take a short break and come back a bit later.

Contact Us diff --git a/apps/dashboard/src/hooks.server.ts b/apps/dashboard/src/hooks.server.ts index c83d017c..7f920834 100644 --- a/apps/dashboard/src/hooks.server.ts +++ b/apps/dashboard/src/hooks.server.ts @@ -38,12 +38,9 @@ export const handle: Handle = async ({ event, resolve }) => { } catch (error) { if (error instanceof Error) { if (error.message === 'Unauthenticated user') { - return new Response( - JSON.stringify({ code: 'unauthenticated', message: 'Unauthenticated user' }), - { - status: 401 - } - ); + return new Response(JSON.stringify({ code: 'unauthenticated', message: 'Unauthenticated user' }), { + status: 401 + }); } } } diff --git a/apps/dashboard/src/lib/components/AI/AIButton/CustomPromptBtn.svelte b/apps/dashboard/src/lib/components/AI/AIButton/CustomPromptBtn.svelte index 5832d5e5..763b5d79 100644 --- a/apps/dashboard/src/lib/components/AI/AIButton/CustomPromptBtn.svelte +++ b/apps/dashboard/src/lib/components/AI/AIButton/CustomPromptBtn.svelte @@ -1,56 +1,76 @@ +
+ diff --git a/apps/dashboard/src/lib/components/Analytics/ActivityCard.svelte b/apps/dashboard/src/lib/components/Analytics/ActivityCard.svelte index fbccee03..e0f3382e 100644 --- a/apps/dashboard/src/lib/components/Analytics/ActivityCard.svelte +++ b/apps/dashboard/src/lib/components/Analytics/ActivityCard.svelte @@ -7,18 +7,22 @@ hidePercentage?: boolean; } - export let activity: Activity; + interface Props { + activity: Activity; + } + + let { activity }: Props = $props();
- +
-

+

{activity.title}

@@ -27,7 +31,7 @@ % {/if}

-

+

{activity.description}

diff --git a/apps/dashboard/src/lib/components/Analytics/HeroProfileCard.svelte b/apps/dashboard/src/lib/components/Analytics/HeroProfileCard.svelte index b78e6f5d..25f3e7ae 100644 --- a/apps/dashboard/src/lib/components/Analytics/HeroProfileCard.svelte +++ b/apps/dashboard/src/lib/components/Analytics/HeroProfileCard.svelte @@ -3,28 +3,32 @@ import { calDateDiff } from '$lib/utils/functions/date'; import { t } from '$lib/utils/functions/translations'; import type { UserAnalytics } from '$lib/utils/types/analytics'; - import Alarm from 'carbon-icons-svelte/lib/Alarm.svelte'; - import Email from 'carbon-icons-svelte/lib/Email.svelte'; + import AlarmClockIcon from '@lucide/svelte/icons/alarm-clock'; + import MailIcon from '@lucide/svelte/icons/mail'; - export let user: UserAnalytics['user']; + interface Props { + user: UserAnalytics['user']; + } + + let { user }: Props = $props();
-

+

{user.fullName}

- + {user.email}

- + {$t('analytics.last_seen')}: {user.lastSeen ? calDateDiff(user.lastSeen) : $t('analytics.a_while_ago')} diff --git a/apps/dashboard/src/lib/components/Apps/components/Notes/index.svelte b/apps/dashboard/src/lib/components/Apps/components/Notes/index.svelte deleted file mode 100644 index 346183b7..00000000 --- a/apps/dashboard/src/lib/components/Apps/components/Notes/index.svelte +++ /dev/null @@ -1,12 +0,0 @@ - - - -

- -
- diff --git a/apps/dashboard/src/lib/components/Apps/components/Poll/components/Avatar.svelte b/apps/dashboard/src/lib/components/Apps/components/Poll/components/Avatar.svelte deleted file mode 100644 index 59d8f52d..00000000 --- a/apps/dashboard/src/lib/components/Apps/components/Poll/components/Avatar.svelte +++ /dev/null @@ -1,7 +0,0 @@ - - -{name} diff --git a/apps/dashboard/src/lib/components/Apps/components/Poll/components/CreatePollForm.svelte b/apps/dashboard/src/lib/components/Apps/components/Poll/components/CreatePollForm.svelte deleted file mode 100644 index 3e29d1a9..00000000 --- a/apps/dashboard/src/lib/components/Apps/components/Poll/components/CreatePollForm.svelte +++ /dev/null @@ -1,126 +0,0 @@ - - -
-
- {title} -
-
- - - -
-

- {$t('course.navItem.lessons.poll.options')} - - - - -

-
- - {#each poll.options as option, index} -
- - - - -
- {/each} -
- -
- - -
-
diff --git a/apps/dashboard/src/lib/components/Apps/components/Poll/components/Label.svelte b/apps/dashboard/src/lib/components/Apps/components/Poll/components/Label.svelte deleted file mode 100644 index c9b3bafb..00000000 --- a/apps/dashboard/src/lib/components/Apps/components/Poll/components/Label.svelte +++ /dev/null @@ -1,5 +0,0 @@ -

- -

diff --git a/apps/dashboard/src/lib/components/Apps/components/Poll/components/Poll.svelte b/apps/dashboard/src/lib/components/Apps/components/Poll/components/Poll.svelte deleted file mode 100644 index b469e030..00000000 --- a/apps/dashboard/src/lib/components/Apps/components/Poll/components/Poll.svelte +++ /dev/null @@ -1,215 +0,0 @@ - - -
- {#if selectedOptionToView} -
-
- -
-

{$t('course.navItem.lessons.poll.voted')}

-
-
- {#each selectedOptionToView.selectedBy as user} -
- -

- {user.fullname} -

-
- {/each} -
- {:else} -
-
-

- {poll.question} -

-

- {$t('course.navItem.lessons.poll.created_by')} - @{poll.author.username} -

-
- - {#if isAuthor} -
- - - -
- {/if} -
- - {#if viewResult} -
-
- -

- {poll.expiration || $t('dashboard.today')} -

-
-
- -

- {totalVotes} -

-
-
- - - {#each poll.options as option} -
-

- {option.label} -

- -
-
- -
- {#if option.selectedBy.length} - - {/if} -
- -
- {#each option.selectedBy.slice(0, 3) as user} - - {/each} -
-
- {/each} - {:else} - {#each poll.options as option, index} - - {/each} -
-

- {$t('course.navItem.lessons.poll.expires')}: {poll.expiration || $t('dashboard.today')} -

- | -

- {$t('course.navItem.lessons.poll.voted')}: {totalVotes} -

-
- {/if} - - {#if isAuthor} -
- (viewResult = !viewResult)} - /> - -
- {/if} - {/if} -
- - diff --git a/apps/dashboard/src/lib/components/Apps/components/Poll/components/Tabs.svelte b/apps/dashboard/src/lib/components/Apps/components/Poll/components/Tabs.svelte deleted file mode 100644 index 1377a060..00000000 --- a/apps/dashboard/src/lib/components/Apps/components/Poll/components/Tabs.svelte +++ /dev/null @@ -1,34 +0,0 @@ - - -
-
- {#each tabs as tab} - - {/each} -
- - - - - - -
diff --git a/apps/dashboard/src/lib/components/Apps/components/Poll/index.svelte b/apps/dashboard/src/lib/components/Apps/components/Poll/index.svelte deleted file mode 100644 index 454ecde1..00000000 --- a/apps/dashboard/src/lib/components/Apps/components/Poll/index.svelte +++ /dev/null @@ -1,290 +0,0 @@ - - - -
- -
-
- -
- {#if openCreatePollForm} - (openCreatePollForm = !openCreatePollForm)} - bind:isSaving={isCreating} - /> - {:else if currentGroupMember} -
- (openCreatePollForm = !openCreatePollForm)} /> - - {#if isLoading} - {$t('course.navItem.lessons.polls.loading')}... - {:else} - {#each selectedTab === tabs[0].value ? activePolls : expiredPolls as poll} - - {:else} -
-

{$t('course.navItem.lessons.polls.no_polls')}

-
- {/each} - {/if} -
- {/if} -
diff --git a/apps/dashboard/src/lib/components/Apps/components/Poll/service.ts b/apps/dashboard/src/lib/components/Apps/components/Poll/service.ts deleted file mode 100644 index ed79ad94..00000000 --- a/apps/dashboard/src/lib/components/Apps/components/Poll/service.ts +++ /dev/null @@ -1,141 +0,0 @@ -import { snackbar } from '$lib/components/Snackbar/store'; -import type { PollType, PollOptionType, FetchPollsResponse } from './types'; -import { getSupabase } from '$lib/utils/functions/supabase'; -import { polls } from './store'; - -const supabase = getSupabase(); - -export async function fetchPolls(courseId: string) { - return await supabase - .from('apps_poll') - .select( - ` - *, - created_at, - author:groupmember( - profile( - username, - fullname, - avatar_url - ) - ), - options: apps_poll_option ( - id, - label, - submissions:apps_poll_submission( - selectedBy:groupmember( - id, - profile( - username, - fullname, - avatar_url - ) - ) - ) - ) - ` - ) - .match({ courseId }) - .order('created_at', { ascending: false }) - .returns(); -} - -export const updatePollStatus = async (pollId: string, status: PollType['status']) => { - const { error } = await supabase.from('apps_poll').update({ status }).match({ id: pollId }); - - if (error) { - console.log(error); - snackbar.error('snackbar.poll.error.updating_poll'); - return; - } -}; - -export const togglePollSubmission = async ( - pollId: PollType['id'], - pollOptionId: PollOptionType['id'], - groupmemberId: string, - add: boolean -) => { - if (add) { - const { error } = await supabase.from('apps_poll_submission').insert({ - poll_id: pollId, - poll_option_id: pollOptionId, - selected_by_id: groupmemberId - }); - if (error) { - console.log(error); - snackbar.error('snackbar.poll.error.submitting_poll'); - return; - } - } else { - const { error } = await supabase.from('apps_poll_submission').delete().match({ - poll_id: pollId, - poll_option_id: pollOptionId, - selected_by_id: groupmemberId - }); - - if (error) { - console.log(error); - snackbar.error('snackbar.poll.error.submitting_poll'); - return; - } - } -}; - -function isOptionSelectedByCurrentUser(option: PollOptionType, groupmemberId: string) { - return option.selectedBy.some((gmember) => gmember.id === groupmemberId); -} - -export function handleVote(pollId: string, groupmemberId: string, author: PollType['author']) { - return (optionId: string) => { - // we have the pollId and the optionId - polls.update((_polls) => { - return [ - ..._polls.map((poll) => { - // Prevent user from voting on their own poll - // if (poll.author.id === currentGroupMember?.id) return poll; - - // Prevent user from voting on a poll that has expired - if (poll.expiration && new Date(poll.expiration) < new Date()) return poll; - - if (poll.id === pollId) { - // Prevent user from voting on a poll that the status is not published - if (poll.status !== 'published') { - snackbar.info('snackbar.poll.info.not_published'); - return poll; - } - - // Prevent user from voting twice - if ( - poll.options.some((option) => isOptionSelectedByCurrentUser(option, groupmemberId)) - ) { - snackbar.info('snackbar.poll.info.vote_once'); - return poll; - } - - poll.options = poll.options.map((option) => { - const isSelected = isOptionSelectedByCurrentUser(option, groupmemberId); - - // If user has not voted on this option, add their vote - if (option.id === optionId && !isSelected) { - option.selectedBy = [...option.selectedBy, author]; - - togglePollSubmission(pollId, optionId, groupmemberId, true); - } - // else if (isSelected) { - // // If user has voted on this option, remove their vote - // option.selectedBy = option.selectedBy.filter( - // (gmember) => gmember.id !== groupmemberId - // ); - // } - - return option; - }); - } - - return poll; - }) - ]; - }); - }; -} diff --git a/apps/dashboard/src/lib/components/Apps/components/Poll/store.ts b/apps/dashboard/src/lib/components/Apps/components/Poll/store.ts deleted file mode 100644 index bac5c500..00000000 --- a/apps/dashboard/src/lib/components/Apps/components/Poll/store.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { writable, type Writable } from 'svelte/store'; -import type { PollType } from './types'; - -export const polls: Writable = writable([]); diff --git a/apps/dashboard/src/lib/components/Apps/components/Poll/types.ts b/apps/dashboard/src/lib/components/Apps/components/Poll/types.ts deleted file mode 100644 index ce1df2c4..00000000 --- a/apps/dashboard/src/lib/components/Apps/components/Poll/types.ts +++ /dev/null @@ -1,69 +0,0 @@ -export type PollOptionType = { - id: string; - label: string; - selectedBy: { - id: string; - username: string; - fullname: string; - avatarUrl: string; - }[]; -}; - -export type PollType = { - courseId: string; - id: string; - question: string; - author: { - id: string; - username: string; - fullname: string; - avatarUrl: string; - }; - status: string; - isPublic: boolean; - expiration: string | Date; - options: PollOptionType[]; -}; - -export type TabsType = { - label: string; - value: number; - number: number; -}[]; - -export type PollOptionsSubmissionType = { - poll_id: string; - poll_option_id: string; - selected_by_id: string; -}; - -export type FetchPollsResponse = { - id: string; - courseId: string; - expiration: string; - authorId: string; - status: string; - question: string; - created_at: string; - author: { - profile: { - username: string; - fullname: string; - avatar_url: string; - }; - }; - options: { - id: string; - label: string; - submissions: { - selectedBy: { - id: string; - profile: { - username: string; - fullname: string; - avatar_url: string; - }; - }; - }[]; - }[]; -}[]; diff --git a/apps/dashboard/src/lib/components/Apps/components/Poll/utils.ts b/apps/dashboard/src/lib/components/Apps/components/Poll/utils.ts deleted file mode 100644 index dbeffb70..00000000 --- a/apps/dashboard/src/lib/components/Apps/components/Poll/utils.ts +++ /dev/null @@ -1,31 +0,0 @@ -import type { PollType, FetchPollsResponse } from './types'; - -export const getPollsData = (data: FetchPollsResponse, isStudent?: boolean) => { - const pollsData: PollType[] = data.map((appsPollItem) => ({ - id: appsPollItem.id, - courseId: appsPollItem.courseId, - expiration: appsPollItem.expiration, - status: appsPollItem.status, - question: appsPollItem.question, - author: { - id: appsPollItem.authorId, - username: appsPollItem.author.profile.username, - fullname: appsPollItem.author.profile.fullname, - avatarUrl: appsPollItem.author.profile.avatar_url - }, - options: appsPollItem.options.map((option) => ({ - id: option.id, - label: option.label, - selectedBy: option.submissions.map((submission) => { - return { - id: submission.selectedBy.id, - username: submission.selectedBy.profile.username, - fullname: submission.selectedBy.profile.fullname, - avatarUrl: submission.selectedBy.profile.avatar_url - }; - }) - })) - })); - - return pollsData.filter((p) => (isStudent ? p.status === 'published' : true)); -}; diff --git a/apps/dashboard/src/lib/components/Apps/components/QandA/index.svelte b/apps/dashboard/src/lib/components/Apps/components/QandA/index.svelte deleted file mode 100644 index 2a8f0638..00000000 --- a/apps/dashboard/src/lib/components/Apps/components/QandA/index.svelte +++ /dev/null @@ -1,135 +0,0 @@ - - - -
- -
-
- -
- {#each questions as question} -
- -
-

{question.name}

-
- {question.question} -
-
- -
- {/each} -
- - - - diff --git a/apps/dashboard/src/lib/components/Apps/constants.js b/apps/dashboard/src/lib/components/Apps/constants.js deleted file mode 100644 index 23abcd24..00000000 --- a/apps/dashboard/src/lib/components/Apps/constants.js +++ /dev/null @@ -1,8 +0,0 @@ -export default { - APPS: { - QANDA: 'QANDA', - NOTES: 'NOTES', - COMMENTS: 'COMMENTS', - POLL: 'POLL' - } -}; diff --git a/apps/dashboard/src/lib/components/Apps/index.svelte b/apps/dashboard/src/lib/components/Apps/index.svelte deleted file mode 100644 index 594935d6..00000000 --- a/apps/dashboard/src/lib/components/Apps/index.svelte +++ /dev/null @@ -1,237 +0,0 @@ - - -
-
-
- - - -
- -
- - - - -
- - -
- - {#if !!$apps.selectedApp} -
- {#key $apps.selectedApp} -
- {#if $apps.selectedApp === APPS_CONSTANTS.APPS.QANDA} - - {:else if $apps.selectedApp === APPS_CONSTANTS.APPS.POLL} - - {:else if $apps.selectedApp === APPS_CONSTANTS.APPS.NOTES} - - {/if} -
- {/key} -
- {/if} -
- - diff --git a/apps/dashboard/src/lib/components/Apps/store.ts b/apps/dashboard/src/lib/components/Apps/store.ts deleted file mode 100644 index 8ff28c68..00000000 --- a/apps/dashboard/src/lib/components/Apps/store.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { writable } from 'svelte/store'; - -export const apps = writable<{ - open: boolean; - dropdown: boolean; - selectedApp: string | undefined; -}>({ - open: false, - dropdown: false, - selectedApp: undefined -}); diff --git a/apps/dashboard/src/lib/components/AuthUI/index.svelte b/apps/dashboard/src/lib/components/AuthUI/index.svelte index 7a6e1c50..84e10c67 100644 --- a/apps/dashboard/src/lib/components/AuthUI/index.svelte +++ b/apps/dashboard/src/lib/components/AuthUI/index.svelte @@ -1,5 +1,7 @@ {name} diff --git a/apps/dashboard/src/lib/components/Backdrop/index.svelte b/apps/dashboard/src/lib/components/Backdrop/index.svelte index d8e50c29..8aa060fd 100644 --- a/apps/dashboard/src/lib/components/Backdrop/index.svelte +++ b/apps/dashboard/src/lib/components/Backdrop/index.svelte @@ -1,13 +1,15 @@ -
- +
+ {@render children?.()}
diff --git a/apps/dashboard/src/lib/components/Icons/CommunityIcon.svelte b/apps/dashboard/src/lib/components/Icons/CommunityIcon.svelte deleted file mode 100644 index da7b294e..00000000 --- a/apps/dashboard/src/lib/components/Icons/CommunityIcon.svelte +++ /dev/null @@ -1,19 +0,0 @@ - - - - - diff --git a/apps/dashboard/src/lib/components/Icons/CourseIcon.svelte b/apps/dashboard/src/lib/components/Icons/CourseIcon.svelte index fad7c44c..04376fb6 100644 --- a/apps/dashboard/src/lib/components/Icons/CourseIcon.svelte +++ b/apps/dashboard/src/lib/components/Icons/CourseIcon.svelte @@ -1,17 +1,14 @@ - - + + - - + + - - - - - - - + + + + + + + + - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/dashboard/src/lib/components/Icons/ErrorIconDarkMode.svelte b/apps/dashboard/src/lib/components/Icons/ErrorIconDarkMode.svelte index c496a621..a03dfc4b 100644 --- a/apps/dashboard/src/lib/components/Icons/ErrorIconDarkMode.svelte +++ b/apps/dashboard/src/lib/components/Icons/ErrorIconDarkMode.svelte @@ -1,99 +1,185 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - \ No newline at end of file diff --git a/apps/dashboard/src/lib/components/Icons/ExerciseIcon.svelte b/apps/dashboard/src/lib/components/Icons/ExerciseIcon.svelte index 2007e968..3eabf5b9 100644 --- a/apps/dashboard/src/lib/components/Icons/ExerciseIcon.svelte +++ b/apps/dashboard/src/lib/components/Icons/ExerciseIcon.svelte @@ -1,15 +1,12 @@ - - - - - diff --git a/apps/dashboard/src/lib/components/Icons/PasswordEye.svelte b/apps/dashboard/src/lib/components/Icons/PasswordEye.svelte index 4684515f..61191b20 100644 --- a/apps/dashboard/src/lib/components/Icons/PasswordEye.svelte +++ b/apps/dashboard/src/lib/components/Icons/PasswordEye.svelte @@ -1,16 +1,13 @@ -
-
-
- +
+
+
+ -
-

+

+

{$profile.fullname}

@@ -103,53 +97,45 @@
- -
    - -
  • - -

    {$t('lms_navigation.help')}

    + +
      + +
    • + +

      {$t('lms_navigation.help')}

    • diff --git a/apps/dashboard/src/lib/components/LMS/components/Learning.svelte b/apps/dashboard/src/lib/components/LMS/components/Learning.svelte index 7e15ab7a..c2406283 100644 --- a/apps/dashboard/src/lib/components/LMS/components/Learning.svelte +++ b/apps/dashboard/src/lib/components/LMS/components/Learning.svelte @@ -11,25 +11,25 @@ goto(`/courses/${id}/lessons?next=true`); }; - $: last3Courses = $courses.length > 0 ? $courses.slice(0, 3) : []; + let last3Courses = $derived($courses.length > 0 ? $courses.slice(0, 3) : []);
      -

      +

      {$t('dashboard.current_lesson')}

      {#if last3Courses.length > 0} -
      +
      {#each last3Courses as course}
      - +

      {course.title}

      @@ -44,20 +44,18 @@ onClick={() => gotoCourse(course.id)} /> -
      +
      + style="width: {Math.round(((course?.progress_rate ?? 0) / (course?.total_lessons ?? 0)) * 100) || 0}%" + class="bg-primary-700 absolute left-0 top-0 h-full" + >
      {/each}
      {:else}
      - +

      {$t('dashboard.no_courses')}

      {$t('dashboard.start_course')}

      diff --git a/apps/dashboard/src/lib/components/LMS/components/Profile.svelte b/apps/dashboard/src/lib/components/LMS/components/Profile.svelte index c0d5d63b..fd43f707 100644 --- a/apps/dashboard/src/lib/components/LMS/components/Profile.svelte +++ b/apps/dashboard/src/lib/components/LMS/components/Profile.svelte @@ -12,10 +12,10 @@ import LanguagePicker from '$lib/components/Org/Settings/LanguagePicker.svelte'; import { handleLocaleChange } from '$lib/utils/functions/translations'; - let avatar = ''; - let loading = false; - let hasLangChanged = false; - let locale = ''; + let avatar = $state(''); + let loading = $state(false); + let hasLangChanged = $state(false); + let locale = $derived($profile.locale); async function handleUpdate() { try { @@ -70,8 +70,6 @@ loading = false; } } - - $: locale = $profile.locale; @@ -104,11 +102,7 @@ className="w-full lg:w-60 mb-4" /> - + diff --git a/apps/dashboard/src/lib/components/MarkdownEditor/index.svelte b/apps/dashboard/src/lib/components/MarkdownEditor/index.svelte index 6a4770f9..4a938144 100644 --- a/apps/dashboard/src/lib/components/MarkdownEditor/index.svelte +++ b/apps/dashboard/src/lib/components/MarkdownEditor/index.svelte @@ -1,10 +1,9 @@ - - import { afterUpdate } from 'svelte'; +
    diff --git a/apps/dashboard/src/lib/components/Navigation/app.svelte b/apps/dashboard/src/lib/components/Navigation/app.svelte index f36e08cc..270efff5 100644 --- a/apps/dashboard/src/lib/components/Navigation/app.svelte +++ b/apps/dashboard/src/lib/components/Navigation/app.svelte @@ -1,23 +1,27 @@ - -