Skip to content

Commit

Permalink
feat: read from normalized metadata content_price in course cards
Browse files Browse the repository at this point in the history
  • Loading branch information
brobro10000 committed Sep 26, 2024
1 parent 0f2ad73 commit fe79b4e
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 39 deletions.
6 changes: 4 additions & 2 deletions .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ ALGOLIA_SEARCH_API_KEY=''
ALGOLIA_INDEX_NAME=''
AUTHN_MINIMAL_HEADER=true
MINIMAL_HEADER=true
EDX_FOR_SUBSCRIPTION_TITLE=''
EDX_ENTERPRISE_ALACARTE_TITLE=''
EDX_FOR_BUSINESS_TITLE:'Business'
EDX_FOR_SUBSCRIPTION_TITLE:'Subscription'
EDX_ENTERPRISE_ALACARTE_TITLE:'A la carte'
EDX_FOR_ONLINE_EDU_TITLE:'Education'
FEATURE_LANGUAGE_FACET=true
HOTJAR_APP_ID=''
HOTJAR_VERSION=6
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
"install-theme": "npm install \"@edx/brand@${THEME}\" --no-save",
"start": "fedx-scripts webpack-dev-server --progress",
"start:with-theme": "THEME=npm:@edx/brand-edx.org@latest npm run install-theme && npm run start",
"test": "fedx-scripts jest --transformIgnorePatterns \"node_modules/(?!@edx/frontend-app-enterprise-public-catalog)/\" --env=jsdom --coverage --passWithNoTests"
"test": "fedx-scripts jest --transformIgnorePatterns \"node_modules/(?!@edx/frontend-app-enterprise-public-catalog)/\" --env=jsdom --coverage --passWithNoTests",
"test:watch": "npm run test -- --watch"
},
"husky": {
"hooks": {
Expand Down
21 changes: 7 additions & 14 deletions src/components/catalogSearchResults/CatalogSearchResults.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ import DownloadCsvButton from './associatedComponents/downloadCsvButton/Download
import messages from './CatalogSearchResults.messages';

import CatalogNoResultsDeck from '../catalogNoResultsDeck/CatalogNoResultsDeck';
import { formatDate, makePlural, getSelectedCatalogFromURL } from '../../utils/common';
import { formatDate, makePlural, getSelectedCatalogFromURL, formatPrice } from '../../utils/common';

Check failure on line 58 in src/components/catalogSearchResults/CatalogSearchResults.jsx

View workflow job for this annotation

GitHub Actions / build (18)

Expected a line break after this opening brace

Check failure on line 58 in src/components/catalogSearchResults/CatalogSearchResults.jsx

View workflow job for this annotation

GitHub Actions / build (18)

Expected a line break before this closing brace

export const ERROR_MESSAGE = 'An error occured while retrieving data';

Expand Down Expand Up @@ -184,11 +184,8 @@ export const BaseCatalogSearchResults = ({
};

const renderCardComponent = (props) => {
if (contentType === CONTENT_TYPE_COURSE) {
return <CourseCard {...props} learningType={contentType} onClick={cardClicked} />;
}
if (contentType === EXEC_ED_TITLE) {
return <CourseCard {...props} learningType={contentType} onClick={cardClicked} />;
if ([CONTENT_TYPE_COURSE, EXEC_ED_TITLE].includes(contentType)) {
return <CourseCard {...props} onClick={cardClicked} />;
}
return <ProgramCard {...props} onClick={cardClicked} />;
};
Expand Down Expand Up @@ -225,10 +222,8 @@ export const BaseCatalogSearchResults = ({
},
{
Header: TABLE_HEADERS.price,
accessor: 'first_enrollable_paid_seat_price',
Cell: ({ row }) => (row.values.first_enrollable_paid_seat_price
? `$${row.values.first_enrollable_paid_seat_price}`
: null),
accessor: 'normalized_metadata',
Cell: ({ row }) => formatPrice(row.values.normalized_metadata.content_price),
},
{
Header: TABLE_HEADERS.catalogs,
Expand All @@ -252,10 +247,8 @@ export const BaseCatalogSearchResults = ({
},
{
Header: TABLE_HEADERS.price,
accessor: 'entitlements',
Cell: ({ row }) => (row.values.entitlements[0].price
? `$${Math.trunc(row.values.entitlements[0].price)}`
: null),
accessor: 'normalized_metadata',
Cell: ({ row }) => formatPrice(row.values.normalized_metadata.content_price),
},
{
Header: TABLE_HEADERS.catalogs,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ const searchResults = {
upgrade_deadline: 1892678399,
pacing_type: 'self_paced',
},
normalized_metadata: {
content_price: 100,
},
},
{
title: TEST_COURSE_NAME_2,
Expand All @@ -105,6 +108,9 @@ const searchResults = {
upgrade_deadline: 1892678399,
pacing_type: 'self_paced',
},
normalized_metadata: {
content_price: 99,
},
},
],
page: 1,
Expand Down Expand Up @@ -159,6 +165,9 @@ const searchResultsExecEd = {
start_date: '2020-01-24T05:00:00Z',
end_date: '2080-01-01T17:00:00Z',
},
normalized_metadata: {
content_price: 100,
},
},
],
page: 1,
Expand Down
23 changes: 7 additions & 16 deletions src/components/courseCard/CourseCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,21 @@ import PropTypes from 'prop-types';
import { Badge, Card } from '@openedx/paragon';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import messages from './CourseCard.messages';
import { CONTENT_TYPE_COURSE } from '../../constants';
import defaultCardHeader from '../../static/default-card-header-light.png';
import { formatPrice } from '../../utils/common';

const CourseCard = ({
intl, onClick, original, learningType,
intl, onClick, original,
}) => {
const {
title,
card_image_url,
partners,
first_enrollable_paid_seat_price,
normalized_metadata,
enterprise_catalog_query_titles,
entitlements,
advertised_course_run,
} = original;
let rowPrice;
let priceText;

if (learningType === CONTENT_TYPE_COURSE) {
rowPrice = first_enrollable_paid_seat_price;
priceText = rowPrice != null ? `$${rowPrice.toString()}` : 'N/A';
} else {
[rowPrice] = entitlements || [null];
priceText = rowPrice != null ? `$${Math.trunc(rowPrice.price)?.toString()}` : 'N/A';
}

const priceText = formatPrice(normalized_metadata.content_price);
let pacingType = 'NA';
if (advertised_course_run) {
pacingType = advertised_course_run.pacing_type === 'self_paced' ? 'Self paced' : 'Instructor led';
Expand Down Expand Up @@ -90,7 +79,6 @@ CourseCard.defaultProps = {
CourseCard.propTypes = {
intl: intlShape.isRequired,
onClick: PropTypes.func,
learningType: PropTypes.string.isRequired,
original: PropTypes.shape({
title: PropTypes.string,
card_image_url: PropTypes.string,
Expand All @@ -102,6 +90,9 @@ CourseCard.propTypes = {
logo_image_url: PropTypes.string,
}),
),
normalized_metadata: PropTypes.shape({
content_price: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
}),
first_enrollable_paid_seat_price: PropTypes.number,
enterprise_catalog_query_titles: PropTypes.arrayOf(PropTypes.string),
original_image_url: PropTypes.string,
Expand Down
6 changes: 6 additions & 0 deletions src/components/courseCard/CourseCard.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ const originalData = {
original_image_url: '',
enterprise_catalog_query_titles: TEST_CATALOG,
advertised_course_run: { pacing_type: 'self_paced' },
normalized_metadata: {
content_price: 100,
},
};

const defaultProps = {
Expand All @@ -37,6 +40,9 @@ const execEdData = {
enterprise_catalog_query_titles: TEST_CATALOG,
advertised_course_run: { pacing_type: 'instructor_paced' },
entitlements: [{ price: '999.00' }],
normalized_metadata: {
content_price: 999,
},
};

const execEdProps = {
Expand Down
13 changes: 7 additions & 6 deletions src/utils/algoliaUtils.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { CONTENT_TYPE_COURSE, CONTENT_TYPE_PROGRAM } from '../constants';
import { formatPrice } from './common';

const extractUuid = (aggregationKey) => aggregationKey.split(':')[1];

Expand All @@ -9,7 +10,7 @@ function mapAlgoliaObjectToCourse(algoliaCourseObject, intl, messages) {
const {
title: courseTitle,
partners,
first_enrollable_paid_seat_price: coursePrice, // todo
normalized_metadata: normalizedMetadata,
enterprise_catalog_query_titles: courseAssociatedCatalogs,
full_description: courseDescription,
original_image_url: bannerImageUrl,
Expand All @@ -19,8 +20,8 @@ function mapAlgoliaObjectToCourse(algoliaCourseObject, intl, messages) {
skill_names: skillNames,
} = algoliaCourseObject;
const { start: startDate, end: endDate } = courseRun;
const priceText = coursePrice != null
? `$${coursePrice.toString()}`
const priceText = normalizedMetadata.content_price != null
? formatPrice(normalizedMetadata.content_price)
: intl.formatMessage(
messages['catalogSearchResult.table.priceNotAvailable'],
);
Expand Down Expand Up @@ -48,7 +49,7 @@ function mapAlgoliaObjectToExecEd(algoliaCourseObject, intl, messages) {
const {
title: courseTitle,
partners,
entitlements: coursePrice, // todo
normalized_metadata: normalizedMetadata,
enterprise_catalog_query_titles: courseAssociatedCatalogs,
full_description: courseDescription,
original_image_url: bannerImageUrl,
Expand All @@ -58,8 +59,8 @@ function mapAlgoliaObjectToExecEd(algoliaCourseObject, intl, messages) {
additional_metadata: additionalMetadata,
} = algoliaCourseObject;
const { start_date: startDate, end_date: endDate } = additionalMetadata;
const priceText = coursePrice != null
? `$${coursePrice[0].price.toString()}`
const priceText = normalizedMetadata.content_price != null
? formatPrice(normalizedMetadata.content_price)
: intl.formatMessage(
messages['catalogSearchResult.table.priceNotAvailable'],
);
Expand Down
10 changes: 10 additions & 0 deletions src/utils/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,13 @@ export function getCourses(numCourses, string) {
export function hasNonEmptyValues(data) {
return Object.values(data).some(item => Array.isArray(item) && item.length > 0);
}

export const formatPrice = (price, options = {}) => {
const USDollar = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 0,
...options,
});
return USDollar.format(Math.abs(price));
};

0 comments on commit fe79b4e

Please sign in to comment.