-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: adding in extra info to invite learners modal (#1216)
* feat: adding in extra modal info * fix: PR requests * fix: more PR requests
- Loading branch information
Showing
14 changed files
with
404 additions
and
90 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import { ProgressBar, Stack } from '@edx/paragon'; | ||
|
||
import { formatPrice } from './data'; | ||
import { BUDGET_STATUSES } from '../EnterpriseApp/data/constants'; | ||
|
||
const BudgetDetail = ({ | ||
available, utilized, limit, status, | ||
}) => { | ||
const currentProgressBarLimit = (available / limit) * 100; | ||
|
||
if (status === BUDGET_STATUSES.expired) { | ||
return ( | ||
<Stack className="border border-light-400 p-4"> | ||
<h4>Spent</h4> | ||
<Stack direction="horizontal" gap={4} className="mt-1"> | ||
<span className="display-1 text-dark" data-testid="budget-detail-spent">{formatPrice(utilized)}</span> | ||
<span className="mt-auto small text-monospace" data-testid="budget-detail-unspent"> | ||
Unspent {formatPrice(available)} | ||
</span> | ||
</Stack> | ||
</Stack> | ||
); | ||
} | ||
|
||
return ( | ||
<Stack className="border border-light-400 p-4"> | ||
<h4>Available</h4> | ||
<Stack direction="horizontal" gap={4} className="mt-1"> | ||
<span className="display-1 text-dark" data-testid="budget-detail-available">{formatPrice(available)}</span> | ||
<span className="mt-auto small text-monospace" data-testid="budget-detail-utilized"> | ||
Utilized {formatPrice(utilized)} | ||
</span> | ||
</Stack> | ||
<Stack gap={2} className="mt-3"> | ||
<ProgressBar now={currentProgressBarLimit} variant="info" /> | ||
<span className="ml-auto small text-monospace" data-testid="budget-detail-limit"> | ||
{formatPrice(limit)} limit | ||
</span> | ||
</Stack> | ||
</Stack> | ||
); | ||
}; | ||
|
||
BudgetDetail.propTypes = { | ||
available: PropTypes.number.isRequired, | ||
utilized: PropTypes.number.isRequired, | ||
limit: PropTypes.number.isRequired, | ||
status: PropTypes.string.isRequired, | ||
}; | ||
|
||
export default BudgetDetail; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
src/components/learner-credit-management/data/hooks/useContentMetadata.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { useQuery } from '@tanstack/react-query'; | ||
import { camelCaseObject } from '@edx/frontend-platform/utils'; | ||
|
||
import { learnerCreditManagementQueryKeys } from '../constants'; | ||
import EnterpriseCatalogApiService from '../../../../data/services/EnterpriseCatalogApiService'; | ||
|
||
const getContentMetadata = async ({ catalogUuid }) => { | ||
const response = await EnterpriseCatalogApiService.fetchEnterpriseCatalogMetadata({ catalogUuid }); | ||
const contentMetadata = camelCaseObject(response.data); | ||
return contentMetadata; | ||
}; | ||
|
||
const useContentMetadata = (catalogUuid, { queryOptions } = {}) => useQuery({ | ||
queryKey: learnerCreditManagementQueryKeys.group(catalogUuid), | ||
queryFn: () => getContentMetadata({ catalogUuid }), | ||
...queryOptions, | ||
}); | ||
|
||
export default useContentMetadata; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
104 changes: 104 additions & 0 deletions
104
src/components/learner-credit-management/invite-modal/InviteModalBudgetCard.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import React from 'react'; | ||
import { connect } from 'react-redux'; | ||
import PropTypes from 'prop-types'; | ||
import { | ||
Card, Col, Row, Skeleton, | ||
} from '@edx/paragon'; | ||
import { makePlural } from '../../../utils'; | ||
|
||
import { | ||
useBudgetDetailHeaderData, | ||
useBudgetId, | ||
useEnterpriseGroupLearners, | ||
useEnterpriseOffer, useSubsidyAccessPolicy, | ||
useSubsidySummaryAnalyticsApi, | ||
} from '../data'; | ||
import BudgetDetail from '../BudgetDetail'; | ||
import { BUDGET_TYPES } from '../../EnterpriseApp/data/constants'; | ||
import BudgetStatusSubtitle from '../BudgetStatusSubtitle'; | ||
|
||
const InviteModalBudgetCard = ({ | ||
enterpriseUUID, | ||
enterpriseFeatures, | ||
}) => { | ||
const { subsidyAccessPolicyId, enterpriseOfferId } = useBudgetId(); | ||
const { data: subsidyAccessPolicy } = useSubsidyAccessPolicy(subsidyAccessPolicyId); | ||
const { data } = useEnterpriseGroupLearners(subsidyAccessPolicy.groupAssociations[0]); | ||
|
||
const memberSubtitle = data?.count ? `${makePlural(data?.count, 'current member')}` : ''; | ||
const budgetType = (enterpriseOfferId !== null) ? BUDGET_TYPES.ecommerce : BUDGET_TYPES.policy; | ||
|
||
const { isLoading: isLoadingSubsidySummary, subsidySummary } = useSubsidySummaryAnalyticsApi( | ||
enterpriseUUID, | ||
enterpriseOfferId, | ||
budgetType, | ||
); | ||
|
||
const { isLoading: isLoadingEnterpriseOffer, data: enterpriseOfferMetadata } = useEnterpriseOffer(enterpriseOfferId); | ||
|
||
const policyOrOfferId = subsidyAccessPolicyId || enterpriseOfferId; | ||
const { | ||
budgetDisplayName, | ||
budgetTotalSummary, | ||
status, | ||
badgeVariant, | ||
term, | ||
date, | ||
isAssignable, | ||
} = useBudgetDetailHeaderData({ | ||
subsidyAccessPolicy, | ||
subsidySummary, | ||
budgetId: policyOrOfferId, | ||
enterpriseOfferMetadata, | ||
isTopDownAssignmentEnabled: enterpriseFeatures.topDownAssignmentRealTimeLcm, | ||
}); | ||
|
||
if (!subsidyAccessPolicy && (isLoadingSubsidySummary || isLoadingEnterpriseOffer)) { | ||
return ( | ||
<div data-testid="budget-detail-skeleton"> | ||
<Skeleton height={180} /> | ||
<span className="sr-only">Loading budget header data</span> | ||
</div> | ||
); | ||
} | ||
|
||
const { available, utilized, limit } = budgetTotalSummary; | ||
return ( | ||
<Card className="budget-overview-card m-3"> | ||
<Card.Section> | ||
<Row> | ||
<Col lg={5}> | ||
<h4>{budgetDisplayName}</h4> | ||
<p>{memberSubtitle}</p> | ||
<BudgetStatusSubtitle | ||
badgeVariant={badgeVariant} | ||
status={status} | ||
isAssignable={isAssignable} | ||
term={term} | ||
date={date} | ||
policy={subsidyAccessPolicy} | ||
enterpriseUUID={enterpriseUUID} | ||
/> | ||
</Col> | ||
<Col lg={7}> | ||
<BudgetDetail available={available} utilized={utilized} limit={limit} status={status} /> | ||
</Col> | ||
</Row> | ||
</Card.Section> | ||
</Card> | ||
); | ||
}; | ||
|
||
const mapStateToProps = state => ({ | ||
enterpriseUUID: state.portalConfiguration.enterpriseId, | ||
enterpriseFeatures: state.portalConfiguration.enterpriseFeatures, | ||
}); | ||
|
||
InviteModalBudgetCard.propTypes = { | ||
enterpriseUUID: PropTypes.string.isRequired, | ||
enterpriseFeatures: PropTypes.shape({ | ||
topDownAssignmentRealTimeLcm: PropTypes.bool, | ||
}).isRequired, | ||
}; | ||
|
||
export default connect(mapStateToProps)(InviteModalBudgetCard); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.