@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
package/README.rst
ADDED
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
frontend-app-catalog
|
|
2
|
+
####################
|
|
3
|
+
|
|
4
|
+
|license-badge| |status-badge| |ci-badge| |codecov-badge|
|
|
5
|
+
|
|
6
|
+
The catalog is a `frontend-base`_ application: a library that plugs into
|
|
7
|
+
the Open edX frontend shell, rather than a standalone micro-frontend
|
|
8
|
+
bundled with its own webpack build.
|
|
9
|
+
|
|
10
|
+
.. _frontend-base: https://github.com/openedx/frontend-base
|
|
11
|
+
|
|
12
|
+
Purpose
|
|
13
|
+
*******
|
|
14
|
+
|
|
15
|
+
The catalog serves the public-facing Home, Course About, and Course
|
|
16
|
+
Catalog pages — the intended replacement for the corresponding legacy
|
|
17
|
+
views in ``edx-platform``.
|
|
18
|
+
|
|
19
|
+
Branches and Releases
|
|
20
|
+
*********************
|
|
21
|
+
|
|
22
|
+
This app is published to NPM by ``semantic-release``, and its branches
|
|
23
|
+
follow `OEP-10 ADR 0002`_:
|
|
24
|
+
|
|
25
|
+
``master``
|
|
26
|
+
Unstable. Every merge publishes a prerelease on the ``alpha``
|
|
27
|
+
dist-tag. Breaking changes land here with no DEPR process and no
|
|
28
|
+
warning, so it is not supported in production. All changes, including
|
|
29
|
+
bug fixes, should target this branch first.
|
|
30
|
+
|
|
31
|
+
``stable``
|
|
32
|
+
Carries the newest stable major and owns the ``latest`` dist-tag.
|
|
33
|
+
Changes arrive here as backports from ``master``, and no breaking
|
|
34
|
+
change lands after publication.
|
|
35
|
+
|
|
36
|
+
``n.x`` and ``n.m.x``
|
|
37
|
+
Maintenance branches for majors and minors that ``stable`` has moved
|
|
38
|
+
past. Each owns the dist-tag matching its own name, so consumers
|
|
39
|
+
select a maintained line by semver range, e.g. ``"1.x"``.
|
|
40
|
+
|
|
41
|
+
``stable`` has not been cut yet: until this app is first ready for
|
|
42
|
+
production use, ``master`` and its alphas are all there is. Both
|
|
43
|
+
``.releaserc`` and the ``Release CI`` workflow already know the whole
|
|
44
|
+
layout, including the maintenance branch patterns, so a new line starts
|
|
45
|
+
publishing as soon as it is pushed.
|
|
46
|
+
|
|
47
|
+
This repository is no longer branched or tagged for Open edX releases in
|
|
48
|
+
its own right. It participates by published version instead, per
|
|
49
|
+
`OEP-10 ADR 0003`_.
|
|
50
|
+
|
|
51
|
+
The micro-frontend this app replaces goes on living on `legacy-mfe`_,
|
|
52
|
+
which is where any further ``release/RELEASENAME`` branches for it are
|
|
53
|
+
cut, for as long as a supported release still ships it.
|
|
54
|
+
|
|
55
|
+
.. _OEP-10 ADR 0002: https://docs.openedx.org/projects/openedx-proposals/en/latest/processes/oep-0010/decisions/0002-frontend-stable-branches.html
|
|
56
|
+
.. _OEP-10 ADR 0003: https://docs.openedx.org/projects/openedx-proposals/en/latest/processes/oep-0010/decisions/0003-frontend-release-strategy.html
|
|
57
|
+
.. _legacy-mfe: https://github.com/openedx/frontend-app-catalog/tree/legacy-mfe
|
|
58
|
+
|
|
59
|
+
Getting Started
|
|
60
|
+
***************
|
|
61
|
+
|
|
62
|
+
Prerequisites
|
|
63
|
+
=============
|
|
64
|
+
|
|
65
|
+
A running Open edX instance is needed to serve this app's backend APIs.
|
|
66
|
+
`Tutor`_ in development mode is the usual choice, and
|
|
67
|
+
``site.config.dev.tsx`` already points at its default hostnames.
|
|
68
|
+
|
|
69
|
+
Unlike a micro-frontend, this app is neither built nor served by
|
|
70
|
+
``tutor-mfe``. The dev server below runs on the host.
|
|
71
|
+
|
|
72
|
+
.. _Tutor: https://github.com/overhangio/tutor
|
|
73
|
+
|
|
74
|
+
Cloning and Startup
|
|
75
|
+
===================
|
|
76
|
+
|
|
77
|
+
1. Clone the repo:
|
|
78
|
+
|
|
79
|
+
``git clone https://github.com/openedx/frontend-app-catalog.git``
|
|
80
|
+
|
|
81
|
+
2. Use the version of Node specified in the ``.nvmrc`` file.
|
|
82
|
+
|
|
83
|
+
Using other major versions of Node *may* work, but is unsupported.
|
|
84
|
+
This repository includes an ``.nvmrc`` file to help set the correct
|
|
85
|
+
Node version via `nvm <https://github.com/nvm-sh/nvm>`_.
|
|
86
|
+
|
|
87
|
+
3. Install npm dependencies:
|
|
88
|
+
|
|
89
|
+
``cd frontend-app-catalog && npm install``
|
|
90
|
+
|
|
91
|
+
4. Start the dev server:
|
|
92
|
+
|
|
93
|
+
``npm run dev``
|
|
94
|
+
|
|
95
|
+
The dev server defaults to ``PORT=1998 PUBLIC_PATH=/catalog`` (set in
|
|
96
|
+
the ``dev`` script in ``package.json``) and is available at
|
|
97
|
+
`http://apps.local.openedx.io:1998/catalog <http://apps.local.openedx.io:1998/catalog>`_.
|
|
98
|
+
|
|
99
|
+
Configuration used by the dev server is defined in
|
|
100
|
+
``site.config.dev.tsx`` at the repo root.
|
|
101
|
+
|
|
102
|
+
Local Development Against ``frontend-base``
|
|
103
|
+
===========================================
|
|
104
|
+
|
|
105
|
+
To develop this app and a local checkout of ``frontend-base`` in
|
|
106
|
+
tandem, use the built-in npm workspace support:
|
|
107
|
+
|
|
108
|
+
.. code-block:: sh
|
|
109
|
+
|
|
110
|
+
mkdir -p packages/frontend-base
|
|
111
|
+
sudo mount --bind /path/to/frontend-base packages/frontend-base
|
|
112
|
+
npm install
|
|
113
|
+
npm run dev:packages
|
|
114
|
+
|
|
115
|
+
Bind mounts are used instead of symlinks because Node resolves
|
|
116
|
+
symlinks to their real paths, which breaks hoisted dependency
|
|
117
|
+
resolution. When you are done, unmount with
|
|
118
|
+
``sudo umount packages/frontend-base``.
|
|
119
|
+
|
|
120
|
+
Configuration
|
|
121
|
+
=============
|
|
122
|
+
|
|
123
|
+
The catalog app declares the following ``AppConfig`` fields (defaults
|
|
124
|
+
live in ``src/app.ts``). Sites can override any of them by spreading
|
|
125
|
+
over ``catalogApp.config`` in ``site.config.*.tsx``:
|
|
126
|
+
|
|
127
|
+
.. list-table::
|
|
128
|
+
:header-rows: 1
|
|
129
|
+
:widths: 40 60
|
|
130
|
+
|
|
131
|
+
* - Field
|
|
132
|
+
- Purpose
|
|
133
|
+
* - ``ENABLE_COURSE_DISCOVERY``
|
|
134
|
+
- Show the Discover / Explore links in the header.
|
|
135
|
+
* - ``ENABLE_PROGRAMS``
|
|
136
|
+
- Show the Programs link in the header.
|
|
137
|
+
* - ``ENABLE_COURSE_SORTING_BY_START_DATE``
|
|
138
|
+
- Enable start-date sorting in the catalog search.
|
|
139
|
+
* - ``HOMEPAGE_COURSE_MAX``
|
|
140
|
+
- Maximum number of courses to render on the homepage list
|
|
141
|
+
(default ``9``).
|
|
142
|
+
* - ``HOMEPAGE_PROMO_VIDEO_YOUTUBE_ID``
|
|
143
|
+
- YouTube video id for the homepage promo video.
|
|
144
|
+
* - ``NON_BROWSABLE_COURSES``
|
|
145
|
+
- When truthy, hides catalog links for authenticated users.
|
|
146
|
+
* - ``INFO_EMAIL``
|
|
147
|
+
- Support email address shown on the catalog error page.
|
|
148
|
+
* - ``SUPPORT_URL``
|
|
149
|
+
- URL of the support / help page linked from the catalog.
|
|
150
|
+
* - ``LEARNING_BASE_URL``
|
|
151
|
+
- Base URL for course-outline links from the course-about page.
|
|
152
|
+
* - ``COURSE_ABOUT_TWITTER_ACCOUNT``
|
|
153
|
+
- Twitter handle used by the course-about sidebar's share widget.
|
|
154
|
+
|
|
155
|
+
See ``site.config.dev.tsx`` in this repo for a worked example of
|
|
156
|
+
overriding these for local development.
|
|
157
|
+
|
|
158
|
+
Slots
|
|
159
|
+
*****
|
|
160
|
+
|
|
161
|
+
This app offers a number of slots for operators to customize its
|
|
162
|
+
pages. See `src/slots/`_ for the current list and per-slot READMEs
|
|
163
|
+
with usage examples.
|
|
164
|
+
|
|
165
|
+
.. _src/slots/: ./src/slots/
|
|
166
|
+
|
|
167
|
+
Developing
|
|
168
|
+
**********
|
|
169
|
+
|
|
170
|
+
Project Structure
|
|
171
|
+
=================
|
|
172
|
+
|
|
173
|
+
The layout follows the standard `frontend-base app layout`_:
|
|
174
|
+
|
|
175
|
+
- ``src/app.ts`` — the app configuration imported by
|
|
176
|
+
``site.config.*.tsx``.
|
|
177
|
+
- ``src/constants.ts`` — the app's ``appId`` and role identifiers.
|
|
178
|
+
- ``src/index.ts`` — the package's public exports (this is a
|
|
179
|
+
library).
|
|
180
|
+
- ``src/routes.tsx`` — the app's react-router routes.
|
|
181
|
+
- ``src/Main.tsx`` — the root component for the app's routes.
|
|
182
|
+
- ``src/slots.tsx`` — the slot operations the app applies to the
|
|
183
|
+
shell.
|
|
184
|
+
- ``src/slots/`` — the slots this app offers to consumers.
|
|
185
|
+
- ``src/style.scss`` — app-scoped runtime styles.
|
|
186
|
+
|
|
187
|
+
For more, see the `frontend-base migration how-to`_.
|
|
188
|
+
|
|
189
|
+
.. _frontend-base app layout: https://github.com/openedx/frontend-base/blob/main/docs/how_tos/migrate-frontend-app.md#src-file-structure
|
|
190
|
+
.. _frontend-base migration how-to: https://github.com/openedx/frontend-base/blob/main/docs/how_tos/migrate-frontend-app.md
|
|
191
|
+
|
|
192
|
+
Build Process Notes
|
|
193
|
+
===================
|
|
194
|
+
|
|
195
|
+
**Library build**
|
|
196
|
+
|
|
197
|
+
``npm run build`` compiles the library into ``dist/`` via ``tsc`` and
|
|
198
|
+
``tsc-alias``. This is what gets published and consumed by sites.
|
|
199
|
+
|
|
200
|
+
**CI build**
|
|
201
|
+
|
|
202
|
+
``npm run build:ci`` runs ``openedx build`` against
|
|
203
|
+
``site.config.ci.tsx`` so webpack traverses the full app graph. This
|
|
204
|
+
catches issues (like broken lazy-loaded imports) that ``tsc`` and
|
|
205
|
+
Jest would not surface.
|
|
206
|
+
|
|
207
|
+
Internationalization
|
|
208
|
+
====================
|
|
209
|
+
|
|
210
|
+
Please refer to the `frontend-base i18n howto`_ for documentation on
|
|
211
|
+
internationalization.
|
|
212
|
+
|
|
213
|
+
.. _frontend-base i18n howto: https://github.com/openedx/frontend-base/blob/main/docs/how_tos/i18n.rst
|
|
214
|
+
|
|
215
|
+
Getting Help
|
|
216
|
+
************
|
|
217
|
+
|
|
218
|
+
If you're having trouble, we have discussion forums at
|
|
219
|
+
https://discuss.openedx.org where you can connect with others in the
|
|
220
|
+
community.
|
|
221
|
+
|
|
222
|
+
Our real-time conversations are on Slack. You can request a `Slack
|
|
223
|
+
invitation`_, then join our `community Slack workspace`_. Because
|
|
224
|
+
this is a frontend repository, the best place to discuss it would be
|
|
225
|
+
in the `#wg-frontend channel`_.
|
|
226
|
+
|
|
227
|
+
For anything non-trivial, the best path is to open an issue in this
|
|
228
|
+
repository with as many details about the issue you are facing as
|
|
229
|
+
you can provide.
|
|
230
|
+
|
|
231
|
+
https://github.com/openedx/frontend-app-catalog/issues
|
|
232
|
+
|
|
233
|
+
For more information about these options, see the `Getting Help`_
|
|
234
|
+
page.
|
|
235
|
+
|
|
236
|
+
.. _Slack invitation: https://openedx.org/slack
|
|
237
|
+
.. _community Slack workspace: https://openedx.slack.com/
|
|
238
|
+
.. _#wg-frontend channel: https://openedx.slack.com/archives/C04BM6YC7A6
|
|
239
|
+
.. _Getting Help: https://openedx.org/getting-help
|
|
240
|
+
|
|
241
|
+
License
|
|
242
|
+
*******
|
|
243
|
+
|
|
244
|
+
The code in this repository is licensed under the AGPLv3 unless
|
|
245
|
+
otherwise noted.
|
|
246
|
+
|
|
247
|
+
Please see `LICENSE <LICENSE>`_ for details.
|
|
248
|
+
|
|
249
|
+
Contributing
|
|
250
|
+
************
|
|
251
|
+
|
|
252
|
+
Contributions are very welcome. Please read `How To Contribute`_ for
|
|
253
|
+
details.
|
|
254
|
+
|
|
255
|
+
.. _How To Contribute: https://openedx.org/r/how-to-contribute
|
|
256
|
+
|
|
257
|
+
This project is currently accepting all types of contributions, bug
|
|
258
|
+
fixes, security fixes, maintenance work, or new features. However,
|
|
259
|
+
please make sure to have a discussion about your new feature idea
|
|
260
|
+
with the maintainers prior to beginning development to maximize the
|
|
261
|
+
chances of your change being accepted. You can start a conversation
|
|
262
|
+
by creating a new issue on this repo summarizing your idea.
|
|
263
|
+
|
|
264
|
+
The Open edX Code of Conduct
|
|
265
|
+
****************************
|
|
266
|
+
|
|
267
|
+
All community members are expected to follow the `Open edX Code of
|
|
268
|
+
Conduct`_.
|
|
269
|
+
|
|
270
|
+
.. _Open edX Code of Conduct: https://openedx.org/code-of-conduct/
|
|
271
|
+
|
|
272
|
+
People
|
|
273
|
+
******
|
|
274
|
+
|
|
275
|
+
The assigned maintainers for this component and other project details
|
|
276
|
+
may be found in `Backstage`_. Backstage pulls this data from the
|
|
277
|
+
``catalog-info.yaml`` file in this repo.
|
|
278
|
+
|
|
279
|
+
.. _Backstage: https://open-edx-backstage.herokuapp.com/catalog/default/component/frontend-app-catalog
|
|
280
|
+
|
|
281
|
+
Reporting Security Issues
|
|
282
|
+
*************************
|
|
283
|
+
|
|
284
|
+
Please do not report security issues in public, and email
|
|
285
|
+
security@openedx.org instead.
|
|
286
|
+
|
|
287
|
+
.. |license-badge| image:: https://img.shields.io/github/license/openedx/frontend-app-catalog.svg
|
|
288
|
+
:target: https://github.com/openedx/frontend-app-catalog/blob/master/LICENSE
|
|
289
|
+
:alt: License
|
|
290
|
+
|
|
291
|
+
.. |status-badge| image:: https://img.shields.io/badge/Status-Maintained-brightgreen
|
|
292
|
+
:alt: Maintained
|
|
293
|
+
|
|
294
|
+
.. |ci-badge| image:: https://github.com/openedx/frontend-app-catalog/actions/workflows/ci.yml/badge.svg
|
|
295
|
+
:target: https://github.com/openedx/frontend-app-catalog/actions/workflows/ci.yml
|
|
296
|
+
:alt: Continuous Integration
|
|
297
|
+
|
|
298
|
+
.. |codecov-badge| image:: https://codecov.io/github/openedx/frontend-app-catalog/coverage.svg?branch=master
|
|
299
|
+
:target: https://codecov.io/github/openedx/frontend-app-catalog?branch=master
|
|
300
|
+
:alt: Codecov
|
package/dist/Main.d.ts
ADDED
package/dist/Main.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { CurrentAppProvider } from '@openedx/frontend-base';
|
|
3
|
+
import { Outlet } from 'react-router-dom';
|
|
4
|
+
import { appId } from './constants';
|
|
5
|
+
import './style.scss';
|
|
6
|
+
const Main = () => (_jsx(CurrentAppProvider, { appId: appId, children: _jsx("main", { className: "d-flex flex-column flex-grow-1", children: _jsx(Outlet, {}) }) }));
|
|
7
|
+
export default Main;
|
|
8
|
+
//# sourceMappingURL=Main.js.map
|
package/dist/Main.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Main.js","sourceRoot":"","sources":["../src/Main.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,OAAO,cAAc,CAAC;AAEtB,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,CACjB,KAAC,kBAAkB,IAAC,KAAK,EAAE,KAAK,YAC9B,eAAM,SAAS,EAAC,gCAAgC,YAC9C,KAAC,MAAM,KAAG,GACL,GACY,CACtB,CAAC;AAEF,eAAe,IAAI,CAAC","sourcesContent":["import { CurrentAppProvider } from '@openedx/frontend-base';\nimport { Outlet } from 'react-router-dom';\n\nimport { appId } from './constants';\n\nimport './style.scss';\n\nconst Main = () => (\n <CurrentAppProvider appId={appId}>\n <main className=\"d-flex flex-column flex-grow-1\">\n <Outlet />\n </main>\n </CurrentAppProvider>\n);\n\nexport default Main;\n"]}
|
package/dist/app.d.ts
ADDED
package/dist/app.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { appId } from './constants';
|
|
2
|
+
import routes from './routes';
|
|
3
|
+
import slots from './slots';
|
|
4
|
+
const app = {
|
|
5
|
+
appId,
|
|
6
|
+
routes,
|
|
7
|
+
slots,
|
|
8
|
+
config: {
|
|
9
|
+
ENABLE_COURSE_DISCOVERY: false,
|
|
10
|
+
ENABLE_PROGRAMS: false,
|
|
11
|
+
HOMEPAGE_PROMO_VIDEO_YOUTUBE_ID: '',
|
|
12
|
+
HOMEPAGE_COURSE_MAX: 9,
|
|
13
|
+
ENABLE_COURSE_SORTING_BY_START_DATE: false,
|
|
14
|
+
NON_BROWSABLE_COURSES: '',
|
|
15
|
+
INFO_EMAIL: '',
|
|
16
|
+
SUPPORT_URL: '',
|
|
17
|
+
LEARNING_BASE_URL: '',
|
|
18
|
+
COURSE_ABOUT_TWITTER_ACCOUNT: '',
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
export default app;
|
|
22
|
+
//# sourceMappingURL=app.js.map
|
package/dist/app.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,KAAK,MAAM,YAAY,CAAC;AAE/B,MAAM,GAAG,GAAQ;IACf,KAAK;IACL,MAAM;IACN,KAAK;IACL,MAAM,EAAE;QACN,uBAAuB,EAAE,KAAK;QAC9B,eAAe,EAAE,KAAK;QACtB,+BAA+B,EAAE,EAAE;QACnC,mBAAmB,EAAE,CAAC;QACtB,mCAAmC,EAAE,KAAK;QAC1C,qBAAqB,EAAE,EAAE;QACzB,UAAU,EAAE,EAAE;QACd,WAAW,EAAE,EAAE;QACf,iBAAiB,EAAE,EAAE;QACrB,4BAA4B,EAAE,EAAE;KACjC;CACF,CAAC;AAEF,eAAe,GAAG,CAAC","sourcesContent":["import { App } from '@openedx/frontend-base';\nimport { appId } from '@src/constants';\nimport routes from '@src/routes';\nimport slots from '@src/slots';\n\nconst app: App = {\n appId,\n routes,\n slots,\n config: {\n ENABLE_COURSE_DISCOVERY: false,\n ENABLE_PROGRAMS: false,\n HOMEPAGE_PROMO_VIDEO_YOUTUBE_ID: '',\n HOMEPAGE_COURSE_MAX: 9,\n ENABLE_COURSE_SORTING_BY_START_DATE: false,\n NON_BROWSABLE_COURSES: '',\n INFO_EMAIL: '',\n SUPPORT_URL: '',\n LEARNING_BASE_URL: '',\n COURSE_ABOUT_TWITTER_ACCOUNT: '',\n },\n};\n\nexport default app;\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg width="386" height="252" viewBox="0 0 386 252" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M380 0H6C2.68629 0 0 2.68629 0 6V246C0 249.314 2.68629 252 6 252H380C383.314 252 386 249.314 386 246V6C386 2.68629 383.314 0 380 0Z" fill="#E1DDDB"/>
|
|
3
|
+
<path d="M211 144V108H175V144H211ZM186 129L191 135.02L198 126L207 138H179L186 129Z" fill="#707070"/>
|
|
4
|
+
</svg>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
@keyframes home-banner-info-animation {
|
|
2
|
+
0% {
|
|
3
|
+
opacity: 0;
|
|
4
|
+
transform: translateY(18.75rem);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
45% {
|
|
8
|
+
opacity: 1;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
65% {
|
|
12
|
+
transform: translateY(-2.5rem);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
85% {
|
|
16
|
+
transform: translateY(.625rem);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
100% {
|
|
20
|
+
top: 0;
|
|
21
|
+
transform: translateY(0);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useMemo } from 'react';
|
|
3
|
+
import { Helmet } from 'react-helmet';
|
|
4
|
+
import { Container, Alert } from '@openedx/paragon';
|
|
5
|
+
import { ErrorPage, getAppConfig, getSiteConfig, useIntl, } from '@openedx/frontend-base';
|
|
6
|
+
import { useSearchParams } from 'react-router-dom';
|
|
7
|
+
import { appId } from '../constants';
|
|
8
|
+
import { DEFAULT_PAGE_SIZE } from '../data/course-list-search/constants';
|
|
9
|
+
import { useCourseListSearch } from '../data/course-list-search/hooks';
|
|
10
|
+
import CourseCatalogIntroSlot from '../slots/CourseCatalogIntroSlot';
|
|
11
|
+
import { CourseCatalogDataTableSlot } from '../slots/CourseCatalogDataTableSlots';
|
|
12
|
+
import CourseCatalogSearchFieldSlot from '../slots/CourseCatalogSearchFieldSlot';
|
|
13
|
+
import { useDebouncedSearchInput } from './hooks/useDebouncedSearchInput';
|
|
14
|
+
import { AlertNotification, Loading } from '../generic';
|
|
15
|
+
import { useCatalog } from './hooks/useCatalog';
|
|
16
|
+
import messages from './messages';
|
|
17
|
+
import { transformAggregationsToFilterChoices } from './utils';
|
|
18
|
+
const CatalogPage = () => {
|
|
19
|
+
var _a, _b, _c, _d;
|
|
20
|
+
const intl = useIntl();
|
|
21
|
+
const [searchParams, setSearchParams] = useSearchParams();
|
|
22
|
+
const searchQuery = searchParams.get('search_query') || '';
|
|
23
|
+
const { data: courseData, isLoading, isError, fetchData, isFetching, } = useCourseListSearch({ searchString: searchQuery });
|
|
24
|
+
const { pageIndex, filterState, searchString, hasInitializedFromUrl, urlSearchQuery, previousCourseData, handleSearch, handleFetchData, resetFilterProgress, } = useCatalog({
|
|
25
|
+
fetchData, courseData, isFetching, searchParams, setSearchParams,
|
|
26
|
+
});
|
|
27
|
+
const { setSearchInput } = useDebouncedSearchInput({
|
|
28
|
+
searchString,
|
|
29
|
+
handleSearch,
|
|
30
|
+
});
|
|
31
|
+
const displayData = useMemo(() => {
|
|
32
|
+
var _a, _b;
|
|
33
|
+
const hasSearchResults = ((_b = (_a = courseData === null || courseData === void 0 ? void 0 : courseData.results) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0;
|
|
34
|
+
const hasActiveSearch = Boolean(searchString);
|
|
35
|
+
const shouldShowPreviousData = hasActiveSearch && !hasSearchResults && previousCourseData;
|
|
36
|
+
return shouldShowPreviousData ? previousCourseData : courseData;
|
|
37
|
+
}, [courseData, searchString, previousCourseData]);
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
if (!isFetching && filterState.isFilterChangeInProgress) {
|
|
40
|
+
resetFilterProgress();
|
|
41
|
+
}
|
|
42
|
+
}, [isFetching, filterState.isFilterChangeInProgress, resetFilterProgress]);
|
|
43
|
+
const tableColumns = useMemo(() => transformAggregationsToFilterChoices(displayData === null || displayData === void 0 ? void 0 : displayData.aggs, intl), [displayData === null || displayData === void 0 ? void 0 : displayData.aggs, intl]);
|
|
44
|
+
if (isLoading || (!hasInitializedFromUrl && urlSearchQuery)) {
|
|
45
|
+
return (_jsx(Loading, {}));
|
|
46
|
+
}
|
|
47
|
+
if (isError) {
|
|
48
|
+
return (_jsx(Container, { className: "py-5.5", children: _jsx(Alert, { variant: "danger", children: _jsx(ErrorPage
|
|
49
|
+
// @ts-expect-error frontend-base ErrorPage declares message?: null but renders the prop as text. Remove when typing is fixed upstream.
|
|
50
|
+
, {
|
|
51
|
+
// @ts-expect-error frontend-base ErrorPage declares message?: null but renders the prop as text. Remove when typing is fixed upstream.
|
|
52
|
+
message: intl.formatMessage(messages.errorMessage, {
|
|
53
|
+
supportEmail: getAppConfig(appId).INFO_EMAIL,
|
|
54
|
+
}) }) }) }));
|
|
55
|
+
}
|
|
56
|
+
const totalCourses = (_b = (_a = displayData === null || displayData === void 0 ? void 0 : displayData.results) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
|
|
57
|
+
const pageCount = Math.ceil(((displayData === null || displayData === void 0 ? void 0 : displayData.total) || totalCourses) / DEFAULT_PAGE_SIZE);
|
|
58
|
+
const hasCourses = totalCourses > 0 || ((_c = previousCourseData === null || previousCourseData === void 0 ? void 0 : previousCourseData.total) !== null && _c !== void 0 ? _c : 0) > 0;
|
|
59
|
+
return (_jsxs(_Fragment, { children: [_jsx(Helmet, { children: _jsx("title", { children: intl.formatMessage(messages.pageTitle, {
|
|
60
|
+
siteName: getSiteConfig().siteName,
|
|
61
|
+
}) }) }), _jsxs(Container, { fluid: false, size: "xl", className: "pt-5.5 mb-6", children: [_jsx(CourseCatalogIntroSlot, { searchString: searchString, courseDataResultsLength: (_d = courseData === null || courseData === void 0 ? void 0 : courseData.results) === null || _d === void 0 ? void 0 : _d.length }), hasCourses ? (_jsxs(_Fragment, { children: [_jsx(CourseCatalogSearchFieldSlot, { setSearchInput: setSearchInput, handleSearch: handleSearch, initialSearchValue: searchString }), _jsx(CourseCatalogDataTableSlot, { displayData: displayData, totalCourses: totalCourses, pageCount: pageCount, pageIndex: pageIndex, tableColumns: tableColumns, handleFetchData: handleFetchData })] })) : (_jsx(AlertNotification, { title: intl.formatMessage(messages.noCoursesAvailable), message: intl.formatMessage(messages.noCoursesAvailableMessage) }))] })] }));
|
|
62
|
+
};
|
|
63
|
+
export default CatalogPage;
|
|
64
|
+
//# sourceMappingURL=CatalogPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CatalogPage.js","sourceRoot":"","sources":["../../src/catalog/CatalogPage.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useMemo } from 'react';\nimport { Helmet } from 'react-helmet';\nimport { Container, Alert } from '@openedx/paragon';\nimport {\n ErrorPage, getAppConfig, getSiteConfig, useIntl,\n} from '@openedx/frontend-base';\nimport { useSearchParams } from 'react-router-dom';\n\nimport { appId } from '@src/constants';\nimport { DEFAULT_PAGE_SIZE } from '@src/data/course-list-search/constants';\nimport { useCourseListSearch } from '@src/data/course-list-search/hooks';\nimport CourseCatalogIntroSlot from '@src/slots/CourseCatalogIntroSlot';\nimport { CourseCatalogDataTableSlot } from '@src/slots/CourseCatalogDataTableSlots';\nimport CourseCatalogSearchFieldSlot from '@src/slots/CourseCatalogSearchFieldSlot';\nimport { useDebouncedSearchInput } from './hooks/useDebouncedSearchInput';\nimport { AlertNotification, Loading } from '../generic';\nimport { useCatalog } from './hooks/useCatalog';\nimport messages from './messages';\nimport { transformAggregationsToFilterChoices } from './utils';\n\nconst CatalogPage = () => {\n const intl = useIntl();\n const [searchParams, setSearchParams] = useSearchParams();\n const searchQuery = searchParams.get('search_query') || '';\n const {\n data: courseData,\n isLoading,\n isError,\n fetchData,\n isFetching,\n } = useCourseListSearch({ searchString: searchQuery });\n\n const {\n pageIndex,\n filterState,\n searchString,\n hasInitializedFromUrl,\n urlSearchQuery,\n previousCourseData,\n handleSearch,\n handleFetchData,\n resetFilterProgress,\n } = useCatalog({\n fetchData, courseData, isFetching, searchParams, setSearchParams,\n });\n\n const { setSearchInput } = useDebouncedSearchInput({\n searchString,\n handleSearch,\n });\n\n const displayData = useMemo(() => {\n const hasSearchResults = (courseData?.results?.length ?? 0) > 0;\n const hasActiveSearch = Boolean(searchString);\n\n const shouldShowPreviousData = hasActiveSearch && !hasSearchResults && previousCourseData;\n\n return shouldShowPreviousData ? previousCourseData : courseData;\n }, [courseData, searchString, previousCourseData]);\n\n useEffect(() => {\n if (!isFetching && filterState.isFilterChangeInProgress) {\n resetFilterProgress();\n }\n }, [isFetching, filterState.isFilterChangeInProgress, resetFilterProgress]);\n\n const tableColumns = useMemo(\n () => transformAggregationsToFilterChoices(displayData?.aggs, intl),\n [displayData?.aggs, intl],\n );\n\n if (isLoading || (!hasInitializedFromUrl && urlSearchQuery)) {\n return (\n <Loading />\n );\n }\n\n if (isError) {\n return (\n <Container className=\"py-5.5\">\n <Alert variant=\"danger\">\n <ErrorPage\n // @ts-expect-error frontend-base ErrorPage declares message?: null but renders the prop as text. Remove when typing is fixed upstream.\n message={intl.formatMessage(messages.errorMessage, {\n supportEmail: getAppConfig(appId).INFO_EMAIL as string,\n })}\n />\n </Alert>\n </Container>\n );\n }\n\n const totalCourses = displayData?.results?.length ?? 0;\n const pageCount = Math.ceil((displayData?.total || totalCourses) / DEFAULT_PAGE_SIZE);\n const hasCourses = totalCourses > 0 || (previousCourseData?.total ?? 0) > 0;\n\n return (\n <>\n <Helmet>\n <title>\n {intl.formatMessage(messages.pageTitle, {\n siteName: getSiteConfig().siteName,\n })}\n </title>\n </Helmet>\n <Container fluid={false} size=\"xl\" className=\"pt-5.5 mb-6\">\n <CourseCatalogIntroSlot searchString={searchString} courseDataResultsLength={courseData?.results?.length} />\n {hasCourses ? (\n <>\n <CourseCatalogSearchFieldSlot\n setSearchInput={setSearchInput}\n handleSearch={handleSearch}\n initialSearchValue={searchString}\n />\n <CourseCatalogDataTableSlot\n displayData={displayData}\n totalCourses={totalCourses}\n pageCount={pageCount}\n pageIndex={pageIndex}\n tableColumns={tableColumns}\n handleFetchData={handleFetchData}\n />\n </>\n ) : (\n <AlertNotification\n title={intl.formatMessage(messages.noCoursesAvailable)}\n message={intl.formatMessage(messages.noCoursesAvailableMessage)}\n />\n )}\n </Container>\n </>\n );\n};\n\nexport default CatalogPage;\n"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { useSearchParams } from 'react-router-dom';
|
|
2
|
+
import type { CourseListSearchResponse, DataTableParams } from '../../data/course-list-search/types';
|
|
3
|
+
export interface UseCatalogProps {
|
|
4
|
+
fetchData: (params: DataTableParams) => void;
|
|
5
|
+
courseData: CourseListSearchResponse | undefined;
|
|
6
|
+
isFetching: boolean;
|
|
7
|
+
searchParams: ReturnType<typeof useSearchParams>[0];
|
|
8
|
+
setSearchParams: ReturnType<typeof useSearchParams>[1];
|
|
9
|
+
}
|
|
10
|
+
export interface UseCourseDataProps {
|
|
11
|
+
courseData: CourseListSearchResponse | undefined;
|
|
12
|
+
searchString: string;
|
|
13
|
+
}
|
|
14
|
+
export interface UseSearchProps {
|
|
15
|
+
fetchData: (params: DataTableParams) => void;
|
|
16
|
+
isFetching: boolean;
|
|
17
|
+
searchParams: ReturnType<typeof useSearchParams>[0];
|
|
18
|
+
setSearchParams: ReturnType<typeof useSearchParams>[1];
|
|
19
|
+
}
|
|
20
|
+
export interface UseDebouncedSearchInputProps {
|
|
21
|
+
searchString: string | null | undefined;
|
|
22
|
+
handleSearch: (value: string) => void;
|
|
23
|
+
debounceDelay?: number;
|
|
24
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/catalog/hooks/types.ts"],"names":[],"mappings":"","sourcesContent":["import { useSearchParams } from 'react-router-dom';\n\nimport type { CourseListSearchResponse, DataTableParams } from '@src/data/course-list-search/types';\n\nexport interface UseCatalogProps {\n fetchData: (params: DataTableParams) => void,\n courseData: CourseListSearchResponse | undefined,\n isFetching: boolean,\n searchParams: ReturnType<typeof useSearchParams>[0],\n setSearchParams: ReturnType<typeof useSearchParams>[1],\n}\n\nexport interface UseCourseDataProps {\n courseData: CourseListSearchResponse | undefined,\n searchString: string,\n}\n\nexport interface UseSearchProps {\n fetchData: (params: DataTableParams) => void,\n isFetching: boolean,\n searchParams: ReturnType<typeof useSearchParams>[0],\n setSearchParams: ReturnType<typeof useSearchParams>[1],\n}\n\nexport interface UseDebouncedSearchInputProps {\n searchString: string | null | undefined,\n handleSearch: (value: string) => void,\n debounceDelay?: number,\n}\n"]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { DataTableParams } from '../../data/course-list-search/types';
|
|
2
|
+
import type { UseCatalogProps } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Main catalog hook that orchestrates all catalog functionality.
|
|
5
|
+
*
|
|
6
|
+
* This hook combines multiple specialized hooks to provide a complete
|
|
7
|
+
* catalog management solution with search, filtering, pagination, and data caching.
|
|
8
|
+
*
|
|
9
|
+
* Features:
|
|
10
|
+
* - Search functionality
|
|
11
|
+
* - Filter management with intelligent change detection
|
|
12
|
+
* - Pagination state management
|
|
13
|
+
* - Course data caching for better UX
|
|
14
|
+
* - Coordinated data fetching with proper state management
|
|
15
|
+
*/
|
|
16
|
+
export declare const useCatalog: ({ fetchData, courseData, isFetching, searchParams, setSearchParams, }: UseCatalogProps) => {
|
|
17
|
+
pageIndex: number;
|
|
18
|
+
filterState: {
|
|
19
|
+
previousFilters: any[] | Record<string, any> | null;
|
|
20
|
+
isFilterChangeInProgress: boolean;
|
|
21
|
+
};
|
|
22
|
+
searchString: string;
|
|
23
|
+
hasInitializedFromUrl: boolean;
|
|
24
|
+
urlSearchQuery: string;
|
|
25
|
+
previousCourseData: import("../../data/course-list-search/types").CourseListSearchResponse | null;
|
|
26
|
+
handleSearch: (query: string) => void;
|
|
27
|
+
handleFetchData: (params: DataTableParams) => void;
|
|
28
|
+
resetFilterProgress: () => void;
|
|
29
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
import { DEFAULT_PAGE_INDEX } from '../../data/course-list-search/constants';
|
|
3
|
+
import { useSearch } from './useSearch';
|
|
4
|
+
import { useFilter } from './useFilter';
|
|
5
|
+
import { usePagination } from './usePagination';
|
|
6
|
+
import { useCourseData } from './useCourseData';
|
|
7
|
+
/**
|
|
8
|
+
* Main catalog hook that orchestrates all catalog functionality.
|
|
9
|
+
*
|
|
10
|
+
* This hook combines multiple specialized hooks to provide a complete
|
|
11
|
+
* catalog management solution with search, filtering, pagination, and data caching.
|
|
12
|
+
*
|
|
13
|
+
* Features:
|
|
14
|
+
* - Search functionality
|
|
15
|
+
* - Filter management with intelligent change detection
|
|
16
|
+
* - Pagination state management
|
|
17
|
+
* - Course data caching for better UX
|
|
18
|
+
* - Coordinated data fetching with proper state management
|
|
19
|
+
*/
|
|
20
|
+
export const useCatalog = ({ fetchData, courseData, isFetching, searchParams, setSearchParams, }) => {
|
|
21
|
+
const { hasInitializedFromUrl, urlSearchQuery, searchString, handleSearch, } = useSearch({
|
|
22
|
+
fetchData, isFetching, searchParams, setSearchParams,
|
|
23
|
+
});
|
|
24
|
+
const { filterState, resetFilterProgress, handleFilterChange } = useFilter();
|
|
25
|
+
const { pageIndex, handlePageChange, resetPagination } = usePagination();
|
|
26
|
+
const { previousCourseData } = useCourseData({
|
|
27
|
+
courseData,
|
|
28
|
+
searchString,
|
|
29
|
+
});
|
|
30
|
+
const handleFetchData = useCallback((params) => {
|
|
31
|
+
const { pageIndex: newPageIndex, filters: newFilters } = params;
|
|
32
|
+
const filterChanged = handleFilterChange(newFilters, fetchData, searchString);
|
|
33
|
+
if (filterChanged) {
|
|
34
|
+
resetPagination();
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
handlePageChange(newPageIndex !== null && newPageIndex !== void 0 ? newPageIndex : DEFAULT_PAGE_INDEX);
|
|
38
|
+
fetchData(Object.assign(Object.assign({}, params), { searchString }));
|
|
39
|
+
}, [handleFilterChange, fetchData, searchString, resetPagination, handlePageChange]);
|
|
40
|
+
return {
|
|
41
|
+
pageIndex,
|
|
42
|
+
filterState,
|
|
43
|
+
searchString,
|
|
44
|
+
hasInitializedFromUrl,
|
|
45
|
+
urlSearchQuery,
|
|
46
|
+
previousCourseData,
|
|
47
|
+
handleSearch,
|
|
48
|
+
handleFetchData,
|
|
49
|
+
resetFilterProgress,
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=useCatalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCatalog.js","sourceRoot":"","sources":["../../../src/catalog/hooks/useCatalog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAGpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,EACzB,SAAS,EACT,UAAU,EACV,UAAU,EACV,YAAY,EACZ,eAAe,GACC,EAAE,EAAE;IACpB,MAAM,EACJ,qBAAqB,EACrB,cAAc,EACd,YAAY,EACZ,YAAY,GACb,GAAG,SAAS,CAAC;QACZ,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,eAAe;KACrD,CAAC,CAAC;IAEH,MAAM,EAAE,WAAW,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,GAAG,SAAS,EAAE,CAAC;IAE7E,MAAM,EAAE,SAAS,EAAE,gBAAgB,EAAE,eAAe,EAAE,GAAG,aAAa,EAAE,CAAC;IAEzE,MAAM,EAAE,kBAAkB,EAAE,GAAG,aAAa,CAAC;QAC3C,UAAU;QACV,YAAY;KACb,CAAC,CAAC;IAEH,MAAM,eAAe,GAAG,WAAW,CAAC,CAAC,MAAuB,EAAE,EAAE;QAC9D,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,MAAM,CAAC;QAEhE,MAAM,aAAa,GAAG,kBAAkB,CAAC,UAA+B,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;QAEnG,IAAI,aAAa,EAAE,CAAC;YAClB,eAAe,EAAE,CAAC;YAClB,OAAO;QACT,CAAC;QAED,gBAAgB,CAAC,YAAY,aAAZ,YAAY,cAAZ,YAAY,GAAI,kBAAkB,CAAC,CAAC;QACrD,SAAS,iCAAM,MAAM,KAAE,YAAY,IAAG,CAAC;IACzC,CAAC,EAAE,CAAC,kBAAkB,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAErF,OAAO;QACL,SAAS;QACT,WAAW;QACX,YAAY;QACZ,qBAAqB;QACrB,cAAc;QACd,kBAAkB;QAClB,YAAY;QACZ,eAAe;QACf,mBAAmB;KACpB,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { useCallback } from 'react';\n\nimport type { DataTableParams, DataTableFilter } from '@src/data/course-list-search/types';\nimport { DEFAULT_PAGE_INDEX } from '@src/data/course-list-search/constants';\nimport { useSearch } from './useSearch';\nimport { useFilter } from './useFilter';\nimport { usePagination } from './usePagination';\nimport { useCourseData } from './useCourseData';\nimport type { UseCatalogProps } from './types';\n\n/**\n * Main catalog hook that orchestrates all catalog functionality.\n *\n * This hook combines multiple specialized hooks to provide a complete\n * catalog management solution with search, filtering, pagination, and data caching.\n *\n * Features:\n * - Search functionality\n * - Filter management with intelligent change detection\n * - Pagination state management\n * - Course data caching for better UX\n * - Coordinated data fetching with proper state management\n */\nexport const useCatalog = ({\n fetchData,\n courseData,\n isFetching,\n searchParams,\n setSearchParams,\n}: UseCatalogProps) => {\n const {\n hasInitializedFromUrl,\n urlSearchQuery,\n searchString,\n handleSearch,\n } = useSearch({\n fetchData, isFetching, searchParams, setSearchParams,\n });\n\n const { filterState, resetFilterProgress, handleFilterChange } = useFilter();\n\n const { pageIndex, handlePageChange, resetPagination } = usePagination();\n\n const { previousCourseData } = useCourseData({\n courseData,\n searchString,\n });\n\n const handleFetchData = useCallback((params: DataTableParams) => {\n const { pageIndex: newPageIndex, filters: newFilters } = params;\n\n const filterChanged = handleFilterChange(newFilters as DataTableFilter[], fetchData, searchString);\n\n if (filterChanged) {\n resetPagination();\n return;\n }\n\n handlePageChange(newPageIndex ?? DEFAULT_PAGE_INDEX);\n fetchData({ ...params, searchString });\n }, [handleFilterChange, fetchData, searchString, resetPagination, handlePageChange]);\n\n return {\n pageIndex,\n filterState,\n searchString,\n hasInitializedFromUrl,\n urlSearchQuery,\n previousCourseData,\n handleSearch,\n handleFetchData,\n resetFilterProgress,\n };\n};\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CourseListSearchResponse } from '../../data/course-list-search/types';
|
|
2
|
+
import type { UseCourseDataProps } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Custom hook for managing course data caching.
|
|
5
|
+
*
|
|
6
|
+
* This hook provides functionality to:
|
|
7
|
+
* - Cache previous course data when not searching
|
|
8
|
+
* - Manage data persistence for better UX
|
|
9
|
+
*/
|
|
10
|
+
export declare const useCourseData: ({ courseData, searchString, }: UseCourseDataProps) => {
|
|
11
|
+
previousCourseData: CourseListSearchResponse | null;
|
|
12
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useState, useEffect } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Custom hook for managing course data caching.
|
|
4
|
+
*
|
|
5
|
+
* This hook provides functionality to:
|
|
6
|
+
* - Cache previous course data when not searching
|
|
7
|
+
* - Manage data persistence for better UX
|
|
8
|
+
*/
|
|
9
|
+
export const useCourseData = ({ courseData, searchString, }) => {
|
|
10
|
+
const [previousCourseData, setPreviousCourseData] = useState(null);
|
|
11
|
+
/**
|
|
12
|
+
* Handles course data state changes.
|
|
13
|
+
*/
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
if (courseData && !searchString && courseData.total > 0) {
|
|
16
|
+
setPreviousCourseData(courseData);
|
|
17
|
+
}
|
|
18
|
+
}, [courseData, searchString]);
|
|
19
|
+
return { previousCourseData };
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=useCourseData.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCourseData.js","sourceRoot":"","sources":["../../../src/catalog/hooks/useCourseData.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAK5C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,EAC5B,UAAU,EACV,YAAY,GACO,EAAE,EAAE;IACvB,MAAM,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,GAAG,QAAQ,CAAkC,IAAI,CAAC,CAAC;IAEpG;;OAEG;IACH,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,UAAU,IAAI,CAAC,YAAY,IAAI,UAAU,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;YACxD,qBAAqB,CAAC,UAAU,CAAC,CAAC;QACpC,CAAC;IACH,CAAC,EAAE,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC;IAE/B,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAChC,CAAC,CAAC","sourcesContent":["import { useState, useEffect } from 'react';\n\nimport type { CourseListSearchResponse } from '@src/data/course-list-search/types';\nimport type { UseCourseDataProps } from './types';\n\n/**\n * Custom hook for managing course data caching.\n *\n * This hook provides functionality to:\n * - Cache previous course data when not searching\n * - Manage data persistence for better UX\n */\nexport const useCourseData = ({\n courseData,\n searchString,\n}: UseCourseDataProps) => {\n const [previousCourseData, setPreviousCourseData] = useState<CourseListSearchResponse | null>(null);\n\n /**\n * Handles course data state changes.\n */\n useEffect(() => {\n if (courseData && !searchString && courseData.total > 0) {\n setPreviousCourseData(courseData);\n }\n }, [courseData, searchString]);\n\n return { previousCourseData };\n};\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { UseDebouncedSearchInputProps } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Custom hook for managing debounced search input with deferred value optimization.
|
|
4
|
+
*/
|
|
5
|
+
export declare const useDebouncedSearchInput: ({ searchString, handleSearch, debounceDelay, }: UseDebouncedSearchInputProps) => {
|
|
6
|
+
setSearchInput: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
7
|
+
};
|