@edx/frontend-app-subscription-learner-dashboard 1.53.0 → 1.53.1
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/ProductCard/index.js +3 -2
- package/dist/containers/ProductCard/index.js.map +1 -1
- package/dist/containers/ProductCard/messages.d.ts +5 -0
- package/dist/containers/ProductCard/messages.js +5 -0
- package/dist/containers/ProductCard/messages.js.map +1 -1
- package/dist/containers/ProgramDashboard/ProgramsList/ProgramListCard.js +2 -2
- package/dist/containers/ProgramDashboard/ProgramsList/ProgramListCard.js.map +1 -1
- package/dist/containers/ProgramDashboard/ProgramsList/index.scss +5 -18
- package/dist/hooks/usePopularCoursesAndPrograms.js +3 -2
- package/dist/hooks/usePopularCoursesAndPrograms.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useIntl } from '@openedx/frontend-base';
|
|
3
3
|
import { Card, Hyperlink, Icon } from '@openedx/paragon';
|
|
4
|
-
import { Timelapse, Speed } from '@openedx/paragon/icons';
|
|
4
|
+
import { Timelapse, Speed, FormatListNumbered } from '@openedx/paragon/icons';
|
|
5
5
|
import './index.scss';
|
|
6
6
|
import cardFallbackImg from '@openedx/brand-openedx/paragon/images/card-imagecap-fallback.png';
|
|
7
7
|
import messages from './messages';
|
|
@@ -20,6 +20,7 @@ const getIdentifyingUrlPath = (marketingUrl) => {
|
|
|
20
20
|
export const ProductCard = ({ item, isLoading }) => {
|
|
21
21
|
const { formatMessage } = useIntl();
|
|
22
22
|
const identifyingUrlPath = getIdentifyingUrlPath(item.marketing_url);
|
|
23
|
-
|
|
23
|
+
const totalProgramCourses = item.product === 'program' && item.subject && item.subject.length ? item.subject.length : 0;
|
|
24
|
+
return (_jsxs(Card, { className: "shadow-sm d-flex flex-column rounded w-100 overflow-hidden align-items-stretch card-container", variant: "light", "data-testid": "product-card", isLoading: isLoading, as: identifyingUrlPath ? Hyperlink : 'div', destination: identifyingUrlPath ? `/subscription-enroll/${identifyingUrlPath}` : undefined, children: [_jsx(Card.Header, { title: item.product === 'program' ? `${item.content_type}` : 'Course', className: "pb-2 pt-2 bg-light-500 text-primary-500 content-type", size: "xs" }), _jsx("div", { className: "position-relative image-container", children: _jsx(Card.ImageCap, { src: item.url || cardFallbackImg, srcAlt: `${item.title} main-image`, "data-testid": "product-card-image", logoSrc: item.thumbnail || '', logoAlt: `${item.title} thumbnail-image` }) }), _jsx(Card.Header, { title: item.title, subtitle: item.partner, size: "sm", className: "product-card-title" }), _jsxs(Card.Section, { className: "d-flex flex-column flex-grow-1 overflow-hidden mt-5", children: [totalProgramCourses > 0 ? (_jsxs("span", { className: "d-flex align-items-center mb-2", children: [_jsx(Icon, { src: FormatListNumbered, className: "mr-2" }), _jsx("span", { children: formatMessage(messages.courses, { count: totalProgramCourses }) })] })) : null, typeof item.weeks_to_complete === 'number' && (_jsxs("span", { className: "d-flex align-items-center mb-2", 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] })] }));
|
|
24
25
|
};
|
|
25
26
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/containers/ProductCard/index.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;
|
|
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,SAAS,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,cAAc,CAAC;AACtB,OAAO,eAAe,MAAM,kEAAkE,CAAC;AAE/F,OAAO,QAAQ,MAAM,YAAY,CAAC;AAElC,MAAM,qBAAqB,GAAG,CAAC,YAAoB,EAAiB,EAAE;IACpE,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACvF,OAAO,IAAI,IAAI,IAAI,CAAC;IACtB,CAAC;IAAC,WAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAyB,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE;IACvE,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,MAAM,kBAAkB,GAAG,qBAAqB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACrE,MAAM,mBAAmB,GAAG,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAExH,OAAO,CACL,MAAC,IAAI,IACH,SAAS,EAAC,+FAA+F,EACzG,OAAO,EAAC,OAAO,iBACH,cAAc,EAC1B,SAAS,EAAE,SAAS,EACpB,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,EAC1C,WAAW,EAAE,kBAAkB,CAAC,CAAC,CAAC,wBAAwB,kBAAkB,EAAE,CAAC,CAAC,CAAC,SAAS,aAE1F,KAAC,IAAI,CAAC,MAAM,IAAC,KAAK,EAAE,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAC,sDAAsD,EAAC,IAAI,EAAC,IAAI,GAAG,EAEjK,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,QAAQ,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,EAAC,IAAI,EAAC,SAAS,EAAC,oBAAoB,GAAG,EAEnG,MAAC,IAAI,CAAC,OAAO,IAAC,SAAS,EAAC,qDAAqD,aAC1E,mBAAmB,GAAG,CAAC,CAAC,CAAC,CAAC,CACzB,gBAAM,SAAS,EAAC,gCAAgC,aAC9C,KAAC,IAAI,IAAC,GAAG,EAAE,kBAAkB,EAAE,SAAS,EAAC,MAAM,GAAG,EAClD,yBAAO,aAAa,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,GAAQ,IACzE,CACR,CAAC,CAAC,CAAC,IAAI,EACP,OAAO,IAAI,CAAC,iBAAiB,KAAK,QAAQ,IAAI,CAC7C,gBAAM,SAAS,EAAC,gCAAgC,aAC9C,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, Hyperlink, Icon } from '@openedx/paragon';\nimport { Timelapse, Speed, FormatListNumbered } from '@openedx/paragon/icons';\nimport './index.scss';\nimport cardFallbackImg from '@openedx/brand-openedx/paragon/images/card-imagecap-fallback.png';\nimport { ProductCardProps } from './data/types';\nimport messages from './messages';\n\nconst getIdentifyingUrlPath = (marketingUrl: string): string | null => {\n if (!marketingUrl) {\n return null;\n }\n try {\n const path = new URL(marketingUrl, window.location.origin).pathname.replace(/^\\//, '');\n return path || null;\n } catch {\n return null;\n }\n};\n\nexport const ProductCard: FC<ProductCardProps> = ({ item, isLoading }) => {\n const { formatMessage } = useIntl();\n const identifyingUrlPath = getIdentifyingUrlPath(item.marketing_url);\n const totalProgramCourses = item.product === 'program' && item.subject && item.subject.length ? item.subject.length : 0;\n\n return (\n <Card\n className=\"shadow-sm d-flex flex-column rounded w-100 overflow-hidden align-items-stretch card-container\"\n variant=\"light\"\n data-testid=\"product-card\"\n isLoading={isLoading}\n as={identifyingUrlPath ? Hyperlink : 'div'}\n destination={identifyingUrlPath ? `/subscription-enroll/${identifyingUrlPath}` : undefined}\n >\n <Card.Header title={item.product === 'program' ? `${item.content_type}` : 'Course'} className=\"pb-2 pt-2 bg-light-500 text-primary-500 content-type\" size=\"xs\" />\n\n <div className=\"position-relative image-container\">\n <Card.ImageCap\n src={item.url || cardFallbackImg}\n srcAlt={`${item.title} main-image`}\n data-testid=\"product-card-image\"\n logoSrc={item.thumbnail || ''}\n logoAlt={`${item.title} thumbnail-image`}\n />\n </div>\n\n <Card.Header title={item.title} subtitle={item.partner} size=\"sm\" className=\"product-card-title\" />\n\n <Card.Section className=\"d-flex flex-column flex-grow-1 overflow-hidden mt-5\">\n {totalProgramCourses > 0 ? (\n <span className=\"d-flex align-items-center mb-2\">\n <Icon src={FormatListNumbered} className=\"mr-2\" />\n <span>{formatMessage(messages.courses, { count: totalProgramCourses })}</span>\n </span>\n ) : null}\n {typeof item.weeks_to_complete === 'number' && (\n <span className=\"d-flex align-items-center mb-2\">\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"]}
|
|
@@ -10,6 +10,11 @@ const messages = defineMessages({
|
|
|
10
10
|
defaultMessage: '{level} level',
|
|
11
11
|
description: 'Label for the level field',
|
|
12
12
|
},
|
|
13
|
+
courses: {
|
|
14
|
+
id: 'subs-dash.courses.label',
|
|
15
|
+
defaultMessage: '{count, plural, one {# course} other {# courses}}',
|
|
16
|
+
description: 'Label for the courses field',
|
|
17
|
+
},
|
|
13
18
|
});
|
|
14
19
|
export default messages;
|
|
15
20
|
//# sourceMappingURL=messages.js.map
|
|
@@ -1 +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"]}
|
|
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;IACD,OAAO,EAAE;QACP,EAAE,EAAE,yBAAyB;QAC7B,cAAc,EAAE,mDAAmD;QACnE,WAAW,EAAE,6BAA6B;KAC3C;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 courses: {\n id: 'subs-dash.courses.label',\n defaultMessage: '{count, plural, one {# course} other {# courses}}',\n description: 'Label for the courses field',\n },\n});\n\nexport default messages;\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Link } from 'react-router-dom';
|
|
3
|
-
import { breakpoints, useWindowSize, Card,
|
|
3
|
+
import { breakpoints, useWindowSize, Card, } from '@openedx/paragon';
|
|
4
4
|
import programCardFallbackImage from '../assets/program-card-fallback.svg';
|
|
5
5
|
import ProgressCategoryBubbles from './ProgressCategoryBubbles';
|
|
6
6
|
const ProgramListCard = ({ program, }) => {
|
|
@@ -36,7 +36,7 @@ const ProgramListCard = ({ program, }) => {
|
|
|
36
36
|
}
|
|
37
37
|
return '';
|
|
38
38
|
};
|
|
39
|
-
return (_jsxs(Card, { className: "program-list-card mb-4 mr-4", isClickable: true, as: Link, to: `/subscription-program-progress/${program.uuid}`, "data-testid": "program-list-card", children: [_jsx(Card.ImageCap, { src: getBannerImageURL() || programCardFallbackImage, srcAlt: `program card image for ${program.title}`, logoSrc: getOrgImageUrl(), logoAlt: program.authoringOrganizations && ((_a = program.authoringOrganizations[0]) === null || _a === void 0 ? void 0 : _a.key), className: "banner-image" }), _jsx(Card.Section, { className: "pb-0
|
|
39
|
+
return (_jsxs(Card, { className: "program-list-card mb-4 mr-4", isClickable: true, as: Link, to: `/subscription-program-progress/${program.uuid}`, "data-testid": "program-list-card", children: [_jsx(Card.ImageCap, { src: getBannerImageURL() || programCardFallbackImage, srcAlt: `program card image for ${program.title}`, logoSrc: getOrgImageUrl(), logoAlt: program.authoringOrganizations && ((_a = program.authoringOrganizations[0]) === null || _a === void 0 ? void 0 : _a.key), className: "banner-image" }), _jsx(Card.Section, { className: "pb-0", children: _jsx("h3", { children: program.title }) }), _jsxs(Card.Section, { className: "d-flex flex-column flex-grow-1 overflow-hidden", children: [program.authoringOrganizations && (_jsx("span", { className: "d-flex align-items-center mb-1", children: program.authoringOrganizations.map(org => org.key).join(', ') })), _jsx("span", { className: "d-flex align-items-center program-type", children: program.type })] }), _jsx(Card.Section, { className: "pt-0", children: _jsx(ProgressCategoryBubbles, { inProgress: program.progress.inProgress, notStarted: program.progress.notStarted, completed: program.progress.completed }) })] }));
|
|
40
40
|
};
|
|
41
41
|
export default ProgramListCard;
|
|
42
42
|
//# sourceMappingURL=ProgramListCard.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProgramListCard.js","sourceRoot":"","sources":["../../../../src/containers/ProgramDashboard/ProgramsList/ProgramListCard.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EACL,WAAW,EACX,aAAa,EACb,IAAI,
|
|
1
|
+
{"version":3,"file":"ProgramListCard.js","sourceRoot":"","sources":["../../../../src/containers/ProgramDashboard/ProgramsList/ProgramListCard.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport { Link } from 'react-router-dom';\nimport {\n breakpoints,\n useWindowSize,\n Card,\n} from '@openedx/paragon';\nimport programCardFallbackImage from '../assets/program-card-fallback.svg';\nimport { ProgramCardProps } from '../data/types';\nimport ProgressCategoryBubbles from './ProgressCategoryBubbles';\n\nconst ProgramListCard: React.FC<ProgramCardProps> = ({\n program,\n}) => {\n const { width: windowWidth } = useWindowSize();\n\n const getBannerImageURL = (): string => {\n let imageURL = '';\n // We need to check that the breakpoint value exists before using it\n // Otherwise TypeScript will flag it as it can potentially be undefined in Paragon\n if (program.bannerImage && Object.keys(program.bannerImage).length > 0) {\n if (!windowWidth) {\n return program.bannerImage.medium.url;\n }\n\n if (typeof breakpoints.large.minWidth === 'number' && windowWidth >= breakpoints.large.minWidth) {\n imageURL = program.bannerImage.large.url;\n } else if (typeof breakpoints.medium.minWidth === 'number' && windowWidth >= breakpoints.medium.minWidth) {\n imageURL = program.bannerImage.medium.url;\n } else if (typeof breakpoints.small.minWidth === 'number' && windowWidth >= breakpoints.small.minWidth) {\n imageURL = program.bannerImage.small.url;\n } else {\n imageURL = program.bannerImage.xSmall.url;\n }\n }\n return imageURL;\n };\n\n const getOrgImageUrl = (): string => {\n if (program.authoringOrganizations?.length === 1 && program.authoringOrganizations[0].logoImageUrl) {\n return program.authoringOrganizations[0].logoImageUrl;\n }\n return '';\n };\n\n return (\n <Card\n className=\"program-list-card mb-4 mr-4\"\n isClickable\n as={Link}\n to={`/subscription-program-progress/${program.uuid}`}\n data-testid=\"program-list-card\"\n >\n <Card.ImageCap\n src={getBannerImageURL() || programCardFallbackImage}\n srcAlt={`program card image for ${program.title}`}\n logoSrc={getOrgImageUrl()}\n logoAlt={program.authoringOrganizations && program.authoringOrganizations[0]?.key}\n className=\"banner-image\"\n />\n <Card.Section className=\"pb-0\">\n <h3>{program.title}</h3>\n </Card.Section>\n <Card.Section className=\"d-flex flex-column flex-grow-1 overflow-hidden\">\n {program.authoringOrganizations && (\n <span className=\"d-flex align-items-center mb-1\">\n {program.authoringOrganizations.map(org => org.key).join(', ')}\n </span>\n )}\n <span className=\"d-flex align-items-center program-type\">\n {program.type}\n </span>\n </Card.Section>\n <Card.Section className=\"pt-0\">\n <ProgressCategoryBubbles\n inProgress={program.progress.inProgress}\n notStarted={program.progress.notStarted}\n completed={program.progress.completed}\n />\n </Card.Section>\n </Card>\n );\n};\nexport default ProgramListCard;\n"]}
|
|
@@ -1,21 +1,8 @@
|
|
|
1
|
-
// The current Truncate component in Paragon is deprecated and soon to be removed
|
|
2
|
-
// See https://github.com/openedx/paragon/issues/3311 for developments on this issue
|
|
3
|
-
|
|
4
|
-
.truncate-text-1 {
|
|
5
|
-
overflow: hidden;
|
|
6
|
-
display: -webkit-box;
|
|
7
|
-
-webkit-box-orient: vertical;
|
|
8
|
-
-webkit-line-clamp: 1;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
.truncate-text-2 {
|
|
12
|
-
overflow: hidden;
|
|
13
|
-
display: -webkit-box;
|
|
14
|
-
-webkit-box-orient: vertical;
|
|
15
|
-
-webkit-line-clamp: 2;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
1
|
.banner-image > .pgn__card-logo-cap {
|
|
19
2
|
width: 12rem;
|
|
20
3
|
height: 4.7rem;
|
|
21
|
-
}
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.program-type {
|
|
7
|
+
font-size: 0.75rem;
|
|
8
|
+
}
|
|
@@ -23,7 +23,7 @@ export const usePopularCoursesAndProgramsData = (searchClient, enabled, productT
|
|
|
23
23
|
queryFn: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
24
24
|
const hits = yield fetchPopularProducts(searchClient, productType, 4);
|
|
25
25
|
return hits.map((hit) => {
|
|
26
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
26
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
27
27
|
const hitDetails = hit;
|
|
28
28
|
return {
|
|
29
29
|
objectID: hit.objectID,
|
|
@@ -32,11 +32,12 @@ export const usePopularCoursesAndProgramsData = (searchClient, enabled, productT
|
|
|
32
32
|
url: (_g = (_f = hitDetails.card_image_url) !== null && _f !== void 0 ? _f : hitDetails.image_url) !== null && _g !== void 0 ? _g : '',
|
|
33
33
|
marketing_url: (_h = hitDetails.marketing_url) !== null && _h !== void 0 ? _h : '',
|
|
34
34
|
thumbnail: (_j = hitDetails.organization_logo_override) !== null && _j !== void 0 ? _j : '',
|
|
35
|
-
content_type: (_l = (_k = hitDetails.
|
|
35
|
+
content_type: (_l = (_k = hitDetails.program_type) !== null && _k !== void 0 ? _k : hitDetails.product) !== null && _l !== void 0 ? _l : 'Course',
|
|
36
36
|
product: productType,
|
|
37
37
|
partner: (_m = hitDetails.partner) !== null && _m !== void 0 ? _m : '',
|
|
38
38
|
weeks_to_complete: (_o = hitDetails.weeks_to_complete) !== null && _o !== void 0 ? _o : undefined,
|
|
39
39
|
level: (_p = hitDetails.level) !== null && _p !== void 0 ? _p : undefined,
|
|
40
|
+
subject: (_q = hitDetails.subject) !== null && _q !== void 0 ? _q : undefined,
|
|
40
41
|
};
|
|
41
42
|
});
|
|
42
43
|
}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePopularCoursesAndPrograms.js","sourceRoot":"","sources":["../../src/hooks/usePopularCoursesAndPrograms.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,QAAQ,EAAkB,MAAM,uBAAuB,CAAC;AAGjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAG/D,iFAAiF;AACjF,oDAAoD;AAEpD,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,GAAG,EAAE,CAAC,QAAQ,CAAU;IACxB,QAAQ,EAAE,CAAC,KAAa,EAAE,IAAc,EAAE,EAAE,CAC1C,CAAC,GAAG,UAAU,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,CAAU;IACvD,OAAO,EAAE,CAAC,KAAa,EAAE,IAAc,EAAE,IAAY,EAAE,EAAE,CACvD,CAAC,GAAG,UAAU,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAU;IAC5D,OAAO,EAAE,CAAC,WAAwB,EAAE,KAAa,EAAE,EAAE,CACnD,CAAC,GAAG,UAAU,CAAC,GAAG,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,CAAU;CAC9D,CAAC;AAEF,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAC9C,YAAiC,EACjC,OAAgB,EAChB,cAA2B,mBAAmB,EACX,EAAE,CACrC,QAAQ,CAAC;IACP,QAAQ,EAAE,UAAU,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAC5C,OAAO,EAAE,GAAS,EAAE;QAClB,MAAM,IAAI,GAAG,MAAM,oBAAoB,CAAC,YAAa,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;QACvE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAmB,EAAE;;YACvC,MAAM,UAAU,GAAG,
|
|
1
|
+
{"version":3,"file":"usePopularCoursesAndPrograms.js","sourceRoot":"","sources":["../../src/hooks/usePopularCoursesAndPrograms.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,QAAQ,EAAkB,MAAM,uBAAuB,CAAC;AAGjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAG/D,iFAAiF;AACjF,oDAAoD;AAEpD,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,GAAG,EAAE,CAAC,QAAQ,CAAU;IACxB,QAAQ,EAAE,CAAC,KAAa,EAAE,IAAc,EAAE,EAAE,CAC1C,CAAC,GAAG,UAAU,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,CAAU;IACvD,OAAO,EAAE,CAAC,KAAa,EAAE,IAAc,EAAE,IAAY,EAAE,EAAE,CACvD,CAAC,GAAG,UAAU,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAU;IAC5D,OAAO,EAAE,CAAC,WAAwB,EAAE,KAAa,EAAE,EAAE,CACnD,CAAC,GAAG,UAAU,CAAC,GAAG,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,CAAU;CAC9D,CAAC;AAEF,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAC9C,YAAiC,EACjC,OAAgB,EAChB,cAA2B,mBAAmB,EACX,EAAE,CACrC,QAAQ,CAAC;IACP,QAAQ,EAAE,UAAU,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAC5C,OAAO,EAAE,GAAS,EAAE;QAClB,MAAM,IAAI,GAAG,MAAM,oBAAoB,CAAC,YAAa,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;QACvE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAmB,EAAE;;YACvC,MAAM,UAAU,GAAG,GAelB,CAAC;YAEF,OAAO;gBACL,QAAQ,EAAE,GAAG,CAAC,QAAQ;gBACtB,KAAK,EAAE,MAAA,MAAA,GAAG,CAAC,KAAK,mCAAI,GAAG,CAAC,IAAI,mCAAI,UAAU;gBAC1C,mBAAmB,EAAE,MAAA,MAAA,MAAA,UAAU,CAAC,mBAAmB,mCAAI,UAAU,CAAC,iBAAiB,mCAAI,UAAU,CAAC,WAAW,mCAAI,EAAE;gBACnH,GAAG,EAAE,MAAA,MAAA,UAAU,CAAC,cAAc,mCAAI,UAAU,CAAC,SAAS,mCAAI,EAAE;gBAC5D,aAAa,EAAE,MAAA,UAAU,CAAC,aAAa,mCAAI,EAAE;gBAC7C,SAAS,EAAE,MAAA,UAAU,CAAC,0BAA0B,mCAAI,EAAE;gBACtD,YAAY,EAAE,MAAA,MAAA,UAAU,CAAC,YAAY,mCAAI,UAAU,CAAC,OAAO,mCAAI,QAAQ;gBACvE,OAAO,EAAE,WAAW;gBACpB,OAAO,EAAE,MAAA,UAAU,CAAC,OAAO,mCAAI,EAAE;gBACjC,iBAAiB,EAAE,MAAA,UAAU,CAAC,iBAAiB,mCAAI,SAAS;gBAC5D,KAAK,EAAE,MAAA,UAAU,CAAC,KAAK,mCAAI,SAAS;gBACpC,OAAO,EAAE,MAAA,UAAU,CAAC,OAAO,mCAAI,SAAS;aACzC,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAA;IACD,OAAO,EAAE,CAAC,CAAC,YAAY,IAAI,OAAO;IAClC,SAAS,EAAE,IAAI,GAAG,EAAE,GAAG,EAAE;CAC1B,CAAC,CAAC","sourcesContent":["import { useQuery, UseQueryResult } from '@tanstack/react-query';\nimport { SearchClient } from 'algoliasearch';\nimport { ProductType } from '@src/types/types';\nimport { PRODUCT_TYPE_COURSE } from '@src/constants';\nimport { fetchPopularProducts } from '@src/utils/algoliaUtils';\nimport { ProductCardItem } from '@src/containers/ProductCard/data/types';\n\n// ─── Query key factories ──────────────────────────────────────────────────────\n// Centralised so cache invalidation is never a typo\n\nexport const searchKeys = {\n all: ['search'] as const,\n programs: (query: string, tags: string[]) =>\n [...searchKeys.all, 'programs', query, tags] as const,\n courses: (query: string, tags: string[], page: number) =>\n [...searchKeys.all, 'courses', query, tags, page] as const,\n popular: (productType: ProductType, limit: number) =>\n [...searchKeys.all, 'popular', productType, limit] as const,\n};\n\nexport const usePopularCoursesAndProgramsData = (\n searchClient: SearchClient | null,\n enabled: boolean,\n productType: ProductType = PRODUCT_TYPE_COURSE\n): UseQueryResult<ProductCardItem[]> =>\n useQuery({\n queryKey: searchKeys.popular(productType, 4),\n queryFn: async () => {\n const hits = await fetchPopularProducts(searchClient!, productType, 4);\n return hits.map((hit): ProductCardItem => {\n const hitDetails = hit as {\n short_description?: string,\n primary_description?: string,\n description?: string,\n marketing_url?: string,\n image_url?: string,\n card_image_url?: string,\n organization_logo_override?: string,\n content_type?: string,\n program_type?: string,\n product?: string,\n partner?: string,\n weeks_to_complete?: number,\n level?: string,\n subject?: string,\n };\n\n return {\n objectID: hit.objectID,\n title: hit.title ?? hit.name ?? 'Untitled',\n primary_description: hitDetails.primary_description ?? hitDetails.short_description ?? hitDetails.description ?? '',\n url: hitDetails.card_image_url ?? hitDetails.image_url ?? '',\n marketing_url: hitDetails.marketing_url ?? '',\n thumbnail: hitDetails.organization_logo_override ?? '',\n content_type: hitDetails.program_type ?? hitDetails.product ?? 'Course',\n product: productType,\n partner: hitDetails.partner ?? '',\n weeks_to_complete: hitDetails.weeks_to_complete ?? undefined,\n level: hitDetails.level ?? undefined,\n subject: hitDetails.subject ?? undefined,\n };\n });\n },\n enabled: !!searchClient && enabled,\n staleTime: 1000 * 60 * 10,\n });\n"]}
|