From 7d87d7d0cfdf0629fdf06906db5f3e50eb161b2b Mon Sep 17 00:00:00 2001 From: jajjibhai008 Date: Fri, 22 Sep 2023 19:09:51 +0500 Subject: [PATCH] fix: incorporate adam's feedback --- .../EnterpriseApp/data/constants.js | 2 +- .../EnterpriseSubsidiesContext/data/hooks.js | 10 +- .../data/tests/hooks.test.js | 16 ++- .../BudgetCard-V2.jsx | 76 +++++-------- .../Budgetcard-V3.jsx | 101 ----------------- .../MultipleBudgetsPage.jsx | 43 ++++---- .../SubBudgetCard.jsx | 103 ++++++++++++++++++ .../learner-credit-management/data/utils.js | 8 ++ .../tests/BudgetCard.test.jsx | 4 +- 9 files changed, 174 insertions(+), 189 deletions(-) delete mode 100644 src/components/learner-credit-management/Budgetcard-V3.jsx create mode 100644 src/components/learner-credit-management/SubBudgetCard.jsx diff --git a/src/components/EnterpriseApp/data/constants.js b/src/components/EnterpriseApp/data/constants.js index 8669c4983a..6feaac51f7 100644 --- a/src/components/EnterpriseApp/data/constants.js +++ b/src/components/EnterpriseApp/data/constants.js @@ -20,7 +20,7 @@ export const BUDGET_STATUSES = { upcoming: 'Upcoming', }; -export const OFFER_TYPES = { +export const BUDGET_TYPES = { ecommerce: 'ecommerce', subsidy: 'subsidy', }; diff --git a/src/components/EnterpriseSubsidiesContext/data/hooks.js b/src/components/EnterpriseSubsidiesContext/data/hooks.js index e10f23bed0..2a5443a25e 100644 --- a/src/components/EnterpriseSubsidiesContext/data/hooks.js +++ b/src/components/EnterpriseSubsidiesContext/data/hooks.js @@ -10,7 +10,7 @@ import { camelCaseObject } from '@edx/frontend-platform/utils'; import EcommerceApiService from '../../../data/services/EcommerceApiService'; import LicenseManagerApiService from '../../../data/services/LicenseManagerAPIService'; import SubsidyApiService from '../../../data/services/EnterpriseSubsidyApiService'; -import { OFFER_TYPES } from '../../EnterpriseApp/data/constants'; +import { BUDGET_TYPES } from '../../EnterpriseApp/data/constants'; export const useEnterpriseOffers = ({ enablePortalLearnerCreditManagementScreen, enterpriseId }) => { const [offers, setOffers] = useState([]); @@ -26,9 +26,7 @@ export const useEnterpriseOffers = ({ enablePortalLearnerCreditManagementScreen, try { const [enterpriseSubsidyResponse, ecommerceApiResponse] = await Promise.all([ SubsidyApiService.getSubsidyByCustomerUUID(enterpriseId, { subsidyType: 'learner_credit' }), - EcommerceApiService.fetchEnterpriseOffers({ - isCurrent: true, - }), + EcommerceApiService.fetchEnterpriseOffers(), ]); // We have to consider both type of offers active and inactive. @@ -40,7 +38,7 @@ export const useEnterpriseOffers = ({ enablePortalLearnerCreditManagementScreen, enterpriseSubsidyResults.forEach((result) => { offerData.push({ - source: OFFER_TYPES.subsidy, + source: BUDGET_TYPES.subsidy, id: result.uuid, name: result.title, start: result.activeDatetime, @@ -51,7 +49,7 @@ export const useEnterpriseOffers = ({ enablePortalLearnerCreditManagementScreen, ecommerceOffersResults.forEach((result) => { offerData.push({ - source: OFFER_TYPES.ecommerce, + source: BUDGET_TYPES.ecommerce, id: result.id, name: result.displayName, start: result.startDatetime, diff --git a/src/components/EnterpriseSubsidiesContext/data/tests/hooks.test.js b/src/components/EnterpriseSubsidiesContext/data/tests/hooks.test.js index 3e3ad44f52..ec1c5466af 100644 --- a/src/components/EnterpriseSubsidiesContext/data/tests/hooks.test.js +++ b/src/components/EnterpriseSubsidiesContext/data/tests/hooks.test.js @@ -4,7 +4,7 @@ import { useCoupons, useCustomerAgreement, useEnterpriseOffers } from '../hooks' import EcommerceApiService from '../../../../data/services/EcommerceApiService'; import LicenseManagerApiService from '../../../../data/services/LicenseManagerAPIService'; import SubsidyApiService from '../../../../data/services/EnterpriseSubsidyApiService'; -import { OFFER_TYPES } from '../../../EnterpriseApp/data/constants'; +import { BUDGET_TYPES } from '../../../EnterpriseApp/data/constants'; jest.mock('@edx/frontend-platform/config', () => ({ getConfig: jest.fn(() => ({ @@ -52,7 +52,7 @@ describe('useEnterpriseOffers', () => { start: '2021-05-15T19:56:09Z', end: '2100-05-15T19:56:09Z', isCurrent: true, - source: OFFER_TYPES.ecommerce, + source: BUDGET_TYPES.ecommerce, }]; SubsidyApiService.getSubsidyByCustomerUUID.mockResolvedValueOnce({ @@ -71,9 +71,7 @@ describe('useEnterpriseOffers', () => { await waitForNextUpdate(); - expect(EcommerceApiService.fetchEnterpriseOffers).toHaveBeenCalledWith({ - isCurrent: true, - }); + expect(EcommerceApiService.fetchEnterpriseOffers).toHaveBeenCalled(); expect(result.current).toEqual({ offers: mockOffers, isLoading: false, @@ -133,7 +131,7 @@ describe('useEnterpriseOffers', () => { start: '2021-05-15T19:56:09Z', end: '2100-05-15T19:56:09Z', isCurrent: true, - source: OFFER_TYPES.subsidy, + source: BUDGET_TYPES.subsidy, }, { id: 'uuid', @@ -141,7 +139,7 @@ describe('useEnterpriseOffers', () => { start: '2021-05-15T19:56:09Z', end: '2100-05-15T19:56:09Z', isCurrent: true, - source: OFFER_TYPES.ecommerce, + source: BUDGET_TYPES.ecommerce, }, ]; @@ -216,7 +214,7 @@ describe('useEnterpriseOffers', () => { start: '2005-05-15T19:56:09Z', end: '2006-05-15T19:56:09Z', isCurrent: false, - source: OFFER_TYPES.subsidy, + source: BUDGET_TYPES.subsidy, }, { id: 'offer-2', @@ -224,7 +222,7 @@ describe('useEnterpriseOffers', () => { start: '2006-05-15T19:56:09Z', end: '2099-05-15T19:56:09Z', isCurrent: true, - source: OFFER_TYPES.subsidy, + source: BUDGET_TYPES.subsidy, }, ]; diff --git a/src/components/learner-credit-management/BudgetCard-V2.jsx b/src/components/learner-credit-management/BudgetCard-V2.jsx index b3ac7c695f..d103c4bad8 100644 --- a/src/components/learner-credit-management/BudgetCard-V2.jsx +++ b/src/components/learner-credit-management/BudgetCard-V2.jsx @@ -1,39 +1,14 @@ -/* eslint-disable */ +/* eslint-disable no-nested-ternary */ import React from 'react'; import PropTypes from 'prop-types'; import { Stack, - Col, - Card, - Skeleton, } from '@edx/paragon'; import { useOfferSummary } from './data/hooks'; -import SubBudgetCard from './Budgetcard-V3'; -import { OFFER_TYPES } from '../EnterpriseApp/data/constants'; +import SubBudgetCard from './SubBudgetCard'; +import { BUDGET_TYPES } from '../EnterpriseApp/data/constants'; -const LoadingCards = () => ( - - - - -
- -
-
-
- - - - -
- -
-
-
- -
-); const BudgetCard = ({ offer, enterpriseUUID, @@ -52,33 +27,34 @@ const BudgetCard = ({ } = useOfferSummary(enterpriseUUID, offer); return ( - - {isLoadingOfferSummary ? ( - - ) : offerType === OFFER_TYPES.ecommerce ? ( - - ) : ( - offerSummary?.budgetsSummary.map((budget) => ( + + {!isLoadingOfferSummary + && (offerType === BUDGET_TYPES.ecommerce ? ( - )) - )} + ) : ( + offerSummary?.budgetsSummary.map((budget) => ( + + )) + ))} ); }; diff --git a/src/components/learner-credit-management/Budgetcard-V3.jsx b/src/components/learner-credit-management/Budgetcard-V3.jsx deleted file mode 100644 index 9d901beea2..0000000000 --- a/src/components/learner-credit-management/Budgetcard-V3.jsx +++ /dev/null @@ -1,101 +0,0 @@ -/* eslint-disable */ -import { Link } from 'react-router-dom'; -import PropTypes from 'prop-types'; -import dayjs from 'dayjs'; -import { - Card, - Button, - Stack, - Row, - Col, -} from '@edx/paragon'; - -import { BUDGET_STATUSES, ROUTE_NAMES } from '../EnterpriseApp/data/constants'; -import { getBudgetStatus } from './data/utils'; - -const SubBudgetCard = ({ - id, - start, - end, - available, - spent, - displayName, - enterpriseSlug, -}) => { - const formattedStartDate = dayjs(start).format('MMMM D, YYYY'); - const formattedExpirationDate = dayjs(end).format('MMMM D, YYYY'); - const budgetStatus = getBudgetStatus(start, end); - - const renderActions = (id) => ( - - ); - - const renderCardHeader = (budgetType, id) => { - const subtitle = ( -
- - {formattedStartDate} - {formattedExpirationDate} - -
- ); - - return ( - - {budgetStatus !== BUDGET_STATUSES.upcoming && renderActions(id)} - - )} - /> - ); - }; - - const renderCardSection = (available, spent) => ( - - - - Available - {available} - - - Spent - {spent} - - - - ); - - return ( - - - {renderCardHeader(displayName || 'Overview', id)} - {budgetStatus !== BUDGET_STATUSES.upcoming && renderCardSection(available, spent)} - - - ); -}; - -SubBudgetCard.propTypes = { - enterpriseSlug: PropTypes.string.isRequired, - id: PropTypes.string, - start: PropTypes.string, - end: PropTypes.string, - spent: PropTypes.number, - available: PropTypes.number, - displayName: PropTypes.string, -}; - -export default SubBudgetCard; diff --git a/src/components/learner-credit-management/MultipleBudgetsPage.jsx b/src/components/learner-credit-management/MultipleBudgetsPage.jsx index 3df18c465a..81f7065ac8 100644 --- a/src/components/learner-credit-management/MultipleBudgetsPage.jsx +++ b/src/components/learner-credit-management/MultipleBudgetsPage.jsx @@ -6,6 +6,7 @@ import { Col, Card, Hyperlink, + Container, } from '@edx/paragon'; import { connect } from 'react-redux'; import { Helmet } from 'react-helmet'; @@ -35,26 +36,28 @@ const MultipleBudgetsPage = ({ - - - - -

No budgets for your organization

-

- We were unable to find any budgets for your organization. Please contact - Customer Support if you have questions. -

- - Contact support - - -
-
-
+ + + + + +

No budgets for your organization

+

+ We were unable to find any budgets for your organization. Please contact + Customer Support if you have questions. +

+ + Contact support + + +
+
+
+
); } diff --git a/src/components/learner-credit-management/SubBudgetCard.jsx b/src/components/learner-credit-management/SubBudgetCard.jsx new file mode 100644 index 0000000000..d3360cea43 --- /dev/null +++ b/src/components/learner-credit-management/SubBudgetCard.jsx @@ -0,0 +1,103 @@ +import { Link } from 'react-router-dom'; +import PropTypes from 'prop-types'; +import dayjs from 'dayjs'; +import { + Card, + Button, + Row, + Col, +} from '@edx/paragon'; + +import { BUDGET_STATUSES, ROUTE_NAMES } from '../EnterpriseApp/data/constants'; +import { formatPrice, getBudgetStatus } from './data/utils'; + +const SubBudgetCard = ({ + id, + start, + end, + available, + spent, + displayName, + enterpriseSlug, + isLoading, +}) => { + const formattedStartDate = dayjs(start).format('MMMM D, YYYY'); + const formattedExpirationDate = dayjs(end).format('MMMM D, YYYY'); + const budgetStatus = getBudgetStatus(start, end); + + const renderActions = (budgetId) => ( + + ); + + const renderCardHeader = (budgetType, budgetId) => { + const subtitle = ( +
+ + {formattedStartDate} - {formattedExpirationDate} + +
+ ); + + return ( + + ); + }; + + const renderCardSection = (availableBalance, spentBalance) => ( + + + + Available + {formatPrice(availableBalance)} + + + Spent + {formatPrice(spentBalance)} + + + + ); + + return ( + + + {renderCardHeader(displayName || 'Overview', id)} + {budgetStatus !== BUDGET_STATUSES.upcoming && renderCardSection(available, spent)} + + + ); +}; + +SubBudgetCard.propTypes = { + enterpriseSlug: PropTypes.string.isRequired, + id: PropTypes.string, + start: PropTypes.string, + end: PropTypes.string, + spent: PropTypes.number, + isLoading: PropTypes.bool, + available: PropTypes.number, + displayName: PropTypes.string, +}; + +export default SubBudgetCard; diff --git a/src/components/learner-credit-management/data/utils.js b/src/components/learner-credit-management/data/utils.js index 15d3eae2a2..47d17e7994 100644 --- a/src/components/learner-credit-management/data/utils.js +++ b/src/components/learner-credit-management/data/utils.js @@ -127,3 +127,11 @@ export const getBudgetStatus = (startDateStr, endDateStr) => { } return BUDGET_STATUSES.expired; }; + +export const formatPrice = (price) => { + const USDollar = new Intl.NumberFormat('en-US', { + style: 'currency', + currency: 'USD', + }); + return USDollar.format(price); +}; diff --git a/src/components/learner-credit-management/tests/BudgetCard.test.jsx b/src/components/learner-credit-management/tests/BudgetCard.test.jsx index 0bffaaf5e6..d8aa511a4a 100644 --- a/src/components/learner-credit-management/tests/BudgetCard.test.jsx +++ b/src/components/learner-credit-management/tests/BudgetCard.test.jsx @@ -14,7 +14,7 @@ import '@testing-library/jest-dom/extend-expect'; import { IntlProvider } from '@edx/frontend-platform/i18n'; import BudgetCard from '../BudgetCard-V2'; import { useOfferSummary, useOfferRedemptions } from '../data/hooks'; -import { OFFER_TYPES } from '../../EnterpriseApp/data/constants'; +import { BUDGET_TYPES } from '../../EnterpriseApp/data/constants'; jest.mock('../data/hooks'); useOfferSummary.mockReturnValue({ @@ -122,7 +122,7 @@ describe('', () => { name: mockOfferDisplayName, start: '2022-01-01', end: '2023-01-01', - offerType: OFFER_TYPES.ecommerce, + offerType: BUDGET_TYPES.ecommerce, }; const mockOfferRedemption = { created: '2022-02-01',