+ const renderCardSection = () => {
+ if (!hasBudgetAggregatesSection()) {
+ return null;
+ }
+
+ return (
+
-
-
+
+ )}
+ muted
+ >
+
+ {!isRetired && (
+ <>
+
+
+
+
+
+ {isFetchingBudgets ? : formatPrice(available)}
+
+
+ {isAssignable && (
+
+
+
+
+
+ {isFetchingBudgets ? : formatPrice(pending)}
+
+
+ )}
+ >
+ )}
+
+
-
- {isFetchingBudgets ? : formatPrice(pending)}
+
+ {isFetchingBudgets ? : formatPrice(spent)}
- )}
-
-
-
-
-
- {isFetchingBudgets ? : formatPrice(spent)}
-
-
-
- );
+
+ );
+ };
return (
{renderCardHeader(displayName || 'Overview', id)}
- {(budgetLabel.status === BUDGET_STATUSES.active || budgetLabel.status === BUDGET_STATUSES.expiring)
- && renderCardSection()}
+ {renderCardSection()}
@@ -219,6 +245,7 @@ BaseSubBudgetCard.propTypes = {
displayName: PropTypes.string,
isAssignable: PropTypes.bool,
isRetired: PropTypes.bool,
+ retiredAt: PropTypes.string,
};
BaseSubBudgetCard.defaultProps = {
diff --git a/src/components/learner-credit-management/data/utils.js b/src/components/learner-credit-management/data/utils.js
index 2fc358df5a..65e86ec30e 100644
--- a/src/components/learner-credit-management/data/utils.js
+++ b/src/components/learner-credit-management/data/utils.js
@@ -163,6 +163,7 @@ export const getBudgetStatus = ({
endDateStr,
isBudgetRetired,
currentDate = new Date(),
+ retiredDateStr = null,
}) => {
const startDate = new Date(startDateStr);
const endDate = new Date(endDateStr);
@@ -171,10 +172,9 @@ export const getBudgetStatus = ({
if (isBudgetRetired) {
return {
status: BUDGET_STATUSES.retired,
- badgeVariant: 'info',
- // no term or date for retired budgets
- term: null,
- date: null,
+ badgeVariant: 'light',
+ term: 'Retired',
+ date: retiredDateStr,
};
}
@@ -532,6 +532,12 @@ export const getTranslatedBudgetTerm = (intl, term) => {
defaultMessage: 'Expired',
description: 'Term for when a budget has expired',
});
+ case 'Retired':
+ return intl.formatMessage({
+ id: 'lcm.budgets.budget.card.term.retired',
+ defaultMessage: 'Retired',
+ description: 'Term for when a budget has retired',
+ });
default:
return '';
}
diff --git a/src/components/learner-credit-management/tests/BudgetCard.test.jsx b/src/components/learner-credit-management/tests/BudgetCard.test.jsx
index 43687867db..7b24d2c4bf 100644
--- a/src/components/learner-credit-management/tests/BudgetCard.test.jsx
+++ b/src/components/learner-credit-management/tests/BudgetCard.test.jsx
@@ -7,6 +7,7 @@ import dayjs from 'dayjs';
import {
screen,
render,
+ within,
} from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
@@ -14,7 +15,7 @@ import { IntlProvider } from '@edx/frontend-platform/i18n';
import { QueryClientProvider } from '@tanstack/react-query';
import BudgetCard from '../BudgetCard';
import { formatPrice, useSubsidySummaryAnalyticsApi, useBudgetRedemptions } from '../data';
-import { BUDGET_TYPES } from '../../EnterpriseApp/data/constants';
+import { BUDGET_STATUSES, BUDGET_TYPES } from '../../EnterpriseApp/data/constants';
import { EnterpriseSubsidiesContext } from '../../EnterpriseSubsidiesContext';
import { queryClient } from '../../test/testUtils';
@@ -547,4 +548,146 @@ describe('', () => {
expect(screen.getByText('Spent')).toBeInTheDocument();
expect(screen.getByText(formatPrice(mockBudgetAggregates.spent))).toBeInTheDocument();
});
+
+ it('displays correctly for a retired Policy (enterprise-access) (%s)', () => {
+ const mockBudgetAggregates = {
+ total: 5000,
+ spent: 200,
+ pending: undefined,
+ available: 4800,
+ };
+ const mockBudget = {
+ id: mockBudgetUuid,
+ name: mockBudgetDisplayName,
+ start: '2022-01-01',
+ end: '3023-01-01',
+ source: BUDGET_TYPES.policy,
+ aggregates: {
+ available: mockBudgetAggregates.available,
+ pending: mockBudgetAggregates.pending,
+ spent: mockBudgetAggregates.spent,
+ },
+ isAssignable: false,
+ enterpriseSlug,
+ enterpriseUUID,
+ isRetired: true,
+ retiredAt: '2022-01-01',
+ };
+
+ useSubsidySummaryAnalyticsApi.mockReturnValue({
+ isLoading: false,
+ subsidySummary: undefined,
+ });
+
+ render();
+
+ // Assertions for budget card display
+ expect(screen.getByText(mockBudgetDisplayName)).toBeInTheDocument();
+ expect(screen.queryByText('Executive Education')).not.toBeInTheDocument();
+
+ const formattedString = `Retired ${dayjs(mockBudget.retiredAt).format('MMMM D, YYYY')}`;
+ const elementsWithTestId = screen.getAllByTestId('budget-date');
+ const firstElementWithTestId = elementsWithTestId[0];
+ expect(firstElementWithTestId).toHaveTextContent(formattedString);
+
+ // Verify 'View budget' CTA
+ const viewBudgetCTA = screen.getByText('View budget history', { selector: 'a' });
+ expect(viewBudgetCTA).toBeInTheDocument(); // Ensure 'View budget' CTA is present
+ expect(viewBudgetCTA).toHaveAttribute(
+ 'href',
+ `/${enterpriseSlug}/admin/learner-credit/${mockBudgetUuid}`,
+ );
+
+ const balanceDetailSection = screen.getByTestId('balance-detail-section');
+
+ // Assertions for aggregates display
+ expect(within(balanceDetailSection).queryByText('Balance')).not.toBeInTheDocument();
+ expect(within(balanceDetailSection).queryByText('Available')).not.toBeInTheDocument();
+ expect(within(balanceDetailSection).getByText('Spent')).toBeInTheDocument();
+ expect(within(balanceDetailSection).getByText(formatPrice(mockBudgetAggregates.spent))).toBeInTheDocument();
+ });
+
+ it.each([
+ {
+ status: BUDGET_STATUSES.active,
+ shouldShow: true,
+ start: '2022-01-01',
+ end: '3023-01-01',
+ retiredAt: null,
+ },
+ {
+ status: BUDGET_STATUSES.retired,
+ shouldShow: true,
+ start: '2022-01-01',
+ end: '3023-01-01',
+ retiredAt: '2022-05-01',
+ },
+ {
+ status: BUDGET_STATUSES.expiring,
+ shouldShow: true,
+ start: '2022-01-01',
+ end: dayjs().add(30, 'day').toString(),
+ retiredAt: null,
+ },
+ {
+ status: BUDGET_STATUSES.scheduled,
+ shouldShow: false,
+ start: '3022-01-01',
+ end: '3023-01-01',
+ retiredAt: null,
+ },
+ {
+ status: BUDGET_STATUSES.expired,
+ shouldShow: false,
+ start: '2022-01-01',
+ end: '2023-01-01',
+ retiredAt: null,
+ },
+ ])('only render aggregates section for appropriate statuses (%s)', (
+ {
+ shouldShow,
+ start,
+ end,
+ retiredAt,
+ },
+ ) => {
+ const mockBudgetAggregates = {
+ total: 5000,
+ spent: 200,
+ pending: undefined,
+ available: 4800,
+ };
+ const mockBudget = {
+ id: mockBudgetUuid,
+ name: mockBudgetDisplayName,
+ start,
+ end,
+ source: BUDGET_TYPES.policy,
+ aggregates: {
+ available: mockBudgetAggregates.available,
+ pending: mockBudgetAggregates.pending,
+ spent: mockBudgetAggregates.spent,
+ },
+ isAssignable: false,
+ enterpriseSlug,
+ enterpriseUUID,
+ isRetired: !!retiredAt,
+ retiredAt,
+ };
+
+ useSubsidySummaryAnalyticsApi.mockReturnValue({
+ isLoading: false,
+ subsidySummary: undefined,
+ });
+
+ render();
+
+ const aggregatesSection = screen.queryByTestId('aggregates-section');
+
+ if (shouldShow) {
+ expect(aggregatesSection).toBeInTheDocument();
+ } else {
+ expect(aggregatesSection).not.toBeInTheDocument();
+ }
+ });
});
diff --git a/src/index.scss b/src/index.scss
index c60d3ff013..f38108a463 100644
--- a/src/index.scss
+++ b/src/index.scss
@@ -79,3 +79,7 @@ form {
.stepper-modal .pgn__modal-header {
border-bottom: solid 7px;
}
+
+.font-size-base {
+ font-size: $font-size-base !important;
+}