1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-10-27 11:02:16 +01:00

feat: add new dates and plan price (#10774)

<img width="2159" height="1617" alt="image"
src="https://github.com/user-attachments/assets/478ea289-dc0f-439e-92e4-a22fa44a0650"
/>
This commit is contained in:
Jaanus Sellin 2025-10-10 13:44:58 +03:00 committed by GitHub
parent 8879cc4b46
commit 0d252558c4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 91 additions and 10 deletions

View File

@ -5,6 +5,8 @@ import { useInstanceStatus } from 'hooks/api/getters/useInstanceStatus/useInstan
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { InstanceState } from 'interfaces/instance';
import { formatApiPath } from 'utils/formatPath';
import { useDetailedInvoices } from 'hooks/api/getters/useDetailedInvoices/useDetailedInvoices';
import { formatCurrency } from '../BillingInvoices/BillingInvoice/formatCurrency.js';
const PORTAL_URL = formatApiPath('api/admin/invoices');
type BillingInfoProps = {};
@ -63,6 +65,7 @@ export const BillingInfo: FC<BillingInfoProps> = () => {
const {
uiConfig: { billing },
} = useUiConfig();
const { planPrice, planCurrency } = useDetailedInvoices();
if (!instanceStatus) {
return (
@ -105,8 +108,13 @@ export const BillingInfo: FC<BillingInfoProps> = () => {
</StyledRow>
<StyledRow>
<StyledItemTitle>Plan price</StyledItemTitle>{' '}
{/* FIXME: where to take data from? */}
<StyledItemValue>$450 / month</StyledItemValue>
<StyledItemValue>
{planPrice !== undefined
? `${formatCurrency(planPrice, planCurrency)} ${
isPAYG ? 'per seat' : '/ month'
}`
: '-'}
</StyledItemValue>
</StyledRow>
<StyledDivider />
<StyledButton

View File

@ -5,7 +5,10 @@ import {
Accordion,
AccordionSummary,
AccordionDetails,
Button,
} from '@mui/material';
import ReceiptLongOutlinedIcon from '@mui/icons-material/ReceiptLongOutlined';
import DownloadOutlinedIcon from '@mui/icons-material/DownloadOutlined';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import { formatCurrency } from './formatCurrency.ts';
import { Badge } from 'component/common/Badge/Badge.tsx';
@ -84,6 +87,13 @@ const StyledTableRow = styled('div')(({ theme }) => ({
padding: theme.spacing(1, 0),
}));
const CardActions = styled('div')(({ theme }) => ({
display: 'flex',
justifyContent: 'flex-end',
gap: theme.spacing(1),
padding: theme.spacing(1.5, 2, 2),
}));
export const BillingInvoice = ({
status,
invoiceDate,
@ -93,20 +103,20 @@ export const BillingInvoice = ({
mainLines,
usageLines,
}: DetailedInvoicesSchemaInvoicesItem) => {
const title = invoiceDate
const currency = mainLines[0]?.currency || usageLines?.[0]?.currency;
const formattedTitle = invoiceDate
? new Date(invoiceDate).toLocaleDateString(undefined, {
month: 'long',
day: 'numeric',
})
: '';
const currency = mainLines[0]?.currency || usageLines?.[0]?.currency;
return (
<CardLikeAccordion defaultExpanded>
<HeaderRoot
expandIcon={<ExpandMoreIcon />}
id={`billing-invoice-${title}-header`}
id={`billing-invoice-${formattedTitle}-header`}
>
<HeaderLeft>
<Typography
@ -114,7 +124,7 @@ export const BillingInvoice = ({
component='h3'
sx={{ fontWeight: 700 }}
>
{title}
{formattedTitle}
</Typography>
</HeaderLeft>
<HeaderRight>
@ -170,6 +180,30 @@ export const BillingInvoice = ({
currency={currency}
/>
</StyledInvoiceGrid>
<CardActions>
{invoiceURL ? (
<Button
variant='outlined'
href={invoiceURL}
target='_blank'
rel='noreferrer'
startIcon={<ReceiptLongOutlinedIcon />}
>
View invoice
</Button>
) : null}
{invoicePDF ? (
<Button
variant='outlined'
href={invoicePDF}
target='_blank'
rel='noreferrer'
startIcon={<DownloadOutlinedIcon />}
>
Download PDF
</Button>
) : null}
</CardActions>
</AccordionDetails>
</CardLikeAccordion>
);

View File

@ -1,7 +1,7 @@
import { formatLargeNumbers } from 'component/impact-metrics/metricsFormatters.ts';
import { formatCurrency } from '../formatCurrency.ts';
import { ConsumptionIndicator } from '../ConsumptionIndicator/ConsumptionIndicator.tsx';
import { styled } from '@mui/material';
import { styled, Typography } from '@mui/material';
import type { DetailedInvoicesLineSchema } from 'openapi';
import { StyledAmountCell } from '../BillingInvoice.styles.tsx';
@ -19,6 +19,17 @@ type BillingInvoiceRowProps = {
usage?: number;
};
const StyledDescriptionCell = styled('div')(({ theme }) => ({
display: 'flex',
flexDirection: 'column',
gap: theme.spacing(0.5),
}));
const StyledSubText = styled(Typography)(({ theme }) => ({
color: theme.palette.text.secondary,
fontSize: theme.typography.body2.fontSize,
}));
export const BillingInvoiceRow = ({
quantity,
consumption,
@ -26,15 +37,37 @@ export const BillingInvoiceRow = ({
description,
currency,
totalAmount,
startDate,
endDate,
}: DetailedInvoicesLineSchema) => {
const percentage =
limit && limit > 0
? Math.min(100, Math.round(((consumption || 0) / limit) * 100))
: undefined;
const formattedStart = startDate
? new Date(startDate).toLocaleDateString(undefined, {
month: 'short',
day: 'numeric',
})
: undefined;
const formattedEnd = endDate
? new Date(endDate).toLocaleDateString(undefined, {
month: 'short',
day: 'numeric',
})
: undefined;
return (
<>
<div>{description}</div>
<StyledDescriptionCell>
<div>{description}</div>
{formattedStart || formattedEnd ? (
<StyledSubText>
{formattedStart} - {formattedEnd}
</StyledSubText>
) : null}
</StyledDescriptionCell>
<StyledCellWithIndicator>
<ConsumptionIndicator percentage={percentage || 0} />
{limit !== undefined ? formatLargeNumbers(limit) : ''}

View File

@ -20,6 +20,8 @@ export const useDetailedInvoices = (options: SWRConfiguration = {}) => {
);
const invoices = useMemo(() => data?.invoices ?? [], [data]);
const planPrice = data?.planPrice;
const planCurrency = data?.planCurrency;
return { invoices, error, loading: isLoading };
return { invoices, planPrice, planCurrency, error, loading: isLoading };
};

View File

@ -11,4 +11,8 @@ import type { DetailedInvoicesSchemaInvoicesItem } from './detailedInvoicesSchem
export interface DetailedInvoicesSchema {
/** List of invoices with their line items */
invoices: DetailedInvoicesSchemaInvoicesItem[];
/** The currency code for the plan price */
planCurrency?: string;
/** The plan price in minor currency units */
planPrice?: number;
}