@edx/frontend-app-subscription-learner-dashboard 1.26.0 → 1.26.2
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/dist/containers/CourseCard/components/CourseCardActions/BeginCourseButton.js +1 -1
- package/dist/containers/CourseCard/components/CourseCardActions/BeginCourseButton.js.map +1 -1
- package/dist/containers/CourseCard/components/CourseCardActions/ResumeButton.js +1 -1
- package/dist/containers/CourseCard/components/CourseCardActions/ResumeButton.js.map +1 -1
- package/dist/containers/CourseCard/components/CourseCardActions/ViewCourseButton.js +1 -1
- package/dist/containers/CourseCard/components/CourseCardActions/ViewCourseButton.js.map +1 -1
- package/dist/containers/Dashboard/DashboardContent.d.ts +1 -5
- package/dist/containers/Dashboard/DashboardContent.js +1 -1
- package/dist/containers/Dashboard/DashboardContent.js.map +1 -1
- package/dist/containers/Dashboard/DashboardTabs.d.ts +1 -4
- package/dist/containers/Dashboard/DashboardTabs.js +12 -3
- package/dist/containers/Dashboard/DashboardTabs.js.map +1 -1
- package/dist/containers/Dashboard/index.js +1 -3
- package/dist/containers/Dashboard/index.js.map +1 -1
- package/dist/containers/HistoryPanel/index.d.ts +3 -4
- package/dist/containers/HistoryPanel/index.js +1 -11
- package/dist/containers/HistoryPanel/index.js.map +1 -1
- package/dist/containers/ProductCard/index.js +15 -2
- package/dist/containers/ProductCard/index.js.map +1 -1
- package/dist/data/constants/app.d.ts +1 -1
- package/dist/data/constants/app.js +1 -1
- package/dist/data/constants/app.js.map +1 -1
- package/dist/hooks/usePopularCoursesAndPrograms.js +2 -1
- package/dist/hooks/usePopularCoursesAndPrograms.js.map +1 -1
- package/dist/utils/algoliaUtils.d.ts +2 -1
- package/dist/utils/algoliaUtils.js +4 -2
- package/dist/utils/algoliaUtils.js.map +1 -1
- package/package.json +1 -1
|
@@ -22,7 +22,7 @@ export const BeginCourseButton = ({ cardId }) => {
|
|
|
22
22
|
}, [courseData.enrollment.mode, learnerData === null || learnerData === void 0 ? void 0 : learnerData.enterpriseDashboard]);
|
|
23
23
|
const { disableBeginCourse } = useActionDisabledState(cardId);
|
|
24
24
|
const handleClick = useCourseTrackingEvent(track.course.enterCourseClicked, cardId, homeUrl + execEdTrackingParam);
|
|
25
|
-
return (_jsx(ActionButton, { disabled: disableBeginCourse, as: "a", href:
|
|
25
|
+
return (_jsx(ActionButton, { disabled: disableBeginCourse, as: "a", href: homeUrl + execEdTrackingParam, onClick: handleClick, children: formatMessage(messages.beginCourse) }));
|
|
26
26
|
};
|
|
27
27
|
BeginCourseButton.propTypes = {
|
|
28
28
|
cardId: PropTypes.string.isRequired,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BeginCourseButton.js","sourceRoot":"","sources":["../../../../../src/containers/CourseCard/components/CourseCardActions/BeginCourseButton.jsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,SAAS,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gCAAgC,EAAE,MAAM,4BAA4B,CAAC;AAE9E,OAAO,KAAK,MAAM,eAAe,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,sBAAsB,MAAM,UAAU,CAAC;AAC9C,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAC1C,OAAO,QAAQ,MAAM,YAAY,CAAC;AAElC,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;;IAC9C,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,0BAA0B,EAAE,CAAC;IAC3D,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,SAAS,0CAAE,OAAO,CAAC;IAC/C,MAAM,mBAAmB,GAAG,OAAO,CAAC,GAAG,EAAE;QACvC,MAAM,gBAAgB,GAAG,gCAAgC,CAAC,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC/F,MAAM,EAAE,SAAS,EAAE,GAAG,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,mBAAmB,KAAI,EAAE,CAAC;QAC7D,OAAO,gBAAgB,CAAC,CAAC,CAAC,WAAW,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACxD,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,EAAE,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,mBAAmB,CAAC,CAAC,CAAC;IACnE,MAAM,EAAE,kBAAkB,EAAE,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAE9D,MAAM,WAAW,GAAG,sBAAsB,CACxC,KAAK,CAAC,MAAM,CAAC,kBAAkB,EAC/B,MAAM,EACN,OAAO,GAAG,mBAAmB,CAC9B,CAAC;IACF,OAAO,CACL,KAAC,YAAY,IACX,QAAQ,EAAE,kBAAkB,EAC5B,EAAE,EAAC,GAAG,EACN,IAAI,
|
|
1
|
+
{"version":3,"file":"BeginCourseButton.js","sourceRoot":"","sources":["../../../../../src/containers/CourseCard/components/CourseCardActions/BeginCourseButton.jsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,SAAS,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gCAAgC,EAAE,MAAM,4BAA4B,CAAC;AAE9E,OAAO,KAAK,MAAM,eAAe,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,sBAAsB,MAAM,UAAU,CAAC;AAC9C,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAC1C,OAAO,QAAQ,MAAM,YAAY,CAAC;AAElC,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;;IAC9C,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,0BAA0B,EAAE,CAAC;IAC3D,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,SAAS,0CAAE,OAAO,CAAC;IAC/C,MAAM,mBAAmB,GAAG,OAAO,CAAC,GAAG,EAAE;QACvC,MAAM,gBAAgB,GAAG,gCAAgC,CAAC,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC/F,MAAM,EAAE,SAAS,EAAE,GAAG,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,mBAAmB,KAAI,EAAE,CAAC;QAC7D,OAAO,gBAAgB,CAAC,CAAC,CAAC,WAAW,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACxD,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,EAAE,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,mBAAmB,CAAC,CAAC,CAAC;IACnE,MAAM,EAAE,kBAAkB,EAAE,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAE9D,MAAM,WAAW,GAAG,sBAAsB,CACxC,KAAK,CAAC,MAAM,CAAC,kBAAkB,EAC/B,MAAM,EACN,OAAO,GAAG,mBAAmB,CAC9B,CAAC;IACF,OAAO,CACL,KAAC,YAAY,IACX,QAAQ,EAAE,kBAAkB,EAC5B,EAAE,EAAC,GAAG,EACN,IAAI,EAAE,OAAO,GAAG,mBAAmB,EACnC,OAAO,EAAE,WAAW,YAEnB,aAAa,CAAC,QAAQ,CAAC,WAAW,CAAC,GACvB,CAChB,CAAC;AACJ,CAAC,CAAC;AACF,iBAAiB,CAAC,SAAS,GAAG;IAC5B,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,UAAU;CACpC,CAAC;AACF,eAAe,iBAAiB,CAAC","sourcesContent":["import React, { useMemo } from 'react';\nimport PropTypes from 'prop-types';\n\nimport { useIntl } from '@openedx/frontend-base';\nimport { EXECUTIVE_EDUCATION_COURSE_MODES } from '@src/data/constants/course';\n\nimport track from '@src/tracking';\nimport { useCourseData, useCourseTrackingEvent } from '@src/hooks';\nimport { useInitializeSubsDashboard } from '@src/data/hooks';\nimport useActionDisabledState from '../hooks';\nimport ActionButton from './ActionButton';\nimport messages from './messages';\n\nexport const BeginCourseButton = ({ cardId }) => {\n const { formatMessage } = useIntl();\n const { data: learnerData } = useInitializeSubsDashboard();\n const courseData = useCourseData(cardId);\n const homeUrl = courseData?.courseRun?.homeUrl;\n const execEdTrackingParam = useMemo(() => {\n const isExecEd2UCourse = EXECUTIVE_EDUCATION_COURSE_MODES.includes(courseData.enrollment.mode);\n const { authOrgId } = learnerData?.enterpriseDashboard || {};\n return isExecEd2UCourse ? `?org_id=${authOrgId}` : '';\n }, [courseData.enrollment.mode, learnerData?.enterpriseDashboard]);\n const { disableBeginCourse } = useActionDisabledState(cardId);\n\n const handleClick = useCourseTrackingEvent(\n track.course.enterCourseClicked,\n cardId,\n homeUrl + execEdTrackingParam,\n );\n return (\n <ActionButton\n disabled={disableBeginCourse}\n as=\"a\"\n href={homeUrl + execEdTrackingParam}\n onClick={handleClick}\n >\n {formatMessage(messages.beginCourse)}\n </ActionButton>\n );\n};\nBeginCourseButton.propTypes = {\n cardId: PropTypes.string.isRequired,\n};\nexport default BeginCourseButton;\n"]}
|
|
@@ -23,7 +23,7 @@ export const ResumeButton = ({ cardId }) => {
|
|
|
23
23
|
}, [courseData.enrollment.mode, learnerData === null || learnerData === void 0 ? void 0 : learnerData.enterpriseDashboard]);
|
|
24
24
|
const { disableResumeCourse } = useActionDisabledState(cardId);
|
|
25
25
|
const handleClick = useCourseTrackingEvent(track.course.enterCourseClicked, cardId, resumeUrl + execEdTrackingParam);
|
|
26
|
-
return (_jsx(ActionButton, { disabled: disableResumeCourse, as: "a", href:
|
|
26
|
+
return (_jsx(ActionButton, { disabled: disableResumeCourse, as: "a", href: resumeUrl + execEdTrackingParam, onClick: handleClick, children: formatMessage(messages.resume) }));
|
|
27
27
|
};
|
|
28
28
|
ResumeButton.propTypes = {
|
|
29
29
|
cardId: PropTypes.string.isRequired,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ResumeButton.js","sourceRoot":"","sources":["../../../../../src/containers/CourseCard/components/CourseCardActions/ResumeButton.jsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,SAAS,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEjD,OAAO,EAAE,gCAAgC,EAAE,MAAM,4BAA4B,CAAC;AAC9E,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,KAAK,MAAM,eAAe,CAAC;AAClC,OAAO,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,sBAAsB,MAAM,UAAU,CAAC;AAC9C,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAC1C,OAAO,QAAQ,MAAM,YAAY,CAAC;AAElC,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;;IACzC,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,0BAA0B,EAAE,CAAC;IAC3D,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,SAAS,GAAG,UAAU,CAAC,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,SAAS,0CAAE,SAAS,CAAC,CAAC;IAC/D,MAAM,mBAAmB,GAAG,OAAO,CAAC,GAAG,EAAE;QACvC,MAAM,gBAAgB,GAAG,gCAAgC,CAAC,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC/F,MAAM,EAAE,SAAS,EAAE,GAAG,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,mBAAmB,KAAI,EAAE,CAAC;QAC7D,OAAO,gBAAgB,CAAC,CAAC,CAAC,WAAW,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACxD,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,EAAE,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,mBAAmB,CAAC,CAAC,CAAC;IACnE,MAAM,EAAE,mBAAmB,EAAE,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAE/D,MAAM,WAAW,GAAG,sBAAsB,CACxC,KAAK,CAAC,MAAM,CAAC,kBAAkB,EAC/B,MAAM,EACN,SAAS,GAAG,mBAAmB,CAChC,CAAC;
|
|
1
|
+
{"version":3,"file":"ResumeButton.js","sourceRoot":"","sources":["../../../../../src/containers/CourseCard/components/CourseCardActions/ResumeButton.jsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,SAAS,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEjD,OAAO,EAAE,gCAAgC,EAAE,MAAM,4BAA4B,CAAC;AAC9E,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,KAAK,MAAM,eAAe,CAAC;AAClC,OAAO,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,sBAAsB,MAAM,UAAU,CAAC;AAC9C,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAC1C,OAAO,QAAQ,MAAM,YAAY,CAAC;AAElC,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;;IACzC,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,0BAA0B,EAAE,CAAC;IAC3D,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,SAAS,GAAG,UAAU,CAAC,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,SAAS,0CAAE,SAAS,CAAC,CAAC;IAC/D,MAAM,mBAAmB,GAAG,OAAO,CAAC,GAAG,EAAE;QACvC,MAAM,gBAAgB,GAAG,gCAAgC,CAAC,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC/F,MAAM,EAAE,SAAS,EAAE,GAAG,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,mBAAmB,KAAI,EAAE,CAAC;QAC7D,OAAO,gBAAgB,CAAC,CAAC,CAAC,WAAW,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACxD,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,EAAE,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,mBAAmB,CAAC,CAAC,CAAC;IACnE,MAAM,EAAE,mBAAmB,EAAE,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAE/D,MAAM,WAAW,GAAG,sBAAsB,CACxC,KAAK,CAAC,MAAM,CAAC,kBAAkB,EAC/B,MAAM,EACN,SAAS,GAAG,mBAAmB,CAChC,CAAC;IAEF,OAAO,CACL,KAAC,YAAY,IACX,QAAQ,EAAE,mBAAmB,EAC7B,EAAE,EAAC,GAAG,EACN,IAAI,EAAE,SAAS,GAAG,mBAAmB,EACrC,OAAO,EAAE,WAAW,YAEnB,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,GAClB,CAChB,CAAC;AACJ,CAAC,CAAC;AACF,YAAY,CAAC,SAAS,GAAG;IACvB,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,UAAU;CACpC,CAAC;AACF,eAAe,YAAY,CAAC","sourcesContent":["import React, { useMemo } from 'react';\nimport PropTypes from 'prop-types';\n\nimport { useIntl } from '@openedx/frontend-base';\n\nimport { EXECUTIVE_EDUCATION_COURSE_MODES } from '@src/data/constants/course';\nimport { baseAppUrl } from '@src/data/services/lms/urls';\nimport track from '@src/tracking';\nimport { useCourseTrackingEvent, useCourseData } from '@src/hooks';\nimport { useInitializeSubsDashboard } from '@src/data/hooks';\nimport useActionDisabledState from '../hooks';\nimport ActionButton from './ActionButton';\nimport messages from './messages';\n\nexport const ResumeButton = ({ cardId }) => {\n const { formatMessage } = useIntl();\n const { data: learnerData } = useInitializeSubsDashboard();\n const courseData = useCourseData(cardId);\n const resumeUrl = baseAppUrl(courseData?.courseRun?.resumeUrl);\n const execEdTrackingParam = useMemo(() => {\n const isExecEd2UCourse = EXECUTIVE_EDUCATION_COURSE_MODES.includes(courseData.enrollment.mode);\n const { authOrgId } = learnerData?.enterpriseDashboard || {};\n return isExecEd2UCourse ? `?org_id=${authOrgId}` : '';\n }, [courseData.enrollment.mode, learnerData?.enterpriseDashboard]);\n const { disableResumeCourse } = useActionDisabledState(cardId);\n\n const handleClick = useCourseTrackingEvent(\n track.course.enterCourseClicked,\n cardId,\n resumeUrl + execEdTrackingParam,\n );\n\n return (\n <ActionButton\n disabled={disableResumeCourse}\n as=\"a\"\n href={resumeUrl + execEdTrackingParam}\n onClick={handleClick}\n >\n {formatMessage(messages.resume)}\n </ActionButton>\n );\n};\nResumeButton.propTypes = {\n cardId: PropTypes.string.isRequired,\n};\nexport default ResumeButton;\n"]}
|
|
@@ -14,7 +14,7 @@ export const ViewCourseButton = ({ cardId }) => {
|
|
|
14
14
|
const homeUrl = (_a = courseData === null || courseData === void 0 ? void 0 : courseData.courseRun) === null || _a === void 0 ? void 0 : _a.homeUrl;
|
|
15
15
|
const { disableViewCourse } = useActionDisabledState(cardId);
|
|
16
16
|
const handleClick = useCourseTrackingEvent(track.course.enterCourseClicked, cardId, homeUrl);
|
|
17
|
-
return (_jsx(ActionButton, { disabled: disableViewCourse, as: "a", href:
|
|
17
|
+
return (_jsx(ActionButton, { disabled: disableViewCourse, as: "a", href: homeUrl, onClick: handleClick, children: formatMessage(messages.viewCourse) }));
|
|
18
18
|
};
|
|
19
19
|
ViewCourseButton.propTypes = {
|
|
20
20
|
cardId: PropTypes.string.isRequired,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ViewCourseButton.js","sourceRoot":"","sources":["../../../../../src/containers/CourseCard/components/CourseCardActions/ViewCourseButton.jsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,SAAS,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEjD,OAAO,KAAK,MAAM,eAAe,CAAC;AAClC,OAAO,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,sBAAsB,MAAM,UAAU,CAAC;AAC9C,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAC1C,OAAO,QAAQ,MAAM,YAAY,CAAC;AAElC,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;;IAC7C,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,SAAS,0CAAE,OAAO,CAAC;IAC/C,MAAM,EAAE,iBAAiB,EAAE,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAE7D,MAAM,WAAW,GAAG,sBAAsB,CACxC,KAAK,CAAC,MAAM,CAAC,kBAAkB,EAC/B,MAAM,EACN,OAAO,CACR,CAAC;IACF,OAAO,CACL,KAAC,YAAY,IACX,QAAQ,EAAE,iBAAiB,EAC3B,EAAE,EAAC,GAAG,EACN,IAAI,
|
|
1
|
+
{"version":3,"file":"ViewCourseButton.js","sourceRoot":"","sources":["../../../../../src/containers/CourseCard/components/CourseCardActions/ViewCourseButton.jsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,SAAS,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEjD,OAAO,KAAK,MAAM,eAAe,CAAC;AAClC,OAAO,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,sBAAsB,MAAM,UAAU,CAAC;AAC9C,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAC1C,OAAO,QAAQ,MAAM,YAAY,CAAC;AAElC,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;;IAC7C,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,SAAS,0CAAE,OAAO,CAAC;IAC/C,MAAM,EAAE,iBAAiB,EAAE,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAE7D,MAAM,WAAW,GAAG,sBAAsB,CACxC,KAAK,CAAC,MAAM,CAAC,kBAAkB,EAC/B,MAAM,EACN,OAAO,CACR,CAAC;IACF,OAAO,CACL,KAAC,YAAY,IACX,QAAQ,EAAE,iBAAiB,EAC3B,EAAE,EAAC,GAAG,EACN,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,WAAW,YAEnB,aAAa,CAAC,QAAQ,CAAC,UAAU,CAAC,GACtB,CAChB,CAAC;AACJ,CAAC,CAAC;AACF,gBAAgB,CAAC,SAAS,GAAG;IAC3B,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,UAAU;CACpC,CAAC;AACF,eAAe,gBAAgB,CAAC","sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport { useIntl } from '@openedx/frontend-base';\n\nimport track from '@src/tracking';\nimport { useCourseTrackingEvent, useCourseData } from '@src/hooks';\nimport useActionDisabledState from '../hooks';\nimport ActionButton from './ActionButton';\nimport messages from './messages';\n\nexport const ViewCourseButton = ({ cardId }) => {\n const { formatMessage } = useIntl();\n const courseData = useCourseData(cardId);\n const homeUrl = courseData?.courseRun?.homeUrl;\n const { disableViewCourse } = useActionDisabledState(cardId);\n\n const handleClick = useCourseTrackingEvent(\n track.course.enterCourseClicked,\n cardId,\n homeUrl,\n );\n return (\n <ActionButton\n disabled={disableViewCourse}\n as=\"a\"\n href={homeUrl}\n onClick={handleClick}\n >\n {formatMessage(messages.viewCourse)}\n </ActionButton>\n );\n};\nViewCourseButton.propTypes = {\n cardId: PropTypes.string.isRequired,\n};\nexport default ViewCourseButton;\n"]}
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
|
|
2
|
-
hasCourseHistory: boolean;
|
|
3
|
-
}
|
|
4
|
-
export declare const DashboardContent: ({ hasCourseHistory }: IDashboardContentProps) => import("react/jsx-runtime").JSX.Element;
|
|
5
|
-
export {};
|
|
1
|
+
export declare const DashboardContent: () => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Row, Col } from '@openedx/paragon';
|
|
3
3
|
import DashboardTabs from './DashboardTabs';
|
|
4
|
-
export const DashboardContent = (
|
|
4
|
+
export const DashboardContent = () => (_jsxs(Row, { children: [_jsx(Col, { xs: 12, lg: 8, children: _jsx(DashboardTabs, {}) }), _jsx(Col, { xs: 12, lg: 4, className: "mt-4", "data-testid": "dashboard-sidebar", children: _jsxs("div", { className: "dashboard-sidebar", children: [_jsx("h2", { children: "Sidebar" }), _jsx("p", { children: "This is the sidebar content." })] }) })] }));
|
|
5
5
|
//# sourceMappingURL=DashboardContent.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DashboardContent.js","sourceRoot":"","sources":["../../../src/containers/Dashboard/DashboardContent.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,aAAa,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"DashboardContent.js","sourceRoot":"","sources":["../../../src/containers/Dashboard/DashboardContent.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAE5C,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,EAAE,CAAC,CACpC,MAAC,GAAG,eACF,KAAC,GAAG,IAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,YAChB,KAAC,aAAa,KAAG,GACb,EACN,KAAC,GAAG,IAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,SAAS,EAAC,MAAM,iBAAa,mBAAmB,YAClE,eAAK,SAAS,EAAC,mBAAmB,aAEhC,mCAAgB,EAChB,uDAAmC,IAC/B,GACF,IACF,CACP,CAAC","sourcesContent":["import { Row, Col } from '@openedx/paragon';\nimport DashboardTabs from './DashboardTabs';\n\nexport const DashboardContent = () => (\n <Row>\n <Col xs={12} lg={8}>\n <DashboardTabs />\n </Col>\n <Col xs={12} lg={4} className=\"mt-4\" data-testid=\"dashboard-sidebar\">\n <div className=\"dashboard-sidebar\">\n {/* Temporary Content added, will be replaced with actual sidebar content */}\n <h2>Sidebar</h2>\n <p>This is the sidebar content.</p>\n </div>\n </Col>\n </Row>\n);\n"]}
|
|
@@ -1,5 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
hasCourseHistory: boolean;
|
|
3
|
-
}
|
|
4
|
-
declare const DashboardTabs: ({ hasCourseHistory }: IDashboardTabsProps) => import("react/jsx-runtime").JSX.Element;
|
|
1
|
+
declare const DashboardTabs: () => import("react/jsx-runtime").JSX.Element;
|
|
5
2
|
export default DashboardTabs;
|
|
@@ -4,8 +4,17 @@ import { Tabs, Tab } from '@openedx/paragon';
|
|
|
4
4
|
import CoursesPanel from '../CoursesPanel';
|
|
5
5
|
import ProgramsPanel from '../ProgramsPanel';
|
|
6
6
|
import HistoryPanel from '../HistoryPanel';
|
|
7
|
-
|
|
7
|
+
import { useInitializeSubsCourseDashboard } from '../../data/hooks';
|
|
8
|
+
const DashboardTabs = () => {
|
|
8
9
|
var _a;
|
|
10
|
+
const { data } = useInitializeSubsCourseDashboard();
|
|
11
|
+
const historyCourses = useMemo(() => {
|
|
12
|
+
const transformedCourses = (data === null || data === void 0 ? void 0 : data.coursesByCardId)
|
|
13
|
+
? Object.values(data.coursesByCardId)
|
|
14
|
+
: [];
|
|
15
|
+
return transformedCourses.filter(course => { var _a; return (_a = course === null || course === void 0 ? void 0 : course.enrollment) === null || _a === void 0 ? void 0 : _a.isAuditAccessExpired; });
|
|
16
|
+
}, [data]);
|
|
17
|
+
const hasCourseHistory = useMemo(() => historyCourses.length > 0, [historyCourses]);
|
|
9
18
|
// Defining the tabs here
|
|
10
19
|
const dashboardTabs = useMemo(() => {
|
|
11
20
|
const tabs = [
|
|
@@ -24,11 +33,11 @@ const DashboardTabs = ({ hasCourseHistory }) => {
|
|
|
24
33
|
tabs.push({
|
|
25
34
|
key: 'history',
|
|
26
35
|
title: 'Course history',
|
|
27
|
-
panel: _jsx(HistoryPanel, {}),
|
|
36
|
+
panel: _jsx(HistoryPanel, { historyCourses: historyCourses }),
|
|
28
37
|
});
|
|
29
38
|
}
|
|
30
39
|
return tabs;
|
|
31
|
-
}, [hasCourseHistory]);
|
|
40
|
+
}, [hasCourseHistory, historyCourses]);
|
|
32
41
|
const [activeTab, setActiveTab] = useState(dashboardTabs[0].key);
|
|
33
42
|
const handleTabSelect = useCallback((tabKey) => {
|
|
34
43
|
if (tabKey) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DashboardTabs.js","sourceRoot":"","sources":["../../../src/containers/Dashboard/DashboardTabs.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,YAAY,MAAM,iBAAiB,CAAC;AAC3C,OAAO,aAAa,MAAM,kBAAkB,CAAC;AAC7C,OAAO,YAAY,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"DashboardTabs.js","sourceRoot":"","sources":["../../../src/containers/Dashboard/DashboardTabs.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,YAAY,MAAM,iBAAiB,CAAC;AAC3C,OAAO,aAAa,MAAM,kBAAkB,CAAC;AAC7C,OAAO,YAAY,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,gCAAgC,EAAE,MAAM,iBAAiB,CAAC;AAEnE,MAAM,aAAa,GAAG,GAAG,EAAE;;IACzB,MAAM,EAAE,IAAI,EAAE,GAAG,gCAAgC,EAAE,CAAC;IAEpD,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,EAAE;QAClC,MAAM,kBAAkB,GAAG,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,eAAe;YAC9C,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAU;YAC9C,CAAC,CAAC,EAAE,CAAC;QAEP,OAAO,kBAAkB,CAAC,MAAM,CAC9B,MAAM,CAAC,EAAE,WAAC,OAAA,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,UAAU,0CAAE,oBAAoB,CAAA,EAAA,CACnD,CAAC;IACJ,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IACX,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;IAEpF,yBAAyB;IACzB,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,EAAE;QACjC,MAAM,IAAI,GAAG;YACX;gBACE,GAAG,EAAE,SAAS;gBACd,KAAK,EAAE,SAAS;gBAChB,KAAK,EAAE,KAAC,YAAY,KAAG;aACxB;YACD;gBACE,GAAG,EAAE,UAAU;gBACf,KAAK,EAAE,UAAU;gBACjB,KAAK,EAAE,KAAC,aAAa,KAAG;aACzB;SACF,CAAC;QAEF,IAAI,gBAAgB,EAAE,CAAC;YACrB,IAAI,CAAC,IAAI,CAAC;gBACR,GAAG,EAAE,SAAS;gBACd,KAAK,EAAE,gBAAgB;gBACvB,KAAK,EAAE,KAAC,YAAY,IAAC,cAAc,EAAE,cAAc,GAAI;aACxD,CAAC,CAAC;QACL,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC,EAAE,CAAC,gBAAgB,EAAE,cAAc,CAAC,CAAC,CAAC;IAEvC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACjE,MAAM,eAAe,GAAG,WAAW,CAAC,CAAC,MAAM,EAAE,EAAE;QAC7C,IAAI,MAAM,EAAE,CAAC;YACX,YAAY,CAAC,MAAM,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,CACL,KAAC,IAAI,IACH,EAAE,EAAC,6BAA6B,EAChC,gBAAgB,EAAE,MAAA,aAAa,CAAC,CAAC,CAAC,0CAAE,GAAG,EACvC,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,eAAe,EACzB,SAAS,EAAC,MAAM,EAChB,YAAY,kBAEX,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CACxB,KAAC,GAAG,IAAC,QAAQ,EAAE,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,YACrC,GAAG,CAAC,KAAK,IADmC,GAAG,CAAC,GAAG,CAEhD,CACP,CAAC,GACG,CACR,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,aAAa,CAAC","sourcesContent":["import React, { useMemo, useState, useCallback } from 'react';\nimport { Tabs, Tab } from '@openedx/paragon';\nimport CoursesPanel from '../CoursesPanel';\nimport ProgramsPanel from '../ProgramsPanel';\nimport HistoryPanel from '../HistoryPanel';\nimport { useInitializeSubsCourseDashboard } from '@src/data/hooks';\n\nconst DashboardTabs = () => {\n const { data } = useInitializeSubsCourseDashboard();\n\n const historyCourses = useMemo(() => {\n const transformedCourses = data?.coursesByCardId\n ? Object.values(data.coursesByCardId) as any[]\n : [];\n\n return transformedCourses.filter(\n course => course?.enrollment?.isAuditAccessExpired,\n );\n }, [data]);\n const hasCourseHistory = useMemo(() => historyCourses.length > 0, [historyCourses]);\n\n // Defining the tabs here\n const dashboardTabs = useMemo(() => {\n const tabs = [\n {\n key: 'courses',\n title: 'Courses',\n panel: <CoursesPanel />,\n },\n {\n key: 'programs',\n title: 'Programs',\n panel: <ProgramsPanel />,\n },\n ];\n\n if (hasCourseHistory) {\n tabs.push({\n key: 'history',\n title: 'Course history',\n panel: <HistoryPanel historyCourses={historyCourses} />,\n });\n }\n\n return tabs;\n }, [hasCourseHistory, historyCourses]);\n\n const [activeTab, setActiveTab] = useState(dashboardTabs[0].key);\n const handleTabSelect = useCallback((tabKey) => {\n if (tabKey) {\n setActiveTab(tabKey);\n }\n }, []);\n\n return (\n <Tabs\n id=\"subscription-dashboard-tabs\"\n defaultActiveKey={dashboardTabs[0]?.key}\n activeKey={activeTab}\n onSelect={handleTabSelect}\n className=\"mb-4\"\n mountOnEnter\n >\n {dashboardTabs.map(tab => (\n <Tab eventKey={tab.key} title={tab.title} key={tab.key}>\n {tab.panel}\n </Tab>\n ))}\n </Tabs>\n );\n};\n\nexport default DashboardTabs;\n"]}
|
|
@@ -16,7 +16,6 @@ import { SubscriptionBanner } from '../SubscriptionBanner';
|
|
|
16
16
|
import { useInitializeSubsDashboard } from '../../data/hooks';
|
|
17
17
|
import DashboardHeroSlot from '../../slots/DashboardHeroSlot';
|
|
18
18
|
export const Dashboard = () => {
|
|
19
|
-
var _a, _b;
|
|
20
19
|
const { data, isPending } = useInitializeSubsCourseDashboard();
|
|
21
20
|
const { data: learnerData } = useInitializeSubsDashboard();
|
|
22
21
|
const { pageTitle } = hooks.useDashboardMessages();
|
|
@@ -25,10 +24,9 @@ export const Dashboard = () => {
|
|
|
25
24
|
const learnerSubscriptionData = (learnerData === null || learnerData === void 0 ? void 0 : learnerData.userSubscription) || {};
|
|
26
25
|
const userSubscriptionStartDate = (learnerSubscriptionData === null || learnerSubscriptionData === void 0 ? void 0 : learnerSubscriptionData.subscriptionStartDate) || '';
|
|
27
26
|
const hasCourses = useMemo(() => { var _a; return ((_a = data === null || data === void 0 ? void 0 : data.subscriptionCourses) === null || _a === void 0 ? void 0 : _a.length) > 0; }, [data]);
|
|
28
|
-
const hasCourseHistory = ((_b = (_a = data === null || data === void 0 ? void 0 : data.nonUpgradeableCourses) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0;
|
|
29
27
|
return (_jsx("div", { id: "learnerdashboardroot", children: _jsx("main", { children: _jsxs("div", { id: "dashboard-container", className: "d-flex flex-column p-2 pt-0", children: [_jsx("h1", { className: "sr-only", children: pageTitle }), !isPending && (_jsxs(_Fragment, { children: [_jsx(DashboardModalSlot, {}), (hasCourses && showSelectSessionModal) && _jsx(SelectSessionModal, {})] })), _jsx("div", { id: "dashboard-content", "data-testid": "dashboard-content", children: isPending
|
|
30
28
|
? (_jsx(LoadingView, {}))
|
|
31
|
-
: (_jsxs(DashboardLayout, { children: [_jsx(DashboardHeader, { startDate: userSubscriptionStartDate }), _jsx(SubscriptionBanner, { learnerSubscriptionData: learnerSubscriptionData }), _jsx(DashboardHeroSlot, {}), _jsx(DashboardContent, {
|
|
29
|
+
: (_jsxs(DashboardLayout, { children: [_jsx(DashboardHeader, { startDate: userSubscriptionStartDate }), _jsx(SubscriptionBanner, { learnerSubscriptionData: learnerSubscriptionData }), _jsx(DashboardHeroSlot, {}), _jsx(DashboardContent, {}), _jsx(PopularCoursePanel, {}), _jsx(PopularProgramsPanel, {})] })) })] }) }) }));
|
|
32
30
|
};
|
|
33
31
|
export default Dashboard;
|
|
34
32
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/containers/Dashboard/index.jsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,gCAAgC,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,kBAAkB,MAAM,qCAAqC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,kBAAkB,MAAM,gCAAgC,CAAC;AAChE,OAAO,kBAAkB,MAAM,uBAAuB,CAAC;AACvD,OAAO,oBAAoB,MAAM,yBAAyB,CAAC;AAE3D,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,OAAO,eAAe,MAAM,mBAAmB,CAAC;AAEhD,OAAO,KAAK,MAAM,SAAS,CAAC;AAC5B,OAAO,cAAc,CAAC;AACtB,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,iBAAiB,MAAM,8BAA8B,CAAC;AAG7D,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,EAAE
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/containers/Dashboard/index.jsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,gCAAgC,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,kBAAkB,MAAM,qCAAqC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,kBAAkB,MAAM,gCAAgC,CAAC;AAChE,OAAO,kBAAkB,MAAM,uBAAuB,CAAC;AACvD,OAAO,oBAAoB,MAAM,yBAAyB,CAAC;AAE3D,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,OAAO,eAAe,MAAM,mBAAmB,CAAC;AAEhD,OAAO,KAAK,MAAM,SAAS,CAAC;AAC5B,OAAO,cAAc,CAAC;AACtB,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,iBAAiB,MAAM,8BAA8B,CAAC;AAG7D,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,EAAE;IAC5B,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,gCAAgC,EAAE,CAAC;IAC/D,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,0BAA0B,EAAE,CAAC;IAC3D,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC,oBAAoB,EAAE,CAAC;IACnD,MAAM,EAAE,kBAAkB,EAAE,GAAG,qBAAqB,EAAE,CAAC;IACvD,MAAM,sBAAsB,GAAG,kBAAkB,CAAC,MAAM,KAAK,IAAI,CAAC;IAClE,MAAM,uBAAuB,GAAG,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,gBAAgB,KAAI,EAAE,CAAC;IACpE,MAAM,yBAAyB,GAAG,CAAA,uBAAuB,aAAvB,uBAAuB,uBAAvB,uBAAuB,CAAE,qBAAqB,KAAI,EAAE,CAAC;IAEvF,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,WAAC,OAAA,CAAA,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,mBAAmB,0CAAE,MAAM,IAAG,CAAC,CAAA,EAAA,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEhF,OAAO,CACL,cAAK,EAAE,EAAC,sBAAsB,YAC5B,yBACE,eAAK,EAAE,EAAC,qBAAqB,EAAC,SAAS,EAAC,6BAA6B,aACnE,aAAI,SAAS,EAAC,SAAS,YAAE,SAAS,GAAM,EACvC,CAAC,SAAS,IAAI,CACb,8BACE,KAAC,kBAAkB,KAAG,EACrB,CAAC,UAAU,IAAI,sBAAsB,CAAC,IAAI,KAAC,kBAAkB,KAAG,IAChE,CACJ,EACD,cAAK,EAAE,EAAC,mBAAmB,iBAAa,mBAAmB,YACxD,SAAS;4BACR,CAAC,CAAC,CAAC,KAAC,WAAW,KAAG,CAAC;4BACnB,CAAC,CAAC,CACA,MAAC,eAAe,eACd,KAAC,eAAe,IAAC,SAAS,EAAE,yBAAyB,GAAI,EACzD,KAAC,kBAAkB,IAAC,uBAAuB,EAAE,uBAAuB,GAAI,EACxE,KAAC,iBAAiB,KAAG,EACrB,KAAC,gBAAgB,KAAG,EACpB,KAAC,kBAAkB,KAAG,EACtB,KAAC,oBAAoB,KAAG,IACR,CACnB,GACC,IACF,GACD,GACH,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,SAAS,CAAC","sourcesContent":["import { useMemo } from 'react';\nimport { DashboardHeader } from './DashboardHeader';\n\nimport { useSelectSessionModal } from '@src/data/context';\nimport { useInitializeSubsCourseDashboard } from '@src/data/hooks';\nimport SelectSessionModal from '../../containers/SelectSessionModal';\nimport { DashboardContent } from './DashboardContent';\nimport DashboardModalSlot from '../../slots/DashboardModalSlot';\nimport PopularCoursePanel from '../PopularCoursePanel';\nimport PopularProgramsPanel from '../PopularProgramsPanel';\n\nimport LoadingView from './LoadingView';\nimport DashboardLayout from './DashboardLayout';\n\nimport hooks from './hooks';\nimport './index.scss';\nimport { SubscriptionBanner } from '../SubscriptionBanner';\nimport { useInitializeSubsDashboard } from '@src/data/hooks';\nimport DashboardHeroSlot from '@src/slots/DashboardHeroSlot';\n\n\nexport const Dashboard = () => {\n const { data, isPending } = useInitializeSubsCourseDashboard();\n const { data: learnerData } = useInitializeSubsDashboard();\n const { pageTitle } = hooks.useDashboardMessages();\n const { selectSessionModal } = useSelectSessionModal();\n const showSelectSessionModal = selectSessionModal.cardId !== null;\n const learnerSubscriptionData = learnerData?.userSubscription || {};\n const userSubscriptionStartDate = learnerSubscriptionData?.subscriptionStartDate || '';\n\n const hasCourses = useMemo(() => data?.subscriptionCourses?.length > 0, [data]);\n\n return (\n <div id=\"learnerdashboardroot\">\n <main>\n <div id=\"dashboard-container\" className=\"d-flex flex-column p-2 pt-0\">\n <h1 className=\"sr-only\">{pageTitle}</h1>\n {!isPending && (\n <>\n <DashboardModalSlot />\n {(hasCourses && showSelectSessionModal) && <SelectSessionModal />}\n </>\n )}\n <div id=\"dashboard-content\" data-testid=\"dashboard-content\">\n {isPending\n ? (<LoadingView />)\n : (\n <DashboardLayout>\n <DashboardHeader startDate={userSubscriptionStartDate} />\n <SubscriptionBanner learnerSubscriptionData={learnerSubscriptionData} />\n <DashboardHeroSlot />\n <DashboardContent />\n <PopularCoursePanel />\n <PopularProgramsPanel />\n </DashboardLayout>\n )}\n </div>\n </div>\n </main>\n </div>\n );\n};\n\nexport default Dashboard;\n"]}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { HistoryPanelProps } from './data/types';
|
|
3
|
+
export declare const HistoryPanel: FC<HistoryPanelProps>;
|
|
5
4
|
export default HistoryPanel;
|
|
@@ -1,21 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React, { useMemo } from 'react';
|
|
3
3
|
import { useIntl } from '@openedx/frontend-base';
|
|
4
|
-
import { useInitializeSubsCourseDashboard } from '../../data/hooks';
|
|
5
4
|
import CourseListSlot from '../../slots/CourseListSlot';
|
|
6
5
|
import { useFilters } from '../../data/context';
|
|
7
6
|
import { getVisibleList } from '../../utils/dataTransformers';
|
|
8
7
|
import messages from './messages';
|
|
9
|
-
export const HistoryPanel = () => {
|
|
8
|
+
export const HistoryPanel = ({ historyCourses }) => {
|
|
10
9
|
const { formatMessage } = useIntl();
|
|
11
|
-
const { data } = useInitializeSubsCourseDashboard();
|
|
12
|
-
const targetAuditAccessExpired = true;
|
|
13
|
-
const historyCourses = useMemo(() => {
|
|
14
|
-
const transformedCourses = (data === null || data === void 0 ? void 0 : data.coursesByCardId)
|
|
15
|
-
? Object.values(data.coursesByCardId)
|
|
16
|
-
: [];
|
|
17
|
-
return transformedCourses.filter(course => { var _a; return ((_a = course === null || course === void 0 ? void 0 : course.enrollment) === null || _a === void 0 ? void 0 : _a.isAuditAccessExpired) === targetAuditAccessExpired; });
|
|
18
|
-
}, [data, targetAuditAccessExpired]);
|
|
19
10
|
const hasCourses = useMemo(() => historyCourses.length > 0, [historyCourses]);
|
|
20
11
|
const { filters, sortBy, pageNumber, setPageNumber, } = useFilters();
|
|
21
12
|
const { visibleList, numPages } = useMemo(() => {
|
|
@@ -36,6 +27,5 @@ export const HistoryPanel = () => {
|
|
|
36
27
|
};
|
|
37
28
|
return (_jsxs("div", { className: "course-list-container", children: [_jsx("div", { className: "course-list-heading-container", children: _jsx("h2", { className: "course-list-title", children: formatMessage(messages.myCourseHistory) }) }), hasCourses && _jsx(CourseListSlot, { courseListData: courseListData })] }));
|
|
38
29
|
};
|
|
39
|
-
HistoryPanel.propTypes = {};
|
|
40
30
|
export default HistoryPanel;
|
|
41
31
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/containers/HistoryPanel/index.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/containers/HistoryPanel/index.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,EAAM,OAAO,EAAE,MAAM,OAAO,CAAC;AAE3C,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEjD,OAAO,cAAc,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D,OAAO,QAAQ,MAAM,YAAY,CAAC;AAGlC,MAAM,CAAC,MAAM,YAAY,GAA0B,CAAC,EAAE,cAAc,EAAE,EAAE,EAAE;IACxE,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;IAE9E,MAAM,EACJ,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,GAC3C,GAAG,UAAU,EAAE,CAAC;IACjB,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE;QAC7C,OAAO,cAAc,CACnB,cAAc,EACd,OAAO,EACP,MAAM,EACN,UAAU,CACX,CAAC;IACJ,CAAC,EAAE,CAAC,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IAElD,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,QAAQ,GAAG,CAAC,IAAI,UAAU,GAAG,QAAQ,EAAE,CAAC;YAC1C,aAAa,CAAC,CAAC,CAAC,CAAC;QACnB,CAAC;IACH,CAAC,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC;IAE1C,MAAM,cAAc,GAAG;QACrB,WAAW,EAAE,IAAI;QACjB,aAAa;QACb,QAAQ;QACR,WAAW;QACX,cAAc,EAAE,IAAI;QACpB,YAAY,EAAE,IAAI;KACnB,CAAC;IAEF,OAAO,CACL,eAAK,SAAS,EAAC,uBAAuB,aACpC,cAAK,SAAS,EAAC,+BAA+B,YAC5C,aAAI,SAAS,EAAC,mBAAmB,YAAE,aAAa,CAAC,QAAQ,CAAC,eAAe,CAAC,GAAM,GAC5E,EACL,UAAU,IAAI,KAAC,cAAc,IAAC,cAAc,EAAE,cAAc,GAAI,IAC7D,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,YAAY,CAAC","sourcesContent":["import React, { FC, useMemo } from 'react';\n\nimport { useIntl } from '@openedx/frontend-base';\n\nimport CourseListSlot from '../../slots/CourseListSlot';\nimport { useFilters } from '@src/data/context';\n\nimport { getVisibleList } from '@src/utils/dataTransformers';\n\nimport messages from './messages';\nimport { HistoryPanelProps } from './data/types';\n\nexport const HistoryPanel: FC<HistoryPanelProps> = ({ historyCourses }) => {\n const { formatMessage } = useIntl();\n const hasCourses = useMemo(() => historyCourses.length > 0, [historyCourses]);\n\n const {\n filters, sortBy, pageNumber, setPageNumber,\n } = useFilters();\n const { visibleList, numPages } = useMemo(() => {\n return getVisibleList(\n historyCourses,\n filters,\n sortBy,\n pageNumber,\n );\n }, [historyCourses, filters, sortBy, pageNumber]);\n\n React.useEffect(() => {\n if (numPages > 0 && pageNumber > numPages) {\n setPageNumber(1);\n }\n }, [numPages, pageNumber, setPageNumber]);\n\n const courseListData = {\n showFilters: true,\n setPageNumber,\n numPages,\n visibleList,\n verifiedCourse: true,\n isHistoryTab: true,\n };\n\n return (\n <div className=\"course-list-container\">\n <div className=\"course-list-heading-container\">\n <h2 className=\"course-list-title\">{formatMessage(messages.myCourseHistory)}</h2>\n </div>\n {hasCourses && <CourseListSlot courseListData={courseListData} />}\n </div>\n );\n};\n\nexport default HistoryPanel;\n"]}
|
|
@@ -1,12 +1,25 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useIntl } from '@openedx/frontend-base';
|
|
3
|
-
import { Card, Icon } from '@openedx/paragon';
|
|
3
|
+
import { Card, Hyperlink, Icon } from '@openedx/paragon';
|
|
4
4
|
import { Timelapse, Speed } from '@openedx/paragon/icons';
|
|
5
5
|
import './index.scss';
|
|
6
6
|
import cardFallbackImg from '@openedx/brand-openedx/paragon/images/card-imagecap-fallback.png';
|
|
7
7
|
import messages from './messages';
|
|
8
|
+
const getIdentifyingUrlPath = (marketingUrl) => {
|
|
9
|
+
if (!marketingUrl) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
const path = new URL(marketingUrl, window.location.origin).pathname.replace(/^\//, '');
|
|
14
|
+
return path || null;
|
|
15
|
+
}
|
|
16
|
+
catch (_a) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
8
20
|
export const ProductCard = ({ item, isLoading }) => {
|
|
9
21
|
const { formatMessage } = useIntl();
|
|
10
|
-
|
|
22
|
+
const identifyingUrlPath = getIdentifyingUrlPath(item.marketing_url);
|
|
23
|
+
return (_jsxs(Card, { className: "shadow-sm d-flex flex-column rounded w-100 overflow-hidden align-items-stretch card-container", variant: "light", "data-testid": "product-card", isLoading: isLoading, as: identifyingUrlPath ? Hyperlink : 'div', destination: identifyingUrlPath ? `/subscription-enroll/${identifyingUrlPath}` : undefined, children: [_jsx(Card.Header, { title: item.content_type, className: "pb-2 pt-2 bg-light-500 text-primary-500 content-type", size: "xs" }), _jsx("div", { className: "position-relative image-container", children: _jsx(Card.ImageCap, { src: item.url || cardFallbackImg, srcAlt: `${item.title} main-image`, "data-testid": "product-card-image", logoSrc: item.thumbnail || '', logoAlt: `${item.title} thumbnail-image` }) }), _jsx(Card.Header, { title: item.title, subtitle: item.partner, size: "sm", className: "product-card-title" }), _jsxs(Card.Section, { className: "d-flex flex-column flex-grow-1 overflow-hidden mt-5", children: [typeof item.weeks_to_complete === 'number' && (_jsxs("span", { className: "d-flex align-items-center", children: [_jsx(Icon, { src: Timelapse, className: "mr-2" }), _jsx("span", { children: formatMessage(messages.weeksToComplete, { count: item.weeks_to_complete }) })] })), item.level ? (_jsxs("span", { className: `d-flex align-items-center${typeof item.weeks_to_complete === 'number' ? ' mt-3' : ''}`, children: [_jsx(Icon, { src: Speed, className: "mr-2" }), _jsx("span", { children: formatMessage(messages.level, { level: item.level }) })] })) : null] })] }));
|
|
11
24
|
};
|
|
12
25
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/containers/ProductCard/index.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/containers/ProductCard/index.tsx"],"names":[],"mappings":"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","sourcesContent":["import { FC } from 'react';\nimport { useIntl } from '@openedx/frontend-base';\nimport { Card, Hyperlink, Icon } from '@openedx/paragon';\nimport { Timelapse, Speed } from '@openedx/paragon/icons';\nimport './index.scss';\nimport cardFallbackImg from '@openedx/brand-openedx/paragon/images/card-imagecap-fallback.png';\nimport { ProductCardProps } from './data/types';\nimport messages from './messages';\n\nconst getIdentifyingUrlPath = (marketingUrl: string): string | null => {\n if (!marketingUrl) {\n return null;\n }\n try {\n const path = new URL(marketingUrl, window.location.origin).pathname.replace(/^\\//, '');\n return path || null;\n } catch {\n return null;\n }\n};\n\nexport const ProductCard: FC<ProductCardProps> = ({ item, isLoading }) => {\n const { formatMessage } = useIntl();\n const identifyingUrlPath = getIdentifyingUrlPath(item.marketing_url);\n return (\n <Card\n className=\"shadow-sm d-flex flex-column rounded w-100 overflow-hidden align-items-stretch card-container\"\n variant=\"light\"\n data-testid=\"product-card\"\n isLoading={isLoading}\n as={identifyingUrlPath ? Hyperlink : 'div'}\n destination={identifyingUrlPath ? `/subscription-enroll/${identifyingUrlPath}` : undefined}\n >\n <Card.Header title={item.content_type} className=\"pb-2 pt-2 bg-light-500 text-primary-500 content-type\" size=\"xs\" />\n\n <div className=\"position-relative image-container\">\n <Card.ImageCap\n src={item.url || cardFallbackImg}\n srcAlt={`${item.title} main-image`}\n data-testid=\"product-card-image\"\n logoSrc={item.thumbnail || ''}\n logoAlt={`${item.title} thumbnail-image`}\n />\n </div>\n\n <Card.Header title={item.title} subtitle={item.partner} size=\"sm\" className=\"product-card-title\" />\n\n <Card.Section className=\"d-flex flex-column flex-grow-1 overflow-hidden mt-5\">\n {typeof item.weeks_to_complete === 'number' && (\n <span className=\"d-flex align-items-center\">\n <Icon src={Timelapse} className=\"mr-2\" />\n <span>{formatMessage(messages.weeksToComplete, { count: item.weeks_to_complete })}</span>\n </span>\n )}\n {item.level ? (\n <span className={`d-flex align-items-center${typeof item.weeks_to_complete === 'number' ? ' mt-3' : ''}`}>\n <Icon src={Speed} className=\"mr-2\" />\n <span>{formatMessage(messages.level, { level: item.level })}</span>\n </span>\n ) : null}\n </Card.Section>\n\n </Card>\n );\n};\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export const locationId: string;
|
|
2
2
|
export const SortKeys: any;
|
|
3
3
|
export const FilterKeys: any;
|
|
4
|
-
export const ListPageSize:
|
|
4
|
+
export const ListPageSize: 6;
|
|
5
5
|
export const subscriptionRenewalURL: "https://courses.edx.org/manage-subscription";
|
|
6
6
|
export const exploreProgramsUrl: "/explore-programs";
|
|
7
7
|
export const manageSubscriptionURL: "/manage-subscription";
|
|
@@ -11,7 +11,7 @@ export const FilterKeys = StrictDict({
|
|
|
11
11
|
notEnrolled: 'notEnrolled',
|
|
12
12
|
upgraded: 'upgraded',
|
|
13
13
|
});
|
|
14
|
-
export const ListPageSize =
|
|
14
|
+
export const ListPageSize = 6;
|
|
15
15
|
// TODO : Below URL is temporary and will be removed once the subscription renewal flow is implemented in the app.
|
|
16
16
|
export const subscriptionRenewalURL = 'https://courses.edx.org/manage-subscription';
|
|
17
17
|
export const exploreProgramsUrl = '/explore-programs';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.js","sourceRoot":"","sources":["../../../src/data/constants/app.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAE5D,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAAC;IACjC,QAAQ,EAAE,UAAU;IACpB,KAAK,EAAE,OAAO;CACf,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,UAAU,GAAG,UAAU,CAAC;IACnC,UAAU,EAAE,YAAY;IACxB,UAAU,EAAE,YAAY;IACxB,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,aAAa;IAC1B,QAAQ,EAAE,UAAU;CACrB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../../../src/data/constants/app.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAE5D,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAAC;IACjC,QAAQ,EAAE,UAAU;IACpB,KAAK,EAAE,OAAO;CACf,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,UAAU,GAAG,UAAU,CAAC;IACnC,UAAU,EAAE,YAAY;IACxB,UAAU,EAAE,YAAY;IACxB,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,aAAa;IAC1B,QAAQ,EAAE,UAAU;CACrB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC;AAC9B,kHAAkH;AAClH,MAAM,CAAC,MAAM,sBAAsB,GAAG,6CAA6C,CAAC;AACpF,MAAM,CAAC,MAAM,kBAAkB,GAAG,mBAAmB,CAAC;AACtD,MAAM,CAAC,MAAM,qBAAqB,GAAG,sBAAsB,CAAC;AAC5D,MAAM,CAAC,MAAM,eAAe,GAAG,gBAAgB,CAAC","sourcesContent":["import { StrictDict } from '../../utils';\nexport const locationId = window.location.pathname.slice(1);\n\nexport const SortKeys = StrictDict({\n enrolled: 'enrolled',\n title: 'title',\n});\n\nexport const FilterKeys = StrictDict({\n inProgress: 'inProgress',\n notStarted: 'notStarted',\n done: 'done',\n notEnrolled: 'notEnrolled',\n upgraded: 'upgraded',\n});\n\nexport const ListPageSize = 6;\n// TODO : Below URL is temporary and will be removed once the subscription renewal flow is implemented in the app.\nexport const subscriptionRenewalURL = 'https://courses.edx.org/manage-subscription';\nexport const exploreProgramsUrl = '/explore-programs';\nexport const manageSubscriptionURL = '/manage-subscription';\nexport const checkoutPageURL = '/checkout-page';\n"]}
|
|
@@ -29,7 +29,8 @@ export const usePopularCoursesAndProgramsData = (searchClient, enabled, productT
|
|
|
29
29
|
objectID: hit.objectID,
|
|
30
30
|
title: (_b = (_a = hit.title) !== null && _a !== void 0 ? _a : hit.name) !== null && _b !== void 0 ? _b : 'Untitled',
|
|
31
31
|
primary_description: (_e = (_d = (_c = hitDetails.primary_description) !== null && _c !== void 0 ? _c : hitDetails.short_description) !== null && _d !== void 0 ? _d : hitDetails.description) !== null && _e !== void 0 ? _e : '',
|
|
32
|
-
url: (
|
|
32
|
+
url: (_g = (_f = hitDetails.card_image_url) !== null && _f !== void 0 ? _f : hitDetails.image_url) !== null && _g !== void 0 ? _g : '',
|
|
33
|
+
marketing_url: (_h = hitDetails.marketing_url) !== null && _h !== void 0 ? _h : '',
|
|
33
34
|
thumbnail: (_j = hitDetails.organization_logo_override) !== null && _j !== void 0 ? _j : '',
|
|
34
35
|
content_type: (_l = (_k = hitDetails.content_type) !== null && _k !== void 0 ? _k : hitDetails.product) !== null && _l !== void 0 ? _l : 'Course',
|
|
35
36
|
product: productType,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePopularCoursesAndPrograms.js","sourceRoot":"","sources":["../../src/hooks/usePopularCoursesAndPrograms.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,QAAQ,EAAkB,MAAM,uBAAuB,CAAC;AAGjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAG/D,iFAAiF;AACjF,oDAAoD;AAEpD,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,GAAG,EAAE,CAAC,QAAQ,CAAU;IACxB,QAAQ,EAAE,CAAC,KAAa,EAAE,IAAc,EAAE,EAAE,CAC1C,CAAC,GAAG,UAAU,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,CAAU;IACvD,OAAO,EAAE,CAAC,KAAa,EAAE,IAAc,EAAE,IAAY,EAAE,EAAE,CACvD,CAAC,GAAG,UAAU,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAU;IAC5D,OAAO,EAAE,CAAC,WAAwB,EAAE,KAAa,EAAE,EAAE,CACnD,CAAC,GAAG,UAAU,CAAC,GAAG,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,CAAU;CAC9D,CAAC;AAEF,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAC9C,YAAiC,EACjC,OAAgB,EAChB,cAA2B,mBAAmB,EACX,EAAE,CACrC,QAAQ,CAAC;IACP,QAAQ,EAAE,UAAU,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAC5C,OAAO,EAAE,GAAS,EAAE;QAClB,MAAM,IAAI,GAAG,MAAM,oBAAoB,CAAC,YAAa,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;QACvE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAmB,EAAE;;YACvC,MAAM,UAAU,GAAG,GAalB,CAAC;YAEF,OAAO;gBACL,QAAQ,EAAE,GAAG,CAAC,QAAQ;gBACtB,KAAK,EAAE,MAAA,MAAA,GAAG,CAAC,KAAK,mCAAI,GAAG,CAAC,IAAI,mCAAI,UAAU;gBAC1C,mBAAmB,EAAE,MAAA,MAAA,MAAA,UAAU,CAAC,mBAAmB,mCAAI,UAAU,CAAC,iBAAiB,mCAAI,UAAU,CAAC,WAAW,mCAAI,EAAE;gBACnH,GAAG,EAAE,MAAA,MAAA,
|
|
1
|
+
{"version":3,"file":"usePopularCoursesAndPrograms.js","sourceRoot":"","sources":["../../src/hooks/usePopularCoursesAndPrograms.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,QAAQ,EAAkB,MAAM,uBAAuB,CAAC;AAGjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAG/D,iFAAiF;AACjF,oDAAoD;AAEpD,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,GAAG,EAAE,CAAC,QAAQ,CAAU;IACxB,QAAQ,EAAE,CAAC,KAAa,EAAE,IAAc,EAAE,EAAE,CAC1C,CAAC,GAAG,UAAU,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,CAAU;IACvD,OAAO,EAAE,CAAC,KAAa,EAAE,IAAc,EAAE,IAAY,EAAE,EAAE,CACvD,CAAC,GAAG,UAAU,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAU;IAC5D,OAAO,EAAE,CAAC,WAAwB,EAAE,KAAa,EAAE,EAAE,CACnD,CAAC,GAAG,UAAU,CAAC,GAAG,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,CAAU;CAC9D,CAAC;AAEF,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAC9C,YAAiC,EACjC,OAAgB,EAChB,cAA2B,mBAAmB,EACX,EAAE,CACrC,QAAQ,CAAC;IACP,QAAQ,EAAE,UAAU,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAC5C,OAAO,EAAE,GAAS,EAAE;QAClB,MAAM,IAAI,GAAG,MAAM,oBAAoB,CAAC,YAAa,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;QACvE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAmB,EAAE;;YACvC,MAAM,UAAU,GAAG,GAalB,CAAC;YAEF,OAAO;gBACL,QAAQ,EAAE,GAAG,CAAC,QAAQ;gBACtB,KAAK,EAAE,MAAA,MAAA,GAAG,CAAC,KAAK,mCAAI,GAAG,CAAC,IAAI,mCAAI,UAAU;gBAC1C,mBAAmB,EAAE,MAAA,MAAA,MAAA,UAAU,CAAC,mBAAmB,mCAAI,UAAU,CAAC,iBAAiB,mCAAI,UAAU,CAAC,WAAW,mCAAI,EAAE;gBACnH,GAAG,EAAE,MAAA,MAAA,UAAU,CAAC,cAAc,mCAAI,UAAU,CAAC,SAAS,mCAAI,EAAE;gBAC5D,aAAa,EAAE,MAAA,UAAU,CAAC,aAAa,mCAAI,EAAE;gBAC7C,SAAS,EAAE,MAAA,UAAU,CAAC,0BAA0B,mCAAI,EAAE;gBACtD,YAAY,EAAE,MAAA,MAAA,UAAU,CAAC,YAAY,mCAAI,UAAU,CAAC,OAAO,mCAAI,QAAQ;gBACvE,OAAO,EAAE,WAAW;gBACpB,OAAO,EAAE,MAAA,UAAU,CAAC,OAAO,mCAAI,EAAE;gBACjC,iBAAiB,EAAE,MAAA,UAAU,CAAC,iBAAiB,mCAAI,SAAS;gBAC5D,KAAK,EAAE,MAAA,UAAU,CAAC,KAAK,mCAAI,SAAS;aACrC,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAA;IACD,OAAO,EAAE,CAAC,CAAC,YAAY,IAAI,OAAO;IAClC,SAAS,EAAE,IAAI,GAAG,EAAE,GAAG,EAAE;CAC1B,CAAC,CAAC","sourcesContent":["import { useQuery, UseQueryResult } from '@tanstack/react-query';\nimport { SearchClient } from 'algoliasearch';\nimport { ProductType } from '@src/types/types';\nimport { PRODUCT_TYPE_COURSE } from '@src/constants';\nimport { fetchPopularProducts } from '@src/utils/algoliaUtils';\nimport { ProductCardItem } from '@src/containers/ProductCard/data/types';\n\n// ─── Query key factories ──────────────────────────────────────────────────────\n// Centralised so cache invalidation is never a typo\n\nexport const searchKeys = {\n all: ['search'] as const,\n programs: (query: string, tags: string[]) =>\n [...searchKeys.all, 'programs', query, tags] as const,\n courses: (query: string, tags: string[], page: number) =>\n [...searchKeys.all, 'courses', query, tags, page] as const,\n popular: (productType: ProductType, limit: number) =>\n [...searchKeys.all, 'popular', productType, limit] as const,\n};\n\nexport const usePopularCoursesAndProgramsData = (\n searchClient: SearchClient | null,\n enabled: boolean,\n productType: ProductType = PRODUCT_TYPE_COURSE\n): UseQueryResult<ProductCardItem[]> =>\n useQuery({\n queryKey: searchKeys.popular(productType, 4),\n queryFn: async () => {\n const hits = await fetchPopularProducts(searchClient!, productType, 4);\n return hits.map((hit): ProductCardItem => {\n const hitDetails = hit as {\n short_description?: string,\n primary_description?: string,\n description?: string,\n marketing_url?: string,\n image_url?: string,\n card_image_url?: string,\n organization_logo_override?: string,\n content_type?: string,\n product?: string,\n partner?: string,\n weeks_to_complete?: number,\n level?: string,\n };\n\n return {\n objectID: hit.objectID,\n title: hit.title ?? hit.name ?? 'Untitled',\n primary_description: hitDetails.primary_description ?? hitDetails.short_description ?? hitDetails.description ?? '',\n url: hitDetails.card_image_url ?? hitDetails.image_url ?? '',\n marketing_url: hitDetails.marketing_url ?? '',\n thumbnail: hitDetails.organization_logo_override ?? '',\n content_type: hitDetails.content_type ?? hitDetails.product ?? 'Course',\n product: productType,\n partner: hitDetails.partner ?? '',\n weeks_to_complete: hitDetails.weeks_to_complete ?? undefined,\n level: hitDetails.level ?? undefined,\n };\n });\n },\n enabled: !!searchClient && enabled,\n staleTime: 1000 * 60 * 10,\n });\n"]}
|
|
@@ -43,8 +43,9 @@ export declare const formatFacetFilterData: (facetFilterType: string, data: stri
|
|
|
43
43
|
* @param facetField Facet attribute to filter tags on (default: 'subjects')
|
|
44
44
|
* @param hitsPerPage Page size
|
|
45
45
|
* @param page 0-indexed page number (Algolia convention)
|
|
46
|
+
* @param staticFacetFilters Additional 'attribute:value' filters always AND-ed in, e.g. ['b2c_subscription_inclusion:true']
|
|
46
47
|
*/
|
|
47
|
-
export declare const searchProducts: (searchClient: SearchClient, productType: ProductType, query: string, activeTags: string[], facetField?: string, hitsPerPage?: number, page?: number) => Promise<AlgoliaSearchResult>;
|
|
48
|
+
export declare const searchProducts: (searchClient: SearchClient, productType: ProductType, query: string, activeTags: string[], facetField?: string, hitsPerPage?: number, page?: number, staticFacetFilters?: string[]) => Promise<AlgoliaSearchResult>;
|
|
48
49
|
/**
|
|
49
50
|
* Fetches top-ranked products with no query or tag filters.
|
|
50
51
|
* Used for the "Popular programs / courses" fallback in the no-results state.
|
|
@@ -77,14 +77,16 @@ export const formatFacetFilterData = (facetFilterType, data) => {
|
|
|
77
77
|
* @param facetField Facet attribute to filter tags on (default: 'subjects')
|
|
78
78
|
* @param hitsPerPage Page size
|
|
79
79
|
* @param page 0-indexed page number (Algolia convention)
|
|
80
|
+
* @param staticFacetFilters Additional 'attribute:value' filters always AND-ed in, e.g. ['b2c_subscription_inclusion:true']
|
|
80
81
|
*/
|
|
81
|
-
export const searchProducts = (searchClient_1, productType_1, query_1, activeTags_1, ...args_1) => __awaiter(void 0, [searchClient_1, productType_1, query_1, activeTags_1, ...args_1], void 0, function* (searchClient, productType, query, activeTags, facetField = FACET_SUBJECTS, hitsPerPage = HITS_PER_PAGE_COURSES, page = 0) {
|
|
82
|
+
export const searchProducts = (searchClient_1, productType_1, query_1, activeTags_1, ...args_1) => __awaiter(void 0, [searchClient_1, productType_1, query_1, activeTags_1, ...args_1], void 0, function* (searchClient, productType, query, activeTags, facetField = FACET_SUBJECTS, hitsPerPage = HITS_PER_PAGE_COURSES, page = 0, staticFacetFilters = []) {
|
|
82
83
|
const indexName = getAppConfig(appId).ALGOLIA_PRODUCT_INDEX_NAME;
|
|
83
84
|
const tagFilters = formatFacetFilterData(facetField, activeTags);
|
|
84
85
|
// Nested arrays = AND between outer elements, OR within inner arrays
|
|
85
86
|
const facetFilters = [
|
|
86
87
|
[`product:${productType}`],
|
|
87
88
|
...(tagFilters.length > 0 ? [tagFilters] : []),
|
|
89
|
+
...staticFacetFilters.map((filter) => [filter]),
|
|
88
90
|
];
|
|
89
91
|
try {
|
|
90
92
|
const { hits, nbHits, nbPages } = yield searchClient.searchSingleIndex({
|
|
@@ -121,7 +123,7 @@ export const searchProducts = (searchClient_1, productType_1, query_1, activeTag
|
|
|
121
123
|
export const fetchPopularProducts = (searchClient, productType, hitsPerPage) => __awaiter(void 0, void 0, void 0, function* () {
|
|
122
124
|
const { hits } = yield searchProducts(searchClient, productType, '', // empty query → Algolia ranks by popularity
|
|
123
125
|
[], // no tag filters
|
|
124
|
-
FACET_SUBJECTS, hitsPerPage, 0);
|
|
126
|
+
FACET_SUBJECTS, hitsPerPage, 0, ['b2c_subscription_inclusion:true']);
|
|
125
127
|
return hits;
|
|
126
128
|
});
|
|
127
129
|
//# sourceMappingURL=algoliaUtils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"algoliaUtils.js","sourceRoot":"","sources":["../../src/utils/algoliaUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;;;;;;;;;;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAgB,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAQvE,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAEvC,iFAAiF;AAEjF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAA0B,EAAE;IAC1D,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACnC,MAAM,YAAY,GAAG,MAAM,CAAC,cAAoC,CAAC;IACjE,MAAM,mBAAmB,GAAG,MAAM,CAAC,sBAA4C,CAAC;IAEhF,MAAM,CAAC,YAAY,CAAC,GAAG,OAAO,CAC5B,GAAG,EAAE;QACH,IAAI,CAAC,YAAY,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC1C,QAAQ,CAAC,IAAI,KAAK,CAAC,yEAAyE,CAAC,CAAC,CAAC;YAC/F,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC;QAED,MAAM,MAAM,GAAG,aAAa,CAAC,YAAY,EAAE,mBAAmB,CAAC,CAAC;QAChE,OAAO,CAAC,MAAM,CAAC,CAAC;IAClB,CAAC,EACD,CAAC,YAAY,EAAE,mBAAmB,CAAC,CACpC,CAAC;IAEF,OAAO,CAAC,YAAY,CAAC,CAAC;AACxB,CAAC,CAAC;AAEF,iFAAiF;AAEjF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,eAAuB,EACvB,IAAc,EACJ,EAAE;IACZ,MAAM,aAAa,GAAa,EAAE,CAAC;IACnC,IAAI,IAAI,EAAE,CAAC;QACT,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,eAAe,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,aAAa,CAAC;AACvB,CAAC,CAAC;AAEF,iFAAiF;AAEjF
|
|
1
|
+
{"version":3,"file":"algoliaUtils.js","sourceRoot":"","sources":["../../src/utils/algoliaUtils.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * utils/algoliaUtils.ts\n *\n * Algolia utility functions for the Search feature.\n * Mirrors the pattern used by the Skills Builder feature, with full TypeScript types.\n */\n\nimport { useMemo } from 'react';\nimport { getAppConfig, logError } from '@openedx/frontend-base';\nimport { algoliasearch, SearchClient } from 'algoliasearch';\nimport { FACET_SUBJECTS, HITS_PER_PAGE_COURSES } from '@src/constants';\n\nimport {\n AlgoliaProductHit,\n AlgoliaSearchResult,\n ProductType,\n} from '../types/types';\n\nimport { appId } from '@src/constants';\n\n// ─── useAlgoliaSearch ─────────────────────────────────────────────────────────\n\n/**\n * Creates and memoises an Algolia search client using app config.\n * Matches the pattern used by the Skills Builder feature.\n *\n * @returns [SearchClient | null] tuple — destructure as: const [searchClient] = useAlgoliaSearch()\n */\nexport const useAlgoliaSearch = (): [SearchClient | null] => {\n const config = getAppConfig(appId);\n const algoliaAppId = config.ALGOLIA_APP_ID as string | undefined;\n const algoliaSearchApiKey = config.ALGOLIA_SEARCH_API_KEY as string | undefined;\n\n const [searchClient] = useMemo<[SearchClient | null]>(\n () => {\n if (!algoliaAppId || !algoliaSearchApiKey) {\n logError(new Error('Missing Algolia configuration: ALGOLIA_APP_ID or ALGOLIA_SEARCH_API_KEY'));\n return [null];\n }\n\n const client = algoliasearch(algoliaAppId, algoliaSearchApiKey);\n return [client];\n },\n [algoliaAppId, algoliaSearchApiKey],\n );\n\n return [searchClient];\n};\n\n// ─── formatFacetFilterData ────────────────────────────────────────────────────\n\n/**\n * Formats an array of values into Algolia facet filter strings.\n *\n * @param facetFilterType Facet attribute name, e.g. 'subjects'\n * @param data Array of values, e.g. ['Leadership', 'AI']\n * @returns e.g. ['subjects:Leadership', 'subjects:AI']\n *\n * @example\n * formatFacetFilterData('subjects', ['Leadership', 'AI'])\n * // → ['subjects:Leadership', 'subjects:AI']\n */\nexport const formatFacetFilterData = (\n facetFilterType: string,\n data: string[],\n): string[] => {\n const formattedData: string[] = [];\n if (data) {\n data.forEach((item) => formattedData.push(`${facetFilterType}:${item}`));\n }\n return formattedData;\n};\n\n// ─── searchProducts ───────────────────────────────────────────────────────────\n\n/**\n * Searches programs or courses from the shared product index.\n *\n * Both product types live in ALGOLIA_PRODUCT_INDEX_NAME, distinguished by the\n * `product` facet. Active tags are OR-ed within their facet and AND-ed with\n * the product-type filter — standard Algolia multi-select pattern.\n *\n * Algolia facetFilters format used here:\n * [ ['product:program'], ['subjects:Leadership', 'subjects:AI'] ]\n * → product = \"program\" AND (subjects = \"Leadership\" OR subjects = \"AI\")\n *\n * @param searchClient Algolia client from useAlgoliaSearch()\n * @param productType 'program' | 'course'\n * @param query Free-text query ('' = browse / rank by popularity)\n * @param activeTags Selected tag values from the filter chips\n * @param facetField Facet attribute to filter tags on (default: 'subjects')\n * @param hitsPerPage Page size\n * @param page 0-indexed page number (Algolia convention)\n * @param staticFacetFilters Additional 'attribute:value' filters always AND-ed in, e.g. ['b2c_subscription_inclusion:true']\n */\nexport const searchProducts = async (\n searchClient: SearchClient,\n productType: ProductType,\n query: string,\n activeTags: string[],\n facetField: string = FACET_SUBJECTS,\n hitsPerPage: number = HITS_PER_PAGE_COURSES,\n page = 0,\n staticFacetFilters: string[] = [],\n): Promise<AlgoliaSearchResult> => {\n const indexName = getAppConfig(appId).ALGOLIA_PRODUCT_INDEX_NAME as string;\n const tagFilters = formatFacetFilterData(facetField, activeTags);\n\n // Nested arrays = AND between outer elements, OR within inner arrays\n const facetFilters: string[][] = [\n [`product:${productType}`],\n ...(tagFilters.length > 0 ? [tagFilters] : []),\n ...staticFacetFilters.map((filter) => [filter]),\n ];\n\n try {\n const { hits, nbHits, nbPages } = await searchClient.searchSingleIndex({\n indexName,\n searchParams: {\n query,\n facetFilters,\n hitsPerPage,\n page,\n },\n });\n\n return {\n hits: hits as AlgoliaProductHit[],\n nbHits: nbHits ?? 0,\n nbPages: nbPages ?? 0,\n };\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n logError(err);\n return { hits: [], nbHits: 0, nbPages: 0 };\n }\n};\n\n// ─── fetchPopularProducts ─────────────────────────────────────────────────────\n\n/**\n * Fetches top-ranked products with no query or tag filters.\n * Used for the \"Popular programs / courses\" fallback in the no-results state.\n *\n * @param searchClient Algolia client\n * @param productType 'program' | 'course'\n * @param hitsPerPage Number of items to fetch\n * @returns Raw Algolia hit objects\n */\nexport const fetchPopularProducts = async (\n searchClient: SearchClient,\n productType: ProductType,\n hitsPerPage: number,\n): Promise<AlgoliaProductHit[]> => {\n const { hits } = await searchProducts(\n searchClient,\n productType,\n '', // empty query → Algolia ranks by popularity\n [], // no tag filters\n FACET_SUBJECTS,\n hitsPerPage,\n 0,\n ['b2c_subscription_inclusion:true'],\n );\n return hits;\n};\n"]}
|