@openedx/frontend-app-catalog 1.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/README.rst +300 -0
- package/dist/Main.d.ts +3 -0
- package/dist/Main.js +8 -0
- package/dist/Main.js.map +1 -0
- package/dist/app.d.ts +3 -0
- package/dist/app.js +22 -0
- package/dist/app.js.map +1 -0
- package/dist/assets/images/no-course-image.svg +4 -0
- package/dist/assets/scss/_animations.scss +23 -0
- package/dist/catalog/CatalogPage.d.ts +2 -0
- package/dist/catalog/CatalogPage.js +64 -0
- package/dist/catalog/CatalogPage.js.map +1 -0
- package/dist/catalog/hooks/types.d.ts +24 -0
- package/dist/catalog/hooks/types.js +2 -0
- package/dist/catalog/hooks/types.js.map +1 -0
- package/dist/catalog/hooks/useCatalog.d.ts +29 -0
- package/dist/catalog/hooks/useCatalog.js +52 -0
- package/dist/catalog/hooks/useCatalog.js.map +1 -0
- package/dist/catalog/hooks/useCourseData.d.ts +12 -0
- package/dist/catalog/hooks/useCourseData.js +21 -0
- package/dist/catalog/hooks/useCourseData.js.map +1 -0
- package/dist/catalog/hooks/useDebouncedSearchInput.d.ts +7 -0
- package/dist/catalog/hooks/useDebouncedSearchInput.js +26 -0
- package/dist/catalog/hooks/useDebouncedSearchInput.js.map +1 -0
- package/dist/catalog/hooks/useFilter.d.ts +18 -0
- package/dist/catalog/hooks/useFilter.js +58 -0
- package/dist/catalog/hooks/useFilter.js.map +1 -0
- package/dist/catalog/hooks/usePagination.d.ts +13 -0
- package/dist/catalog/hooks/usePagination.js +25 -0
- package/dist/catalog/hooks/usePagination.js.map +1 -0
- package/dist/catalog/hooks/useSearch.d.ts +16 -0
- package/dist/catalog/hooks/useSearch.js +63 -0
- package/dist/catalog/hooks/useSearch.js.map +1 -0
- package/dist/catalog/messages.d.ts +68 -0
- package/dist/catalog/messages.js +70 -0
- package/dist/catalog/messages.js.map +1 -0
- package/dist/catalog/types.d.ts +6 -0
- package/dist/catalog/types.js +2 -0
- package/dist/catalog/types.js.map +1 -0
- package/dist/catalog/utils.d.ts +25 -0
- package/dist/catalog/utils.js +82 -0
- package/dist/catalog/utils.js.map +1 -0
- package/dist/constants.d.ts +18 -0
- package/dist/constants.js +15 -0
- package/dist/constants.js.map +1 -0
- package/dist/course-about/CourseAboutPage.d.ts +2 -0
- package/dist/course-about/CourseAboutPage.js +39 -0
- package/dist/course-about/CourseAboutPage.js.map +1 -0
- package/dist/course-about/CourseAboutPage.scss +36 -0
- package/dist/course-about/course-intro/CourseIntro.d.ts +4 -0
- package/dist/course-about/course-intro/CourseIntro.js +19 -0
- package/dist/course-about/course-intro/CourseIntro.js.map +1 -0
- package/dist/course-about/course-intro/components/EnrolledStatus.d.ts +2 -0
- package/dist/course-about/course-intro/components/EnrolledStatus.js +13 -0
- package/dist/course-about/course-intro/components/EnrolledStatus.js.map +1 -0
- package/dist/course-about/course-intro/components/EnrollmentButton.d.ts +2 -0
- package/dist/course-about/course-intro/components/EnrollmentButton.js +12 -0
- package/dist/course-about/course-intro/components/EnrollmentButton.js.map +1 -0
- package/dist/course-about/course-intro/components/StatusMessage.d.ts +2 -0
- package/dist/course-about/course-intro/components/StatusMessage.js +12 -0
- package/dist/course-about/course-intro/components/StatusMessage.js.map +1 -0
- package/dist/course-about/course-intro/components/index.d.ts +3 -0
- package/dist/course-about/course-intro/components/index.js +4 -0
- package/dist/course-about/course-intro/components/index.js.map +1 -0
- package/dist/course-about/course-intro/components/types.d.ts +18 -0
- package/dist/course-about/course-intro/components/types.js +2 -0
- package/dist/course-about/course-intro/components/types.js.map +1 -0
- package/dist/course-about/course-intro/constants.d.ts +10 -0
- package/dist/course-about/course-intro/constants.js +12 -0
- package/dist/course-about/course-intro/constants.js.map +1 -0
- package/dist/course-about/course-intro/course-media/CourseMedia.d.ts +3 -0
- package/dist/course-about/course-intro/course-media/CourseMedia.js +17 -0
- package/dist/course-about/course-intro/course-media/CourseMedia.js.map +1 -0
- package/dist/course-about/course-intro/course-media/CourseMedia.scss +24 -0
- package/dist/course-about/course-intro/course-media/messages.d.ts +8 -0
- package/dist/course-about/course-intro/course-media/messages.js +10 -0
- package/dist/course-about/course-intro/course-media/messages.js.map +1 -0
- package/dist/course-about/course-intro/course-media/types.d.ts +8 -0
- package/dist/course-about/course-intro/course-media/types.js +2 -0
- package/dist/course-about/course-intro/course-media/types.js.map +1 -0
- package/dist/course-about/course-intro/course-media/utils.d.ts +12 -0
- package/dist/course-about/course-intro/course-media/utils.js +18 -0
- package/dist/course-about/course-intro/course-media/utils.js.map +1 -0
- package/dist/course-about/course-intro/hooks/index.d.ts +2 -0
- package/dist/course-about/course-intro/hooks/index.js +3 -0
- package/dist/course-about/course-intro/hooks/index.js.map +1 -0
- package/dist/course-about/course-intro/hooks/types.d.ts +16 -0
- package/dist/course-about/course-intro/hooks/types.js +2 -0
- package/dist/course-about/course-intro/hooks/types.js.map +1 -0
- package/dist/course-about/course-intro/hooks/useEnrollmentActions.d.ts +7 -0
- package/dist/course-about/course-intro/hooks/useEnrollmentActions.js +47 -0
- package/dist/course-about/course-intro/hooks/useEnrollmentActions.js.map +1 -0
- package/dist/course-about/course-intro/hooks/useEnrollmentStatus.d.ts +4 -0
- package/dist/course-about/course-intro/hooks/useEnrollmentStatus.js +35 -0
- package/dist/course-about/course-intro/hooks/useEnrollmentStatus.js.map +1 -0
- package/dist/course-about/course-intro/messages.d.ts +43 -0
- package/dist/course-about/course-intro/messages.js +45 -0
- package/dist/course-about/course-intro/messages.js.map +1 -0
- package/dist/course-about/course-intro/utils.d.ts +4 -0
- package/dist/course-about/course-intro/utils.js +7 -0
- package/dist/course-about/course-intro/utils.js.map +1 -0
- package/dist/course-about/course-overview/index.d.ts +2 -0
- package/dist/course-about/course-overview/index.js +21 -0
- package/dist/course-about/course-overview/index.js.map +1 -0
- package/dist/course-about/course-overview/types.d.ts +4 -0
- package/dist/course-about/course-overview/types.js +2 -0
- package/dist/course-about/course-overview/types.js.map +1 -0
- package/dist/course-about/course-overview/utils.d.ts +6 -0
- package/dist/course-about/course-overview/utils.js +12 -0
- package/dist/course-about/course-overview/utils.js.map +1 -0
- package/dist/course-about/course-sidebar/CourseSidebar.d.ts +5 -0
- package/dist/course-about/course-sidebar/CourseSidebar.js +7 -0
- package/dist/course-about/course-sidebar/CourseSidebar.js.map +1 -0
- package/dist/course-about/course-sidebar/sidebar-details/SidebarDetails.d.ts +5 -0
- package/dist/course-about/course-sidebar/sidebar-details/SidebarDetails.js +38 -0
- package/dist/course-about/course-sidebar/sidebar-details/SidebarDetails.js.map +1 -0
- package/dist/course-about/course-sidebar/sidebar-details/SidebarDetailsItem.d.ts +3 -0
- package/dist/course-about/course-sidebar/sidebar-details/SidebarDetailsItem.js +5 -0
- package/dist/course-about/course-sidebar/sidebar-details/SidebarDetailsItem.js.map +1 -0
- package/dist/course-about/course-sidebar/sidebar-details/constants.d.ts +7 -0
- package/dist/course-about/course-sidebar/sidebar-details/constants.js +8 -0
- package/dist/course-about/course-sidebar/sidebar-details/constants.js.map +1 -0
- package/dist/course-about/course-sidebar/sidebar-details/messages.d.ts +43 -0
- package/dist/course-about/course-sidebar/sidebar-details/messages.js +45 -0
- package/dist/course-about/course-sidebar/sidebar-details/messages.js.map +1 -0
- package/dist/course-about/course-sidebar/sidebar-details/types.d.ts +8 -0
- package/dist/course-about/course-sidebar/sidebar-details/types.js +2 -0
- package/dist/course-about/course-sidebar/sidebar-details/types.js.map +1 -0
- package/dist/course-about/course-sidebar/sidebar-details/utils.d.ts +37 -0
- package/dist/course-about/course-sidebar/sidebar-details/utils.js +49 -0
- package/dist/course-about/course-sidebar/sidebar-details/utils.js.map +1 -0
- package/dist/course-about/course-sidebar/sidebar-social/SidebarSocial.d.ts +5 -0
- package/dist/course-about/course-sidebar/sidebar-social/SidebarSocial.js +14 -0
- package/dist/course-about/course-sidebar/sidebar-social/SidebarSocial.js.map +1 -0
- package/dist/course-about/course-sidebar/sidebar-social/SocialLinks.d.ts +5 -0
- package/dist/course-about/course-sidebar/sidebar-social/SocialLinks.js +5 -0
- package/dist/course-about/course-sidebar/sidebar-social/SocialLinks.js.map +1 -0
- package/dist/course-about/course-sidebar/sidebar-social/messages.d.ts +43 -0
- package/dist/course-about/course-sidebar/sidebar-social/messages.js +45 -0
- package/dist/course-about/course-sidebar/sidebar-social/messages.js.map +1 -0
- package/dist/course-about/course-sidebar/sidebar-social/types.d.ts +7 -0
- package/dist/course-about/course-sidebar/sidebar-social/types.js +2 -0
- package/dist/course-about/course-sidebar/sidebar-social/types.js.map +1 -0
- package/dist/course-about/course-sidebar/sidebar-social/utils.d.ts +23 -0
- package/dist/course-about/course-sidebar/sidebar-social/utils.js +71 -0
- package/dist/course-about/course-sidebar/sidebar-social/utils.js.map +1 -0
- package/dist/course-about/data/api.d.ts +10 -0
- package/dist/course-about/data/api.js +36 -0
- package/dist/course-about/data/api.js.map +1 -0
- package/dist/course-about/data/hooks.d.ts +3 -0
- package/dist/course-about/data/hooks.js +35 -0
- package/dist/course-about/data/hooks.js.map +1 -0
- package/dist/course-about/data/types.d.ts +10 -0
- package/dist/course-about/data/types.js +2 -0
- package/dist/course-about/data/types.js.map +1 -0
- package/dist/course-about/data/urls.d.ts +8 -0
- package/dist/course-about/data/urls.js +10 -0
- package/dist/course-about/data/urls.js.map +1 -0
- package/dist/course-about/layout.d.ts +31 -0
- package/dist/course-about/layout.js +11 -0
- package/dist/course-about/layout.js.map +1 -0
- package/dist/course-about/messages.d.ts +18 -0
- package/dist/course-about/messages.js +20 -0
- package/dist/course-about/messages.js.map +1 -0
- package/dist/course-about/types.d.ts +125 -0
- package/dist/course-about/types.js +2 -0
- package/dist/course-about/types.js.map +1 -0
- package/dist/data/course-list-search/api.d.ts +6 -0
- package/dist/data/course-list-search/api.js +33 -0
- package/dist/data/course-list-search/api.js.map +1 -0
- package/dist/data/course-list-search/constants.d.ts +2 -0
- package/dist/data/course-list-search/constants.js +3 -0
- package/dist/data/course-list-search/constants.js.map +1 -0
- package/dist/data/course-list-search/hooks.d.ts +5 -0
- package/dist/data/course-list-search/hooks.js +47 -0
- package/dist/data/course-list-search/hooks.js.map +1 -0
- package/dist/data/course-list-search/types.d.ts +65 -0
- package/dist/data/course-list-search/types.js +2 -0
- package/dist/data/course-list-search/types.js.map +1 -0
- package/dist/data/course-list-search/urls.d.ts +2 -0
- package/dist/data/course-list-search/urls.js +4 -0
- package/dist/data/course-list-search/urls.js.map +1 -0
- package/dist/data/course-list-search/utils.d.ts +9 -0
- package/dist/data/course-list-search/utils.js +40 -0
- package/dist/data/course-list-search/utils.js.map +1 -0
- package/dist/generic/alert-notification/index.d.ts +2 -0
- package/dist/generic/alert-notification/index.js +5 -0
- package/dist/generic/alert-notification/index.js.map +1 -0
- package/dist/generic/alert-notification/types.d.ts +6 -0
- package/dist/generic/alert-notification/types.js +2 -0
- package/dist/generic/alert-notification/types.js.map +1 -0
- package/dist/generic/course-card/index.d.ts +2 -0
- package/dist/generic/course-card/index.js +27 -0
- package/dist/generic/course-card/index.js.map +1 -0
- package/dist/generic/course-card/messages.d.ts +8 -0
- package/dist/generic/course-card/messages.js +10 -0
- package/dist/generic/course-card/messages.js.map +1 -0
- package/dist/generic/course-card/types.d.ts +35 -0
- package/dist/generic/course-card/types.js +2 -0
- package/dist/generic/course-card/types.js.map +1 -0
- package/dist/generic/course-card/utils.d.ts +10 -0
- package/dist/generic/course-card/utils.js +24 -0
- package/dist/generic/course-card/utils.js.map +1 -0
- package/dist/generic/index.d.ts +5 -0
- package/dist/generic/index.js +6 -0
- package/dist/generic/index.js.map +1 -0
- package/dist/generic/loading-spinner/index.d.ts +3 -0
- package/dist/generic/loading-spinner/index.js +10 -0
- package/dist/generic/loading-spinner/index.js.map +1 -0
- package/dist/generic/loading-spinner/messages.d.ts +8 -0
- package/dist/generic/loading-spinner/messages.js +10 -0
- package/dist/generic/loading-spinner/messages.js.map +1 -0
- package/dist/generic/loading-spinner/types.d.ts +3 -0
- package/dist/generic/loading-spinner/types.js +2 -0
- package/dist/generic/loading-spinner/types.js.map +1 -0
- package/dist/generic/sub-header/index.d.ts +2 -0
- package/dist/generic/sub-header/index.js +4 -0
- package/dist/generic/sub-header/index.js.map +1 -0
- package/dist/generic/sub-header/types.d.ts +4 -0
- package/dist/generic/sub-header/types.js +2 -0
- package/dist/generic/sub-header/types.js.map +1 -0
- package/dist/generic/video-modal/index.d.ts +2 -0
- package/dist/generic/video-modal/index.js +10 -0
- package/dist/generic/video-modal/index.js.map +1 -0
- package/dist/generic/video-modal/messages.d.ts +13 -0
- package/dist/generic/video-modal/messages.js +15 -0
- package/dist/generic/video-modal/messages.js.map +1 -0
- package/dist/generic/video-modal/types.d.ts +6 -0
- package/dist/generic/video-modal/types.js +2 -0
- package/dist/generic/video-modal/types.js.map +1 -0
- package/dist/home/HomePage.d.ts +2 -0
- package/dist/home/HomePage.js +14 -0
- package/dist/home/HomePage.js.map +1 -0
- package/dist/home/components/courses-list/CoursesList.d.ts +2 -0
- package/dist/home/components/courses-list/CoursesList.js +50 -0
- package/dist/home/components/courses-list/CoursesList.js.map +1 -0
- package/dist/home/components/courses-list/messages.d.ts +23 -0
- package/dist/home/components/courses-list/messages.js +25 -0
- package/dist/home/components/courses-list/messages.js.map +1 -0
- package/dist/home/components/home-banner/HomeBanner.d.ts +2 -0
- package/dist/home/components/home-banner/HomeBanner.js +25 -0
- package/dist/home/components/home-banner/HomeBanner.js.map +1 -0
- package/dist/home/components/home-banner/HomePageOverlay.d.ts +2 -0
- package/dist/home/components/home-banner/HomePageOverlay.js +10 -0
- package/dist/home/components/home-banner/HomePageOverlay.js.map +1 -0
- package/dist/home/components/home-banner/HomePromoVideoBtn.d.ts +3 -0
- package/dist/home/components/home-banner/HomePromoVideoBtn.js +10 -0
- package/dist/home/components/home-banner/HomePromoVideoBtn.js.map +1 -0
- package/dist/home/components/home-banner/index.scss +20 -0
- package/dist/home/components/home-banner/messages.d.ts +28 -0
- package/dist/home/components/home-banner/messages.js +30 -0
- package/dist/home/components/home-banner/messages.js.map +1 -0
- package/dist/home/components/home-banner/types.d.ts +3 -0
- package/dist/home/components/home-banner/types.js +2 -0
- package/dist/home/components/home-banner/types.js.map +1 -0
- package/dist/home/components/index.d.ts +2 -0
- package/dist/home/components/index.js +3 -0
- package/dist/home/components/index.js.map +1 -0
- package/dist/home/constants.d.ts +1 -0
- package/dist/home/constants.js +2 -0
- package/dist/home/constants.js.map +1 -0
- package/dist/home/messages.d.ts +8 -0
- package/dist/home/messages.js +10 -0
- package/dist/home/messages.js.map +1 -0
- package/dist/i18n/index.d.ts +1 -0
- package/dist/i18n/index.js +2 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/routes.d.ts +28 -0
- package/dist/routes.js +62 -0
- package/dist/routes.js.map +1 -0
- package/dist/slots/CourseAboutCourseImageSlot/index.d.ts +6 -0
- package/dist/slots/CourseAboutCourseImageSlot/index.js +9 -0
- package/dist/slots/CourseAboutCourseImageSlot/index.js.map +1 -0
- package/dist/slots/CourseAboutCourseMediaSlot/index.d.ts +9 -0
- package/dist/slots/CourseAboutCourseMediaSlot/index.js +6 -0
- package/dist/slots/CourseAboutCourseMediaSlot/index.js.map +1 -0
- package/dist/slots/CourseAboutEnrollmentButtonSlot/index.d.ts +10 -0
- package/dist/slots/CourseAboutEnrollmentButtonSlot/index.js +6 -0
- package/dist/slots/CourseAboutEnrollmentButtonSlot/index.js.map +1 -0
- package/dist/slots/CourseAboutIntroSlot/index.d.ts +6 -0
- package/dist/slots/CourseAboutIntroSlot/index.js +6 -0
- package/dist/slots/CourseAboutIntroSlot/index.js.map +1 -0
- package/dist/slots/CourseAboutIntroVideoSlots/CourseAboutIntroVideoButtonSlot/index.d.ts +6 -0
- package/dist/slots/CourseAboutIntroVideoSlots/CourseAboutIntroVideoButtonSlot/index.js +11 -0
- package/dist/slots/CourseAboutIntroVideoSlots/CourseAboutIntroVideoButtonSlot/index.js.map +1 -0
- package/dist/slots/CourseAboutIntroVideoSlots/CourseAboutIntroVideoModalContentSlot/index.d.ts +6 -0
- package/dist/slots/CourseAboutIntroVideoSlots/CourseAboutIntroVideoModalContentSlot/index.js +9 -0
- package/dist/slots/CourseAboutIntroVideoSlots/CourseAboutIntroVideoModalContentSlot/index.js.map +1 -0
- package/dist/slots/CourseAboutIntroVideoSlots/CourseAboutIntroVideoModalSlot/index.d.ts +6 -0
- package/dist/slots/CourseAboutIntroVideoSlots/CourseAboutIntroVideoModalSlot/index.js +6 -0
- package/dist/slots/CourseAboutIntroVideoSlots/CourseAboutIntroVideoModalSlot/index.js.map +1 -0
- package/dist/slots/CourseAboutIntroVideoSlots/index.d.ts +4 -0
- package/dist/slots/CourseAboutIntroVideoSlots/index.js +5 -0
- package/dist/slots/CourseAboutIntroVideoSlots/index.js.map +1 -0
- package/dist/slots/CourseAboutOverviewSlot/index.d.ts +6 -0
- package/dist/slots/CourseAboutOverviewSlot/index.js +6 -0
- package/dist/slots/CourseAboutOverviewSlot/index.js.map +1 -0
- package/dist/slots/CourseAboutSidebarCoursePriceSlot/index.d.ts +6 -0
- package/dist/slots/CourseAboutSidebarCoursePriceSlot/index.js +11 -0
- package/dist/slots/CourseAboutSidebarCoursePriceSlot/index.js.map +1 -0
- package/dist/slots/CourseAboutSidebarSlot/index.d.ts +6 -0
- package/dist/slots/CourseAboutSidebarSlot/index.js +6 -0
- package/dist/slots/CourseAboutSidebarSlot/index.js.map +1 -0
- package/dist/slots/CourseAboutSidebarSocialSlot/index.d.ts +6 -0
- package/dist/slots/CourseAboutSidebarSocialSlot/index.js +22 -0
- package/dist/slots/CourseAboutSidebarSocialSlot/index.js.map +1 -0
- package/dist/slots/CourseCatalogDataTableSlots/CourseCatalogDataTableCardViewSlot/CourseCatalogDataTableCourseCardSlot/index.d.ts +16 -0
- package/dist/slots/CourseCatalogDataTableSlots/CourseCatalogDataTableCardViewSlot/CourseCatalogDataTableCourseCardSlot/index.js +18 -0
- package/dist/slots/CourseCatalogDataTableSlots/CourseCatalogDataTableCardViewSlot/CourseCatalogDataTableCourseCardSlot/index.js.map +1 -0
- package/dist/slots/CourseCatalogDataTableSlots/CourseCatalogDataTableCardViewSlot/index.d.ts +6 -0
- package/dist/slots/CourseCatalogDataTableSlots/CourseCatalogDataTableCardViewSlot/index.js +11 -0
- package/dist/slots/CourseCatalogDataTableSlots/CourseCatalogDataTableCardViewSlot/index.js.map +1 -0
- package/dist/slots/CourseCatalogDataTableSlots/CourseCatalogDataTableControlBarSlot/index.d.ts +6 -0
- package/dist/slots/CourseCatalogDataTableSlots/CourseCatalogDataTableControlBarSlot/index.js +6 -0
- package/dist/slots/CourseCatalogDataTableSlots/CourseCatalogDataTableControlBarSlot/index.js.map +1 -0
- package/dist/slots/CourseCatalogDataTableSlots/CourseCatalogDataTableSlot/index.d.ts +23 -0
- package/dist/slots/CourseCatalogDataTableSlots/CourseCatalogDataTableSlot/index.js +17 -0
- package/dist/slots/CourseCatalogDataTableSlots/CourseCatalogDataTableSlot/index.js.map +1 -0
- package/dist/slots/CourseCatalogDataTableSlots/CourseCatalogDataTableTableFooterSlot/index.d.ts +2 -0
- package/dist/slots/CourseCatalogDataTableSlots/CourseCatalogDataTableTableFooterSlot/index.js +6 -0
- package/dist/slots/CourseCatalogDataTableSlots/CourseCatalogDataTableTableFooterSlot/index.js.map +1 -0
- package/dist/slots/CourseCatalogDataTableSlots/index.d.ts +6 -0
- package/dist/slots/CourseCatalogDataTableSlots/index.js +7 -0
- package/dist/slots/CourseCatalogDataTableSlots/index.js.map +1 -0
- package/dist/slots/CourseCatalogIntroSlot/index.d.ts +6 -0
- package/dist/slots/CourseCatalogIntroSlot/index.js +17 -0
- package/dist/slots/CourseCatalogIntroSlot/index.js.map +1 -0
- package/dist/slots/CourseCatalogSearchFieldSlot/index.d.ts +7 -0
- package/dist/slots/CourseCatalogSearchFieldSlot/index.js +21 -0
- package/dist/slots/CourseCatalogSearchFieldSlot/index.js.map +1 -0
- package/dist/slots/HomeBannerSlot/index.d.ts +2 -0
- package/dist/slots/HomeBannerSlot/index.js +6 -0
- package/dist/slots/HomeBannerSlot/index.js.map +1 -0
- package/dist/slots/HomeCourseCardSlot/index.d.ts +16 -0
- package/dist/slots/HomeCourseCardSlot/index.js +18 -0
- package/dist/slots/HomeCourseCardSlot/index.js.map +1 -0
- package/dist/slots/HomeCoursesListSlot/index.d.ts +2 -0
- package/dist/slots/HomeCoursesListSlot/index.js +6 -0
- package/dist/slots/HomeCoursesListSlot/index.js.map +1 -0
- package/dist/slots/HomeOverlayHtmlSlot/index.d.ts +2 -0
- package/dist/slots/HomeOverlayHtmlSlot/index.js +6 -0
- package/dist/slots/HomeOverlayHtmlSlot/index.js.map +1 -0
- package/dist/slots/HomePromoVideoSlots/HomePromoVideoButtonSlot/index.d.ts +4 -0
- package/dist/slots/HomePromoVideoSlots/HomePromoVideoButtonSlot/index.js +8 -0
- package/dist/slots/HomePromoVideoSlots/HomePromoVideoButtonSlot/index.js.map +1 -0
- package/dist/slots/HomePromoVideoSlots/HomePromoVideoModalContentSlot/index.d.ts +6 -0
- package/dist/slots/HomePromoVideoSlots/HomePromoVideoModalContentSlot/index.js +9 -0
- package/dist/slots/HomePromoVideoSlots/HomePromoVideoModalContentSlot/index.js.map +1 -0
- package/dist/slots/HomePromoVideoSlots/HomePromoVideoModalSlot/index.d.ts +6 -0
- package/dist/slots/HomePromoVideoSlots/HomePromoVideoModalSlot/index.js +6 -0
- package/dist/slots/HomePromoVideoSlots/HomePromoVideoModalSlot/index.js.map +1 -0
- package/dist/slots/HomePromoVideoSlots/index.d.ts +4 -0
- package/dist/slots/HomePromoVideoSlots/index.js +5 -0
- package/dist/slots/HomePromoVideoSlots/index.js.map +1 -0
- package/dist/slots/LoaderSlot/index.d.ts +3 -0
- package/dist/slots/LoaderSlot/index.js +4 -0
- package/dist/slots/LoaderSlot/index.js.map +1 -0
- package/dist/slots.d.ts +3 -0
- package/dist/slots.js +7 -0
- package/dist/slots.js.map +1 -0
- package/dist/style.scss +4 -0
- package/dist/utils.d.ts +6 -0
- package/dist/utils.js +9 -0
- package/dist/utils.js.map +1 -0
- package/dist/widgets/CatalogHeader/CoursesLinkMenuItem.d.ts +3 -0
- package/dist/widgets/CatalogHeader/CoursesLinkMenuItem.js +9 -0
- package/dist/widgets/CatalogHeader/CoursesLinkMenuItem.js.map +1 -0
- package/dist/widgets/CatalogHeader/DiscoverLinkMenuItem.d.ts +3 -0
- package/dist/widgets/CatalogHeader/DiscoverLinkMenuItem.js +9 -0
- package/dist/widgets/CatalogHeader/DiscoverLinkMenuItem.js.map +1 -0
- package/dist/widgets/CatalogHeader/ExploreCoursesLinkMenuItem.d.ts +3 -0
- package/dist/widgets/CatalogHeader/ExploreCoursesLinkMenuItem.js +9 -0
- package/dist/widgets/CatalogHeader/ExploreCoursesLinkMenuItem.js.map +1 -0
- package/dist/widgets/CatalogHeader/ProgramsLinkMenuItem.d.ts +3 -0
- package/dist/widgets/CatalogHeader/ProgramsLinkMenuItem.js +9 -0
- package/dist/widgets/CatalogHeader/ProgramsLinkMenuItem.js.map +1 -0
- package/dist/widgets/CatalogHeader/app.d.ts +3 -0
- package/dist/widgets/CatalogHeader/app.js +55 -0
- package/dist/widgets/CatalogHeader/app.js.map +1 -0
- package/dist/widgets/CatalogHeader/index.d.ts +1 -0
- package/dist/widgets/CatalogHeader/index.js +2 -0
- package/dist/widgets/CatalogHeader/index.js.map +1 -0
- package/dist/widgets/CatalogHeader/messages.d.ts +32 -0
- package/dist/widgets/CatalogHeader/messages.js +25 -0
- package/dist/widgets/CatalogHeader/messages.js.map +1 -0
- package/package.json +86 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { useEffect, useMemo, useState, useDeferredValue, useRef, } from 'react';
|
|
2
|
+
import debounce from 'lodash.debounce';
|
|
3
|
+
/**
|
|
4
|
+
* Custom hook for managing debounced search input with deferred value optimization.
|
|
5
|
+
*/
|
|
6
|
+
export const useDebouncedSearchInput = ({ searchString, handleSearch, debounceDelay = 300, }) => {
|
|
7
|
+
const [searchInput, setSearchInput] = useState(searchString !== null && searchString !== void 0 ? searchString : '');
|
|
8
|
+
const deferredSearchInput = useDeferredValue(searchInput);
|
|
9
|
+
const lastQueryRef = useRef('');
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
setSearchInput(searchString !== null && searchString !== void 0 ? searchString : '');
|
|
12
|
+
}, [searchString]);
|
|
13
|
+
const debouncedHandleSearch = useMemo(() => debounce((value) => {
|
|
14
|
+
handleSearch(value);
|
|
15
|
+
}, debounceDelay), [handleSearch, debounceDelay]);
|
|
16
|
+
useEffect(() => () => debouncedHandleSearch.cancel(), [debouncedHandleSearch]);
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (deferredSearchInput === lastQueryRef.current) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
lastQueryRef.current = deferredSearchInput;
|
|
22
|
+
debouncedHandleSearch(deferredSearchInput);
|
|
23
|
+
}, [deferredSearchInput, debouncedHandleSearch]);
|
|
24
|
+
return { setSearchInput };
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=useDebouncedSearchInput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDebouncedSearchInput.js","sourceRoot":"","sources":["../../../src/catalog/hooks/useDebouncedSearchInput.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,GACvD,MAAM,OAAO,CAAC;AACf,OAAO,QAAQ,MAAM,iBAAiB,CAAC;AAIvC;;GAEG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,EACtC,YAAY,EACZ,YAAY,EACZ,aAAa,GAAG,GAAG,GACU,EAAE,EAAE;IACjC,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,YAAY,aAAZ,YAAY,cAAZ,YAAY,GAAI,EAAE,CAAC,CAAC;IACnE,MAAM,mBAAmB,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;IAC1D,MAAM,YAAY,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;IAEhC,SAAS,CAAC,GAAG,EAAE;QACb,cAAc,CAAC,YAAY,aAAZ,YAAY,cAAZ,YAAY,GAAI,EAAE,CAAC,CAAC;IACrC,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IAEnB,MAAM,qBAAqB,GAAG,OAAO,CACnC,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,KAAa,EAAE,EAAE;QAC/B,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC,EAAE,aAAa,CAAC,EACjB,CAAC,YAAY,EAAE,aAAa,CAAC,CAC9B,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,qBAAqB,CAAC,MAAM,EAAE,EAAE,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAE/E,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,mBAAmB,KAAK,YAAY,CAAC,OAAO,EAAE,CAAC;YACjD,OAAO;QACT,CAAC;QAED,YAAY,CAAC,OAAO,GAAG,mBAAmB,CAAC;QAC3C,qBAAqB,CAAC,mBAAmB,CAAC,CAAC;IAC7C,CAAC,EAAE,CAAC,mBAAmB,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAEjD,OAAO,EAAE,cAAc,EAAE,CAAC;AAC5B,CAAC,CAAC","sourcesContent":["import {\n useEffect, useMemo, useState, useDeferredValue, useRef,\n} from 'react';\nimport debounce from 'lodash.debounce';\n\nimport type { UseDebouncedSearchInputProps } from './types';\n\n/**\n * Custom hook for managing debounced search input with deferred value optimization.\n */\nexport const useDebouncedSearchInput = ({\n searchString,\n handleSearch,\n debounceDelay = 300,\n}: UseDebouncedSearchInputProps) => {\n const [searchInput, setSearchInput] = useState(searchString ?? '');\n const deferredSearchInput = useDeferredValue(searchInput);\n const lastQueryRef = useRef('');\n\n useEffect(() => {\n setSearchInput(searchString ?? '');\n }, [searchString]);\n\n const debouncedHandleSearch = useMemo(\n () => debounce((value: string) => {\n handleSearch(value);\n }, debounceDelay),\n [handleSearch, debounceDelay],\n );\n\n useEffect(() => () => debouncedHandleSearch.cancel(), [debouncedHandleSearch]);\n\n useEffect(() => {\n if (deferredSearchInput === lastQueryRef.current) {\n return;\n }\n\n lastQueryRef.current = deferredSearchInput;\n debouncedHandleSearch(deferredSearchInput);\n }, [deferredSearchInput, debouncedHandleSearch]);\n\n return { setSearchInput };\n};\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { DataTableFilter, DataTableParams } from '../../data/course-list-search/types';
|
|
2
|
+
/**
|
|
3
|
+
* Custom hook for managing filter state and handling filter changes in the catalog.
|
|
4
|
+
*
|
|
5
|
+
* This hook provides functionality to:
|
|
6
|
+
* - Track previous filter state to detect changes
|
|
7
|
+
* - Prevent duplicate API calls during filter transitions
|
|
8
|
+
* - Reset pagination when filters change
|
|
9
|
+
* - Handle filter change progress state
|
|
10
|
+
*/
|
|
11
|
+
export declare const useFilter: () => {
|
|
12
|
+
filterState: {
|
|
13
|
+
previousFilters: any[] | Record<string, any> | null;
|
|
14
|
+
isFilterChangeInProgress: boolean;
|
|
15
|
+
};
|
|
16
|
+
resetFilterProgress: () => void;
|
|
17
|
+
handleFilterChange: (newFilters: DataTableFilter[], fetchData: (params: DataTableParams) => void, searchString: string) => boolean;
|
|
18
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { useState, useCallback } from 'react';
|
|
2
|
+
import { DEFAULT_PAGE_SIZE, DEFAULT_PAGE_INDEX } from '../../data/course-list-search/constants';
|
|
3
|
+
import { compareFilters } from '../utils';
|
|
4
|
+
const INITIAL_FILTER_STATE = {
|
|
5
|
+
previousFilters: null,
|
|
6
|
+
isFilterChangeInProgress: false,
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Custom hook for managing filter state and handling filter changes in the catalog.
|
|
10
|
+
*
|
|
11
|
+
* This hook provides functionality to:
|
|
12
|
+
* - Track previous filter state to detect changes
|
|
13
|
+
* - Prevent duplicate API calls during filter transitions
|
|
14
|
+
* - Reset pagination when filters change
|
|
15
|
+
* - Handle filter change progress state
|
|
16
|
+
*/
|
|
17
|
+
export const useFilter = () => {
|
|
18
|
+
const [filterState, setFilterState] = useState(INITIAL_FILTER_STATE);
|
|
19
|
+
/**
|
|
20
|
+
* Resets the filter change progress flag.
|
|
21
|
+
*
|
|
22
|
+
* This function should be called when the API request completes
|
|
23
|
+
* to allow new filter changes to be processed.
|
|
24
|
+
*/
|
|
25
|
+
const resetFilterProgress = useCallback(() => {
|
|
26
|
+
setFilterState(prev => (Object.assign(Object.assign({}, prev), { isFilterChangeInProgress: false })));
|
|
27
|
+
}, []);
|
|
28
|
+
/**
|
|
29
|
+
* Handles filter changes to prevent duplicate API calls.
|
|
30
|
+
*/
|
|
31
|
+
const handleFilterChange = useCallback((newFilters, fetchData, searchString) => {
|
|
32
|
+
const hasFilters = Array.isArray(newFilters) && Object.keys(newFilters).length > 0;
|
|
33
|
+
const hadFilters = filterState.previousFilters && Object.keys(filterState.previousFilters).length > 0;
|
|
34
|
+
const filtersChanged = filterState.previousFilters !== null
|
|
35
|
+
&& !compareFilters(newFilters, filterState.previousFilters);
|
|
36
|
+
const isFirstFilterApplied = !hadFilters && hasFilters;
|
|
37
|
+
if (filterState.isFilterChangeInProgress) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
if (filtersChanged || isFirstFilterApplied) {
|
|
41
|
+
setFilterState(prev => (Object.assign(Object.assign({}, prev), { isFilterChangeInProgress: true, previousFilters: newFilters || {} })));
|
|
42
|
+
fetchData({
|
|
43
|
+
pageIndex: DEFAULT_PAGE_INDEX,
|
|
44
|
+
pageSize: DEFAULT_PAGE_SIZE,
|
|
45
|
+
filters: newFilters,
|
|
46
|
+
searchString,
|
|
47
|
+
});
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
}, [filterState]);
|
|
52
|
+
return {
|
|
53
|
+
filterState,
|
|
54
|
+
resetFilterProgress,
|
|
55
|
+
handleFilterChange,
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=useFilter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFilter.js","sourceRoot":"","sources":["../../../src/catalog/hooks/useFilter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAE9C,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAE/F,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE1C,MAAM,oBAAoB,GAAG;IAC3B,eAAe,EAAE,IAA0C;IAC3D,wBAAwB,EAAE,KAAK;CAChC,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,EAAE;IAC5B,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,oBAAoB,CAAC,CAAC;IAErE;;;;;OAKG;IACH,MAAM,mBAAmB,GAAG,WAAW,CAAC,GAAG,EAAE;QAC3C,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,iCAClB,IAAI,KACP,wBAAwB,EAAE,KAAK,IAC/B,CAAC,CAAC;IACN,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP;;OAEG;IACH,MAAM,kBAAkB,GAAG,WAAW,CAAC,CACrC,UAA6B,EAC7B,SAA4C,EAC5C,YAAoB,EACpB,EAAE;QACF,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;QACnF,MAAM,UAAU,GAAG,WAAW,CAAC,eAAe,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;QACtG,MAAM,cAAc,GAAG,WAAW,CAAC,eAAe,KAAK,IAAI;eACtD,CAAC,cAAc,CAAC,UAAU,EAAE,WAAW,CAAC,eAAoC,CAAC,CAAC;QACnF,MAAM,oBAAoB,GAAG,CAAC,UAAU,IAAI,UAAU,CAAC;QAEvD,IAAI,WAAW,CAAC,wBAAwB,EAAE,CAAC;YACzC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,cAAc,IAAI,oBAAoB,EAAE,CAAC;YAC3C,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,iCAClB,IAAI,KACP,wBAAwB,EAAE,IAAI,EAC9B,eAAe,EAAE,UAAU,IAAI,EAAE,IACjC,CAAC,CAAC;YAEJ,SAAS,CAAC;gBACR,SAAS,EAAE,kBAAkB;gBAC7B,QAAQ,EAAE,iBAAiB;gBAC3B,OAAO,EAAE,UAAU;gBACnB,YAAY;aACb,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IAElB,OAAO;QACL,WAAW;QACX,mBAAmB;QACnB,kBAAkB;KACnB,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { useState, useCallback } from 'react';\n\nimport { DEFAULT_PAGE_SIZE, DEFAULT_PAGE_INDEX } from '@src/data/course-list-search/constants';\nimport type { DataTableFilter, DataTableParams } from '@src/data/course-list-search/types';\nimport { compareFilters } from '../utils';\n\nconst INITIAL_FILTER_STATE = {\n previousFilters: null as any[] | Record<string, any> | null,\n isFilterChangeInProgress: false,\n};\n\n/**\n * Custom hook for managing filter state and handling filter changes in the catalog.\n *\n * This hook provides functionality to:\n * - Track previous filter state to detect changes\n * - Prevent duplicate API calls during filter transitions\n * - Reset pagination when filters change\n * - Handle filter change progress state\n */\nexport const useFilter = () => {\n const [filterState, setFilterState] = useState(INITIAL_FILTER_STATE);\n\n /**\n * Resets the filter change progress flag.\n *\n * This function should be called when the API request completes\n * to allow new filter changes to be processed.\n */\n const resetFilterProgress = useCallback(() => {\n setFilterState(prev => ({\n ...prev,\n isFilterChangeInProgress: false,\n }));\n }, []);\n\n /**\n * Handles filter changes to prevent duplicate API calls.\n */\n const handleFilterChange = useCallback((\n newFilters: DataTableFilter[],\n fetchData: (params: DataTableParams) => void,\n searchString: string,\n ) => {\n const hasFilters = Array.isArray(newFilters) && Object.keys(newFilters).length > 0;\n const hadFilters = filterState.previousFilters && Object.keys(filterState.previousFilters).length > 0;\n const filtersChanged = filterState.previousFilters !== null\n && !compareFilters(newFilters, filterState.previousFilters as DataTableFilter[]);\n const isFirstFilterApplied = !hadFilters && hasFilters;\n\n if (filterState.isFilterChangeInProgress) {\n return false;\n }\n\n if (filtersChanged || isFirstFilterApplied) {\n setFilterState(prev => ({\n ...prev,\n isFilterChangeInProgress: true,\n previousFilters: newFilters || {},\n }));\n\n fetchData({\n pageIndex: DEFAULT_PAGE_INDEX,\n pageSize: DEFAULT_PAGE_SIZE,\n filters: newFilters,\n searchString,\n });\n return true;\n }\n\n return false;\n }, [filterState]);\n\n return {\n filterState,\n resetFilterProgress,\n handleFilterChange,\n };\n};\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom hook for managing pagination state in the DataTable.
|
|
3
|
+
*
|
|
4
|
+
* This hook provides functionality to:
|
|
5
|
+
* - Track current page index
|
|
6
|
+
* - Handle page changes
|
|
7
|
+
* - Reset pagination to the first page
|
|
8
|
+
*/
|
|
9
|
+
export declare const usePagination: () => {
|
|
10
|
+
pageIndex: number;
|
|
11
|
+
handlePageChange: (newPageIndex: number) => void;
|
|
12
|
+
resetPagination: () => void;
|
|
13
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { useState, useCallback } from 'react';
|
|
2
|
+
import { DEFAULT_PAGE_INDEX } from '../../data/course-list-search/constants';
|
|
3
|
+
/**
|
|
4
|
+
* Custom hook for managing pagination state in the DataTable.
|
|
5
|
+
*
|
|
6
|
+
* This hook provides functionality to:
|
|
7
|
+
* - Track current page index
|
|
8
|
+
* - Handle page changes
|
|
9
|
+
* - Reset pagination to the first page
|
|
10
|
+
*/
|
|
11
|
+
export const usePagination = () => {
|
|
12
|
+
const [pageIndex, setPageIndex] = useState(DEFAULT_PAGE_INDEX);
|
|
13
|
+
const handlePageChange = useCallback((newPageIndex) => {
|
|
14
|
+
setPageIndex(newPageIndex);
|
|
15
|
+
}, []);
|
|
16
|
+
const resetPagination = useCallback(() => {
|
|
17
|
+
setPageIndex(DEFAULT_PAGE_INDEX);
|
|
18
|
+
}, []);
|
|
19
|
+
return {
|
|
20
|
+
pageIndex,
|
|
21
|
+
handlePageChange,
|
|
22
|
+
resetPagination,
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=usePagination.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePagination.js","sourceRoot":"","sources":["../../../src/catalog/hooks/usePagination.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAE9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAE5E;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,EAAE;IAChC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IAE/D,MAAM,gBAAgB,GAAG,WAAW,CAAC,CAAC,YAAoB,EAAE,EAAE;QAC5D,YAAY,CAAC,YAAY,CAAC,CAAC;IAC7B,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,eAAe,GAAG,WAAW,CAAC,GAAG,EAAE;QACvC,YAAY,CAAC,kBAAkB,CAAC,CAAC;IACnC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO;QACL,SAAS;QACT,gBAAgB;QAChB,eAAe;KAChB,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { useState, useCallback } from 'react';\n\nimport { DEFAULT_PAGE_INDEX } from '@src/data/course-list-search/constants';\n\n/**\n * Custom hook for managing pagination state in the DataTable.\n *\n * This hook provides functionality to:\n * - Track current page index\n * - Handle page changes\n * - Reset pagination to the first page\n */\nexport const usePagination = () => {\n const [pageIndex, setPageIndex] = useState(DEFAULT_PAGE_INDEX);\n\n const handlePageChange = useCallback((newPageIndex: number) => {\n setPageIndex(newPageIndex);\n }, []);\n\n const resetPagination = useCallback(() => {\n setPageIndex(DEFAULT_PAGE_INDEX);\n }, []);\n\n return {\n pageIndex,\n handlePageChange,\n resetPagination,\n };\n};\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { UseSearchProps } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Custom hook for managing search functionality in the catalog.
|
|
4
|
+
*
|
|
5
|
+
* This hook provides functionality to:
|
|
6
|
+
* - Handle search queries and synchronize them with URL parameters
|
|
7
|
+
* - Manage search state (current query and URL query)
|
|
8
|
+
* - Initialize search from URL parameters on component mount
|
|
9
|
+
* - Track initialization state to prevent duplicate API calls
|
|
10
|
+
*/
|
|
11
|
+
export declare const useSearch: ({ fetchData, isFetching, searchParams, setSearchParams, }: UseSearchProps) => {
|
|
12
|
+
hasInitializedFromUrl: boolean;
|
|
13
|
+
urlSearchQuery: string;
|
|
14
|
+
searchString: string;
|
|
15
|
+
handleSearch: (query: string) => void;
|
|
16
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { useState, useCallback, useEffect } from 'react';
|
|
2
|
+
import { DEFAULT_PAGE_SIZE, DEFAULT_PAGE_INDEX } from '../../data/course-list-search/constants';
|
|
3
|
+
/**
|
|
4
|
+
* Custom hook for managing search functionality in the catalog.
|
|
5
|
+
*
|
|
6
|
+
* This hook provides functionality to:
|
|
7
|
+
* - Handle search queries and synchronize them with URL parameters
|
|
8
|
+
* - Manage search state (current query and URL query)
|
|
9
|
+
* - Initialize search from URL parameters on component mount
|
|
10
|
+
* - Track initialization state to prevent duplicate API calls
|
|
11
|
+
*/
|
|
12
|
+
export const useSearch = ({ fetchData, isFetching, searchParams, setSearchParams, }) => {
|
|
13
|
+
const [searchString, setSearchString] = useState('');
|
|
14
|
+
const [hasInitializedFromUrl, setHasInitializedFromUrl] = useState(false);
|
|
15
|
+
const urlSearchQuery = searchParams.get('search_query') || '';
|
|
16
|
+
/**
|
|
17
|
+
* Handles search operations to ensure proper state management and API calls.
|
|
18
|
+
*/
|
|
19
|
+
const handleSearch = useCallback((query) => {
|
|
20
|
+
setSearchString(query);
|
|
21
|
+
const newParams = new URLSearchParams(searchParams.toString());
|
|
22
|
+
if (query) {
|
|
23
|
+
newParams.set('search_query', query);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
newParams.delete('search_query');
|
|
27
|
+
}
|
|
28
|
+
setSearchParams(newParams, { replace: true });
|
|
29
|
+
fetchData({
|
|
30
|
+
pageIndex: DEFAULT_PAGE_INDEX,
|
|
31
|
+
pageSize: DEFAULT_PAGE_SIZE,
|
|
32
|
+
filters: [],
|
|
33
|
+
searchString: query,
|
|
34
|
+
});
|
|
35
|
+
}, [fetchData, searchParams, setSearchParams]);
|
|
36
|
+
/**
|
|
37
|
+
* Initializes search state from URL parameters on component mount.
|
|
38
|
+
*/
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
if (hasInitializedFromUrl) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (urlSearchQuery && !searchString) {
|
|
44
|
+
setSearchString(urlSearchQuery);
|
|
45
|
+
if (!isFetching) {
|
|
46
|
+
fetchData({
|
|
47
|
+
pageIndex: DEFAULT_PAGE_INDEX,
|
|
48
|
+
pageSize: DEFAULT_PAGE_SIZE,
|
|
49
|
+
filters: [],
|
|
50
|
+
searchString: urlSearchQuery,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
setHasInitializedFromUrl(true);
|
|
55
|
+
}, [urlSearchQuery, hasInitializedFromUrl, isFetching, fetchData, searchString]);
|
|
56
|
+
return {
|
|
57
|
+
hasInitializedFromUrl,
|
|
58
|
+
urlSearchQuery,
|
|
59
|
+
searchString,
|
|
60
|
+
handleSearch,
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=useSearch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSearch.js","sourceRoot":"","sources":["../../../src/catalog/hooks/useSearch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEzD,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAG/F;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,EACxB,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,eAAe,GACrC,EAAE,EAAE;IACnB,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IAErD,MAAM,CAAC,qBAAqB,EAAE,wBAAwB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE1E,MAAM,cAAc,GAAG,YAAY,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;IAE9D;;OAEG;IACH,MAAM,YAAY,GAAG,WAAW,CAAC,CAAC,KAAa,EAAE,EAAE;QACjD,eAAe,CAAC,KAAK,CAAC,CAAC;QAEvB,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC/D,IAAI,KAAK,EAAE,CAAC;YACV,SAAS,CAAC,GAAG,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QACnC,CAAC;QACD,eAAe,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAE9C,SAAS,CAAC;YACR,SAAS,EAAE,kBAAkB;YAC7B,QAAQ,EAAE,iBAAiB;YAC3B,OAAO,EAAE,EAAE;YACX,YAAY,EAAE,KAAK;SACpB,CAAC,CAAC;IACL,CAAC,EAAE,CAAC,SAAS,EAAE,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC;IAE/C;;OAEG;IACH,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,qBAAqB,EAAE,CAAC;YAC1B,OAAO;QACT,CAAC;QAED,IAAI,cAAc,IAAI,CAAC,YAAY,EAAE,CAAC;YACpC,eAAe,CAAC,cAAc,CAAC,CAAC;YAChC,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,SAAS,CAAC;oBACR,SAAS,EAAE,kBAAkB;oBAC7B,QAAQ,EAAE,iBAAiB;oBAC3B,OAAO,EAAE,EAAE;oBACX,YAAY,EAAE,cAAc;iBAC7B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,wBAAwB,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC,EAAE,CAAC,cAAc,EAAE,qBAAqB,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC,CAAC;IAEjF,OAAO;QACL,qBAAqB;QACrB,cAAc;QACd,YAAY;QACZ,YAAY;KACb,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { useState, useCallback, useEffect } from 'react';\n\nimport { DEFAULT_PAGE_SIZE, DEFAULT_PAGE_INDEX } from '@src/data/course-list-search/constants';\nimport type { UseSearchProps } from './types';\n\n/**\n * Custom hook for managing search functionality in the catalog.\n *\n * This hook provides functionality to:\n * - Handle search queries and synchronize them with URL parameters\n * - Manage search state (current query and URL query)\n * - Initialize search from URL parameters on component mount\n * - Track initialization state to prevent duplicate API calls\n */\nexport const useSearch = ({\n fetchData, isFetching, searchParams, setSearchParams,\n}: UseSearchProps) => {\n const [searchString, setSearchString] = useState('');\n\n const [hasInitializedFromUrl, setHasInitializedFromUrl] = useState(false);\n\n const urlSearchQuery = searchParams.get('search_query') || '';\n\n /**\n * Handles search operations to ensure proper state management and API calls.\n */\n const handleSearch = useCallback((query: string) => {\n setSearchString(query);\n\n const newParams = new URLSearchParams(searchParams.toString());\n if (query) {\n newParams.set('search_query', query);\n } else {\n newParams.delete('search_query');\n }\n setSearchParams(newParams, { replace: true });\n\n fetchData({\n pageIndex: DEFAULT_PAGE_INDEX,\n pageSize: DEFAULT_PAGE_SIZE,\n filters: [],\n searchString: query,\n });\n }, [fetchData, searchParams, setSearchParams]);\n\n /**\n * Initializes search state from URL parameters on component mount.\n */\n useEffect(() => {\n if (hasInitializedFromUrl) {\n return;\n }\n\n if (urlSearchQuery && !searchString) {\n setSearchString(urlSearchQuery);\n if (!isFetching) {\n fetchData({\n pageIndex: DEFAULT_PAGE_INDEX,\n pageSize: DEFAULT_PAGE_SIZE,\n filters: [],\n searchString: urlSearchQuery,\n });\n }\n }\n setHasInitializedFromUrl(true);\n }, [urlSearchQuery, hasInitializedFromUrl, isFetching, fetchData, searchString]);\n\n return {\n hasInitializedFromUrl,\n urlSearchQuery,\n searchString,\n handleSearch,\n };\n};\n"]}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
declare const messages: {
|
|
2
|
+
pageTitle: {
|
|
3
|
+
id: string;
|
|
4
|
+
defaultMessage: string;
|
|
5
|
+
description: string;
|
|
6
|
+
};
|
|
7
|
+
pageHeading: {
|
|
8
|
+
id: string;
|
|
9
|
+
defaultMessage: string;
|
|
10
|
+
description: string;
|
|
11
|
+
};
|
|
12
|
+
errorMessage: {
|
|
13
|
+
id: string;
|
|
14
|
+
defaultMessage: string;
|
|
15
|
+
description: string;
|
|
16
|
+
};
|
|
17
|
+
noCoursesAvailable: {
|
|
18
|
+
id: string;
|
|
19
|
+
defaultMessage: string;
|
|
20
|
+
description: string;
|
|
21
|
+
};
|
|
22
|
+
noCoursesAvailableMessage: {
|
|
23
|
+
id: string;
|
|
24
|
+
defaultMessage: string;
|
|
25
|
+
description: string;
|
|
26
|
+
};
|
|
27
|
+
searchPlaceholder: {
|
|
28
|
+
id: string;
|
|
29
|
+
defaultMessage: string;
|
|
30
|
+
description: string;
|
|
31
|
+
};
|
|
32
|
+
searchResults: {
|
|
33
|
+
id: string;
|
|
34
|
+
defaultMessage: string;
|
|
35
|
+
description: string;
|
|
36
|
+
};
|
|
37
|
+
noSearchResults: {
|
|
38
|
+
id: string;
|
|
39
|
+
defaultMessage: string;
|
|
40
|
+
description: string;
|
|
41
|
+
};
|
|
42
|
+
exploreCourses: {
|
|
43
|
+
id: string;
|
|
44
|
+
defaultMessage: string;
|
|
45
|
+
description: string;
|
|
46
|
+
};
|
|
47
|
+
noResultsFound: {
|
|
48
|
+
id: string;
|
|
49
|
+
defaultMessage: string;
|
|
50
|
+
description: string;
|
|
51
|
+
};
|
|
52
|
+
organizations: {
|
|
53
|
+
id: string;
|
|
54
|
+
defaultMessage: string;
|
|
55
|
+
description: string;
|
|
56
|
+
};
|
|
57
|
+
languages: {
|
|
58
|
+
id: string;
|
|
59
|
+
defaultMessage: string;
|
|
60
|
+
description: string;
|
|
61
|
+
};
|
|
62
|
+
courseTypes: {
|
|
63
|
+
id: string;
|
|
64
|
+
defaultMessage: string;
|
|
65
|
+
description: string;
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
export default messages;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { defineMessages } from '@openedx/frontend-base';
|
|
2
|
+
const messages = defineMessages({
|
|
3
|
+
pageTitle: {
|
|
4
|
+
id: 'courses.page.title',
|
|
5
|
+
defaultMessage: 'Courses | {siteName}',
|
|
6
|
+
description: 'Document title for the courses listing page.',
|
|
7
|
+
},
|
|
8
|
+
pageHeading: {
|
|
9
|
+
id: 'category.catalog.page-title',
|
|
10
|
+
defaultMessage: 'Courses',
|
|
11
|
+
description: 'Catalog page heading.',
|
|
12
|
+
},
|
|
13
|
+
errorMessage: {
|
|
14
|
+
id: 'category.catalog.error-page-message',
|
|
15
|
+
defaultMessage: 'If you experience repeated failures, please email support at {supportEmail}',
|
|
16
|
+
description: 'Error page message.',
|
|
17
|
+
},
|
|
18
|
+
noCoursesAvailable: {
|
|
19
|
+
id: 'category.catalog.alert.no-courses-available',
|
|
20
|
+
defaultMessage: 'No courses available',
|
|
21
|
+
description: 'No courses available alert title.',
|
|
22
|
+
},
|
|
23
|
+
noCoursesAvailableMessage: {
|
|
24
|
+
id: 'category.catalog.alert.no-courses-available-message',
|
|
25
|
+
defaultMessage: 'There are currently no courses available in the catalog. Please check back later for new offerings.',
|
|
26
|
+
description: 'No courses available alert message.',
|
|
27
|
+
},
|
|
28
|
+
searchPlaceholder: {
|
|
29
|
+
id: 'category.catalog.search-placeholder',
|
|
30
|
+
defaultMessage: 'Search for a course',
|
|
31
|
+
description: 'Search placeholder.',
|
|
32
|
+
},
|
|
33
|
+
searchResults: {
|
|
34
|
+
id: 'category.catalog.search-results',
|
|
35
|
+
defaultMessage: 'Search results for "{query}"',
|
|
36
|
+
description: 'Search results heading.',
|
|
37
|
+
},
|
|
38
|
+
noSearchResults: {
|
|
39
|
+
id: 'category.catalog.no-search-results',
|
|
40
|
+
defaultMessage: 'We couldn\'t find any results for "{query}"',
|
|
41
|
+
description: 'No search results.',
|
|
42
|
+
},
|
|
43
|
+
exploreCourses: {
|
|
44
|
+
id: 'category.catalog.explore-courses',
|
|
45
|
+
defaultMessage: 'Explore courses',
|
|
46
|
+
description: 'Explore courses.',
|
|
47
|
+
},
|
|
48
|
+
noResultsFound: {
|
|
49
|
+
id: 'category.catalog.no-results-found',
|
|
50
|
+
defaultMessage: 'No results found',
|
|
51
|
+
description: 'No results found.',
|
|
52
|
+
},
|
|
53
|
+
organizations: {
|
|
54
|
+
id: 'category.catalog.filter.organizations',
|
|
55
|
+
defaultMessage: 'Organizations',
|
|
56
|
+
description: 'Organizations filter.',
|
|
57
|
+
},
|
|
58
|
+
languages: {
|
|
59
|
+
id: 'category.catalog.filter.languages',
|
|
60
|
+
defaultMessage: 'Languages',
|
|
61
|
+
description: 'Languages filter.',
|
|
62
|
+
},
|
|
63
|
+
courseTypes: {
|
|
64
|
+
id: 'category.catalog.filter.course-types',
|
|
65
|
+
defaultMessage: 'Course types',
|
|
66
|
+
description: 'Course types filter.',
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
export default messages;
|
|
70
|
+
//# sourceMappingURL=messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/catalog/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,QAAQ,GAAG,cAAc,CAAC;IAC9B,SAAS,EAAE;QACT,EAAE,EAAE,oBAAoB;QACxB,cAAc,EAAE,sBAAsB;QACtC,WAAW,EAAE,8CAA8C;KAC5D;IACD,WAAW,EAAE;QACX,EAAE,EAAE,6BAA6B;QACjC,cAAc,EAAE,SAAS;QACzB,WAAW,EAAE,uBAAuB;KACrC;IACD,YAAY,EAAE;QACZ,EAAE,EAAE,qCAAqC;QACzC,cAAc,EAAE,6EAA6E;QAC7F,WAAW,EAAE,qBAAqB;KACnC;IACD,kBAAkB,EAAE;QAClB,EAAE,EAAE,6CAA6C;QACjD,cAAc,EAAE,sBAAsB;QACtC,WAAW,EAAE,mCAAmC;KACjD;IACD,yBAAyB,EAAE;QACzB,EAAE,EAAE,qDAAqD;QACzD,cAAc,EAAE,qGAAqG;QACrH,WAAW,EAAE,qCAAqC;KACnD;IACD,iBAAiB,EAAE;QACjB,EAAE,EAAE,qCAAqC;QACzC,cAAc,EAAE,qBAAqB;QACrC,WAAW,EAAE,qBAAqB;KACnC;IACD,aAAa,EAAE;QACb,EAAE,EAAE,iCAAiC;QACrC,cAAc,EAAE,8BAA8B;QAC9C,WAAW,EAAE,yBAAyB;KACvC;IACD,eAAe,EAAE;QACf,EAAE,EAAE,oCAAoC;QACxC,cAAc,EAAE,6CAA6C;QAC7D,WAAW,EAAE,oBAAoB;KAClC;IACD,cAAc,EAAE;QACd,EAAE,EAAE,kCAAkC;QACtC,cAAc,EAAE,iBAAiB;QACjC,WAAW,EAAE,kBAAkB;KAChC;IACD,cAAc,EAAE;QACd,EAAE,EAAE,mCAAmC;QACvC,cAAc,EAAE,kBAAkB;QAClC,WAAW,EAAE,mBAAmB;KACjC;IACD,aAAa,EAAE;QACb,EAAE,EAAE,uCAAuC;QAC3C,cAAc,EAAE,eAAe;QAC/B,WAAW,EAAE,uBAAuB;KACrC;IACD,SAAS,EAAE;QACT,EAAE,EAAE,mCAAmC;QACvC,cAAc,EAAE,WAAW;QAC3B,WAAW,EAAE,mBAAmB;KACjC;IACD,WAAW,EAAE;QACX,EAAE,EAAE,sCAAsC;QAC1C,cAAc,EAAE,cAAc;QAC9B,WAAW,EAAE,sBAAsB;KACpC;CACF,CAAC,CAAC;AAEH,eAAe,QAAQ,CAAC","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n pageTitle: {\n id: 'courses.page.title',\n defaultMessage: 'Courses | {siteName}',\n description: 'Document title for the courses listing page.',\n },\n pageHeading: {\n id: 'category.catalog.page-title',\n defaultMessage: 'Courses',\n description: 'Catalog page heading.',\n },\n errorMessage: {\n id: 'category.catalog.error-page-message',\n defaultMessage: 'If you experience repeated failures, please email support at {supportEmail}',\n description: 'Error page message.',\n },\n noCoursesAvailable: {\n id: 'category.catalog.alert.no-courses-available',\n defaultMessage: 'No courses available',\n description: 'No courses available alert title.',\n },\n noCoursesAvailableMessage: {\n id: 'category.catalog.alert.no-courses-available-message',\n defaultMessage: 'There are currently no courses available in the catalog. Please check back later for new offerings.',\n description: 'No courses available alert message.',\n },\n searchPlaceholder: {\n id: 'category.catalog.search-placeholder',\n defaultMessage: 'Search for a course',\n description: 'Search placeholder.',\n },\n searchResults: {\n id: 'category.catalog.search-results',\n defaultMessage: 'Search results for \"{query}\"',\n description: 'Search results heading.',\n },\n noSearchResults: {\n id: 'category.catalog.no-search-results',\n defaultMessage: 'We couldn\\'t find any results for \"{query}\"',\n description: 'No search results.',\n },\n exploreCourses: {\n id: 'category.catalog.explore-courses',\n defaultMessage: 'Explore courses',\n description: 'Explore courses.',\n },\n noResultsFound: {\n id: 'category.catalog.no-results-found',\n defaultMessage: 'No results found',\n description: 'No results found.',\n },\n organizations: {\n id: 'category.catalog.filter.organizations',\n defaultMessage: 'Organizations',\n description: 'Organizations filter.',\n },\n languages: {\n id: 'category.catalog.filter.languages',\n defaultMessage: 'Languages',\n description: 'Languages filter.',\n },\n courseTypes: {\n id: 'category.catalog.filter.course-types',\n defaultMessage: 'Course types',\n description: 'Course types filter.',\n },\n});\n\nexport default messages;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/catalog/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { IntlShape } from '@src/utils';\n\nexport interface GetPageTitleProps {\n intl: IntlShape,\n searchString: string,\n courseDataResultsLength?: number,\n}\n"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { IntlShape } from '../utils';
|
|
2
|
+
import type { Aggregations, DataTableFilter } from '../data/course-list-search/types';
|
|
3
|
+
import type { GetPageTitleProps } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* Transforms aggregations into filter choices for DataTable.
|
|
6
|
+
*/
|
|
7
|
+
export declare const transformAggregationsToFilterChoices: (aggregations: Aggregations | undefined, intl: IntlShape) => {
|
|
8
|
+
Header: string;
|
|
9
|
+
accessor: string;
|
|
10
|
+
Filter: any;
|
|
11
|
+
filter: string;
|
|
12
|
+
filterChoices: {
|
|
13
|
+
name: string;
|
|
14
|
+
number: number;
|
|
15
|
+
value: string;
|
|
16
|
+
}[];
|
|
17
|
+
}[];
|
|
18
|
+
/**
|
|
19
|
+
* Compares two arrays of filters and returns true if they are the same.
|
|
20
|
+
*/
|
|
21
|
+
export declare const compareFilters: (filters1: DataTableFilter[] | undefined, filters2: DataTableFilter[] | undefined) => boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Determines the appropriate page title based on search state and results.
|
|
24
|
+
*/
|
|
25
|
+
export declare const getPageTitle: ({ intl, searchString, courseDataResultsLength, }: GetPageTitleProps) => string;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { CheckboxFilter } from '@openedx/paragon';
|
|
2
|
+
import capitalize from 'lodash.capitalize';
|
|
3
|
+
import messages from './messages';
|
|
4
|
+
/**
|
|
5
|
+
* Gets the display name for a language code.
|
|
6
|
+
*/
|
|
7
|
+
const getLanguageName = (languageCode, locale = 'en') => {
|
|
8
|
+
try {
|
|
9
|
+
const languageNames = new Intl.DisplayNames([locale], { type: 'language' });
|
|
10
|
+
return languageNames.of(languageCode) || languageCode;
|
|
11
|
+
}
|
|
12
|
+
catch (error) {
|
|
13
|
+
return capitalize(languageCode);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Transforms aggregations into filter choices for DataTable.
|
|
18
|
+
*/
|
|
19
|
+
export const transformAggregationsToFilterChoices = (aggregations, intl) => {
|
|
20
|
+
if (!aggregations) {
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
const headerMap = {
|
|
24
|
+
org: intl.formatMessage(messages.organizations),
|
|
25
|
+
language: intl.formatMessage(messages.languages),
|
|
26
|
+
modes: intl.formatMessage(messages.courseTypes),
|
|
27
|
+
};
|
|
28
|
+
return Object.entries(aggregations).map(([key, aggValue]) => {
|
|
29
|
+
const terms = aggValue.terms || {};
|
|
30
|
+
const filterChoices = Object.entries(terms).map(([termKey, count]) => {
|
|
31
|
+
const displayName = key === 'language'
|
|
32
|
+
? getLanguageName(termKey, intl.locale)
|
|
33
|
+
: capitalize(termKey);
|
|
34
|
+
return {
|
|
35
|
+
name: displayName,
|
|
36
|
+
number: count,
|
|
37
|
+
value: termKey,
|
|
38
|
+
};
|
|
39
|
+
});
|
|
40
|
+
return {
|
|
41
|
+
Header: headerMap[key] || capitalize(key),
|
|
42
|
+
accessor: key,
|
|
43
|
+
Filter: CheckboxFilter,
|
|
44
|
+
filter: 'includesValue',
|
|
45
|
+
filterChoices,
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Compares two arrays of filters and returns true if they are the same.
|
|
51
|
+
*/
|
|
52
|
+
export const compareFilters = (filters1, filters2) => {
|
|
53
|
+
if (filters1 === filters2) {
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
if (!filters1 || !filters2) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
if (filters1.length !== filters2.length) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
const createFilterKey = (filter) => {
|
|
63
|
+
const sortedValues = [...filter.value].sort().join(',');
|
|
64
|
+
return `${filter.id}:${sortedValues}`;
|
|
65
|
+
};
|
|
66
|
+
const set1 = new Set(filters1.map(createFilterKey));
|
|
67
|
+
const set2 = new Set(filters2.map(createFilterKey));
|
|
68
|
+
return set1.size === set2.size && [...set1].every(key => set2.has(key));
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Determines the appropriate page title based on search state and results.
|
|
72
|
+
*/
|
|
73
|
+
export const getPageTitle = ({ intl, searchString, courseDataResultsLength, }) => {
|
|
74
|
+
if (!searchString) {
|
|
75
|
+
return intl.formatMessage(messages.exploreCourses);
|
|
76
|
+
}
|
|
77
|
+
if ((courseDataResultsLength !== null && courseDataResultsLength !== void 0 ? courseDataResultsLength : 0) === 0) {
|
|
78
|
+
return intl.formatMessage(messages.noSearchResults, { query: searchString });
|
|
79
|
+
}
|
|
80
|
+
return intl.formatMessage(messages.searchResults, { query: searchString });
|
|
81
|
+
};
|
|
82
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/catalog/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,UAAU,MAAM,mBAAmB,CAAC;AAK3C,OAAO,QAAQ,MAAM,YAAY,CAAC;AAElC;;GAEG;AACH,MAAM,eAAe,GAAG,CAAC,YAAoB,EAAE,MAAM,GAAG,IAAI,EAAU,EAAE;IACtE,IAAI,CAAC;QACH,MAAM,aAAa,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;QAC5E,OAAO,aAAa,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,YAAY,CAAC;IACxD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,UAAU,CAAC,YAAY,CAAC,CAAC;IAClC,CAAC;AACH,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,oCAAoC,GAAG,CAAC,YAAsC,EAAE,IAAe,EAAE,EAAE;IAC9G,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,SAAS,GAA2B;QACxC,GAAG,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC;QAC/C,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,SAAS,CAAC;QAChD,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,WAAW,CAAC;KAChD,CAAC;IAEF,OAAO,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,EAAE;QAC1D,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC;QACnC,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE;YACnE,MAAM,WAAW,GAAG,GAAG,KAAK,UAAU;gBACpC,CAAC,CAAC,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC;gBACvC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YAExB,OAAO;gBACL,IAAI,EAAE,WAAW;gBACjB,MAAM,EAAE,KAAK;gBACb,KAAK,EAAE,OAAO;aACf,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,OAAO;YACL,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC;YACzC,QAAQ,EAAE,GAAG;YACb,MAAM,EAAE,cAAc;YACtB,MAAM,EAAE,eAAe;YACvB,aAAa;SACd,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,QAAuC,EACvC,QAAuC,EAC9B,EAAE;IACX,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;QACxC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,eAAe,GAAG,CAAC,MAAuB,EAAE,EAAE;QAClD,MAAM,YAAY,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxD,OAAO,GAAG,MAAM,CAAC,EAAE,IAAI,YAAY,EAAE,CAAC;IACxC,CAAC,CAAC;IAEF,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC;IAEpD,OAAO,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1E,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,EAC3B,IAAI,EACJ,YAAY,EACZ,uBAAuB,GACL,EAAE,EAAE;IACtB,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;IACrD,CAAC;IAED,IAAI,CAAC,uBAAuB,aAAvB,uBAAuB,cAAvB,uBAAuB,GAAI,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;QACzC,OAAO,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,eAAe,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC;IAC/E,CAAC;IAED,OAAO,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC;AAC7E,CAAC,CAAC","sourcesContent":["import { CheckboxFilter } from '@openedx/paragon';\nimport capitalize from 'lodash.capitalize';\n\nimport type { IntlShape } from '@src/utils';\nimport type { Aggregations, DataTableFilter } from '@src/data/course-list-search/types';\nimport type { GetPageTitleProps } from './types';\nimport messages from './messages';\n\n/**\n * Gets the display name for a language code.\n */\nconst getLanguageName = (languageCode: string, locale = 'en'): string => {\n try {\n const languageNames = new Intl.DisplayNames([locale], { type: 'language' });\n return languageNames.of(languageCode) || languageCode;\n } catch (error) {\n return capitalize(languageCode);\n }\n};\n\n/**\n * Transforms aggregations into filter choices for DataTable.\n */\nexport const transformAggregationsToFilterChoices = (aggregations: Aggregations | undefined, intl: IntlShape) => {\n if (!aggregations) {\n return [];\n }\n\n const headerMap: Record<string, string> = {\n org: intl.formatMessage(messages.organizations),\n language: intl.formatMessage(messages.languages),\n modes: intl.formatMessage(messages.courseTypes),\n };\n\n return Object.entries(aggregations).map(([key, aggValue]) => {\n const terms = aggValue.terms || {};\n const filterChoices = Object.entries(terms).map(([termKey, count]) => {\n const displayName = key === 'language'\n ? getLanguageName(termKey, intl.locale)\n : capitalize(termKey);\n\n return {\n name: displayName,\n number: count,\n value: termKey,\n };\n });\n\n return {\n Header: headerMap[key] || capitalize(key),\n accessor: key,\n Filter: CheckboxFilter,\n filter: 'includesValue',\n filterChoices,\n };\n });\n};\n\n/**\n * Compares two arrays of filters and returns true if they are the same.\n */\nexport const compareFilters = (\n filters1: DataTableFilter[] | undefined,\n filters2: DataTableFilter[] | undefined,\n): boolean => {\n if (filters1 === filters2) {\n return true;\n }\n\n if (!filters1 || !filters2) {\n return false;\n }\n\n if (filters1.length !== filters2.length) {\n return false;\n }\n\n const createFilterKey = (filter: DataTableFilter) => {\n const sortedValues = [...filter.value].sort().join(',');\n return `${filter.id}:${sortedValues}`;\n };\n\n const set1 = new Set(filters1.map(createFilterKey));\n const set2 = new Set(filters2.map(createFilterKey));\n\n return set1.size === set2.size && [...set1].every(key => set2.has(key));\n};\n\n/**\n * Determines the appropriate page title based on search state and results.\n */\nexport const getPageTitle = ({\n intl,\n searchString,\n courseDataResultsLength,\n}: GetPageTitleProps) => {\n if (!searchString) {\n return intl.formatMessage(messages.exploreCourses);\n }\n\n if ((courseDataResultsLength ?? 0) === 0) {\n return intl.formatMessage(messages.noSearchResults, { query: searchString });\n }\n\n return intl.formatMessage(messages.searchResults, { query: searchString });\n};\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare const appId = "org.openedx.frontend.app.catalog";
|
|
2
|
+
export declare const catalogRole = "org.openedx.frontend.role.catalog";
|
|
3
|
+
export declare const coursesRole = "org.openedx.frontend.role.courses";
|
|
4
|
+
export declare const courseAboutRole = "org.openedx.frontend.role.courseAbout";
|
|
5
|
+
/**
|
|
6
|
+
* Feature policy for iframe, allowing access to courseware-related media.
|
|
7
|
+
* Selected in conference with the edX Security Working Group; changes to
|
|
8
|
+
* it should be vetted by them (security@edx.org).
|
|
9
|
+
*/
|
|
10
|
+
export declare const IFRAME_FEATURE_POLICY = "microphone *; camera *; midi *; geolocation *; encrypted-media *; clipboard-write *";
|
|
11
|
+
export declare const DEFAULT_VIDEO_MODAL_HEIGHT = 500;
|
|
12
|
+
export declare const DEFAULT_VIDEO_MODAL_WIDTH = "auto";
|
|
13
|
+
export declare const DEFAULT_VIDEO_MODAL_SIZE = "lg";
|
|
14
|
+
export declare const DATE_FORMAT_OPTIONS: {
|
|
15
|
+
readonly month: "short";
|
|
16
|
+
readonly day: "numeric";
|
|
17
|
+
readonly year: "numeric";
|
|
18
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const appId = 'org.openedx.frontend.app.catalog';
|
|
2
|
+
export const catalogRole = 'org.openedx.frontend.role.catalog';
|
|
3
|
+
export const coursesRole = 'org.openedx.frontend.role.courses';
|
|
4
|
+
export const courseAboutRole = 'org.openedx.frontend.role.courseAbout';
|
|
5
|
+
/**
|
|
6
|
+
* Feature policy for iframe, allowing access to courseware-related media.
|
|
7
|
+
* Selected in conference with the edX Security Working Group; changes to
|
|
8
|
+
* it should be vetted by them (security@edx.org).
|
|
9
|
+
*/
|
|
10
|
+
export const IFRAME_FEATURE_POLICY = ('microphone *; camera *; midi *; geolocation *; encrypted-media *; clipboard-write *');
|
|
11
|
+
export const DEFAULT_VIDEO_MODAL_HEIGHT = 500;
|
|
12
|
+
export const DEFAULT_VIDEO_MODAL_WIDTH = 'auto';
|
|
13
|
+
export const DEFAULT_VIDEO_MODAL_SIZE = 'lg';
|
|
14
|
+
export const DATE_FORMAT_OPTIONS = { month: 'short', day: 'numeric', year: 'numeric' };
|
|
15
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,KAAK,GAAG,kCAAkC,CAAC;AACxD,MAAM,CAAC,MAAM,WAAW,GAAG,mCAAmC,CAAC;AAC/D,MAAM,CAAC,MAAM,WAAW,GAAG,mCAAmC,CAAC;AAC/D,MAAM,CAAC,MAAM,eAAe,GAAG,uCAAuC,CAAC;AAEvE;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,qFAAqF,CACtF,CAAC;AAEF,MAAM,CAAC,MAAM,0BAA0B,GAAG,GAAG,CAAC;AAC9C,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC;AAChD,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAI,CAAC;AAE7C,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAW,CAAC","sourcesContent":["export const appId = 'org.openedx.frontend.app.catalog';\nexport const catalogRole = 'org.openedx.frontend.role.catalog';\nexport const coursesRole = 'org.openedx.frontend.role.courses';\nexport const courseAboutRole = 'org.openedx.frontend.role.courseAbout';\n\n/**\n * Feature policy for iframe, allowing access to courseware-related media.\n * Selected in conference with the edX Security Working Group; changes to\n * it should be vetted by them (security@edx.org).\n */\nexport const IFRAME_FEATURE_POLICY = (\n 'microphone *; camera *; midi *; geolocation *; encrypted-media *; clipboard-write *'\n);\n\nexport const DEFAULT_VIDEO_MODAL_HEIGHT = 500;\nexport const DEFAULT_VIDEO_MODAL_WIDTH = 'auto';\nexport const DEFAULT_VIDEO_MODAL_SIZE = 'lg';\n\nexport const DATE_FORMAT_OPTIONS = { month: 'short', day: 'numeric', year: 'numeric' } as const;\n"]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useParams } from 'react-router';
|
|
3
|
+
import { Helmet } from 'react-helmet';
|
|
4
|
+
import { Container, Layout, Alert, useMediaQuery, breakpoints, Stack, } from '@openedx/paragon';
|
|
5
|
+
import { ErrorPage, getAppConfig, getSiteConfig, useIntl, } from '@openedx/frontend-base';
|
|
6
|
+
import { Loading } from '../generic';
|
|
7
|
+
import { appId } from '../constants';
|
|
8
|
+
import CourseAboutIntroSlot from '../slots/CourseAboutIntroSlot';
|
|
9
|
+
import CourseAboutCourseMediaSlot from '../slots/CourseAboutCourseMediaSlot';
|
|
10
|
+
import CourseAboutOverviewSlot from '../slots/CourseAboutOverviewSlot';
|
|
11
|
+
import CourseAboutSidebarSlot from '../slots/CourseAboutSidebarSlot';
|
|
12
|
+
import { useCourseAboutData } from './data/hooks';
|
|
13
|
+
import messages from './messages';
|
|
14
|
+
import { GRID_LAYOUT } from './layout';
|
|
15
|
+
const CourseAboutPage = () => {
|
|
16
|
+
var _a;
|
|
17
|
+
const intl = useIntl();
|
|
18
|
+
const { courseId = '' } = useParams();
|
|
19
|
+
const isSmallScreen = useMediaQuery({ maxWidth: breakpoints.large.maxWidth });
|
|
20
|
+
const { data: courseAboutData, isLoading, isError, } = useCourseAboutData(courseId);
|
|
21
|
+
if (isLoading) {
|
|
22
|
+
return _jsx(Loading, {});
|
|
23
|
+
}
|
|
24
|
+
if (isError) {
|
|
25
|
+
return (_jsx(Container, { className: "py-5.5", children: _jsx(Alert, { variant: "danger", children: _jsx(ErrorPage
|
|
26
|
+
// @ts-expect-error frontend-base ErrorPage declares message?: null but renders the prop as text. Remove when typing is fixed upstream.
|
|
27
|
+
, {
|
|
28
|
+
// @ts-expect-error frontend-base ErrorPage declares message?: null but renders the prop as text. Remove when typing is fixed upstream.
|
|
29
|
+
message: intl.formatMessage(messages.errorMessage, {
|
|
30
|
+
supportEmail: getAppConfig(appId).INFO_EMAIL,
|
|
31
|
+
}) }) }) }));
|
|
32
|
+
}
|
|
33
|
+
return (_jsxs(_Fragment, { children: [_jsx(Helmet, { children: _jsx("title", { children: intl.formatMessage(messages.pageTitle, {
|
|
34
|
+
courseName: (_a = courseAboutData === null || courseAboutData === void 0 ? void 0 : courseAboutData.name) !== null && _a !== void 0 ? _a : '',
|
|
35
|
+
siteName: getSiteConfig().siteName,
|
|
36
|
+
}) }) }), _jsx(Container, { fluid: false, size: "xl", className: "py-5.5", children: _jsxs(Layout, Object.assign({}, GRID_LAYOUT, { children: [_jsx(Layout.Element, { children: isSmallScreen ? (_jsxs(Stack, { gap: 4, children: [_jsx(Layout.Element, { className: "course-media-wrapper text-center", children: _jsx(CourseAboutCourseMediaSlot, { courseAboutData: courseAboutData }) }), _jsx(CourseAboutIntroSlot, { courseAboutData: courseAboutData }), _jsx(CourseAboutOverviewSlot, { overviewData: courseAboutData.overview, courseId: courseId }), _jsx(CourseAboutSidebarSlot, { courseAboutData: courseAboutData })] })) : (_jsxs(Stack, { gap: 4, children: [_jsx(CourseAboutIntroSlot, { courseAboutData: courseAboutData }), _jsx(CourseAboutOverviewSlot, { overviewData: courseAboutData.overview, courseId: courseId })] })) }), _jsx(Layout.Element, { children: !isSmallScreen && (_jsxs(Stack, { gap: 4, children: [_jsx(Layout.Element, { className: "course-media-wrapper", children: _jsx(CourseAboutCourseMediaSlot, { courseAboutData: courseAboutData }) }), _jsx(CourseAboutSidebarSlot, { courseAboutData: courseAboutData })] })) })] })) })] }));
|
|
37
|
+
};
|
|
38
|
+
export default CourseAboutPage;
|
|
39
|
+
//# sourceMappingURL=CourseAboutPage.js.map
|