@edx/frontend-app-subscription-learner-dashboard 1.16.0 → 1.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/containers/Dashboard/DashboardHeader.d.ts +3 -0
- package/dist/containers/Dashboard/DashboardHeader.js +10 -0
- package/dist/containers/Dashboard/DashboardHeader.js.map +1 -0
- package/dist/containers/Dashboard/index.js +8 -4
- package/dist/containers/Dashboard/index.js.map +1 -1
- package/dist/containers/Dashboard/index.scss +12 -1
- package/dist/containers/Dashboard/messages.d.ts +10 -0
- package/dist/containers/Dashboard/messages.js +10 -0
- package/dist/containers/Dashboard/messages.js.map +1 -1
- package/dist/containers/PopularCoursePanel/NoPopularCourseItems/index.d.ts +3 -0
- package/dist/containers/PopularCoursePanel/NoPopularCourseItems/index.js +9 -0
- package/dist/containers/PopularCoursePanel/NoPopularCourseItems/index.js.map +1 -0
- package/dist/containers/{RecentlyViewedPanel/NoRecentlyViewedItems → PopularCoursePanel/NoPopularCourseItems}/messages.d.ts +1 -1
- package/dist/containers/PopularCoursePanel/NoPopularCourseItems/messages.js +10 -0
- package/dist/containers/PopularCoursePanel/NoPopularCourseItems/messages.js.map +1 -0
- package/dist/containers/PopularCoursePanel/PopularCourses/index.d.ts +4 -0
- package/dist/containers/{RecentlyViewedPanel/RecentlyViewedCourseProgram → PopularCoursePanel/PopularCourses}/index.js +3 -3
- package/dist/containers/PopularCoursePanel/PopularCourses/index.js.map +1 -0
- package/dist/containers/PopularCoursePanel/index.d.ts +3 -0
- package/dist/containers/PopularCoursePanel/index.js +21 -0
- package/dist/containers/PopularCoursePanel/index.js.map +1 -0
- package/dist/containers/{RecentlyViewedPanel → PopularCoursePanel}/messages.d.ts +2 -2
- package/dist/containers/PopularCoursePanel/messages.js +15 -0
- package/dist/containers/PopularCoursePanel/messages.js.map +1 -0
- package/dist/containers/ProductCard/index.d.ts +1 -1
- package/dist/containers/ProductCard/index.js +7 -6
- package/dist/containers/ProductCard/index.js.map +1 -1
- package/dist/containers/ProductCard/index.scss +17 -6
- package/dist/containers/ProductCard/messages.d.ts +13 -0
- package/dist/containers/ProductCard/messages.js +15 -0
- package/dist/containers/ProductCard/messages.js.map +1 -0
- package/dist/containers/ProgramDashboard/ProgramProgress/InProgressTabData/index.d.ts +2 -0
- package/dist/containers/ProgramDashboard/ProgramProgress/InProgressTabData/index.js +39 -0
- package/dist/containers/ProgramDashboard/ProgramProgress/InProgressTabData/index.js.map +1 -0
- package/dist/containers/ProgramDashboard/ProgramProgress/ProgramProgressTabs/index.js +2 -1
- package/dist/containers/ProgramDashboard/ProgramProgress/ProgramProgressTabs/index.js.map +1 -1
- package/dist/containers/ProgramDashboard/ProgramProgress/ProgressCard/index.js +20 -2
- package/dist/containers/ProgramDashboard/ProgramProgress/ProgressCard/index.js.map +1 -1
- package/dist/containers/ProgramDashboard/ProgramProgress/ProgressCardActions/ProgressCardButton.js +15 -6
- package/dist/containers/ProgramDashboard/ProgramProgress/ProgressCardActions/ProgressCardButton.js.map +1 -1
- package/dist/containers/ProgramDashboard/ProgramProgress/ProgressCardActions/index.js +5 -2
- package/dist/containers/ProgramDashboard/ProgramProgress/ProgressCardActions/index.js.map +1 -1
- package/dist/containers/ProgramDashboard/ProgramProgress/index.scss +6 -0
- package/dist/containers/ProgramDashboard/ProgramProgress/messages.d.ts +45 -0
- package/dist/containers/ProgramDashboard/ProgramProgress/messages.js +45 -0
- package/dist/containers/ProgramDashboard/ProgramProgress/messages.js.map +1 -1
- package/dist/containers/ProgramDashboard/data/util.d.ts +14 -0
- package/dist/containers/ProgramDashboard/data/util.js +26 -0
- package/dist/containers/ProgramDashboard/data/util.js.map +1 -1
- package/dist/data/services/subs/urls.d.ts +1 -0
- package/dist/data/services/subs/urls.js +1 -1
- package/dist/data/services/subs/urls.js.map +1 -1
- package/dist/hooks/{useRecentlyViewedCoursesAndProgramsData.d.ts → usePopularCourses.d.ts} +1 -1
- package/dist/hooks/{useRecentlyViewedCoursesAndProgramsData.js → usePopularCourses.js} +7 -4
- package/dist/hooks/usePopularCourses.js.map +1 -0
- package/dist/routes.d.ts +2 -3
- package/dist/routes.js +28 -3
- package/dist/routes.js.map +1 -1
- package/package.json +1 -1
- package/dist/containers/RecentlyViewedPanel/NoRecentlyViewedItems/index.d.ts +0 -3
- package/dist/containers/RecentlyViewedPanel/NoRecentlyViewedItems/index.js +0 -9
- package/dist/containers/RecentlyViewedPanel/NoRecentlyViewedItems/index.js.map +0 -1
- package/dist/containers/RecentlyViewedPanel/NoRecentlyViewedItems/messages.js +0 -10
- package/dist/containers/RecentlyViewedPanel/NoRecentlyViewedItems/messages.js.map +0 -1
- package/dist/containers/RecentlyViewedPanel/RecentlyViewedCourseProgram/index.d.ts +0 -4
- package/dist/containers/RecentlyViewedPanel/RecentlyViewedCourseProgram/index.js.map +0 -1
- package/dist/containers/RecentlyViewedPanel/index.d.ts +0 -3
- package/dist/containers/RecentlyViewedPanel/index.js +0 -21
- package/dist/containers/RecentlyViewedPanel/index.js.map +0 -1
- package/dist/containers/RecentlyViewedPanel/messages.js +0 -15
- package/dist/containers/RecentlyViewedPanel/messages.js.map +0 -1
- package/dist/hooks/useRecentlyViewedCoursesAndProgramsData.js.map +0 -1
|
@@ -0,0 +1,10 @@
|
|
|
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 { dateFormatter } from '../../utils/dateFormatter';
|
|
5
|
+
export const DashboardHeader = ({ startDate }) => {
|
|
6
|
+
const { formatMessage, formatDate } = useIntl();
|
|
7
|
+
const formattedDate = startDate ? dateFormatter(formatDate, startDate, 'long') : '';
|
|
8
|
+
return (_jsxs("div", { className: "my-4.5", children: [_jsx("h2", { className: "font-weight-bold mb-3 dashboard-header-title", "data-testid": "dashboard-header-title", children: formatMessage(messages.dashboardHeaderWelcomeTitle) }), startDate ? (_jsx("p", { className: "mb-0 text-body dashboard-header-subtitle", "data-testid": "dashboard-header-subtitle", children: formatMessage(messages.dashboardHeaderWelcomeMessage, { startDate: formattedDate || '' }) })) : null] }));
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=DashboardHeader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DashboardHeader.js","sourceRoot":"","sources":["../../../src/containers/Dashboard/DashboardHeader.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,QAAQ,MAAM,YAAY,CAAC;AAElC,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,MAAM,CAAC,MAAM,eAAe,GAA6B,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE;IACzE,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,GAAG,OAAO,EAAE,CAAC;IAChD,MAAM,aAAa,GAAG,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,UAAU,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAEpF,OAAO,CACL,eAAK,SAAS,EAAC,QAAQ,aACrB,aAAI,SAAS,EAAC,8CAA8C,iBAAa,wBAAwB,YAC9F,aAAa,CAAC,QAAQ,CAAC,2BAA2B,CAAC,GACjD,EACJ,SAAS,CAAC,CAAC,CAAC,CACX,YAAG,SAAS,EAAC,0CAA0C,iBAAa,2BAA2B,YAC5F,aAAa,CAAC,QAAQ,CAAC,6BAA6B,EAAE,EAAE,SAAS,EAAE,aAAa,IAAI,EAAE,EAAE,CAAC,GACxF,CACL,CAAC,CAAC,CAAC,IAAI,IACJ,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { FC } from 'react';\nimport { useIntl } from '@openedx/frontend-base';\nimport messages from './messages';\nimport type { DashboardHeaderProps } from './data/types';\nimport { dateFormatter } from '@src/utils/dateFormatter';\n\nexport const DashboardHeader: FC<DashboardHeaderProps> = ({ startDate }) => {\n const { formatMessage, formatDate } = useIntl();\n const formattedDate = startDate ? dateFormatter(formatDate, startDate, 'long') : '';\n\n return (\n <div className=\"my-4.5\">\n <h2 className=\"font-weight-bold mb-3 dashboard-header-title\" data-testid=\"dashboard-header-title\">\n {formatMessage(messages.dashboardHeaderWelcomeTitle)}\n </h2>\n {startDate ? (\n <p className=\"mb-0 text-body dashboard-header-subtitle\" data-testid=\"dashboard-header-subtitle\">\n {formatMessage(messages.dashboardHeaderWelcomeMessage, { startDate: formattedDate || '' })}\n </p>\n ) : null}\n </div>\n );\n};\n"]}
|
|
@@ -1,28 +1,32 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useMemo } from 'react';
|
|
3
|
+
import { DashboardHeader } from './DashboardHeader';
|
|
3
4
|
import { useSelectSessionModal } from '../../data/context';
|
|
4
5
|
import { useInitializeSubsCourseDashboard } from '../../data/hooks';
|
|
5
6
|
import SelectSessionModal from '../../containers/SelectSessionModal';
|
|
6
7
|
import { DashboardContent } from './DashboardContent';
|
|
7
8
|
import DashboardModalSlot from '../../slots/DashboardModalSlot';
|
|
8
|
-
import
|
|
9
|
+
import PopularCoursePanel from '../PopularCoursePanel';
|
|
9
10
|
import LoadingView from './LoadingView';
|
|
10
11
|
import DashboardLayout from './DashboardLayout';
|
|
11
12
|
import hooks from './hooks';
|
|
12
13
|
import './index.scss';
|
|
13
14
|
import { SubscriptionBanner } from '../SubscriptionBanner';
|
|
14
15
|
import { DashboardTitle } from './DashboardTitle';
|
|
16
|
+
import { useInitializeSubsDashboard } from '../../data/hooks';
|
|
15
17
|
export const Dashboard = () => {
|
|
16
|
-
var _a, _b;
|
|
18
|
+
var _a, _b, _c;
|
|
17
19
|
const { data, isPending } = useInitializeSubsCourseDashboard();
|
|
20
|
+
const { data: learnerData } = useInitializeSubsDashboard();
|
|
18
21
|
const { pageTitle } = hooks.useDashboardMessages();
|
|
19
22
|
const { selectSessionModal } = useSelectSessionModal();
|
|
20
23
|
const showSelectSessionModal = selectSessionModal.cardId !== null;
|
|
24
|
+
const userSubscriptionStartDate = ((_a = learnerData === null || learnerData === void 0 ? void 0 : learnerData.userSubscription) === null || _a === void 0 ? void 0 : _a.subscriptionStartDate) || '';
|
|
21
25
|
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]);
|
|
22
|
-
const hasCourseHistory = ((
|
|
26
|
+
const hasCourseHistory = ((_c = (_b = data === null || data === void 0 ? void 0 : data.nonUpgradeableCourses) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 0) > 0;
|
|
23
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
|
|
24
28
|
? (_jsx(LoadingView, {}))
|
|
25
|
-
: (_jsxs(DashboardLayout, { children: [_jsx(SubscriptionBanner, {}), _jsx(DashboardTitle, {}), _jsx(DashboardContent, { hasCourseHistory: hasCourseHistory }), _jsx(
|
|
29
|
+
: (_jsxs(DashboardLayout, { children: [_jsx(DashboardHeader, { startDate: userSubscriptionStartDate }), _jsx(SubscriptionBanner, {}), _jsx(DashboardTitle, {}), _jsx(DashboardContent, { hasCourseHistory: hasCourseHistory }), _jsx(PopularCoursePanel, {})] })) })] }) }) }));
|
|
26
30
|
};
|
|
27
31
|
export default Dashboard;
|
|
28
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;
|
|
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;AAEvD,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,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAE7D,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,yBAAyB,GAAG,CAAA,MAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,gBAAgB,0CAAE,qBAAqB,KAAI,EAAE,CAAC;IAE7F,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;IAChF,MAAM,gBAAgB,GAAG,CAAC,MAAA,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,qBAAqB,0CAAE,MAAM,mCAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAExE,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,KAAG,EACtB,KAAC,cAAc,KAAG,EAClB,KAAC,gBAAgB,IAAC,gBAAgB,EAAE,gBAAgB,GAAI,EACxD,KAAC,kBAAkB,KAAG,IACN,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';\n\nimport LoadingView from './LoadingView';\nimport DashboardLayout from './DashboardLayout';\n\nimport hooks from './hooks';\nimport './index.scss';\nimport { SubscriptionBanner } from '../SubscriptionBanner';\nimport { DashboardTitle } from './DashboardTitle';\nimport { useInitializeSubsDashboard } from '@src/data/hooks';\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 userSubscriptionStartDate = learnerData?.userSubscription?.subscriptionStartDate || '';\n\n const hasCourses = useMemo(() => data?.subscriptionCourses?.length > 0, [data]);\n const hasCourseHistory = (data?.nonUpgradeableCourses?.length ?? 0) > 0;\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 />\n <DashboardTitle />\n <DashboardContent hasCourseHistory={hasCourseHistory} />\n <PopularCoursePanel />\n </DashboardLayout>\n )}\n </div>\n </div>\n </main>\n </div>\n );\n};\n\nexport default Dashboard;\n"]}
|
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
@use "@openedx/paragon/styles/css/core/custom-media-breakpoints.css";
|
|
2
|
+
$title-color: #002B2B !default;
|
|
3
|
+
$subtitle-color: #454545 !default;
|
|
2
4
|
|
|
3
5
|
.course-list-column {
|
|
4
6
|
padding: 0 var(--pgn-spacing-spacer-4);
|
|
5
|
-
}
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.dashboard-header-title {
|
|
10
|
+
color: $title-color;
|
|
11
|
+
font-size: var(--pgn-typography-font-size-h3-base);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.dashboard-header-subtitle {
|
|
15
|
+
color: $subtitle-color;
|
|
16
|
+
}
|
|
@@ -9,5 +9,15 @@ declare const messages: {
|
|
|
9
9
|
defaultMessage: string;
|
|
10
10
|
description: string;
|
|
11
11
|
};
|
|
12
|
+
dashboardHeaderWelcomeTitle: {
|
|
13
|
+
id: string;
|
|
14
|
+
defaultMessage: string;
|
|
15
|
+
description: string;
|
|
16
|
+
};
|
|
17
|
+
dashboardHeaderWelcomeMessage: {
|
|
18
|
+
id: string;
|
|
19
|
+
defaultMessage: string;
|
|
20
|
+
description: string;
|
|
21
|
+
};
|
|
12
22
|
};
|
|
13
23
|
export default messages;
|
|
@@ -10,6 +10,16 @@ const messages = defineMessages({
|
|
|
10
10
|
defaultMessage: 'Your home for all of your future learning with edX Unlimited.',
|
|
11
11
|
description: 'Subtitle for the subscriber dashboard',
|
|
12
12
|
},
|
|
13
|
+
dashboardHeaderWelcomeTitle: {
|
|
14
|
+
id: 'Dashboard.Header.Welcome.Title',
|
|
15
|
+
defaultMessage: 'Welcome to your learning home.',
|
|
16
|
+
description: 'Welcome message for the subscriber dashboard',
|
|
17
|
+
},
|
|
18
|
+
dashboardHeaderWelcomeMessage: {
|
|
19
|
+
id: 'Dashboard.Header.Welcome.Message',
|
|
20
|
+
defaultMessage: 'Subscriber since {startDate}.',
|
|
21
|
+
description: 'Additional content for the subscriber dashboard',
|
|
22
|
+
},
|
|
13
23
|
});
|
|
14
24
|
export default messages;
|
|
15
25
|
//# sourceMappingURL=messages.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../src/containers/Dashboard/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,QAAQ,GAAG,cAAc,CAAC;IAC9B,cAAc,EAAE;QACd,EAAE,EAAE,iBAAiB;QACrB,cAAc,EAAE,sBAAsB;QACtC,WAAW,EAAE,oCAAoC;KAClD;IACD,iBAAiB,EAAE;QACjB,EAAE,EAAE,oBAAoB;QACxB,cAAc,EAAE,+DAA+D;QAC/E,WAAW,EAAE,uCAAuC;KACrD;CACF,CAAC,CAAC;AAEH,eAAe,QAAQ,CAAC","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n dashboardTitle: {\n id: 'Dashboard.Title',\n defaultMessage: 'Subscriber Dashboard',\n description: 'Title for the subscriber dashboard',\n },\n dashboardSubtitle: {\n id: 'Dashboard.Subtitle',\n defaultMessage: 'Your home for all of your future learning with edX Unlimited.',\n description: 'Subtitle for the subscriber dashboard',\n },\n});\n\nexport default messages;\n"]}
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../src/containers/Dashboard/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,QAAQ,GAAG,cAAc,CAAC;IAC9B,cAAc,EAAE;QACd,EAAE,EAAE,iBAAiB;QACrB,cAAc,EAAE,sBAAsB;QACtC,WAAW,EAAE,oCAAoC;KAClD;IACD,iBAAiB,EAAE;QACjB,EAAE,EAAE,oBAAoB;QACxB,cAAc,EAAE,+DAA+D;QAC/E,WAAW,EAAE,uCAAuC;KACrD;IACD,2BAA2B,EAAE;QAC3B,EAAE,EAAE,gCAAgC;QACpC,cAAc,EAAE,gCAAgC;QAChD,WAAW,EAAE,8CAA8C;KAC5D;IACD,6BAA6B,EAAE;QAC7B,EAAE,EAAE,kCAAkC;QACtC,cAAc,EAAE,+BAA+B;QAC/C,WAAW,EAAE,iDAAiD;KAC/D;CACF,CAAC,CAAC;AAEH,eAAe,QAAQ,CAAC","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n dashboardTitle: {\n id: 'Dashboard.Title',\n defaultMessage: 'Subscriber Dashboard',\n description: 'Title for the subscriber dashboard',\n },\n dashboardSubtitle: {\n id: 'Dashboard.Subtitle',\n defaultMessage: 'Your home for all of your future learning with edX Unlimited.',\n description: 'Subtitle for the subscriber dashboard',\n },\n dashboardHeaderWelcomeTitle: {\n id: 'Dashboard.Header.Welcome.Title',\n defaultMessage: 'Welcome to your learning home.',\n description: 'Welcome message for the subscriber dashboard',\n },\n dashboardHeaderWelcomeMessage: {\n id: 'Dashboard.Header.Welcome.Message',\n defaultMessage: 'Subscriber since {startDate}.',\n description: 'Additional content for the subscriber dashboard',\n },\n});\n\nexport default messages;\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useIntl } from '@openedx/frontend-base';
|
|
3
|
+
import messages from './messages';
|
|
4
|
+
const NoPopularCourseItems = () => {
|
|
5
|
+
const { formatMessage } = useIntl();
|
|
6
|
+
return (_jsx("div", { "data-testid": "no-popular-course-items", children: _jsx("p", { className: "mb-0", children: formatMessage(messages.popularCourseEmptyState) }) }));
|
|
7
|
+
};
|
|
8
|
+
export default NoPopularCourseItems;
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/containers/PopularCoursePanel/NoPopularCourseItems/index.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEjD,OAAO,QAAQ,MAAM,YAAY,CAAC;AAElC,MAAM,oBAAoB,GAAO,GAAG,EAAE;IACpC,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IAEpC,OAAO,CACL,6BAAiB,yBAAyB,YACxC,YAAG,SAAS,EAAC,MAAM,YAAE,aAAa,CAAC,QAAQ,CAAC,uBAAuB,CAAC,GAAK,GACrE,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,oBAAoB,CAAC","sourcesContent":["import { FC } from 'react';\nimport { useIntl } from '@openedx/frontend-base';\n\nimport messages from './messages';\n\nconst NoPopularCourseItems: FC = () => {\n const { formatMessage } = useIntl();\n\n return (\n <div data-testid=\"no-popular-course-items\">\n <p className=\"mb-0\">{formatMessage(messages.popularCourseEmptyState)}</p>\n </div>\n );\n};\n\nexport default NoPopularCourseItems;\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { defineMessages } from '@openedx/frontend-base';
|
|
2
|
+
const messages = defineMessages({
|
|
3
|
+
popularCourseEmptyState: {
|
|
4
|
+
id: 'subs-dash.popularCoursePanel.emptyState',
|
|
5
|
+
defaultMessage: 'When you browse the edX Unlimited catalog, we\'ll show popular courses here.',
|
|
6
|
+
description: 'Placeholder text for popular courses section',
|
|
7
|
+
}
|
|
8
|
+
});
|
|
9
|
+
export default messages;
|
|
10
|
+
//# sourceMappingURL=messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../../src/containers/PopularCoursePanel/NoPopularCourseItems/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,QAAQ,GAAG,cAAc,CAAC;IAC9B,uBAAuB,EAAE;QACvB,EAAE,EAAE,yCAAyC;QAC7C,cAAc,EAAE,8EAA8E;QAC9F,WAAW,EAAE,8CAA8C;KAC5D;CACF,CAAC,CAAC;AAEH,eAAe,QAAQ,CAAC","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n popularCourseEmptyState: {\n id: 'subs-dash.popularCoursePanel.emptyState',\n defaultMessage: 'When you browse the edX Unlimited catalog, we\\'ll show popular courses here.',\n description: 'Placeholder text for popular courses section',\n }\n});\n\nexport default messages;\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { ProductCard } from '../../ProductCard';
|
|
3
|
-
export const
|
|
4
|
-
return (_jsx("div", { "data-testid": "
|
|
3
|
+
export const PopularCourses = ({ items, isLoading }) => {
|
|
4
|
+
return (_jsx("div", { "data-testid": "popular-courses-items", children: _jsx("div", { className: "row g-3 flex-nowrap flex-md-wrap overflow-auto", children: items.map((item) => (_jsx("div", { className: "col-12 col-md-6 col-xl-3 d-flex mb-2", children: _jsx(ProductCard, { item: item, isLoading: isLoading }) }, item.objectID))) }) }));
|
|
5
5
|
};
|
|
6
|
-
export default
|
|
6
|
+
export default PopularCourses;
|
|
7
7
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/containers/PopularCoursePanel/PopularCourses/index.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,MAAM,CAAC,MAAM,cAAc,GAA4B,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE;IAC9E,OAAO,CACL,6BAAiB,uBAAuB,YACtC,cAAK,SAAS,EAAC,gDAAgD,YAC5D,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CACnB,cAAyB,SAAS,EAAC,sCAAsC,YACvE,KAAC,WAAW,IAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,GAAI,IADzC,IAAI,CAAC,QAAQ,CAEjB,CACP,CAAC,GACE,GACF,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,cAAc,CAAC","sourcesContent":["import { FC } from 'react';\n\nimport { ProductCard } from '../../ProductCard';\nimport { PopularCoursesProps } from './data/types';\n\nexport const PopularCourses: FC<PopularCoursesProps> = ({ items, isLoading }) => {\n return (\n <div data-testid=\"popular-courses-items\">\n <div className=\"row g-3 flex-nowrap flex-md-wrap overflow-auto\">\n {items.map((item) => (\n <div key={item.objectID} className=\"col-12 col-md-6 col-xl-3 d-flex mb-2\">\n <ProductCard item={item} isLoading={isLoading} />\n </div>\n ))}\n </div>\n </div>\n );\n};\n\nexport default PopularCourses;\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import { Alert } from '@openedx/paragon';
|
|
4
|
+
import { useIntl } from '@openedx/frontend-base';
|
|
5
|
+
import { usePopularCoursesData } from '../../hooks/usePopularCourses';
|
|
6
|
+
import { useAlgoliaSearch } from '../../utils/algoliaUtils';
|
|
7
|
+
import messages from './messages';
|
|
8
|
+
import NoPopularCourseItems from './NoPopularCourseItems';
|
|
9
|
+
import PopularCourses from './PopularCourses';
|
|
10
|
+
export const PopularCoursePanel = () => {
|
|
11
|
+
const { formatMessage } = useIntl();
|
|
12
|
+
const [searchClient] = useAlgoliaSearch();
|
|
13
|
+
const { data: popularCoursesData = [], isError, isLoading, } = usePopularCoursesData(searchClient, true);
|
|
14
|
+
const hasPopularCoursesData = useMemo(() => popularCoursesData.length > 0, [popularCoursesData]);
|
|
15
|
+
if (isError) {
|
|
16
|
+
return (_jsx("div", { className: "popular-courses-container mt-5 mb-3", "data-testid": "popular-courses-panel", children: _jsx(Alert, { variant: "danger", "data-testid": "popular-courses-error", children: formatMessage(messages.popularCoursesErrorText) }) }));
|
|
17
|
+
}
|
|
18
|
+
return (_jsxs("div", { className: "popular-courses-container mt-5 mb-3", "data-testid": "popular-courses-panel", children: [_jsx("div", { className: "popular-courses-heading-container mb-4", children: _jsx("h2", { children: formatMessage(messages.popularCoursesHeader) }) }), (isLoading || hasPopularCoursesData) ? (_jsx(PopularCourses, { items: popularCoursesData, isLoading: isLoading })) : (_jsx(NoPopularCourseItems, {}))] }));
|
|
19
|
+
};
|
|
20
|
+
export default PopularCoursePanel;
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/containers/PopularCoursePanel/index.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAM,OAAO,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,oBAAoB,MAAM,wBAAwB,CAAC;AAC1D,OAAO,cAAc,MAAM,kBAAkB,CAAC;AAE9C,MAAM,CAAC,MAAM,kBAAkB,GAAO,GAAG,EAAE;IACzC,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,MAAM,CAAC,YAAY,CAAC,GAAG,gBAAgB,EAAE,CAAC;IAC1C,MAAM,EACJ,IAAI,EAAE,kBAAkB,GAAG,EAAE,EAC7B,OAAO,EACP,SAAS,GACV,GAAG,qBAAqB,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IAC9C,MAAM,qBAAqB,GAAG,OAAO,CACnC,GAAG,EAAE,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC,EACnC,CAAC,kBAAkB,CAAC,CACrB,CAAC;IAEF,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CACL,cAAK,SAAS,EAAC,qCAAqC,iBAAa,uBAAuB,YACtF,KAAC,KAAK,IAAC,OAAO,EAAC,QAAQ,iBAAa,uBAAuB,YACxD,aAAa,CAAC,QAAQ,CAAC,uBAAuB,CAAC,GAC1C,GACJ,CACP,CAAC;IACJ,CAAC;IAED,OAAO,CACL,eAAK,SAAS,EAAC,qCAAqC,iBAAa,uBAAuB,aACtF,cAAK,SAAS,EAAC,wCAAwC,YACrD,uBAAK,aAAa,CAAC,QAAQ,CAAC,oBAAoB,CAAC,GAAM,GACnD,EACL,CAAC,SAAS,IAAI,qBAAqB,CAAC,CAAC,CAAC,CAAC,CACtC,KAAC,cAAc,IACb,KAAK,EAAE,kBAAkB,EACzB,SAAS,EAAE,SAAS,GACpB,CACH,CAAC,CAAC,CAAC,CACF,KAAC,oBAAoB,KAAG,CACzB,IACG,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,kBAAkB,CAAC","sourcesContent":["import { FC, useMemo } from 'react';\nimport { Alert } from '@openedx/paragon';\nimport { useIntl } from '@openedx/frontend-base';\n\nimport { usePopularCoursesData } from '@src/hooks/usePopularCourses';\nimport { useAlgoliaSearch } from '@src/utils/algoliaUtils';\nimport messages from './messages';\nimport NoPopularCourseItems from './NoPopularCourseItems';\nimport PopularCourses from './PopularCourses';\n\nexport const PopularCoursePanel: FC = () => {\n const { formatMessage } = useIntl();\n const [searchClient] = useAlgoliaSearch();\n const {\n data: popularCoursesData = [],\n isError,\n isLoading,\n } = usePopularCoursesData(searchClient, true);\n const hasPopularCoursesData = useMemo(\n () => popularCoursesData.length > 0,\n [popularCoursesData]\n );\n\n if (isError) {\n return (\n <div className=\"popular-courses-container mt-5 mb-3\" data-testid=\"popular-courses-panel\">\n <Alert variant=\"danger\" data-testid=\"popular-courses-error\">\n {formatMessage(messages.popularCoursesErrorText)}\n </Alert>\n </div>\n );\n }\n\n return (\n <div className=\"popular-courses-container mt-5 mb-3\" data-testid=\"popular-courses-panel\">\n <div className=\"popular-courses-heading-container mb-4\">\n <h2>{formatMessage(messages.popularCoursesHeader)}</h2>\n </div>\n {(isLoading || hasPopularCoursesData) ? (\n <PopularCourses\n items={popularCoursesData}\n isLoading={isLoading}\n />\n ) : (\n <NoPopularCourseItems />\n )}\n </div>\n );\n};\n\nexport default PopularCoursePanel;\n"]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
declare const messages: {
|
|
2
|
-
|
|
2
|
+
popularCoursesHeader: {
|
|
3
3
|
id: string;
|
|
4
4
|
defaultMessage: string;
|
|
5
5
|
description: string;
|
|
6
6
|
};
|
|
7
|
-
|
|
7
|
+
popularCoursesErrorText: {
|
|
8
8
|
id: string;
|
|
9
9
|
defaultMessage: string;
|
|
10
10
|
description: string;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { defineMessages } from '@openedx/frontend-base';
|
|
2
|
+
const messages = defineMessages({
|
|
3
|
+
popularCoursesHeader: {
|
|
4
|
+
id: 'subs-dash.popularCoursesPanel.header',
|
|
5
|
+
defaultMessage: 'Popular courses',
|
|
6
|
+
description: 'Label for the popular courses section',
|
|
7
|
+
},
|
|
8
|
+
popularCoursesErrorText: {
|
|
9
|
+
id: 'subs-dash.popularCoursesPanel.errorText',
|
|
10
|
+
defaultMessage: 'Failed to load popular courses. Please try again later.',
|
|
11
|
+
description: 'Error text for failing to load popular courses',
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
export default messages;
|
|
15
|
+
//# sourceMappingURL=messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../src/containers/PopularCoursePanel/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,QAAQ,GAAG,cAAc,CAAC;IAC9B,oBAAoB,EAAE;QACpB,EAAE,EAAE,sCAAsC;QAC1C,cAAc,EAAE,iBAAiB;QACjC,WAAW,EAAE,uCAAuC;KACrD;IACD,uBAAuB,EAAE;QACvB,EAAE,EAAE,yCAAyC;QAC7C,cAAc,EAAE,yDAAyD;QACzE,WAAW,EAAE,gDAAgD;KAC9D;CACF,CAAC,CAAC;AAEH,eAAe,QAAQ,CAAC","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n popularCoursesHeader: {\n id: 'subs-dash.popularCoursesPanel.header',\n defaultMessage: 'Popular courses',\n description: 'Label for the popular courses section',\n },\n popularCoursesErrorText: {\n id: 'subs-dash.popularCoursesPanel.errorText',\n defaultMessage: 'Failed to load popular courses. Please try again later.',\n description: 'Error text for failing to load popular courses',\n },\n});\n\nexport default messages;\n"]}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { useIntl } from '@openedx/frontend-base';
|
|
3
|
+
import { Card, Icon } from '@openedx/paragon';
|
|
4
|
+
import { Timelapse, Speed } from '@openedx/paragon/icons';
|
|
4
5
|
import './index.scss';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const truncateText = (value, maxLength) => (value.length > maxLength ? `${value.slice(0, maxLength).trimEnd()}...` : value);
|
|
6
|
+
import cardFallbackImg from '@openedx/brand-openedx/paragon/images/card-imagecap-fallback.png';
|
|
7
|
+
import messages from './messages';
|
|
8
8
|
export const ProductCard = ({ item, isLoading }) => {
|
|
9
|
-
|
|
9
|
+
const { formatMessage } = useIntl();
|
|
10
|
+
return (_jsxs(Card, { className: "shadow-sm d-flex flex-column rounded w-100 overflow-hidden card-container", variant: item.product === 'Course' ? 'light' : 'dark', "data-testid": "product-card", isLoading: isLoading, 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, size: "sm", className: "product-card-title" }), item.partner ? (_jsx(Card.Header, { title: item.partner, className: "d-flex justify-content-between align-items-center", size: "xs" })) : null, _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] })] }));
|
|
10
11
|
};
|
|
11
12
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/containers/ProductCard/index.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,
|
|
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;AAC9C,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,cAAc,CAAC;AACtB,OAAO,eAAe,MAAM,kEAAkE,CAAC;AAE/F,OAAO,QAAQ,MAAM,YAAY,CAAC;AAElC,MAAM,CAAC,MAAM,WAAW,GAAyB,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE;IACvE,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,OAAO,CACL,MAAC,IAAI,IACH,SAAS,EAAC,2EAA2E,EACrF,OAAO,EAAE,IAAI,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,iBACzC,cAAc,EAC1B,SAAS,EAAE,SAAS,aAEpB,KAAC,IAAI,CAAC,MAAM,IAAC,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,SAAS,EAAC,sDAAsD,EAAC,IAAI,EAAC,IAAI,GAAG,EAEpH,cAAK,SAAS,EAAC,mCAAmC,YAChD,KAAC,IAAI,CAAC,QAAQ,IACZ,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,eAAe,EAChC,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,aAAa,iBACtB,oBAAoB,EAChC,OAAO,EAAE,IAAI,CAAC,SAAS,IAAI,EAAE,EAC7B,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,kBAAkB,GACxC,GACE,EAEN,KAAC,IAAI,CAAC,MAAM,IAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAC,IAAI,EAAC,SAAS,EAAC,oBAAoB,GAAG,EAE1E,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CACd,KAAC,IAAI,CAAC,MAAM,IAAC,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,SAAS,EAAC,mDAAmD,EAAC,IAAI,EAAC,IAAI,GAAG,CAC7G,CAAC,CAAC,CAAC,IAAI,EAER,MAAC,IAAI,CAAC,OAAO,IAAC,SAAS,EAAC,qDAAqD,aAC1E,OAAO,IAAI,CAAC,iBAAiB,KAAK,QAAQ,IAAI,CAC7C,gBAAM,SAAS,EAAC,2BAA2B,aACzC,KAAC,IAAI,IAAC,GAAG,EAAE,SAAS,EAAE,SAAS,EAAC,MAAM,GAAG,EACzC,yBAAO,aAAa,CAAC,QAAQ,CAAC,eAAe,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,iBAAiB,EAAE,CAAC,GAAQ,IACpF,CACR,EACA,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CACZ,gBAAM,SAAS,EAAE,4BAA4B,OAAO,IAAI,CAAC,iBAAiB,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,aACtG,KAAC,IAAI,IAAC,GAAG,EAAE,KAAK,EAAE,SAAS,EAAC,MAAM,GAAG,EACrC,yBAAO,aAAa,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,GAAQ,IAC9D,CACR,CAAC,CAAC,CAAC,IAAI,IACK,IAEV,CACR,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { FC } from 'react';\nimport { useIntl } from '@openedx/frontend-base';\nimport { Card, 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\nexport const ProductCard: FC<ProductCardProps> = ({ item, isLoading }) => {\n const { formatMessage } = useIntl();\n return (\n <Card\n className=\"shadow-sm d-flex flex-column rounded w-100 overflow-hidden card-container\"\n variant={item.product === 'Course' ? 'light' : 'dark'}\n data-testid=\"product-card\"\n isLoading={isLoading}\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} size=\"sm\" className=\"product-card-title\" />\n\n {item.partner ? (\n <Card.Header title={item.partner} className=\"d-flex justify-content-between align-items-center\" size=\"xs\" />\n ) : null}\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,6 +1,17 @@
|
|
|
1
|
-
.
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
.product-card-title {
|
|
2
|
+
min-height: 6.4rem;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.card-container > .content-type > .pgn__card-header-content {
|
|
6
|
+
margin-top: 0;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.card-container .pgn__card-logo-cap {
|
|
10
|
+
position: absolute;
|
|
11
|
+
top: 50%;
|
|
12
|
+
transform: translateY(-50%);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.card-container .pgn__card-image-cap {
|
|
16
|
+
border-radius: 0 !important;
|
|
17
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { defineMessages } from '@openedx/frontend-base';
|
|
2
|
+
const messages = defineMessages({
|
|
3
|
+
weeksToComplete: {
|
|
4
|
+
id: 'subs-dash.weeksToComplete.label',
|
|
5
|
+
defaultMessage: '{count, plural, one {# week to complete} other {# weeks to complete}}',
|
|
6
|
+
description: 'Label for the weeks to complete field',
|
|
7
|
+
},
|
|
8
|
+
level: {
|
|
9
|
+
id: 'subs-dash.level.label',
|
|
10
|
+
defaultMessage: '{level} level',
|
|
11
|
+
description: 'Label for the level field',
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
export default messages;
|
|
15
|
+
//# sourceMappingURL=messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../src/containers/ProductCard/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,QAAQ,GAAG,cAAc,CAAC;IAC9B,eAAe,EAAE;QACf,EAAE,EAAE,iCAAiC;QACrC,cAAc,EAAE,uEAAuE;QACvF,WAAW,EAAE,uCAAuC;KACrD;IACD,KAAK,EAAE;QACL,EAAE,EAAE,uBAAuB;QAC3B,cAAc,EAAE,eAAe;QAC/B,WAAW,EAAE,2BAA2B;KACzC;CACF,CAAC,CAAC;AAEH,eAAe,QAAQ,CAAC","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n weeksToComplete: {\n id: 'subs-dash.weeksToComplete.label',\n defaultMessage: '{count, plural, one {# week to complete} other {# weeks to complete}}',\n description: 'Label for the weeks to complete field',\n },\n level: {\n id: 'subs-dash.level.label',\n defaultMessage: '{level} level',\n description: 'Label for the level field',\n },\n});\n\nexport default messages;\n"]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useProgressData } from '../../../../hooks';
|
|
3
|
+
import { useIntl } from '@openedx/frontend-base';
|
|
4
|
+
import { ProgressCard } from '../ProgressCard';
|
|
5
|
+
import messages from '../messages';
|
|
6
|
+
export const InProgressTabData = () => {
|
|
7
|
+
var _a, _b, _c, _d;
|
|
8
|
+
const { programProgressData, isLoading } = useProgressData();
|
|
9
|
+
const { formatMessage } = useIntl();
|
|
10
|
+
const courseData = programProgressData === null || programProgressData === void 0 ? void 0 : programProgressData.courseData;
|
|
11
|
+
const remainingCount = ((_a = courseData === null || courseData === void 0 ? void 0 : courseData.notStarted) === null || _a === void 0 ? void 0 : _a.length) || 0;
|
|
12
|
+
const inProgressData = (courseData === null || courseData === void 0 ? void 0 : courseData.inProgress) || [];
|
|
13
|
+
const completedCount = ((_b = courseData === null || courseData === void 0 ? void 0 : courseData.completed) === null || _b === void 0 ? void 0 : _b.length) || 0;
|
|
14
|
+
const inProgressCount = inProgressData.length;
|
|
15
|
+
const programType = ((_c = programProgressData === null || programProgressData === void 0 ? void 0 : programProgressData.programData) === null || _c === void 0 ? void 0 : _c.type) || '';
|
|
16
|
+
const checkoutUrl = ((_d = programProgressData === null || programProgressData === void 0 ? void 0 : programProgressData.urls) === null || _d === void 0 ? void 0 : _d.buyButtonUrl) || '';
|
|
17
|
+
const inProgressTabType = formatMessage(messages.programProgressInProgressTab).toLowerCase();
|
|
18
|
+
const shouldShowRemainingMessage = !inProgressCount && remainingCount > 0;
|
|
19
|
+
const shouldShowCompletedMessage = !inProgressCount && !remainingCount && completedCount > 0;
|
|
20
|
+
const progressCards = inProgressData.map((course) => {
|
|
21
|
+
const courseRuns = course.courseRuns || [];
|
|
22
|
+
const [{ pacingType = '', start = '', end = '', courseUrl = '', upgradeUrl = '', seats = [] } = {}] = Array.isArray(courseRuns) ? courseRuns : [];
|
|
23
|
+
const progressCardData = {
|
|
24
|
+
title: course.title,
|
|
25
|
+
start: start,
|
|
26
|
+
end: end || '',
|
|
27
|
+
pacingType: pacingType,
|
|
28
|
+
courseUrl: courseUrl || '',
|
|
29
|
+
upgradeUrl: upgradeUrl || '',
|
|
30
|
+
programType: programType || '',
|
|
31
|
+
checkoutUrl: checkoutUrl || '',
|
|
32
|
+
seats: seats || [],
|
|
33
|
+
expired: course.expired || false, // using expired from course object to determine if the course is expired as per condition on confluence and learners dashboard code.
|
|
34
|
+
};
|
|
35
|
+
return (_jsx(ProgressCard, { progressCardData: progressCardData, isLoading: isLoading, tabType: inProgressTabType }, course.key));
|
|
36
|
+
});
|
|
37
|
+
return (_jsxs("div", { children: [_jsx("h5", { children: formatMessage(messages.programProgressInProgressCourse) }), inProgressCount > 0 ? (progressCards) : shouldShowRemainingMessage ? (_jsx("p", { children: formatMessage(messages.programProgressInProgressRemainingCourses) })) : shouldShowCompletedMessage ? (_jsx("p", { children: formatMessage(messages.programProgressInProgressCompletedCourses) })) : null] }));
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/containers/ProgramDashboard/ProgramProgress/InProgressTabData/index.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEjD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,QAAQ,MAAM,aAAa,CAAC;AAEnC,MAAM,CAAC,MAAM,iBAAiB,GAAO,GAAG,EAAE;;IACxC,MAAM,EAAE,mBAAmB,EAAE,SAAS,EAAE,GAAG,eAAe,EAAE,CAAC;IAE7D,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,MAAM,UAAU,GAAG,mBAAmB,aAAnB,mBAAmB,uBAAnB,mBAAmB,CAAE,UAAU,CAAC;IACnD,MAAM,cAAc,GAAG,CAAA,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,UAAU,0CAAE,MAAM,KAAI,CAAC,CAAC;IAC3D,MAAM,cAAc,GAAG,CAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,UAAU,KAAI,EAAE,CAAC;IACpD,MAAM,cAAc,GAAG,CAAA,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,SAAS,0CAAE,MAAM,KAAI,CAAC,CAAC;IAC1D,MAAM,eAAe,GAAG,cAAc,CAAC,MAAM,CAAC;IAC9C,MAAM,WAAW,GAAG,CAAA,MAAA,mBAAmB,aAAnB,mBAAmB,uBAAnB,mBAAmB,CAAE,WAAW,0CAAE,IAAI,KAAI,EAAE,CAAC;IACjE,MAAM,WAAW,GAAG,CAAA,MAAA,mBAAmB,aAAnB,mBAAmB,uBAAnB,mBAAmB,CAAE,IAAI,0CAAE,YAAY,KAAI,EAAE,CAAC;IAClE,MAAM,iBAAiB,GAAG,aAAa,CAAC,QAAQ,CAAC,4BAA4B,CAAC,CAAC,WAAW,EAAE,CAAC;IAE7F,MAAM,0BAA0B,GAAG,CAAC,eAAe,IAAI,cAAc,GAAG,CAAC,CAAC;IAC1E,MAAM,0BAA0B,GAAG,CAAC,eAAe,IAAI,CAAC,cAAc,IAAI,cAAc,GAAG,CAAC,CAAC;IAE7F,MAAM,aAAa,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QAClD,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC;QAC3C,MAAM,CAAC,EAAE,UAAU,GAAG,EAAE,EAAE,KAAK,GAAG,EAAE,EAAE,GAAG,GAAG,EAAE,EAAE,SAAS,GAAG,EAAE,EAAE,UAAU,GAAG,EAAE,EAAE,KAAK,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;QAElJ,MAAM,gBAAgB,GAAG;YACvB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,KAAK,EAAE,KAAK;YACZ,GAAG,EAAE,GAAG,IAAI,EAAE;YACd,UAAU,EAAE,UAAU;YACtB,SAAS,EAAE,SAAS,IAAI,EAAE;YAC1B,UAAU,EAAE,UAAU,IAAI,EAAE;YAC5B,WAAW,EAAE,WAAW,IAAI,EAAE;YAC9B,WAAW,EAAE,WAAW,IAAI,EAAE;YAC9B,KAAK,EAAE,KAAK,IAAI,EAAE;YAClB,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,KAAK,EAAE,qIAAqI;SACxK,CAAC;QAEF,OAAO,CACL,KAAC,YAAY,IAEX,gBAAgB,EAAE,gBAAgB,EAClC,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,iBAAiB,IAHrB,MAAM,CAAC,GAAG,CAIf,CACH,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,0BACE,uBAAK,aAAa,CAAC,QAAQ,CAAC,+BAA+B,CAAC,GAAM,EACjE,eAAe,GAAG,CAAC,CAAC,CAAC,CAAC,CACrB,aAAa,CACd,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,CAC/B,sBAAI,aAAa,CAAC,QAAQ,CAAC,yCAAyC,CAAC,GAAK,CAC3E,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,CAC/B,sBAAI,aAAa,CAAC,QAAQ,CAAC,yCAAyC,CAAC,GAAK,CAC3E,CAAC,CAAC,CAAC,IAAI,IACJ,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { FC } from 'react';\nimport { useProgressData } from '@src/hooks';\nimport { useIntl } from '@openedx/frontend-base';\n\nimport { ProgressCard } from '../ProgressCard';\nimport messages from '../messages';\n\nexport const InProgressTabData: FC = () => {\n const { programProgressData, isLoading } = useProgressData();\n\n const { formatMessage } = useIntl();\n const courseData = programProgressData?.courseData;\n const remainingCount = courseData?.notStarted?.length || 0;\n const inProgressData = courseData?.inProgress || [];\n const completedCount = courseData?.completed?.length || 0;\n const inProgressCount = inProgressData.length;\n const programType = programProgressData?.programData?.type || '';\n const checkoutUrl = programProgressData?.urls?.buyButtonUrl || '';\n const inProgressTabType = formatMessage(messages.programProgressInProgressTab).toLowerCase();\n\n const shouldShowRemainingMessage = !inProgressCount && remainingCount > 0;\n const shouldShowCompletedMessage = !inProgressCount && !remainingCount && completedCount > 0;\n\n const progressCards = inProgressData.map((course) => {\n const courseRuns = course.courseRuns || [];\n const [{ pacingType = '', start = '', end = '', courseUrl = '', upgradeUrl = '', seats = [] } = {}] = Array.isArray(courseRuns) ? courseRuns : [];\n\n const progressCardData = {\n title: course.title,\n start: start,\n end: end || '',\n pacingType: pacingType,\n courseUrl: courseUrl || '',\n upgradeUrl: upgradeUrl || '',\n programType: programType || '',\n checkoutUrl: checkoutUrl || '',\n seats: seats || [],\n expired: course.expired || false, // using expired from course object to determine if the course is expired as per condition on confluence and learners dashboard code.\n };\n\n return (\n <ProgressCard\n key={course.key}\n progressCardData={progressCardData}\n isLoading={isLoading}\n tabType={inProgressTabType}\n />\n );\n });\n\n return (\n <div>\n <h5>{formatMessage(messages.programProgressInProgressCourse)}</h5>\n {inProgressCount > 0 ? (\n progressCards\n ) : shouldShowRemainingMessage ? (\n <p>{formatMessage(messages.programProgressInProgressRemainingCourses)}</p>\n ) : shouldShowCompletedMessage ? (\n <p>{formatMessage(messages.programProgressInProgressCompletedCourses)}</p>\n ) : null}\n </div>\n );\n};\n"]}
|
|
@@ -5,6 +5,7 @@ import { useIntl } from '@openedx/frontend-base';
|
|
|
5
5
|
import messages from '../messages';
|
|
6
6
|
import { RemainingTabData } from '../RemainingTabData';
|
|
7
7
|
import { CompletedTabData } from '../CompletedTabData';
|
|
8
|
+
import { InProgressTabData } from '../InProgressTabData';
|
|
8
9
|
export const ProgramProgressTabs = ({ type, counts }) => {
|
|
9
10
|
const { inProgress, remaining, completed } = counts;
|
|
10
11
|
const { formatMessage } = useIntl();
|
|
@@ -13,7 +14,7 @@ export const ProgramProgressTabs = ({ type, counts }) => {
|
|
|
13
14
|
key: 'in-progress',
|
|
14
15
|
title: formatMessage(messages.programProgressInProgressTab),
|
|
15
16
|
count: inProgress,
|
|
16
|
-
panel: _jsx(
|
|
17
|
+
panel: _jsx(InProgressTabData, {}),
|
|
17
18
|
},
|
|
18
19
|
{
|
|
19
20
|
key: 'remaining',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/containers/ProgramDashboard/ProgramProgress/ProgramProgressTabs/index.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAM,QAAQ,EAAE,MAAM,OAAO,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAGjD,OAAO,QAAQ,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/containers/ProgramDashboard/ProgramProgress/ProgramProgressTabs/index.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAM,QAAQ,EAAE,MAAM,OAAO,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAGjD,OAAO,QAAQ,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEzD,MAAM,CAAC,MAAM,mBAAmB,GAAiC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE;IACpF,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IACpD,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IAEpC,MAAM,QAAQ,GAA8B;QAC1C;YACE,GAAG,EAAE,aAAa;YAClB,KAAK,EAAE,aAAa,CAAC,QAAQ,CAAC,4BAA4B,CAAC;YAC3D,KAAK,EAAE,UAAU;YACjB,KAAK,EAAE,KAAC,iBAAiB,KAAG;SAC7B;QACD;YACE,GAAG,EAAE,WAAW;YAChB,KAAK,EAAE,aAAa,CAAC,QAAQ,CAAC,2BAA2B,CAAC;YAC1D,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE,KAAC,gBAAgB,KAAG;SAC5B;QACD;YACE,GAAG,EAAE,WAAW;YAChB,KAAK,EAAE,aAAa,CAAC,QAAQ,CAAC,2BAA2B,CAAC;YAC1D,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE,KAAC,gBAAgB,KAAG;SAC5B;QACD,GAAG,CAAC,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,WAAW,EAAE,MAAK,cAAc;YACxC,CAAC,CAAC,CAAC;oBACC,GAAG,EAAE,UAAU;oBACf,KAAK,EAAE,aAAa,CAAC,QAAQ,CAAC,0BAA0B,CAAC;oBACzD,KAAK,EAAE,uEAAsD;iBAC9D,CAAC;YACJ,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;IAEF,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAS,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAEpE,MAAM,eAAe,GAAG,CAAC,MAAqB,EAAE,EAAE;QAChD,IAAI,MAAM;YAAE,YAAY,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC,CAAC;IAEF,OAAO,CACL,KAAC,IAAI,IACH,EAAE,EAAC,uBAAuB,EAC1B,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,eAAe,EACzB,SAAS,EAAC,MAAM,EAChB,YAAY,kBAEX,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CACnB,KAAC,GAAG,IAAC,QAAQ,EAAE,GAAG,CAAC,GAAG,EAAgB,KAAK,EAAE,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,KAAK,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,YAC7G,GAAG,CAAC,KAAK,IADiB,GAAG,CAAC,GAAG,CAE9B,CACP,CAAC,GACG,CACR,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { FC, useState } from 'react';\nimport { Tabs, Tab } from '@openedx/paragon';\nimport { useIntl } from '@openedx/frontend-base';\n\nimport { ProgramProgressTabsProps, ProgramProgressTabItems } from '../../data/types';\nimport messages from '../messages';\nimport { RemainingTabData } from '../RemainingTabData';\nimport { CompletedTabData } from '../CompletedTabData';\nimport { InProgressTabData } from '../InProgressTabData';\n\nexport const ProgramProgressTabs: FC<ProgramProgressTabsProps> = ({ type, counts }) => {\n const { inProgress, remaining, completed } = counts;\n const { formatMessage } = useIntl();\n\n const tabsData: ProgramProgressTabItems[] = [\n {\n key: 'in-progress',\n title: formatMessage(messages.programProgressInProgressTab),\n count: inProgress,\n panel: <InProgressTabData />,\n },\n {\n key: 'remaining',\n title: formatMessage(messages.programProgressRemainingTab),\n count: remaining,\n panel: <RemainingTabData />,\n },\n {\n key: 'completed',\n title: formatMessage(messages.programProgressCompletedTab),\n count: completed,\n panel: <CompletedTabData />,\n },\n ...(type?.toLowerCase() === 'micromasters'\n ? [{\n key: 'pathways',\n title: formatMessage(messages.programProgressPathwaysTab),\n panel: <span>Pathways tab data will be available soon.</span>,\n }]\n : []),\n ];\n\n const [activeTab, setActiveTab] = useState<string>(tabsData[0].key);\n\n const handleTabSelect = (tabKey: string | null) => {\n if (tabKey) setActiveTab(tabKey);\n };\n\n return (\n <Tabs\n id=\"program-progress-tabs\"\n activeKey={activeTab}\n onSelect={handleTabSelect}\n className=\"mb-4\"\n mountOnEnter\n >\n {tabsData.map(tab => (\n <Tab eventKey={tab.key} key={tab.key} title={tab.count !== undefined ? `${tab.title} (${tab.count})` : tab.title}>\n {tab.panel}\n </Tab>\n ))}\n </Tabs>\n );\n};\n"]}
|
|
@@ -6,9 +6,15 @@ import './index.scss';
|
|
|
6
6
|
import { ProgressCardActions } from '../ProgressCardActions';
|
|
7
7
|
import { dateFormatter } from '../../../../utils/dateFormatter';
|
|
8
8
|
import { ProgressCardButton } from '../ProgressCardActions/ProgressCardButton';
|
|
9
|
+
import { PROGRAM_TYPE_MAP } from '../../data/constants';
|
|
10
|
+
import { getCertificatePriceString } from '../../data/util';
|
|
9
11
|
export const ProgressCard = ({ progressCardData, isLoading, tabType }) => {
|
|
10
12
|
const { formatMessage, formatDate } = useIntl();
|
|
11
|
-
const { title, pacingType, start, end, certificateUrl, courseUrl } = progressCardData;
|
|
13
|
+
const { title, pacingType, start, end, certificateUrl, courseUrl, upgradeUrl, programType, checkoutUrl, expired, seats } = progressCardData;
|
|
14
|
+
const inProgressTabKey = formatMessage(messages.programProgressInProgressTab).toLowerCase();
|
|
15
|
+
const isInProgressTab = tabType === inProgressTabKey;
|
|
16
|
+
const isProfessionalProgram = programType === PROGRAM_TYPE_MAP.PROFESSIONAL_CERTIFICATE;
|
|
17
|
+
const isMicroMastersProgram = programType === PROGRAM_TYPE_MAP.MICROMASTERS;
|
|
12
18
|
/*
|
|
13
19
|
- Formatting pacing type safely
|
|
14
20
|
- replace underscores with spaces
|
|
@@ -30,8 +36,20 @@ export const ProgressCard = ({ progressCardData, isLoading, tabType }) => {
|
|
|
30
36
|
? `${enrollmentInfo} ${formatMessage(messages.programProgressCardStartText)} ${startDate}`
|
|
31
37
|
: `${formatMessage(messages.programProgressCardStartText)} ${startDate}`;
|
|
32
38
|
}
|
|
39
|
+
// using expired key from course object to determine if the course is expired as per condition on confluence and learners dashboard code.
|
|
40
|
+
const canUpgrade = Boolean(upgradeUrl) && !expired;
|
|
33
41
|
return (_jsx(Card, { className: "progress-card mb-3", "data-testid": "progress-card", isLoading: isLoading, children: _jsxs(Card.Section, { className: "pt-3 pb-2 px-4", children: [_jsxs(Row, { className: "mb-2", children: [_jsxs(Col, { xs: 12, children: [_jsx("h4", { className: "mb-1 font-weight-bold", children: title }), _jsx("div", { className: "text-muted", children: enrollmentInfo })] }), _jsx(ProgressCardActions, { tabType: tabType, redirectUrl: courseUrl })] }), tabType === (formatMessage(messages.programProgressCompletedTab).toLowerCase()) && (_jsx(Row, { className: "pt-3 pb-2 px-2 border-top border-2 border-muted mb-2 align-items-center", children: _jsxs(Col, { xs: 12, className: "d-flex justify-content-between align-items-center px-0", children: [_jsx("span", { className: "text-start", children: end && (formatMessage(messages.programProgressCardCompletedCertificateText, {
|
|
34
42
|
certificateDate: (end ? dateFormatter(formatDate, end, 'short') : ''),
|
|
35
|
-
})) }), _jsx(ProgressCardButton, { variant: "brand", redirectUrl: certificateUrl || '', buttonText: formatMessage(messages.programProgressCardCompletedCertificateButton) })] }) }))
|
|
43
|
+
})) }), _jsx(ProgressCardButton, { variant: "brand", redirectUrl: certificateUrl || '', buttonText: formatMessage(messages.programProgressCardCompletedCertificateButton) })] }) })), isInProgressTab && (_jsx(Row, { className: "pt-3 pb-2 px-2 border-top border-2 border-muted mb-2 align-items-center", children: _jsxs(Col, { xs: 12, className: "d-flex justify-content-between align-items-center px-0", children: [_jsx("span", { className: "text-start", children: formatMessage(messages.programProgressInProgressCertificateStatus, {
|
|
44
|
+
status: canUpgrade ? formatMessage(messages.programProgressInProgressCertificateNeedsVerified) : formatMessage(messages.programProgressInProgressCertificateNotEarned), // TODO : Certificate status will change after Upgrade is successful through api
|
|
45
|
+
}) }), isProfessionalProgram
|
|
46
|
+
&& canUpgrade
|
|
47
|
+
&& getCertificatePriceString(seats)
|
|
48
|
+
&& (_jsx(ProgressCardButton, { variant: "brand", redirectUrl: "", buttonText: formatMessage(messages.programProgressCardUpgradeButton), type: "upgrade", title: title, price: getCertificatePriceString(seats), courseUrl: courseUrl })), isMicroMastersProgram
|
|
49
|
+
&& checkoutUrl
|
|
50
|
+
&& canUpgrade
|
|
51
|
+
&& (_jsx(ProgressCardButton, { variant: "brand", redirectUrl: checkoutUrl, buttonText: formatMessage(messages.programProgressInProgressCourseMicromastersUpgrade, {
|
|
52
|
+
price: getCertificatePriceString(seats, true),
|
|
53
|
+
}) }))] }) }))] }) }));
|
|
36
54
|
};
|
|
37
55
|
//# sourceMappingURL=index.js.map
|