@edx/frontend-app-subscription-learner-dashboard 1.3.0 → 1.5.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.
Files changed (60) hide show
  1. package/dist/Main.js +3 -2
  2. package/dist/Main.js.map +1 -1
  3. package/dist/containers/Dashboard/DashboardTabs.js +3 -2
  4. package/dist/containers/Dashboard/DashboardTabs.js.map +1 -1
  5. package/dist/containers/ProgramDashboard/ProgramProgress/ProgramProgress.d.ts +2 -2
  6. package/dist/containers/ProgramDashboard/ProgramProgress/ProgramProgress.js +11 -29
  7. package/dist/containers/ProgramDashboard/ProgramProgress/ProgramProgress.js.map +1 -1
  8. package/dist/containers/ProgramDashboard/ProgramProgress/UpgradeButton/UpgradeAllButton.d.ts +2 -2
  9. package/dist/containers/ProgramDashboard/ProgramProgress/UpgradeButton/UpgradeAllButton.js +7 -5
  10. package/dist/containers/ProgramDashboard/ProgramProgress/UpgradeButton/UpgradeAllButton.js.map +1 -1
  11. package/dist/containers/ProgramDashboard/ProgramProgress/index.d.ts +2 -2
  12. package/dist/containers/ProgramDashboard/ProgramProgress/index.js +1 -4
  13. package/dist/containers/ProgramDashboard/ProgramProgress/index.js.map +1 -1
  14. package/dist/containers/ProgramsPanel/NoProgramsView/index.d.ts +3 -0
  15. package/dist/containers/ProgramsPanel/NoProgramsView/index.js +13 -0
  16. package/dist/containers/ProgramsPanel/NoProgramsView/index.js.map +1 -0
  17. package/dist/containers/ProgramsPanel/NoProgramsView/messages.d.ts +13 -0
  18. package/dist/containers/ProgramsPanel/NoProgramsView/messages.js +15 -0
  19. package/dist/containers/ProgramsPanel/NoProgramsView/messages.js.map +1 -0
  20. package/dist/containers/ProgramsPanel/index.d.ts +3 -0
  21. package/dist/containers/ProgramsPanel/index.js +12 -0
  22. package/dist/containers/ProgramsPanel/index.js.map +1 -0
  23. package/dist/containers/ProgramsPanel/messages.d.ts +23 -0
  24. package/dist/containers/ProgramsPanel/messages.js +25 -0
  25. package/dist/containers/ProgramsPanel/messages.js.map +1 -0
  26. package/dist/containers/SubscriptionInformation/components/SubscriptionInformation.d.ts +2 -0
  27. package/dist/containers/SubscriptionInformation/components/SubscriptionInformation.js +32 -0
  28. package/dist/containers/SubscriptionInformation/components/SubscriptionInformation.js.map +1 -0
  29. package/dist/containers/SubscriptionInformation/index.d.ts +1 -0
  30. package/dist/containers/SubscriptionInformation/index.js +2 -0
  31. package/dist/containers/SubscriptionInformation/index.js.map +1 -0
  32. package/dist/containers/SubscriptionInformation/messages.d.ts +28 -0
  33. package/dist/containers/SubscriptionInformation/messages.js +30 -0
  34. package/dist/containers/SubscriptionInformation/messages.js.map +1 -0
  35. package/dist/data/constants/app.d.ts +3 -1
  36. package/dist/data/constants/app.js +3 -1
  37. package/dist/data/constants/app.js.map +1 -1
  38. package/dist/data/hooks/index.d.ts +2 -2
  39. package/dist/data/hooks/index.js +2 -2
  40. package/dist/data/hooks/index.js.map +1 -1
  41. package/dist/data/hooks/queryHooks.d.ts +3 -2
  42. package/dist/data/hooks/queryHooks.js +11 -1
  43. package/dist/data/hooks/queryHooks.js.map +1 -1
  44. package/dist/data/services/subs/api.d.ts +1 -0
  45. package/dist/data/services/subs/api.js +12 -0
  46. package/dist/data/services/subs/api.js.map +1 -1
  47. package/dist/data/services/subs/index.d.ts +1 -1
  48. package/dist/data/services/subs/index.js +1 -1
  49. package/dist/data/services/subs/index.js.map +1 -1
  50. package/dist/data/services/subs/urls.d.ts +2 -0
  51. package/dist/data/services/subs/urls.js +4 -0
  52. package/dist/data/services/subs/urls.js.map +1 -0
  53. package/dist/routes.d.ts +12 -2
  54. package/package.json +1 -1
  55. package/dist/containers/ProgramDashboard/ProgramProgress/ProgramProgressProvider.d.ts +0 -10
  56. package/dist/containers/ProgramDashboard/ProgramProgress/ProgramProgressProvider.js +0 -30
  57. package/dist/containers/ProgramDashboard/ProgramProgress/ProgramProgressProvider.js.map +0 -1
  58. package/dist/containers/ProgramDashboard/data/api.d.ts +0 -1
  59. package/dist/containers/ProgramDashboard/data/api.js +0 -18
  60. package/dist/containers/ProgramDashboard/data/api.js.map +0 -1
package/dist/Main.js CHANGED
@@ -1,9 +1,10 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { CurrentAppProvider, PageWrap } from '@openedx/frontend-base';
3
3
  import { appId } from './constants';
4
4
  import ContextProviders from './data/context';
5
5
  import Dashboard from './containers/Dashboard';
6
+ import { SubscriptionInformation } from './containers/SubscriptionInformation';
6
7
  import './style.scss';
7
- const Main = () => (_jsx(CurrentAppProvider, { appId: appId, children: _jsx(ContextProviders, { children: _jsx(PageWrap, { children: _jsx(Dashboard, {}) }) }) }));
8
+ const Main = () => (_jsx(CurrentAppProvider, { appId: appId, children: _jsx(ContextProviders, { children: _jsxs(PageWrap, { children: [_jsx(Dashboard, {}), _jsx(SubscriptionInformation, {})] }) }) }));
8
9
  export default Main;
9
10
  //# sourceMappingURL=Main.js.map
package/dist/Main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Main.js","sourceRoot":"","sources":["../src/Main.jsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAEtE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,gBAAgB,MAAM,gBAAgB,CAAC;AAC9C,OAAO,SAAS,MAAM,wBAAwB,CAAC;AAE/C,OAAO,cAAc,CAAC;AAEtB,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,CACjB,KAAC,kBAAkB,IAAC,KAAK,EAAE,KAAK,YAC9B,KAAC,gBAAgB,cACf,KAAC,QAAQ,cACP,KAAC,SAAS,KAAG,GACJ,GACM,GACA,CACtB,CAAC;AAEF,eAAe,IAAI,CAAC","sourcesContent":["import { CurrentAppProvider, PageWrap } from '@openedx/frontend-base';\n\nimport { appId } from './constants';\nimport ContextProviders from './data/context';\nimport Dashboard from './containers/Dashboard';\n\nimport './style.scss';\n\nconst Main = () => (\n <CurrentAppProvider appId={appId}>\n <ContextProviders>\n <PageWrap>\n <Dashboard />\n </PageWrap>\n </ContextProviders>\n </CurrentAppProvider>\n);\n\nexport default Main;\n"]}
1
+ {"version":3,"file":"Main.js","sourceRoot":"","sources":["../src/Main.jsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAEtE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,gBAAgB,MAAM,gBAAgB,CAAC;AAC9C,OAAO,SAAS,MAAM,wBAAwB,CAAC;AAC/C,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAE/E,OAAO,cAAc,CAAC;AAEtB,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,CACjB,KAAC,kBAAkB,IAAC,KAAK,EAAE,KAAK,YAC9B,KAAC,gBAAgB,cACf,MAAC,QAAQ,eACP,KAAC,SAAS,KAAG,EACb,KAAC,uBAAuB,KAAG,IAClB,GACM,GACA,CACtB,CAAC;AAEF,eAAe,IAAI,CAAC","sourcesContent":["import { CurrentAppProvider, PageWrap } from '@openedx/frontend-base';\n\nimport { appId } from './constants';\nimport ContextProviders from './data/context';\nimport Dashboard from './containers/Dashboard';\nimport { SubscriptionInformation } from './containers/SubscriptionInformation';\n\nimport './style.scss';\n\nconst Main = () => (\n <CurrentAppProvider appId={appId}>\n <ContextProviders>\n <PageWrap>\n <Dashboard />\n <SubscriptionInformation />\n </PageWrap>\n </ContextProviders>\n </CurrentAppProvider>\n);\n\nexport default Main;\n"]}
@@ -1,7 +1,8 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useMemo, useState, useCallback } from 'react';
3
3
  import { Tabs, Tab } from '@openedx/paragon';
4
- import CoursesPanel from '../../containers/CoursesPanel';
4
+ import CoursesPanel from '../CoursesPanel';
5
+ import ProgramsPanel from '../ProgramsPanel';
5
6
  const DashboardTabs = () => {
6
7
  var _a;
7
8
  // Defining the tabs here
@@ -14,7 +15,7 @@ const DashboardTabs = () => {
14
15
  {
15
16
  key: 'programs',
16
17
  title: 'Programs',
17
- panel: _jsx("span", { children: "Programs tab will be available soon." }),
18
+ panel: _jsx(ProgramsPanel, {}),
18
19
  },
19
20
  {
20
21
  key: 'history',
@@ -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,+BAA+B,CAAC;AAEzD,MAAM,aAAa,GAAG,GAAG,EAAE;;IACzB,yBAAyB;IACzB,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QACnC;YACE,GAAG,EAAE,SAAS;YACd,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE,KAAC,YAAY,KAAG;SACxB;QACD;YACE,GAAG,EAAE,UAAU;YACf,KAAK,EAAE,UAAU;YACjB,KAAK,EAAE,kEAAiD;SACzD;QACD;YACE,GAAG,EAAE,SAAS;YACd,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE,iEAAgD;SACxD;KACF,CAAC,EAAE,EAAE,CAAC,CAAC;IAER,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 '../../containers/CoursesPanel';\n\nconst DashboardTabs = () => {\n // Defining the tabs here\n const dashboardTabs = useMemo(() => ([\n {\n key: 'courses',\n title: 'Courses',\n panel: <CoursesPanel />,\n },\n {\n key: 'programs',\n title: 'Programs',\n panel: <span>Programs tab will be available soon.</span>,\n },\n {\n key: 'history',\n title: 'History',\n panel: <span>History tab will be available soon.</span>,\n },\n ]), []);\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"]}
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;AAE7C,MAAM,aAAa,GAAG,GAAG,EAAE;;IACzB,yBAAyB;IACzB,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QACnC;YACE,GAAG,EAAE,SAAS;YACd,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE,KAAC,YAAY,KAAG;SACxB;QACD;YACE,GAAG,EAAE,UAAU;YACf,KAAK,EAAE,UAAU;YACjB,KAAK,EAAE,KAAC,aAAa,KAAG;SACzB;QACD;YACE,GAAG,EAAE,SAAS;YACd,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE,iEAAgD;SACxD;KACF,CAAC,EAAE,EAAE,CAAC,CAAC;IAER,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';\n\nconst DashboardTabs = () => {\n // Defining the tabs here\n const dashboardTabs = useMemo(() => ([\n {\n key: 'courses',\n title: 'Courses',\n panel: <CoursesPanel />,\n },\n {\n key: 'programs',\n title: 'Programs',\n panel: <ProgramsPanel />,\n },\n {\n key: 'history',\n title: 'History',\n panel: <span>History tab will be available soon.</span>,\n },\n ]), []);\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"]}
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import { FC } from 'react';
2
2
  import './index.scss';
3
- declare const ProgramProgress: React.FC;
3
+ declare const ProgramProgress: FC;
4
4
  export default ProgramProgress;
@@ -1,45 +1,27 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useContext, useEffect, useState } from 'react';
3
2
  import { Helmet } from 'react-helmet';
4
3
  import { useParams } from 'react-router-dom';
5
4
  import { Col, Container, Row } from '@openedx/paragon';
6
- import { logError, camelCaseObject } from '@openedx/frontend-base';
7
- import { getProgramProgressData } from '../data/api';
8
- import { ProgramProgressContext } from './ProgramProgressProvider';
5
+ import { camelCaseObject } from '@openedx/frontend-base';
6
+ import './index.scss';
7
+ import { useProgramProgressData } from '../../../data/hooks';
9
8
  import ProgramProgressHeader from './ProgramProgressHeader';
10
9
  import ProgramProgressInfo from './ProgramProgressInfo';
11
- import './index.scss';
12
10
  import { ProgramProgressTabs } from './ProgramProgressTabs';
13
11
  const ProgramProgress = () => {
14
12
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
15
- const { programProgressData, setProgramProgressData, } = useContext(ProgramProgressContext);
16
- const [programProgressEndpointError, setProgramProgressEndpointError] = useState(false);
17
- const hasProgramProgressData = !!((programProgressData === null || programProgressData === void 0 ? void 0 : programProgressData.courseData)
18
- && programProgressData.programData
19
- && programProgressData.urls);
20
13
  // Fetch UUID from route params
21
14
  const { uuid } = useParams();
22
- useEffect(() => {
23
- if (!uuid) {
24
- return;
25
- }
26
- getProgramProgressData(uuid)
27
- .then(responseData => {
28
- setProgramProgressData(camelCaseObject(responseData.data));
29
- })
30
- .catch(err => {
31
- logError(err);
32
- setProgramProgressEndpointError(true);
33
- });
34
- }, [uuid, setProgramProgressData]);
35
- if (programProgressEndpointError) {
36
- return (_jsx("div", { children: "Not found page" }));
37
- }
15
+ const { data, isLoading, error } = useProgramProgressData(uuid);
16
+ const programProgressData = camelCaseObject(data);
38
17
  if (!uuid) {
39
- return (_jsx("div", { children: "Program uuid is missing." }));
18
+ return _jsx("div", { children: "Invalid URL" });
19
+ }
20
+ if (isLoading) {
21
+ return _jsx("div", { children: "Loading..." });
40
22
  }
41
- if (!hasProgramProgressData) {
42
- return (_jsx("div", { children: "Loading..." }));
23
+ if (error) {
24
+ return _jsx("div", { children: "Error occurred" });
43
25
  }
44
26
  const programData = programProgressData === null || programProgressData === void 0 ? void 0 : programProgressData.programData;
45
27
  const courseData = programProgressData === null || programProgressData === void 0 ? void 0 : programProgressData.courseData;
@@ -1 +1 @@
1
- {"version":3,"file":"ProgramProgress.js","sourceRoot":"","sources":["../../../../src/containers/ProgramDashboard/ProgramProgress/ProgramProgress.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useContext, useEffect, useState } from 'react';\nimport { Helmet } from 'react-helmet';\nimport { useParams } from 'react-router-dom';\nimport { Col, Container, Row } from '@openedx/paragon';\nimport { logError, camelCaseObject } from '@openedx/frontend-base';\nimport { getProgramProgressData } from '../data/api';\nimport { ProgramProgressContext, ProgramProgressContextValueType } from './ProgramProgressProvider';\nimport ProgramProgressHeader from './ProgramProgressHeader';\nimport ProgramProgressInfo from './ProgramProgressInfo';\n\nimport './index.scss';\nimport { ProgramProgressTabs } from './ProgramProgressTabs';\n\nconst ProgramProgress: React.FC = () => {\n const {\n programProgressData,\n setProgramProgressData,\n } = useContext<ProgramProgressContextValueType>(ProgramProgressContext);\n\n const [programProgressEndpointError, setProgramProgressEndpointError] = useState<boolean>(false);\n const hasProgramProgressData = !!(\n programProgressData?.courseData\n && programProgressData.programData\n && programProgressData.urls\n );\n\n // Fetch UUID from route params\n const { uuid } = useParams() as { uuid: string };\n\n useEffect(() => {\n if (!uuid) {\n return;\n }\n\n getProgramProgressData(uuid)\n .then(responseData => {\n setProgramProgressData(camelCaseObject(responseData.data));\n })\n .catch(err => {\n logError(err);\n setProgramProgressEndpointError(true);\n });\n }, [uuid, setProgramProgressData]);\n\n if (programProgressEndpointError) {\n return (\n <div>Not found page</div>\n );\n }\n\n if (!uuid) {\n return (\n <div>Program uuid is missing.</div>\n );\n }\n\n if (!hasProgramProgressData) {\n return (\n <div>Loading...</div>\n );\n }\n\n const programData = programProgressData?.programData;\n const courseData = programProgressData?.courseData;\n\n const totalCoursesInProgram = (courseData.notStarted?.length || 0)\n + (courseData.completed?.length || 0)\n + (courseData.inProgress?.length || 0);\n\n const allCoursesCompleted = !courseData.notStarted?.length\n && !courseData.inProgress?.length\n && courseData.completed?.length;\n\n const programType = programData?.type ?? '';\n\n return (\n <>\n <Helmet title={`${programData?.title}`} />\n <Container fluid={false} size=\"xl\" className=\"p-4.5\">\n <ProgramProgressHeader\n programTitle={programData?.title ?? ''}\n programType={programData?.type ?? ''}\n authoringOrganizations={programData?.authoringOrganizations}\n />\n <Row>\n <Col sm={12} md={8}>\n <ProgramProgressInfo\n allCoursesCompleted={allCoursesCompleted}\n totalCoursesInProgram={totalCoursesInProgram}\n programTitle={programData?.title ?? ''}\n />\n </Col>\n </Row>\n\n {/* TODO [TEMP]: Replace the below course count with actual count. For now, returning hardcoded data.\n Action: Revisit when data is being made dynamic.\n */}\n <ProgramProgressTabs counts={{ inProgress: 1, remaining: 2, completed: 0 }} type={programType} />\n </Container>\n </>\n );\n};\n\nexport default ProgramProgress;\n"]}
1
+ {"version":3,"file":"ProgramProgress.js","sourceRoot":"","sources":["../../../../src/containers/ProgramDashboard/ProgramProgress/ProgramProgress.tsx"],"names":[],"mappings":"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","sourcesContent":["import { FC } from 'react';\nimport { Helmet } from 'react-helmet';\nimport { useParams } from 'react-router-dom';\nimport { Col, Container, Row } from '@openedx/paragon';\nimport { camelCaseObject } from '@openedx/frontend-base';\n\nimport './index.scss';\nimport { useProgramProgressData } from '@src/data/hooks';\nimport ProgramProgressHeader from './ProgramProgressHeader';\nimport ProgramProgressInfo from './ProgramProgressInfo';\nimport { ProgramProgressTabs } from './ProgramProgressTabs';\n\nconst ProgramProgress: FC = () => {\n // Fetch UUID from route params\n const { uuid } = useParams() as { uuid: string };\n\n const { data, isLoading, error } = useProgramProgressData(uuid);\n const programProgressData = camelCaseObject(data);\n\n if (!uuid) {\n return <div>Invalid URL</div>;\n }\n\n if (isLoading) {\n return <div>Loading...</div>;\n }\n\n if (error) {\n return <div>Error occurred</div>;\n }\n\n const programData = programProgressData?.programData;\n const courseData = programProgressData?.courseData;\n\n const totalCoursesInProgram = (courseData.notStarted?.length || 0)\n + (courseData.completed?.length || 0)\n + (courseData.inProgress?.length || 0);\n\n const allCoursesCompleted = !courseData.notStarted?.length\n && !courseData.inProgress?.length\n && courseData.completed?.length;\n\n const programType = programData?.type ?? '';\n\n return (\n <>\n <Helmet title={`${programData?.title}`} />\n <Container fluid={false} size=\"xl\" className=\"p-4.5\">\n <ProgramProgressHeader\n programTitle={programData?.title ?? ''}\n programType={programData?.type ?? ''}\n authoringOrganizations={programData?.authoringOrganizations}\n />\n <Row>\n <Col sm={12} md={8}>\n <ProgramProgressInfo\n allCoursesCompleted={allCoursesCompleted}\n totalCoursesInProgram={totalCoursesInProgram}\n programTitle={programData?.title ?? ''}\n />\n </Col>\n </Row>\n\n {/* TODO [TEMP]: Replace the below course count with actual count. For now, returning hardcoded data.\n Action: Revisit when data is being made dynamic.\n */}\n <ProgramProgressTabs counts={{ inProgress: 1, remaining: 2, completed: 0 }} type={programType} />\n </Container>\n </>\n );\n};\n\nexport default ProgramProgress;\n"]}
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import { FC } from 'react';
2
2
  import './index.scss';
3
- declare const UpgradeAllButton: React.FC;
3
+ declare const UpgradeAllButton: FC;
4
4
  export default UpgradeAllButton;
@@ -1,13 +1,15 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useContext } from 'react';
2
+ import { useParams } from 'react-router-dom';
3
3
  import { Button } from '@openedx/paragon';
4
- import { FormattedNumber, useIntl } from '@openedx/frontend-base';
5
- import messages from './messages';
4
+ import { FormattedNumber, useIntl, camelCaseObject } from '@openedx/frontend-base';
5
+ import { useProgramProgressData } from '../../../../data/hooks/queryHooks';
6
6
  import './index.scss';
7
- import { ProgramProgressContext } from '../ProgramProgressProvider';
7
+ import messages from './messages';
8
8
  const UpgradeAllButton = () => {
9
+ const { uuid } = useParams();
10
+ const { data } = useProgramProgressData(uuid);
11
+ const programProgressData = camelCaseObject(data);
9
12
  const { formatMessage } = useIntl();
10
- const { programProgressData } = useContext(ProgramProgressContext);
11
13
  const { urls } = programProgressData;
12
14
  const getAllRemainingCoursesPrice = () => {
13
15
  if (!programProgressData.programData) {
@@ -1 +1 @@
1
- {"version":3,"file":"UpgradeAllButton.js","sourceRoot":"","sources":["../../../../../src/containers/ProgramDashboard/ProgramProgress/UpgradeButton/UpgradeAllButton.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,cAAc,CAAC;AACtB,OAAO,EAAE,sBAAsB,EAAmC,MAAM,4BAA4B,CAAC;AAErG,MAAM,gBAAgB,GAAa,GAAG,EAAE;IACtC,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,MAAM,EAAE,mBAAmB,EAAE,GAAG,UAAU,CAAkC,sBAAsB,CAAC,CAAC;IACpG,MAAM,EAAE,IAAI,EAAE,GAAG,mBAAmB,CAAC;IAErC,MAAM,2BAA2B,GAAG,GAAG,EAAE;QACvC,IAAI,CAAC,mBAAmB,CAAC,WAAW,EAAE,CAAC;YACrC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,EAAE,YAAY,EAAE,GAAG,mBAAmB,CAAC,WAAW,CAAC;QAEzD,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,EACJ,QAAQ,EACR,YAAY,EACZ,yBAAyB,EACzB,YAAY,GACb,GAAG,YAAY,CAAC;YAEjB,IAAI,YAAY,EAAE,CAAC;gBACjB,OAAO,CACL,8BACE,eAAM,SAAS,EAAC,YAAY,YAC1B,KAAC,eAAe,IACd,KAAK,EAAE,yBAAyB,EAChC,KAAK,EAAC,UAAU,EAChB,QAAQ,EAAE,QAAQ,EAClB,qBAAqB,EAAE,CAAC,EACxB,qBAAqB,EAAE,CAAC,GACxB,GACG,EACP,yBACE,KAAC,eAAe,IACd,KAAK,EAAE,YAAY,EACnB,KAAK,EAAC,UAAU,EAChB,QAAQ,EAAE,QAAQ,EAClB,qBAAqB,EAAE,CAAC,EACxB,qBAAqB,EAAE,CAAC,GACxB,GACG,IACN,CACJ,CAAC;YACJ,CAAC;YACD,OAAO,CACL,yBACE,KAAC,eAAe,IACd,KAAK,EAAE,YAAY,EACnB,KAAK,EAAC,UAAU,EAChB,QAAQ,EAAE,QAAQ,EAClB,qBAAqB,EAAE,CAAC,EACxB,qBAAqB,EAAE,CAAC,GACxB,GACG,CACR,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IAEF,OAAO,CACL,MAAC,MAAM,IACL,EAAE,EAAC,GAAG,EACN,SAAS,EAAC,oBAAoB,EAC9B,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC,YAAY,iBACnB,oBAAoB,EAChC,OAAO,EAAC,OAAO,aAEf,yBACG,aAAa,CAAC,QAAQ,CAAC,oCAAoC,CAAC,GACxD,EACN,2BAA2B,EAAE,IAAI,CAChC,eAAM,SAAS,EAAC,6BAA6B,YAC1C,2BAA2B,EAAE,GACzB,CACR,IACM,CACV,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,gBAAgB,CAAC","sourcesContent":["import React, { useContext } from 'react';\nimport { Button } from '@openedx/paragon';\nimport { FormattedNumber, useIntl } from '@openedx/frontend-base';\nimport messages from './messages';\nimport './index.scss';\nimport { ProgramProgressContext, ProgramProgressContextValueType } from '../ProgramProgressProvider';\n\nconst UpgradeAllButton: React.FC = () => {\n const { formatMessage } = useIntl();\n const { programProgressData } = useContext<ProgramProgressContextValueType>(ProgramProgressContext);\n const { urls } = programProgressData;\n\n const getAllRemainingCoursesPrice = () => {\n if (!programProgressData.programData) {\n return null;\n }\n const { discountData } = programProgressData.programData;\n\n if (discountData) {\n const {\n currency,\n isDiscounted,\n totalInclTaxExclDiscounts,\n totalInclTax,\n } = discountData;\n\n if (isDiscounted) {\n return (\n <>\n <span className=\"list-price\">\n <FormattedNumber\n value={totalInclTaxExclDiscounts}\n style=\"currency\"\n currency={currency}\n maximumFractionDigits={2}\n minimumFractionDigits={2}\n />\n </span>\n <span>\n <FormattedNumber\n value={totalInclTax}\n style=\"currency\"\n currency={currency}\n maximumFractionDigits={2}\n minimumFractionDigits={2}\n />\n </span>\n </>\n );\n }\n return (\n <span>\n <FormattedNumber\n value={totalInclTax}\n style=\"currency\"\n currency={currency}\n maximumFractionDigits={2}\n minimumFractionDigits={2}\n />\n </span>\n );\n }\n return null;\n };\n\n return (\n <Button\n as=\"a\"\n className=\"upgrade-all-button\"\n href={urls && urls.buyButtonUrl}\n data-testid=\"upgrade-all-button\"\n variant=\"brand\"\n >\n <span>\n {formatMessage(messages.upgradeAllRemainingCoursesButtonText)}\n </span>\n {getAllRemainingCoursesPrice() && (\n <span className=\"all-remaining-courses-price\">\n {getAllRemainingCoursesPrice()}\n </span>\n )}\n </Button>\n );\n};\n\nexport default UpgradeAllButton;\n"]}
1
+ {"version":3,"file":"UpgradeAllButton.js","sourceRoot":"","sources":["../../../../../src/containers/ProgramDashboard/ProgramProgress/UpgradeButton/UpgradeAllButton.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEnF,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,cAAc,CAAC;AACtB,OAAO,QAAQ,MAAM,YAAY,CAAC;AAElC,MAAM,gBAAgB,GAAO,GAAG,EAAE;IAChC,MAAM,EAAE,IAAI,EAAE,GAAG,SAAS,EAAsB,CAAC;IAEjD,MAAM,EAAE,IAAI,EAAE,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,mBAAmB,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IAElD,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,MAAM,EAAE,IAAI,EAAE,GAAG,mBAAmB,CAAC;IAErC,MAAM,2BAA2B,GAAG,GAAG,EAAE;QACvC,IAAI,CAAC,mBAAmB,CAAC,WAAW,EAAE,CAAC;YACrC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,EAAE,YAAY,EAAE,GAAG,mBAAmB,CAAC,WAAW,CAAC;QAEzD,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,EACJ,QAAQ,EACR,YAAY,EACZ,yBAAyB,EACzB,YAAY,GACb,GAAG,YAAY,CAAC;YAEjB,IAAI,YAAY,EAAE,CAAC;gBACjB,OAAO,CACL,8BACE,eAAM,SAAS,EAAC,YAAY,YAC1B,KAAC,eAAe,IACd,KAAK,EAAE,yBAAyB,EAChC,KAAK,EAAC,UAAU,EAChB,QAAQ,EAAE,QAAQ,EAClB,qBAAqB,EAAE,CAAC,EACxB,qBAAqB,EAAE,CAAC,GACxB,GACG,EACP,yBACE,KAAC,eAAe,IACd,KAAK,EAAE,YAAY,EACnB,KAAK,EAAC,UAAU,EAChB,QAAQ,EAAE,QAAQ,EAClB,qBAAqB,EAAE,CAAC,EACxB,qBAAqB,EAAE,CAAC,GACxB,GACG,IACN,CACJ,CAAC;YACJ,CAAC;YACD,OAAO,CACL,yBACE,KAAC,eAAe,IACd,KAAK,EAAE,YAAY,EACnB,KAAK,EAAC,UAAU,EAChB,QAAQ,EAAE,QAAQ,EAClB,qBAAqB,EAAE,CAAC,EACxB,qBAAqB,EAAE,CAAC,GACxB,GACG,CACR,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IAEF,OAAO,CACL,MAAC,MAAM,IACL,EAAE,EAAC,GAAG,EACN,SAAS,EAAC,oBAAoB,EAC9B,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC,YAAY,iBACnB,oBAAoB,EAChC,OAAO,EAAC,OAAO,aAEf,yBACG,aAAa,CAAC,QAAQ,CAAC,oCAAoC,CAAC,GACxD,EACN,2BAA2B,EAAE,IAAI,CAChC,eAAM,SAAS,EAAC,6BAA6B,YAC1C,2BAA2B,EAAE,GACzB,CACR,IACM,CACV,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,gBAAgB,CAAC","sourcesContent":["import { FC } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { Button } from '@openedx/paragon';\nimport { FormattedNumber, useIntl, camelCaseObject } from '@openedx/frontend-base';\n\nimport { useProgramProgressData } from '@src/data/hooks/queryHooks';\nimport './index.scss';\nimport messages from './messages';\n\nconst UpgradeAllButton: FC = () => {\n const { uuid } = useParams() as { uuid: string };\n\n const { data } = useProgramProgressData(uuid);\n const programProgressData = camelCaseObject(data);\n\n const { formatMessage } = useIntl();\n const { urls } = programProgressData;\n\n const getAllRemainingCoursesPrice = () => {\n if (!programProgressData.programData) {\n return null;\n }\n const { discountData } = programProgressData.programData;\n\n if (discountData) {\n const {\n currency,\n isDiscounted,\n totalInclTaxExclDiscounts,\n totalInclTax,\n } = discountData;\n\n if (isDiscounted) {\n return (\n <>\n <span className=\"list-price\">\n <FormattedNumber\n value={totalInclTaxExclDiscounts}\n style=\"currency\"\n currency={currency}\n maximumFractionDigits={2}\n minimumFractionDigits={2}\n />\n </span>\n <span>\n <FormattedNumber\n value={totalInclTax}\n style=\"currency\"\n currency={currency}\n maximumFractionDigits={2}\n minimumFractionDigits={2}\n />\n </span>\n </>\n );\n }\n return (\n <span>\n <FormattedNumber\n value={totalInclTax}\n style=\"currency\"\n currency={currency}\n maximumFractionDigits={2}\n minimumFractionDigits={2}\n />\n </span>\n );\n }\n return null;\n };\n\n return (\n <Button\n as=\"a\"\n className=\"upgrade-all-button\"\n href={urls && urls.buyButtonUrl}\n data-testid=\"upgrade-all-button\"\n variant=\"brand\"\n >\n <span>\n {formatMessage(messages.upgradeAllRemainingCoursesButtonText)}\n </span>\n {getAllRemainingCoursesPrice() && (\n <span className=\"all-remaining-courses-price\">\n {getAllRemainingCoursesPrice()}\n </span>\n )}\n </Button>\n );\n};\n\nexport default UpgradeAllButton;\n"]}
@@ -1,2 +1,2 @@
1
- declare const ProgramProgressWithProvider: () => import("react/jsx-runtime").JSX.Element;
2
- export default ProgramProgressWithProvider;
1
+ import ProgramProgress from './ProgramProgress';
2
+ export default ProgramProgress;
@@ -1,6 +1,3 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { ProgramProgressContextProvider } from './ProgramProgressProvider';
3
1
  import ProgramProgress from './ProgramProgress';
4
- const ProgramProgressWithProvider = () => (_jsx(ProgramProgressContextProvider, { children: _jsx(ProgramProgress, {}) }));
5
- export default ProgramProgressWithProvider;
2
+ export default ProgramProgress;
6
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/containers/ProgramDashboard/ProgramProgress/index.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,8BAA8B,EAAE,MAAM,2BAA2B,CAAC;AAC3E,OAAO,eAAe,MAAM,mBAAmB,CAAC;AAEhD,MAAM,2BAA2B,GAAG,GAAG,EAAE,CAAC,CACxC,KAAC,8BAA8B,cAC7B,KAAC,eAAe,KAAG,GACY,CAClC,CAAC;AAEF,eAAe,2BAA2B,CAAC","sourcesContent":["import React from 'react';\nimport { ProgramProgressContextProvider } from './ProgramProgressProvider';\nimport ProgramProgress from './ProgramProgress';\n\nconst ProgramProgressWithProvider = () => (\n <ProgramProgressContextProvider>\n <ProgramProgress />\n </ProgramProgressContextProvider>\n);\n\nexport default ProgramProgressWithProvider;\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/containers/ProgramDashboard/ProgramProgress/index.tsx"],"names":[],"mappings":"AAAA,OAAO,eAAe,MAAM,mBAAmB,CAAC;AAEhD,eAAe,eAAe,CAAC","sourcesContent":["import ProgramProgress from './ProgramProgress';\n\nexport default ProgramProgress;\n"]}
@@ -0,0 +1,3 @@
1
+ import { FC } from 'react';
2
+ export declare const NoProgramsView: FC;
3
+ export default NoProgramsView;
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useIntl } from '@openedx/frontend-base';
3
+ import messages from './messages';
4
+ import { Button } from '@openedx/paragon';
5
+ import { Search } from '@openedx/paragon/icons';
6
+ import { baseAppUrl } from '../../../data/services/lms/urls';
7
+ import { exploreProgramsUrl } from '../../../data/constants/app';
8
+ export const NoProgramsView = () => {
9
+ const { formatMessage } = useIntl();
10
+ return (_jsxs("div", { className: "no-programs-content-view", children: [_jsx("p", { children: formatMessage(messages.inProgressProgramsPrompt) }), _jsx(Button, { variant: "brand", as: "a", href: baseAppUrl(exploreProgramsUrl), iconBefore: Search, children: formatMessage(messages.findProgramsButton) })] }));
11
+ };
12
+ export default NoProgramsView;
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/containers/ProgramsPanel/NoProgramsView/index.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D,MAAM,CAAC,MAAM,cAAc,GAAO,GAAG,EAAE;IACrC,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IAEpC,OAAO,CACL,eAAK,SAAS,EAAC,0BAA0B,aACvC,sBAAI,aAAa,CAAC,QAAQ,CAAC,wBAAwB,CAAC,GAAK,EACzD,KAAC,MAAM,IACL,OAAO,EAAC,OAAO,EACf,EAAE,EAAC,GAAG,EACN,IAAI,EAAE,UAAU,CAAC,kBAAkB,CAAC,EACpC,UAAU,EAAE,MAAM,YAEjB,aAAa,CAAC,QAAQ,CAAC,kBAAkB,CAAC,GACpC,IACL,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,cAAc,CAAC","sourcesContent":["import { FC } from 'react';\nimport { useIntl } from '@openedx/frontend-base';\nimport messages from './messages';\nimport { Button } from '@openedx/paragon';\nimport { Search } from '@openedx/paragon/icons';\nimport { baseAppUrl } from '@src/data/services/lms/urls';\nimport { exploreProgramsUrl } from '@src/data/constants/app';\n\nexport const NoProgramsView: FC = () => {\n const { formatMessage } = useIntl();\n\n return (\n <div className=\"no-programs-content-view\">\n <p>{formatMessage(messages.inProgressProgramsPrompt)}</p>\n <Button\n variant=\"brand\"\n as=\"a\"\n href={baseAppUrl(exploreProgramsUrl)}\n iconBefore={Search}\n >\n {formatMessage(messages.findProgramsButton)}\n </Button>\n </div>\n );\n};\n\nexport default NoProgramsView;\n"]}
@@ -0,0 +1,13 @@
1
+ declare const messages: {
2
+ inProgressProgramsPrompt: {
3
+ id: string;
4
+ defaultMessage: string;
5
+ description: string;
6
+ };
7
+ findProgramsButton: {
8
+ id: string;
9
+ defaultMessage: string;
10
+ description: string;
11
+ };
12
+ };
13
+ export default messages;
@@ -0,0 +1,15 @@
1
+ import { defineMessages } from '@openedx/frontend-base';
2
+ const messages = defineMessages({
3
+ inProgressProgramsPrompt: {
4
+ id: 'Dashboard.NoProgramsView.inProgressProgramsPrompt',
5
+ defaultMessage: 'In-progress professional certificate programs will be found here.',
6
+ description: 'Placeholder text for in-progress programs section',
7
+ },
8
+ findProgramsButton: {
9
+ id: 'Dashboard.NoProgramsView.findProgramsButton',
10
+ defaultMessage: 'Find a program',
11
+ description: 'Button to find more programs',
12
+ }
13
+ });
14
+ export default messages;
15
+ //# sourceMappingURL=messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../../src/containers/ProgramsPanel/NoProgramsView/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,QAAQ,GAAG,cAAc,CAAC;IAC9B,wBAAwB,EAAE;QACxB,EAAE,EAAE,mDAAmD;QACvD,cAAc,EAAE,mEAAmE;QACnF,WAAW,EAAE,mDAAmD;KACjE;IACD,kBAAkB,EAAE;QAClB,EAAE,EAAE,6CAA6C;QACjD,cAAc,EAAE,gBAAgB;QAChC,WAAW,EAAE,8BAA8B;KAC5C;CACF,CAAC,CAAC;AAEH,eAAe,QAAQ,CAAC","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n inProgressProgramsPrompt: {\n id: 'Dashboard.NoProgramsView.inProgressProgramsPrompt',\n defaultMessage: 'In-progress professional certificate programs will be found here.',\n description: 'Placeholder text for in-progress programs section',\n },\n findProgramsButton: {\n id: 'Dashboard.NoProgramsView.findProgramsButton',\n defaultMessage: 'Find a program',\n description: 'Button to find more programs',\n }\n});\n\nexport default messages;\n"]}
@@ -0,0 +1,3 @@
1
+ import { FC } from 'react';
2
+ export declare const ProgramsPanel: FC;
3
+ export default ProgramsPanel;
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { useIntl } from '@openedx/frontend-base';
4
+ import messages from './messages';
5
+ import NoProgramsView from './NoProgramsView';
6
+ export const ProgramsPanel = () => {
7
+ const { formatMessage } = useIntl();
8
+ const [hasProgramsEnrollment] = useState(false);
9
+ return (_jsx(_Fragment, { children: _jsxs("div", { className: "programs-list-container mb-5", "data-testid": "programs-list", children: [_jsx("div", { className: "d-flex flex-row justify-content-between text-center", children: _jsx("h3", { className: "programs-list-title mb-3", children: formatMessage(messages.myPrograms) }) }), !hasProgramsEnrollment && _jsx(NoProgramsView, {})] }) }));
10
+ };
11
+ export default ProgramsPanel;
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/containers/ProgramsPanel/index.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAM,QAAQ,EAAE,MAAM,OAAO,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,cAAc,MAAM,kBAAkB,CAAC;AAE9C,MAAM,CAAC,MAAM,aAAa,GAAO,GAAG,EAAE;IACpC,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,MAAM,CAAC,qBAAqB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAEhD,OAAO,CACL,4BACE,eAAK,SAAS,EAAC,8BAA8B,iBAAa,eAAe,aACvE,cAAK,SAAS,EAAC,qDAAqD,YAClE,aAAI,SAAS,EAAC,0BAA0B,YAAE,aAAa,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAM,GAC9E,EACL,CAAC,qBAAqB,IAAI,KAAC,cAAc,KAAG,IACzC,GACL,CACJ,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,aAAa,CAAC","sourcesContent":["import { FC, useState } from 'react';\nimport { useIntl } from '@openedx/frontend-base';\nimport messages from './messages';\nimport NoProgramsView from './NoProgramsView';\n\nexport const ProgramsPanel: FC = () => {\n const { formatMessage } = useIntl();\n const [hasProgramsEnrollment] = useState(false);\n\n return (\n <>\n <div className=\"programs-list-container mb-5\" data-testid=\"programs-list\">\n <div className=\"d-flex flex-row justify-content-between text-center\">\n <h3 className=\"programs-list-title mb-3\">{formatMessage(messages.myPrograms)}</h3>\n </div>\n {!hasProgramsEnrollment && <NoProgramsView />}\n </div>\n </>\n );\n};\n\nexport default ProgramsPanel;\n"]}
@@ -0,0 +1,23 @@
1
+ declare const messages: {
2
+ myPrograms: {
3
+ id: string;
4
+ defaultMessage: string;
5
+ description: string;
6
+ };
7
+ emptyProgramsMessage: {
8
+ id: string;
9
+ defaultMessage: string;
10
+ description: string;
11
+ };
12
+ explorePrograms: {
13
+ id: string;
14
+ defaultMessage: string;
15
+ description: string;
16
+ };
17
+ exploreProgramsCTAMessage: {
18
+ id: string;
19
+ defaultMessage: string;
20
+ description: string;
21
+ };
22
+ };
23
+ export default messages;
@@ -0,0 +1,25 @@
1
+ import { defineMessages } from '@openedx/frontend-base';
2
+ const messages = defineMessages({
3
+ myPrograms: {
4
+ id: 'dashboard.myPrograms',
5
+ defaultMessage: 'Programs',
6
+ description: 'Label for Programs belonging to a user\'s active subscription',
7
+ },
8
+ emptyProgramsMessage: {
9
+ id: 'subs.emptyProgramsMessage',
10
+ defaultMessage: 'In-progress professional certificate programs will be found here.',
11
+ description: 'Message shown in the Programs tab of the learner dashboard',
12
+ },
13
+ explorePrograms: {
14
+ id: 'subs.explorePrograms',
15
+ defaultMessage: 'Explore programs',
16
+ description: 'Message shown in the explore programs button in the Programs tab of the learner dashboard',
17
+ },
18
+ exploreProgramsCTAMessage: {
19
+ id: 'subs.exploreProgramsCTAMessage',
20
+ defaultMessage: 'Advance your learning by exploring a program curriculum.',
21
+ description: 'Message shown in the explore programs button in the Programs tab of the learner dashboard',
22
+ }
23
+ });
24
+ export default messages;
25
+ //# sourceMappingURL=messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../src/containers/ProgramsPanel/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,QAAQ,GAAG,cAAc,CAAC;IAC9B,UAAU,EAAE;QACV,EAAE,EAAE,sBAAsB;QAC1B,cAAc,EAAE,UAAU;QAC1B,WAAW,EAAE,+DAA+D;KAC7E;IACD,oBAAoB,EAAE;QACpB,EAAE,EAAE,2BAA2B;QAC/B,cAAc,EAAE,mEAAmE;QACnF,WAAW,EAAE,4DAA4D;KAC1E;IACD,eAAe,EAAE;QACf,EAAE,EAAE,sBAAsB;QAC1B,cAAc,EAAE,kBAAkB;QAClC,WAAW,EAAE,2FAA2F;KACzG;IACD,yBAAyB,EAAE;QACzB,EAAE,EAAE,gCAAgC;QACpC,cAAc,EAAE,0DAA0D;QAC1E,WAAW,EAAE,2FAA2F;KACzG;CACF,CAAC,CAAC;AAEH,eAAe,QAAQ,CAAC","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n myPrograms: {\n id: 'dashboard.myPrograms',\n defaultMessage: 'Programs',\n description: 'Label for Programs belonging to a user\\'s active subscription',\n },\n emptyProgramsMessage: {\n id: 'subs.emptyProgramsMessage',\n defaultMessage: 'In-progress professional certificate programs will be found here.',\n description: 'Message shown in the Programs tab of the learner dashboard',\n },\n explorePrograms: {\n id: 'subs.explorePrograms',\n defaultMessage: 'Explore programs',\n description: 'Message shown in the explore programs button in the Programs tab of the learner dashboard',\n },\n exploreProgramsCTAMessage: {\n id: 'subs.exploreProgramsCTAMessage',\n defaultMessage: 'Advance your learning by exploring a program curriculum.',\n description: 'Message shown in the explore programs button in the Programs tab of the learner dashboard',\n }\n});\n\nexport default messages;\n"]}
@@ -0,0 +1,2 @@
1
+ import { FC } from 'react';
2
+ export declare const SubscriptionInformation: FC;
@@ -0,0 +1,32 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Alert, Button, Image } from '@openedx/paragon';
3
+ import { useIntl } from '@openedx/frontend-base';
4
+ import { utilHooks } from '../../../hooks';
5
+ import messages from '../messages';
6
+ import { manageSubscriptionURL } from '../../../data/constants/app';
7
+ // TODO: We can replace the below hardcoded subscriptionInformationData with the actual data from the API once we have the API ready.
8
+ // For now, we can use this hardcoded data to test the SubscriptionInformation component.
9
+ const subscriptionInformationData = {
10
+ isSubscribed: true,
11
+ subscriptionStatus: 'cancelled', // can be 'active', 'cancelled', 'expired'
12
+ subscriptionStartDate: '05/22/25',
13
+ subscriptionEndDate: '05/22/26',
14
+ subscriptionRenewalDate: '05/22/26',
15
+ subscriptionRenewalPrice: '$36',
16
+ numberOfCoursesEnrolled: 5,
17
+ totalSavings: '$120',
18
+ };
19
+ export const SubscriptionInformation = () => {
20
+ const { formatMessage } = useIntl();
21
+ const formatDate = utilHooks.useFormatDate();
22
+ const subscriptionActions = [
23
+ _jsx(Button, { variant: "outline-brand", "data-testid": "manage-button", href: manageSubscriptionURL, target: "_blank", rel: "noopener noreferrer", role: "link", children: formatMessage(messages.manageSubscriptionMessage) }, "manage-subscription"),
24
+ ];
25
+ return (_jsxs("div", { className: "container subscription-information p-3\\.5", children: [_jsx(Image, { className: "mr-2", src: "https://www.edx.org/trademark-logos/edx-logo-elm.svg", rounded: true, alt: "edX Logo", width: 40, height: 60 }), subscriptionInformationData.subscriptionStatus === 'cancelled' && (_jsx("h3", { children: formatMessage(messages.cancelledMessage, { totalSavings: subscriptionInformationData.totalSavings }) })), _jsx("p", { children: formatMessage(messages.coursesEnrollmentMessage, {
26
+ numberOfCoursesEnrolled: subscriptionInformationData.numberOfCoursesEnrolled,
27
+ totalSavings: subscriptionInformationData.totalSavings,
28
+ }) }), _jsxs(Alert, { dismissible: false, show: true, actions: subscriptionActions, className: "subscription-status-alert bg-light-200", children: [_jsx(Alert.Heading, { children: formatMessage(messages.statusMessage) }), _jsx("p", { children: formatMessage(messages.renewalMessage, {
29
+ subscriptionRenewalDate: formatDate(subscriptionInformationData.subscriptionRenewalDate),
30
+ }) })] })] }));
31
+ };
32
+ //# sourceMappingURL=SubscriptionInformation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SubscriptionInformation.js","sourceRoot":"","sources":["../../../../src/containers/SubscriptionInformation/components/SubscriptionInformation.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,QAAQ,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,qIAAqI;AACrI,yFAAyF;AACzF,MAAM,2BAA2B,GAAG;IAClC,YAAY,EAAE,IAAI;IAClB,kBAAkB,EAAE,WAAW,EAAE,0CAA0C;IAC3E,qBAAqB,EAAE,UAAU;IACjC,mBAAmB,EAAE,UAAU;IAC/B,uBAAuB,EAAE,UAAU;IACnC,wBAAwB,EAAE,KAAK;IAC/B,uBAAuB,EAAE,CAAC;IAC1B,YAAY,EAAE,MAAM;CACrB,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAO,GAAG,EAAE;IAC9C,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,MAAM,UAAU,GAAG,SAAS,CAAC,aAAa,EAAE,CAAC;IAE7C,MAAM,mBAAmB,GAAG;QAC1B,KAAC,MAAM,IAEL,OAAO,EAAC,eAAe,iBACX,eAAe,EAC3B,IAAI,EAAE,qBAAqB,EAC3B,MAAM,EAAC,QAAQ,EACf,GAAG,EAAC,qBAAqB,EACzB,IAAI,EAAC,MAAM,YAEV,aAAa,CAAC,QAAQ,CAAC,yBAAyB,CAAC,IAR9C,qBAAqB,CASlB;KACV,CAAC;IAEF,OAAO,CACL,eAAK,SAAS,EAAC,4CAA2C,aACxD,KAAC,KAAK,IACJ,SAAS,EAAC,MAAM,EAChB,GAAG,EAAC,sDAAsD,EAC1D,OAAO,QACP,GAAG,EAAC,UAAU,EACd,KAAK,EAAE,EAAE,EACT,MAAM,EAAE,EAAE,GACV,EACD,2BAA2B,CAAC,kBAAkB,KAAK,WAAW,IAAI,CACjE,uBAAK,aAAa,CAAC,QAAQ,CAAC,gBAAgB,EAAE,EAAE,YAAY,EAAE,2BAA2B,CAAC,YAAY,EAAE,CAAC,GAAM,CAChH,EACD,sBACG,aAAa,CAAC,QAAQ,CAAC,wBAAwB,EAAE;oBAChD,uBAAuB,EAAE,2BAA2B,CAAC,uBAAuB;oBAC5E,YAAY,EAAE,2BAA2B,CAAC,YAAY;iBACvD,CAAC,GACA,EACJ,MAAC,KAAK,IACJ,WAAW,EAAE,KAAK,EAClB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,mBAAmB,EAC5B,SAAS,EAAC,wCAAwC,aAElD,KAAC,KAAK,CAAC,OAAO,cAAE,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAiB,EACtE,sBACG,aAAa,CAAC,QAAQ,CAAC,cAAc,EAAE;4BACtC,uBAAuB,EAAE,UAAU,CAAC,2BAA2B,CAAC,uBAAuB,CAAC;yBACzF,CAAC,GACA,IACE,IACJ,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { FC } from 'react';\nimport { Alert, Button, Image } from '@openedx/paragon';\nimport { useIntl } from '@openedx/frontend-base';\nimport { utilHooks } from '@src/hooks';\nimport messages from '../messages';\nimport { manageSubscriptionURL } from '@src/data/constants/app';\n\n// TODO: We can replace the below hardcoded subscriptionInformationData with the actual data from the API once we have the API ready.\n// For now, we can use this hardcoded data to test the SubscriptionInformation component.\nconst subscriptionInformationData = {\n isSubscribed: true,\n subscriptionStatus: 'cancelled', // can be 'active', 'cancelled', 'expired'\n subscriptionStartDate: '05/22/25',\n subscriptionEndDate: '05/22/26',\n subscriptionRenewalDate: '05/22/26',\n subscriptionRenewalPrice: '$36',\n numberOfCoursesEnrolled: 5,\n totalSavings: '$120',\n};\n\nexport const SubscriptionInformation: FC = () => {\n const { formatMessage } = useIntl();\n const formatDate = utilHooks.useFormatDate();\n\n const subscriptionActions = [\n <Button\n key=\"manage-subscription\"\n variant=\"outline-brand\"\n data-testid=\"manage-button\"\n href={manageSubscriptionURL}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n role=\"link\"\n >\n {formatMessage(messages.manageSubscriptionMessage)}\n </Button>,\n ];\n\n return (\n <div className=\"container subscription-information p-3\\.5\">\n <Image\n className=\"mr-2\"\n src=\"https://www.edx.org/trademark-logos/edx-logo-elm.svg\"\n rounded\n alt=\"edX Logo\"\n width={40}\n height={60}\n />\n {subscriptionInformationData.subscriptionStatus === 'cancelled' && (\n <h3>{formatMessage(messages.cancelledMessage, { totalSavings: subscriptionInformationData.totalSavings })}</h3>\n )}\n <p>\n {formatMessage(messages.coursesEnrollmentMessage, {\n numberOfCoursesEnrolled: subscriptionInformationData.numberOfCoursesEnrolled,\n totalSavings: subscriptionInformationData.totalSavings,\n })}\n </p>\n <Alert\n dismissible={false}\n show={true}\n actions={subscriptionActions}\n className=\"subscription-status-alert bg-light-200\"\n >\n <Alert.Heading>{formatMessage(messages.statusMessage)}</Alert.Heading>\n <p>\n {formatMessage(messages.renewalMessage, {\n subscriptionRenewalDate: formatDate(subscriptionInformationData.subscriptionRenewalDate),\n })}\n </p>\n </Alert>\n </div>\n );\n};\n"]}
@@ -0,0 +1 @@
1
+ export { SubscriptionInformation } from "./components/SubscriptionInformation";
@@ -0,0 +1,2 @@
1
+ export { SubscriptionInformation } from './components/SubscriptionInformation';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/containers/SubscriptionInformation/index.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC","sourcesContent":["export { SubscriptionInformation } from './components/SubscriptionInformation';\n"]}
@@ -0,0 +1,28 @@
1
+ declare const messages: {
2
+ statusMessage: {
3
+ id: string;
4
+ description: string;
5
+ defaultMessage: string;
6
+ };
7
+ cancelledMessage: {
8
+ id: string;
9
+ description: string;
10
+ defaultMessage: string;
11
+ };
12
+ coursesEnrollmentMessage: {
13
+ id: string;
14
+ description: string;
15
+ defaultMessage: string;
16
+ };
17
+ renewalMessage: {
18
+ id: string;
19
+ description: string;
20
+ defaultMessage: string;
21
+ };
22
+ manageSubscriptionMessage: {
23
+ id: string;
24
+ description: string;
25
+ defaultMessage: string;
26
+ };
27
+ };
28
+ export default messages;
@@ -0,0 +1,30 @@
1
+ import { defineMessages } from '@openedx/frontend-base';
2
+ const messages = defineMessages({
3
+ statusMessage: {
4
+ id: 'learner-dash.subscriptionInformation.information.subscriptionStatus',
5
+ description: 'Status Message',
6
+ defaultMessage: 'Subscription Status',
7
+ },
8
+ cancelledMessage: {
9
+ id: 'learner-dash.subscriptionInformation.information.courseInformation',
10
+ description: 'Information of courses enrolled and savings',
11
+ defaultMessage: `You have saved {totalSavings} with your subscription so far!`,
12
+ },
13
+ coursesEnrollmentMessage: {
14
+ id: 'learner-dash.subscriptionInformation.information.enrollmentInformation',
15
+ description: 'Information of courses enrolled and savings',
16
+ defaultMessage: `As a subscriber, you've enrolled in {numberOfCoursesEnrolled} courses and saved {totalSavings}.`,
17
+ },
18
+ renewalMessage: {
19
+ id: 'learner-dash.subscriptionInformation.information.subscriptionSchedule',
20
+ description: 'Subscription Schedule',
21
+ defaultMessage: 'Subscription payment scheduled for {subscriptionRenewalDate}.',
22
+ },
23
+ manageSubscriptionMessage: {
24
+ id: 'learner-dash.subscriptionInformation.information.manageSubscription',
25
+ description: 'Manage Subscription',
26
+ defaultMessage: 'Manage my subscription',
27
+ },
28
+ });
29
+ export default messages;
30
+ //# sourceMappingURL=messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../src/containers/SubscriptionInformation/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,QAAQ,GAAG,cAAc,CAAC;IAC9B,aAAa,EAAE;QACb,EAAE,EAAE,qEAAqE;QACzE,WAAW,EAAE,gBAAgB;QAC7B,cAAc,EAAE,qBAAqB;KACtC;IACD,gBAAgB,EAAE;QAChB,EAAE,EAAE,oEAAoE;QACxE,WAAW,EAAE,6CAA6C;QAC1D,cAAc,EAAE,8DAA8D;KAC/E;IACD,wBAAwB,EAAE;QACxB,EAAE,EAAE,wEAAwE;QAC5E,WAAW,EAAE,6CAA6C;QAC1D,cAAc,EAAE,iGAAiG;KAClH;IACD,cAAc,EAAE;QACd,EAAE,EAAE,uEAAuE;QAC3E,WAAW,EAAE,uBAAuB;QACpC,cAAc,EAAE,+DAA+D;KAChF;IACD,yBAAyB,EAAE;QACzB,EAAE,EAAE,qEAAqE;QACzE,WAAW,EAAE,qBAAqB;QAClC,cAAc,EAAE,wBAAwB;KACzC;CACF,CAAC,CAAC;AAEH,eAAe,QAAQ,CAAC","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n statusMessage: {\n id: 'learner-dash.subscriptionInformation.information.subscriptionStatus',\n description: 'Status Message',\n defaultMessage: 'Subscription Status',\n },\n cancelledMessage: {\n id: 'learner-dash.subscriptionInformation.information.courseInformation',\n description: 'Information of courses enrolled and savings',\n defaultMessage: `You have saved {totalSavings} with your subscription so far!`,\n },\n coursesEnrollmentMessage: {\n id: 'learner-dash.subscriptionInformation.information.enrollmentInformation',\n description: 'Information of courses enrolled and savings',\n defaultMessage: `As a subscriber, you've enrolled in {numberOfCoursesEnrolled} courses and saved {totalSavings}.`,\n },\n renewalMessage: {\n id: 'learner-dash.subscriptionInformation.information.subscriptionSchedule',\n description: 'Subscription Schedule',\n defaultMessage: 'Subscription payment scheduled for {subscriptionRenewalDate}.',\n },\n manageSubscriptionMessage: {\n id: 'learner-dash.subscriptionInformation.information.manageSubscription',\n description: 'Manage Subscription',\n defaultMessage: 'Manage my subscription',\n },\n});\n\nexport default messages;\n"]}
@@ -2,4 +2,6 @@ export const locationId: string;
2
2
  export const SortKeys: any;
3
3
  export const FilterKeys: any;
4
4
  export const ListPageSize: 25;
5
- export const subscriptionRenewalURL: "https://courses.edx.org/renew-subscription";
5
+ export const subscriptionRenewalURL: "https://courses.edx.org/manage-subscription";
6
+ export const exploreProgramsUrl: "/explore-programs";
7
+ export const manageSubscriptionURL: "/manage-subscription";
@@ -13,5 +13,7 @@ export const FilterKeys = StrictDict({
13
13
  });
14
14
  export const ListPageSize = 25;
15
15
  // TODO : Below URL is temporary and will be removed once the subscription renewal flow is implemented in the app.
16
- export const subscriptionRenewalURL = 'https://courses.edx.org/renew-subscription';
16
+ export const subscriptionRenewalURL = 'https://courses.edx.org/manage-subscription';
17
+ export const exploreProgramsUrl = '/explore-programs';
18
+ export const manageSubscriptionURL = '/manage-subscription';
17
19
  //# sourceMappingURL=app.js.map
@@ -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,EAAE,CAAC;AAC/B,kHAAkH;AAClH,MAAM,CAAC,MAAM,sBAAsB,GAAG,4CAA4C,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 = 25;\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/renew-subscription';\n"]}
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,EAAE,CAAC;AAC/B,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","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 = 25;\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';\n"]}
@@ -1,3 +1,3 @@
1
- import { useInitializeLearnerHome, useProgramsListData } from './queryHooks';
1
+ import { useInitializeLearnerHome, useProgramsListData, useProgramProgressData } from './queryHooks';
2
2
  import { useUnenrollFromCourse, useUpdateEntitlementEnrollment, useDeleteEntitlementEnrollment, useUpdateEmailSettings, useCreateCreditRequest, useSendConfirmEmail } from './mutationHooks';
3
- export { useInitializeLearnerHome, useUnenrollFromCourse, useUpdateEntitlementEnrollment, useDeleteEntitlementEnrollment, useUpdateEmailSettings, useCreateCreditRequest, useSendConfirmEmail, useProgramsListData, };
3
+ export { useInitializeLearnerHome, useUnenrollFromCourse, useUpdateEntitlementEnrollment, useDeleteEntitlementEnrollment, useUpdateEmailSettings, useCreateCreditRequest, useSendConfirmEmail, useProgramsListData, useProgramProgressData, };
@@ -1,4 +1,4 @@
1
- import { useInitializeLearnerHome, useProgramsListData } from './queryHooks';
1
+ import { useInitializeLearnerHome, useProgramsListData, useProgramProgressData } from './queryHooks';
2
2
  import { useUnenrollFromCourse, useUpdateEntitlementEnrollment, useDeleteEntitlementEnrollment, useUpdateEmailSettings, useCreateCreditRequest, useSendConfirmEmail, } from './mutationHooks';
3
- export { useInitializeLearnerHome, useUnenrollFromCourse, useUpdateEntitlementEnrollment, useDeleteEntitlementEnrollment, useUpdateEmailSettings, useCreateCreditRequest, useSendConfirmEmail, useProgramsListData, };
3
+ export { useInitializeLearnerHome, useUnenrollFromCourse, useUpdateEntitlementEnrollment, useDeleteEntitlementEnrollment, useUpdateEmailSettings, useCreateCreditRequest, useSendConfirmEmail, useProgramsListData, useProgramProgressData, };
4
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/data/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAC7E,OAAO,EACL,qBAAqB,EACrB,8BAA8B,EAC9B,8BAA8B,EAC9B,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,wBAAwB,EACxB,qBAAqB,EACrB,8BAA8B,EAC9B,8BAA8B,EAC9B,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,GACpB,CAAC","sourcesContent":["import { useInitializeLearnerHome, useProgramsListData } from './queryHooks';\nimport {\n useUnenrollFromCourse,\n useUpdateEntitlementEnrollment,\n useDeleteEntitlementEnrollment,\n useUpdateEmailSettings,\n useCreateCreditRequest,\n useSendConfirmEmail,\n} from './mutationHooks';\n\nexport {\n useInitializeLearnerHome,\n useUnenrollFromCourse,\n useUpdateEntitlementEnrollment,\n useDeleteEntitlementEnrollment,\n useUpdateEmailSettings,\n useCreateCreditRequest,\n useSendConfirmEmail,\n useProgramsListData,\n};\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/data/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACrG,OAAO,EACL,qBAAqB,EACrB,8BAA8B,EAC9B,8BAA8B,EAC9B,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,wBAAwB,EACxB,qBAAqB,EACrB,8BAA8B,EAC9B,8BAA8B,EAC9B,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,GACvB,CAAC","sourcesContent":["import { useInitializeLearnerHome, useProgramsListData, useProgramProgressData } from './queryHooks';\nimport {\n useUnenrollFromCourse,\n useUpdateEntitlementEnrollment,\n useDeleteEntitlementEnrollment,\n useUpdateEmailSettings,\n useCreateCreditRequest,\n useSendConfirmEmail,\n} from './mutationHooks';\n\nexport {\n useInitializeLearnerHome,\n useUnenrollFromCourse,\n useUpdateEntitlementEnrollment,\n useDeleteEntitlementEnrollment,\n useUpdateEmailSettings,\n useCreateCreditRequest,\n useSendConfirmEmail,\n useProgramsListData,\n useProgramProgressData,\n};\n"]}
@@ -1,4 +1,4 @@
1
- import { ProgramData } from '@src/containers/ProgramDashboard/data/types';
1
+ import { ProgramData, ProgramProgressData } from '@src/containers/ProgramDashboard/data/types';
2
2
  declare const useInitializeLearnerHome: () => {
3
3
  data: any;
4
4
  error: any;
@@ -163,4 +163,5 @@ declare const useInitializeLearnerHome: () => {
163
163
  promise: Promise<any>;
164
164
  };
165
165
  declare const useProgramsListData: () => import("@tanstack/react-query").UseQueryResult<ProgramData[], Error>;
166
- export { useInitializeLearnerHome, useProgramsListData, };
166
+ declare const useProgramProgressData: (uuid: string) => import("@tanstack/react-query").UseQueryResult<ProgramProgressData, Error>;
167
+ export { useInitializeLearnerHome, useProgramProgressData, useProgramsListData, };
@@ -14,6 +14,7 @@ import GlobalDataContext from '../../data/contexts/GlobalDataContext';
14
14
  import { initializeList, fetchProgramsListData, } from '../../data/services/lms/api';
15
15
  import { getTransformedCourseDataObject } from '../../utils/dataTransformers';
16
16
  import { learnerDashboardQueryKeys } from './queryKeys';
17
+ import { getProgramProgressData } from '../../data/services/subs';
17
18
  const useInitializeLearnerHome = () => {
18
19
  const { masqueradeUser } = useMasquerade();
19
20
  const queryClient = useQueryClient();
@@ -61,5 +62,14 @@ const useProgramsListData = () => {
61
62
  refetchOnWindowFocus: false,
62
63
  });
63
64
  };
64
- export { useInitializeLearnerHome, useProgramsListData, };
65
+ const useProgramProgressData = (uuid) => {
66
+ return useQuery({
67
+ queryKey: ['programProgress', uuid],
68
+ queryFn: () => getProgramProgressData(uuid),
69
+ enabled: !!uuid,
70
+ staleTime: 1000 * 60 * 5, // 5 min caching
71
+ retry: 2,
72
+ });
73
+ };
74
+ export { useInitializeLearnerHome, useProgramProgressData, useProgramsListData, };
65
75
  //# sourceMappingURL=queryHooks.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"queryHooks.js","sourceRoot":"","sources":["../../../src/data/hooks/queryHooks.ts"],"names":[],"mappings":"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","sourcesContent":["import { useQuery, useQueryClient } from '@tanstack/react-query';\nimport { useContext, useEffect } from 'react';\nimport { useMasquerade } from '@src/data/context';\nimport GlobalDataContext from '@src/data/contexts/GlobalDataContext';\nimport {\n initializeList,\n fetchProgramsListData,\n} from '@src/data/services/lms/api';\nimport { ProgramData } from '@src/containers/ProgramDashboard/data/types';\nimport { getTransformedCourseDataObject } from '@src/utils/dataTransformers';\nimport { learnerDashboardQueryKeys } from './queryKeys';\n\nconst useInitializeLearnerHome = () => {\n const { masqueradeUser } = useMasquerade();\n const queryClient = useQueryClient();\n const { setEmailConfirmation, setPlatformSettings } = useContext(GlobalDataContext);\n\n const query = useQuery({\n queryKey: learnerDashboardQueryKeys.initialize(masqueradeUser),\n queryFn: async () => {\n const data = await initializeList(masqueradeUser);\n return {\n ...data,\n coursesByCardId: getTransformedCourseDataObject(data?.courses || []),\n };\n },\n staleTime: 5 * 60 * 1000, // 5 minutes — dashboard data rarely changes while viewing\n retry: (failureCount, error: any) => {\n // Don't retry client errors (4xx) — they won't resolve on retry\n if (error?.response?.status >= 400 && error?.response?.status < 500) return false;\n return failureCount < 3;\n },\n retryOnMount: !masqueradeUser,\n refetchOnMount: !masqueradeUser,\n });\n\n // Populate shell-level GlobalDataProvider so header widgets can access this data\n useEffect(() => {\n if (query.data && !masqueradeUser) {\n if (query.data.emailConfirmation && setEmailConfirmation) {\n setEmailConfirmation(query.data.emailConfirmation);\n }\n if (query.data.platformSettings && setPlatformSettings) {\n setPlatformSettings(query.data.platformSettings);\n }\n }\n }, [masqueradeUser, query.data, setEmailConfirmation, setPlatformSettings]);\n\n // When masquerading fails, fall back to the normal user's cached data\n let { data } = query;\n if (masqueradeUser && query.isError) {\n data = queryClient.getQueryData(learnerDashboardQueryKeys.initialize(undefined));\n }\n\n return { ...query, data };\n};\n\nconst useProgramsListData = () => {\n return useQuery<ProgramData[]>({\n queryKey: ['programsList'],\n queryFn: fetchProgramsListData,\n retry: false,\n refetchOnWindowFocus: false,\n });\n};\n\nexport {\n useInitializeLearnerHome,\n useProgramsListData,\n};\n"]}
1
+ {"version":3,"file":"queryHooks.js","sourceRoot":"","sources":["../../../src/data/hooks/queryHooks.ts"],"names":[],"mappings":"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","sourcesContent":["import { useQuery, useQueryClient } from '@tanstack/react-query';\nimport { useContext, useEffect } from 'react';\nimport { useMasquerade } from '@src/data/context';\nimport GlobalDataContext from '@src/data/contexts/GlobalDataContext';\nimport {\n initializeList,\n fetchProgramsListData,\n} from '@src/data/services/lms/api';\nimport { ProgramData, ProgramProgressData } from '@src/containers/ProgramDashboard/data/types';\nimport { getTransformedCourseDataObject } from '@src/utils/dataTransformers';\nimport { learnerDashboardQueryKeys } from './queryKeys';\nimport { getProgramProgressData } from '@src/data/services/subs';\n\nconst useInitializeLearnerHome = () => {\n const { masqueradeUser } = useMasquerade();\n const queryClient = useQueryClient();\n const { setEmailConfirmation, setPlatformSettings } = useContext(GlobalDataContext);\n\n const query = useQuery({\n queryKey: learnerDashboardQueryKeys.initialize(masqueradeUser),\n queryFn: async () => {\n const data = await initializeList(masqueradeUser);\n return {\n ...data,\n coursesByCardId: getTransformedCourseDataObject(data?.courses || []),\n };\n },\n staleTime: 5 * 60 * 1000, // 5 minutes — dashboard data rarely changes while viewing\n retry: (failureCount, error: any) => {\n // Don't retry client errors (4xx) — they won't resolve on retry\n if (error?.response?.status >= 400 && error?.response?.status < 500) return false;\n return failureCount < 3;\n },\n retryOnMount: !masqueradeUser,\n refetchOnMount: !masqueradeUser,\n });\n\n // Populate shell-level GlobalDataProvider so header widgets can access this data\n useEffect(() => {\n if (query.data && !masqueradeUser) {\n if (query.data.emailConfirmation && setEmailConfirmation) {\n setEmailConfirmation(query.data.emailConfirmation);\n }\n if (query.data.platformSettings && setPlatformSettings) {\n setPlatformSettings(query.data.platformSettings);\n }\n }\n }, [masqueradeUser, query.data, setEmailConfirmation, setPlatformSettings]);\n\n // When masquerading fails, fall back to the normal user's cached data\n let { data } = query;\n if (masqueradeUser && query.isError) {\n data = queryClient.getQueryData(learnerDashboardQueryKeys.initialize(undefined));\n }\n\n return { ...query, data };\n};\n\nconst useProgramsListData = () => {\n return useQuery<ProgramData[]>({\n queryKey: ['programsList'],\n queryFn: fetchProgramsListData,\n retry: false,\n refetchOnWindowFocus: false,\n });\n};\n\nconst useProgramProgressData = (uuid: string) => {\n return useQuery<ProgramProgressData>({\n queryKey: ['programProgress', uuid],\n queryFn: () => getProgramProgressData(uuid),\n enabled: !!uuid,\n staleTime: 1000 * 60 * 5, // 5 min caching\n retry: 2,\n });\n};\n\nexport {\n useInitializeLearnerHome,\n useProgramProgressData,\n useProgramsListData,\n};\n"]}
@@ -8,3 +8,4 @@ export declare const fetchRecommendedCourses: () => Promise<{
8
8
  tagText: string;
9
9
  footerLabel: string;
10
10
  }[]>;
11
+ export declare const getProgramProgressData: (uuid: string) => Promise<any>;
@@ -7,6 +7,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
+ import { getAuthenticatedHttpClient } from '@openedx/frontend-base';
11
+ import { programProgressUrl } from './urls';
10
12
  export const fetchRecommendedCourses = () => __awaiter(void 0, void 0, void 0, function* () {
11
13
  /* TODO [TEMP]: Replace with actual API call to fetch recommended courses data. For now, returning hardcoded data to simulate the API response. Also, built the test case for the same.
12
14
  Reason: The API endpoint is not yet available and the data structure is still being finalized.
@@ -63,4 +65,14 @@ export const fetchRecommendedCourses = () => __awaiter(void 0, void 0, void 0, f
63
65
  throw error;
64
66
  }
65
67
  });
68
+ export const getProgramProgressData = (uuid) => __awaiter(void 0, void 0, void 0, function* () {
69
+ try {
70
+ const { data } = yield getAuthenticatedHttpClient().get(programProgressUrl(uuid));
71
+ return data;
72
+ }
73
+ catch (error) {
74
+ console.error('Error fetching program progress data:', error);
75
+ throw error;
76
+ }
77
+ });
66
78
  //# sourceMappingURL=api.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../../src/data/services/subs/api.ts"],"names":[],"mappings":";;;;;;;;;AAAA,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAS,EAAE;IAChD;;;QAGI;IAEJ,MAAM,aAAa,GAAG,CAAC,IAAY,EAAE,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IAE9G,IAAI,CAAC;QACH,MAAM,SAAS,GAAG;YAChB;gBACE,EAAE,EAAE,CAAC;gBACL,KAAK,EAAE,aAAa,CAAC,+BAA+B,EAAE,EAAE,CAAC;gBACzD,IAAI,EAAE,aAAa,CAAC,mLAAmL,EAAE,GAAG,CAAC;gBAC7M,GAAG,EAAE,sFAAsF;gBAC3F,SAAS,EAAE,8FAA8F;gBACzG,SAAS,EAAE,KAAK;gBAChB,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,QAAQ;aACtB;YACD;gBACE,EAAE,EAAE,CAAC;gBACL,KAAK,EAAE,aAAa,CAAC,+BAA+B,EAAE,EAAE,CAAC;gBACzD,IAAI,EAAE,aAAa,CAAC,2LAA2L,EAAE,GAAG,CAAC;gBACrN,GAAG,EAAE,sFAAsF;gBAC3F,SAAS,EAAE,8FAA8F;gBACzG,SAAS,EAAE,KAAK;gBAChB,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,QAAQ;aACtB;YACD;gBACE,EAAE,EAAE,CAAC;gBACL,KAAK,EAAE,aAAa,CAAC,iBAAiB,EAAE,EAAE,CAAC;gBAC3C,IAAI,EAAE,aAAa,CAAC,oLAAoL,EAAE,GAAG,CAAC;gBAC9M,GAAG,EAAE,wEAAwE;gBAC7E,SAAS,EAAE,gFAAgF;gBAC3F,SAAS,EAAE,IAAI,EAAE,OAAO;gBACxB,OAAO,EAAE,0BAA0B;gBACnC,WAAW,EAAE,WAAW;aACzB;YACD;gBACE,EAAE,EAAE,CAAC;gBACL,KAAK,EAAE,aAAa,CAAC,cAAc,EAAE,EAAE,CAAC;gBACxC,IAAI,EAAE,aAAa,CAAC,2KAA2K,EAAE,GAAG,CAAC;gBACrM,GAAG,EAAE,qEAAqE;gBAC1E,SAAS,EAAE,6EAA6E;gBACxF,SAAS,EAAE,KAAK;gBAChB,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,QAAQ;aACtB;SACF,CAAC;QAEF,OAAO,SAAS,CAAC;IACnB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;QACnD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC,CAAA,CAAC","sourcesContent":["export const fetchRecommendedCourses = async () => {\n /* TODO [TEMP]: Replace with actual API call to fetch recommended courses data. For now, returning hardcoded data to simulate the API response. Also, built the test case for the same.\n Reason: The API endpoint is not yet available and the data structure is still being finalized.\n Action: Revisit after endpoint is made available.\n */\n\n const optimizedData = (data: string, size: number) => data.length > size ? `${data.slice(0, size)}...` : data;\n\n try {\n const finalData = [\n {\n id: 1,\n title: optimizedData('Essence Mascara Lash Princess', 30),\n body: optimizedData('The Essence Mascara Lash Princess is a popular mascara known for its volumizing and lengthening effects. Achieve dramatic lashes with this long-lasting and cruelty-free formula.', 100),\n url: 'https://cdn.dummyjson.com/product-images/beauty/essence-mascara-lash-princess/1.webp',\n thumbnail: 'https://cdn.dummyjson.com/product-images/beauty/essence-mascara-lash-princess/thumbnail.webp',\n isProgram: false,\n tagText: '',\n footerLabel: 'Course'\n },\n {\n id: 2,\n title: optimizedData('Eyeshadow Palette with Mirror', 30),\n body: optimizedData(\"The Eyeshadow Palette with Mirror offers a versatile range of eyeshadow shades for creating stunning eye looks. With a built-in mirror, it's convenient for on-the-go makeup application.\", 100),\n url: 'https://cdn.dummyjson.com/product-images/beauty/eyeshadow-palette-with-mirror/1.webp',\n thumbnail: 'https://cdn.dummyjson.com/product-images/beauty/eyeshadow-palette-with-mirror/thumbnail.webp',\n isProgram: false,\n tagText: '',\n footerLabel: 'Course'\n },\n {\n id: 3,\n title: optimizedData('Powder Canister', 30),\n body: optimizedData('The Powder Canister is a finely milled setting powder designed to set makeup and control shine. With a lightweight and translucent formula, it provides a smooth and matte finish.', 100),\n url: 'https://cdn.dummyjson.com/product-images/beauty/powder-canister/1.webp',\n thumbnail: 'https://cdn.dummyjson.com/product-images/beauty/powder-canister/thumbnail.webp',\n isProgram: true, // TODO\n tagText: 'Professional Certificate',\n footerLabel: '2 Courses'\n },\n {\n id: 4,\n title: optimizedData('Red Lipstick', 30),\n body: optimizedData('The Red Lipstick is a classic and bold choice for adding a pop of color to your lips. With a creamy and pigmented formula, it provides a vibrant and long-lasting finish.', 100),\n url: 'https://cdn.dummyjson.com/product-images/beauty/red-lipstick/1.webp',\n thumbnail: 'https://cdn.dummyjson.com/product-images/beauty/red-lipstick/thumbnail.webp',\n isProgram: false,\n tagText: '',\n footerLabel: 'Course'\n }\n ];\n\n return finalData;\n } catch (error) {\n console.error('Error fetching cards data:', error);\n throw error;\n }\n};\n"]}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../../src/data/services/subs/api.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAE5C,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAS,EAAE;IAChD;;;QAGI;IAEJ,MAAM,aAAa,GAAG,CAAC,IAAY,EAAE,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IAE9G,IAAI,CAAC;QACH,MAAM,SAAS,GAAG;YAChB;gBACE,EAAE,EAAE,CAAC;gBACL,KAAK,EAAE,aAAa,CAAC,+BAA+B,EAAE,EAAE,CAAC;gBACzD,IAAI,EAAE,aAAa,CAAC,mLAAmL,EAAE,GAAG,CAAC;gBAC7M,GAAG,EAAE,sFAAsF;gBAC3F,SAAS,EAAE,8FAA8F;gBACzG,SAAS,EAAE,KAAK;gBAChB,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,QAAQ;aACtB;YACD;gBACE,EAAE,EAAE,CAAC;gBACL,KAAK,EAAE,aAAa,CAAC,+BAA+B,EAAE,EAAE,CAAC;gBACzD,IAAI,EAAE,aAAa,CAAC,2LAA2L,EAAE,GAAG,CAAC;gBACrN,GAAG,EAAE,sFAAsF;gBAC3F,SAAS,EAAE,8FAA8F;gBACzG,SAAS,EAAE,KAAK;gBAChB,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,QAAQ;aACtB;YACD;gBACE,EAAE,EAAE,CAAC;gBACL,KAAK,EAAE,aAAa,CAAC,iBAAiB,EAAE,EAAE,CAAC;gBAC3C,IAAI,EAAE,aAAa,CAAC,oLAAoL,EAAE,GAAG,CAAC;gBAC9M,GAAG,EAAE,wEAAwE;gBAC7E,SAAS,EAAE,gFAAgF;gBAC3F,SAAS,EAAE,IAAI,EAAE,OAAO;gBACxB,OAAO,EAAE,0BAA0B;gBACnC,WAAW,EAAE,WAAW;aACzB;YACD;gBACE,EAAE,EAAE,CAAC;gBACL,KAAK,EAAE,aAAa,CAAC,cAAc,EAAE,EAAE,CAAC;gBACxC,IAAI,EAAE,aAAa,CAAC,2KAA2K,EAAE,GAAG,CAAC;gBACrM,GAAG,EAAE,qEAAqE;gBAC1E,SAAS,EAAE,6EAA6E;gBACxF,SAAS,EAAE,KAAK;gBAChB,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,QAAQ;aACtB;SACF,CAAC;QAEF,OAAO,SAAS,CAAC;IACnB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;QACnD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC,CAAA,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAO,IAAY,EAAE,EAAE;IAC3D,IAAI,CAAC;QACH,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC;QAClF,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,uCAAuC,EAAE,KAAK,CAAC,CAAC;QAC9D,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC,CAAA,CAAC","sourcesContent":["import { getAuthenticatedHttpClient } from '@openedx/frontend-base';\nimport { programProgressUrl } from './urls';\n\nexport const fetchRecommendedCourses = async () => {\n /* TODO [TEMP]: Replace with actual API call to fetch recommended courses data. For now, returning hardcoded data to simulate the API response. Also, built the test case for the same.\n Reason: The API endpoint is not yet available and the data structure is still being finalized.\n Action: Revisit after endpoint is made available.\n */\n\n const optimizedData = (data: string, size: number) => data.length > size ? `${data.slice(0, size)}...` : data;\n\n try {\n const finalData = [\n {\n id: 1,\n title: optimizedData('Essence Mascara Lash Princess', 30),\n body: optimizedData('The Essence Mascara Lash Princess is a popular mascara known for its volumizing and lengthening effects. Achieve dramatic lashes with this long-lasting and cruelty-free formula.', 100),\n url: 'https://cdn.dummyjson.com/product-images/beauty/essence-mascara-lash-princess/1.webp',\n thumbnail: 'https://cdn.dummyjson.com/product-images/beauty/essence-mascara-lash-princess/thumbnail.webp',\n isProgram: false,\n tagText: '',\n footerLabel: 'Course'\n },\n {\n id: 2,\n title: optimizedData('Eyeshadow Palette with Mirror', 30),\n body: optimizedData(\"The Eyeshadow Palette with Mirror offers a versatile range of eyeshadow shades for creating stunning eye looks. With a built-in mirror, it's convenient for on-the-go makeup application.\", 100),\n url: 'https://cdn.dummyjson.com/product-images/beauty/eyeshadow-palette-with-mirror/1.webp',\n thumbnail: 'https://cdn.dummyjson.com/product-images/beauty/eyeshadow-palette-with-mirror/thumbnail.webp',\n isProgram: false,\n tagText: '',\n footerLabel: 'Course'\n },\n {\n id: 3,\n title: optimizedData('Powder Canister', 30),\n body: optimizedData('The Powder Canister is a finely milled setting powder designed to set makeup and control shine. With a lightweight and translucent formula, it provides a smooth and matte finish.', 100),\n url: 'https://cdn.dummyjson.com/product-images/beauty/powder-canister/1.webp',\n thumbnail: 'https://cdn.dummyjson.com/product-images/beauty/powder-canister/thumbnail.webp',\n isProgram: true, // TODO\n tagText: 'Professional Certificate',\n footerLabel: '2 Courses'\n },\n {\n id: 4,\n title: optimizedData('Red Lipstick', 30),\n body: optimizedData('The Red Lipstick is a classic and bold choice for adding a pop of color to your lips. With a creamy and pigmented formula, it provides a vibrant and long-lasting finish.', 100),\n url: 'https://cdn.dummyjson.com/product-images/beauty/red-lipstick/1.webp',\n thumbnail: 'https://cdn.dummyjson.com/product-images/beauty/red-lipstick/thumbnail.webp',\n isProgram: false,\n tagText: '',\n footerLabel: 'Course'\n }\n ];\n\n return finalData;\n } catch (error) {\n console.error('Error fetching cards data:', error);\n throw error;\n }\n};\n\nexport const getProgramProgressData = async (uuid: string) => {\n try {\n const { data } = await getAuthenticatedHttpClient().get(programProgressUrl(uuid));\n return data;\n } catch (error) {\n console.error('Error fetching program progress data:', error);\n throw error;\n }\n};\n"]}
@@ -1 +1 @@
1
- export { fetchRecommendedCourses } from './api';
1
+ export { fetchRecommendedCourses, getProgramProgressData } from './api';
@@ -1,2 +1,2 @@
1
- export { fetchRecommendedCourses } from './api';
1
+ export { fetchRecommendedCourses, getProgramProgressData } from './api';
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/data/services/subs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,OAAO,CAAC","sourcesContent":["export { fetchRecommendedCourses } from './api';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/data/services/subs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,OAAO,CAAC","sourcesContent":["export { fetchRecommendedCourses, getProgramProgressData } from './api';\n"]}
@@ -0,0 +1,2 @@
1
+ export declare const getApiUrl: () => string;
2
+ export declare const programProgressUrl: (uuid: string) => string;
@@ -0,0 +1,4 @@
1
+ import { getSiteConfig } from '@openedx/frontend-base';
2
+ export const getApiUrl = () => (`${getSiteConfig().lmsBaseUrl}/api`);
3
+ export const programProgressUrl = (uuid) => `${getApiUrl()}/dashboard/v0/programs/${encodeURIComponent(uuid)}/progress_details/`;
4
+ //# sourceMappingURL=urls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"urls.js","sourceRoot":"","sources":["../../../../src/data/services/subs/urls.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC,CAAC,GAAG,aAAa,EAAE,CAAC,UAAU,MAAM,CAAC,CAAC;AAErE,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,GAAG,SAAS,EAAE,0BAA0B,kBAAkB,CAAC,IAAI,CAAC,oBAAoB,CAAC","sourcesContent":["import { getSiteConfig } from '@openedx/frontend-base';\n\nexport const getApiUrl = () => (`${getSiteConfig().lmsBaseUrl}/api`);\n\nexport const programProgressUrl = (uuid: string) => `${getApiUrl()}/dashboard/v0/programs/${encodeURIComponent(uuid)}/progress_details/`;\n"]}
package/dist/routes.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export default routes;
2
- declare const routes: {
2
+ declare const routes: ({
3
3
  id: string;
4
4
  path: string;
5
5
  loader: typeof authenticatedLoader;
@@ -9,5 +9,15 @@ declare const routes: {
9
9
  lazy(): Promise<{
10
10
  Component: () => import("react/jsx-runtime").JSX.Element;
11
11
  }>;
12
- }[];
12
+ } | {
13
+ id: string;
14
+ path: string;
15
+ loader: typeof authenticatedLoader;
16
+ handle: {
17
+ role: string;
18
+ };
19
+ lazy(): Promise<{
20
+ Component: import("react").FC;
21
+ }>;
22
+ })[];
13
23
  import { authenticatedLoader } from '@openedx/frontend-base';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edx/frontend-app-subscription-learner-dashboard",
3
- "version": "1.3.0",
3
+ "version": "1.5.0",
4
4
  "description": "",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,10 +0,0 @@
1
- import React from 'react';
2
- import { ProgramProgressProviderProps, ProgramProgressContextValueType } from '../data/types';
3
- export type { ProgramProgressProviderProps, ProgramProgressContextValueType };
4
- export declare const ProgramProgressContext: React.Context<ProgramProgressContextValueType>;
5
- export declare const ProgramProgressContextProvider: React.FC<ProgramProgressProviderProps>;
6
- declare const _default: {
7
- ProgramProgressContextProvider: React.FC<ProgramProgressProviderProps>;
8
- ProgramProgressContext: React.Context<ProgramProgressContextValueType>;
9
- };
10
- export default _default;
@@ -1,30 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { createContext, useMemo, useState, } from 'react';
3
- const defaultContextValue = {
4
- programProgressData: {
5
- urls: {
6
- programListingUrl: undefined,
7
- trackSelectionUrl: undefined,
8
- commerceApiUrl: undefined,
9
- buyButtonUrl: undefined,
10
- programRecordUrl: undefined,
11
- },
12
- programData: null,
13
- courseData: null,
14
- },
15
- setProgramProgressData: () => { },
16
- };
17
- export const ProgramProgressContext = createContext(defaultContextValue);
18
- export const ProgramProgressContextProvider = ({ children }) => {
19
- const [programProgressData, setProgramProgressData] = useState(defaultContextValue.programProgressData);
20
- const memoValue = useMemo(() => ({
21
- programProgressData,
22
- setProgramProgressData,
23
- }), [programProgressData, setProgramProgressData]);
24
- return (_jsx(ProgramProgressContext.Provider, { value: memoValue, children: children }));
25
- };
26
- export default {
27
- ProgramProgressContextProvider,
28
- ProgramProgressContext,
29
- };
30
- //# sourceMappingURL=ProgramProgressProvider.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ProgramProgressProvider.js","sourceRoot":"","sources":["../../../../src/containers/ProgramDashboard/ProgramProgress/ProgramProgressProvider.tsx"],"names":[],"mappings":";AAAA,OAAc,EACZ,aAAa,EAAE,OAAO,EAAE,QAAQ,GACjC,MAAM,OAAO,CAAC;AAQf,MAAM,mBAAmB,GAAoC;IAC3D,mBAAmB,EAAE;QACnB,IAAI,EAAE;YACJ,iBAAiB,EAAE,SAAS;YAC5B,iBAAiB,EAAE,SAAS;YAC5B,cAAc,EAAE,SAAS;YACzB,YAAY,EAAE,SAAS;YACvB,gBAAgB,EAAE,SAAS;SAC5B;QACD,WAAW,EAAE,IAAI;QACjB,UAAU,EAAE,IAAI;KACjB;IACD,sBAAsB,EAAE,GAAG,EAAE,GAAE,CAAC;CACjC,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,aAAa,CAAkC,mBAAmB,CAAC,CAAC;AAE1G,MAAM,CAAC,MAAM,8BAA8B,GAA2C,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE;IACrG,MAAM,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,GAAG,QAAQ,CAAC,mBAAmB,CAAC,mBAAmB,CAAC,CAAC;IAExG,MAAM,SAAS,GAAG,OAAO,CAAC,GAAoC,EAAE,CAAC,CAAC;QAChE,mBAAmB;QACnB,sBAAsB;KACvB,CAAC,EAAE,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,CAAC,CAAC;IAEnD,OAAO,CACL,KAAC,sBAAsB,CAAC,QAAQ,IAC9B,KAAK,EAAE,SAAS,YAEf,QAAQ,GACuB,CACnC,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe;IACb,8BAA8B;IAC9B,sBAAsB;CACvB,CAAC","sourcesContent":["import React, {\n createContext, useMemo, useState,\n} from 'react';\nimport {\n ProgramProgressProviderProps,\n ProgramProgressContextValueType,\n} from '../data/types';\n\nexport type { ProgramProgressProviderProps, ProgramProgressContextValueType };\n\nconst defaultContextValue: ProgramProgressContextValueType = {\n programProgressData: {\n urls: {\n programListingUrl: undefined,\n trackSelectionUrl: undefined,\n commerceApiUrl: undefined,\n buyButtonUrl: undefined,\n programRecordUrl: undefined,\n },\n programData: null,\n courseData: null,\n },\n setProgramProgressData: () => {},\n};\n\nexport const ProgramProgressContext = createContext<ProgramProgressContextValueType>(defaultContextValue);\n\nexport const ProgramProgressContextProvider: React.FC<ProgramProgressProviderProps> = ({ children }) => {\n const [programProgressData, setProgramProgressData] = useState(defaultContextValue.programProgressData);\n\n const memoValue = useMemo((): ProgramProgressContextValueType => ({\n programProgressData,\n setProgramProgressData,\n }), [programProgressData, setProgramProgressData]);\n\n return (\n <ProgramProgressContext.Provider\n value={memoValue}\n >\n {children}\n </ProgramProgressContext.Provider>\n );\n};\n\nexport default {\n ProgramProgressContextProvider,\n ProgramProgressContext,\n};\n"]}
@@ -1 +0,0 @@
1
- export declare function getProgramProgressData(uuid: string): Promise<any>;
@@ -1,18 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import { getAuthenticatedHttpClient, getSiteConfig } from '@openedx/frontend-base';
11
- export function getProgramProgressData(uuid) {
12
- return __awaiter(this, void 0, void 0, function* () {
13
- const baseUrl = getSiteConfig().lmsBaseUrl;
14
- const url = `${baseUrl}/api/dashboard/v0/programs/${encodeURIComponent(uuid)}/progress_details/`;
15
- return getAuthenticatedHttpClient().get(url);
16
- });
17
- }
18
- //# sourceMappingURL=api.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../../src/containers/ProgramDashboard/data/api.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,0BAA0B,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEnF,MAAM,UAAgB,sBAAsB,CAAC,IAAY;;QACvD,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC,UAAU,CAAC;QAC3C,MAAM,GAAG,GAAG,GAAG,OAAO,8BAA8B,kBAAkB,CAAC,IAAI,CAAC,oBAAoB,CAAC;QACjG,OAAO,0BAA0B,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/C,CAAC;CAAA","sourcesContent":["import { getAuthenticatedHttpClient, getSiteConfig } from '@openedx/frontend-base';\n\nexport async function getProgramProgressData(uuid: string) {\n const baseUrl = getSiteConfig().lmsBaseUrl;\n const url = `${baseUrl}/api/dashboard/v0/programs/${encodeURIComponent(uuid)}/progress_details/`;\n return getAuthenticatedHttpClient().get(url);\n}\n"]}