1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-07-26 13:48:33 +02:00

feat: enterprise consumption billing (#9862)

Initial PR that adds logic for displaying a link to stripe to view
consumption based pricing in the billing overview

---------

Co-authored-by: Nuno Góis <github@nunogois.com>
This commit is contained in:
Fredrik Strand Oseberg 2025-05-06 13:15:31 +02:00 committed by GitHub
parent c6ab2a1cf7
commit db90ad9c6c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 62 additions and 5 deletions

View File

@ -1,15 +1,18 @@
import { type IInstanceStatus, InstancePlan } from 'interfaces/instance';
import { BillingDetailsPro } from './BillingDetailsPro';
import { BillingDetailsPAYG } from './BillingDetailsPAYG';
import { BillingDetailsEnterpriseConsumption } from './BillingDetailsEnterpriseConsumption';
interface IBillingDetailsProps {
instanceStatus: IInstanceStatus;
isPAYG: boolean;
isEnterpriseConsumption: boolean;
}
export const BillingDetails = ({
instanceStatus,
isPAYG,
isEnterpriseConsumption,
}: IBillingDetailsProps) => {
if (isPAYG) {
return <BillingDetailsPAYG instanceStatus={instanceStatus} />;
@ -19,5 +22,9 @@ export const BillingDetails = ({
return <BillingDetailsPro instanceStatus={instanceStatus} />;
}
if (isEnterpriseConsumption) {
return <BillingDetailsEnterpriseConsumption />;
}
return null;
};

View File

@ -0,0 +1,40 @@
import { styled, Typography, Grid, Button } from '@mui/material';
import { Link } from 'react-router-dom';
import { GridRow } from 'component/common/GridRow/GridRow';
import { GridCol } from 'component/common/GridCol/GridCol';
import LaunchIcon from '@mui/icons-material/Launch';
import { useInstanceStatus } from 'hooks/api/getters/useInstanceStatus/useInstanceStatus';
import { formatApiPath } from 'utils/formatPath';
const StyledInfoLabel = styled(Typography)(({ theme }) => ({
fontSize: theme.fontSizes.smallerBody,
color: theme.palette.text.secondary,
}));
const StyledButton = styled(Button)(({ theme }) => ({
marginTop: theme.spacing(1),
display: 'inline-flex',
alignItems: 'center',
}));
export const BillingDetailsEnterpriseConsumption = () => {
const PORTAL_URL = formatApiPath('api/admin/invoices/portal');
return (
<>
<Grid container>
<GridRow sx={(theme) => ({ marginBottom: theme.spacing(3) })}>
<GridCol vertical>
<StyledButton
href={PORTAL_URL}
variant='outlined'
endIcon={<LaunchIcon />}
>
View usage charges
</StyledButton>
</GridCol>
</GridRow>
</Grid>
</>
);
};

View File

@ -1,6 +1,6 @@
import { Alert, Grid, styled } from '@mui/material';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { InstanceState } from 'interfaces/instance';
import { InstancePlan, InstanceState } from 'interfaces/instance';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { trialHasExpired, isTrialInstance } from 'utils/instanceTrial';
import { GridRow } from 'component/common/GridRow/GridRow';
@ -65,7 +65,10 @@ export const BillingPlan = () => {
} = useUiConfig();
const { instanceStatus } = useInstanceStatus();
const isPro =
instanceStatus?.plan && instanceStatus?.plan === InstancePlan.PRO;
const isPAYG = billing === 'pay-as-you-go';
const isEnterpriseConsumption = billing === 'enterprise-consumption';
if (!instanceStatus)
return (
@ -130,7 +133,7 @@ export const BillingPlan = () => {
</GridCol>
<GridCol>
<ConditionallyRender
condition={!isPAYG}
condition={Boolean(isPro)}
show={
<StyledPriceSpan>
${baseProPrice.toFixed(2)}
@ -141,9 +144,14 @@ export const BillingPlan = () => {
</GridRow>
<GridRow>
<ConditionallyRender
condition={isPAYG}
condition={isPAYG || isEnterpriseConsumption}
show={
<StyledPAYGSpan>Pay-as-You-Go</StyledPAYGSpan>
<StyledPAYGSpan>
Pay-as-You-Go{' '}
{isEnterpriseConsumption
? 'Consumption'
: ''}
</StyledPAYGSpan>
}
/>
</GridRow>
@ -151,6 +159,7 @@ export const BillingPlan = () => {
<BillingDetails
instanceStatus={instanceStatus}
isPAYG={isPAYG}
isEnterpriseConsumption={isEnterpriseConsumption}
/>
</StyledPlanBox>
</Grid>

View File

@ -39,6 +39,7 @@ export const useInstanceStatus = (): IUseInstanceStatusOutput => {
refresh,
isBilling:
uiConfig.billing === 'pay-as-you-go' ||
uiConfig.billing === 'enterprise-consumption' ||
billingPlans.includes(data?.plan ?? InstancePlan.UNKNOWN),
loading,
error,

View File

@ -19,7 +19,7 @@ export interface IUiConfig {
name: string;
slogan: string;
environment?: string;
billing?: 'subscription' | 'pay-as-you-go';
billing?: 'subscription' | 'pay-as-you-go' | 'enterprise-consumption';
unleashUrl?: string;
version: string;
versionInfo?: IVersionInfo;