mirror of
https://github.com/Unleash/unleash.git
synced 2025-09-24 17:51:14 +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:
parent
c6ab2a1cf7
commit
db90ad9c6c
@ -1,15 +1,18 @@
|
|||||||
import { type IInstanceStatus, InstancePlan } from 'interfaces/instance';
|
import { type IInstanceStatus, InstancePlan } from 'interfaces/instance';
|
||||||
import { BillingDetailsPro } from './BillingDetailsPro';
|
import { BillingDetailsPro } from './BillingDetailsPro';
|
||||||
import { BillingDetailsPAYG } from './BillingDetailsPAYG';
|
import { BillingDetailsPAYG } from './BillingDetailsPAYG';
|
||||||
|
import { BillingDetailsEnterpriseConsumption } from './BillingDetailsEnterpriseConsumption';
|
||||||
|
|
||||||
interface IBillingDetailsProps {
|
interface IBillingDetailsProps {
|
||||||
instanceStatus: IInstanceStatus;
|
instanceStatus: IInstanceStatus;
|
||||||
isPAYG: boolean;
|
isPAYG: boolean;
|
||||||
|
isEnterpriseConsumption: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const BillingDetails = ({
|
export const BillingDetails = ({
|
||||||
instanceStatus,
|
instanceStatus,
|
||||||
isPAYG,
|
isPAYG,
|
||||||
|
isEnterpriseConsumption,
|
||||||
}: IBillingDetailsProps) => {
|
}: IBillingDetailsProps) => {
|
||||||
if (isPAYG) {
|
if (isPAYG) {
|
||||||
return <BillingDetailsPAYG instanceStatus={instanceStatus} />;
|
return <BillingDetailsPAYG instanceStatus={instanceStatus} />;
|
||||||
@ -19,5 +22,9 @@ export const BillingDetails = ({
|
|||||||
return <BillingDetailsPro instanceStatus={instanceStatus} />;
|
return <BillingDetailsPro instanceStatus={instanceStatus} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isEnterpriseConsumption) {
|
||||||
|
return <BillingDetailsEnterpriseConsumption />;
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
@ -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>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
@ -1,6 +1,6 @@
|
|||||||
import { Alert, Grid, styled } from '@mui/material';
|
import { Alert, Grid, styled } from '@mui/material';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
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 useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||||
import { trialHasExpired, isTrialInstance } from 'utils/instanceTrial';
|
import { trialHasExpired, isTrialInstance } from 'utils/instanceTrial';
|
||||||
import { GridRow } from 'component/common/GridRow/GridRow';
|
import { GridRow } from 'component/common/GridRow/GridRow';
|
||||||
@ -65,7 +65,10 @@ export const BillingPlan = () => {
|
|||||||
} = useUiConfig();
|
} = useUiConfig();
|
||||||
const { instanceStatus } = useInstanceStatus();
|
const { instanceStatus } = useInstanceStatus();
|
||||||
|
|
||||||
|
const isPro =
|
||||||
|
instanceStatus?.plan && instanceStatus?.plan === InstancePlan.PRO;
|
||||||
const isPAYG = billing === 'pay-as-you-go';
|
const isPAYG = billing === 'pay-as-you-go';
|
||||||
|
const isEnterpriseConsumption = billing === 'enterprise-consumption';
|
||||||
|
|
||||||
if (!instanceStatus)
|
if (!instanceStatus)
|
||||||
return (
|
return (
|
||||||
@ -130,7 +133,7 @@ export const BillingPlan = () => {
|
|||||||
</GridCol>
|
</GridCol>
|
||||||
<GridCol>
|
<GridCol>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={!isPAYG}
|
condition={Boolean(isPro)}
|
||||||
show={
|
show={
|
||||||
<StyledPriceSpan>
|
<StyledPriceSpan>
|
||||||
${baseProPrice.toFixed(2)}
|
${baseProPrice.toFixed(2)}
|
||||||
@ -141,9 +144,14 @@ export const BillingPlan = () => {
|
|||||||
</GridRow>
|
</GridRow>
|
||||||
<GridRow>
|
<GridRow>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={isPAYG}
|
condition={isPAYG || isEnterpriseConsumption}
|
||||||
show={
|
show={
|
||||||
<StyledPAYGSpan>Pay-as-You-Go</StyledPAYGSpan>
|
<StyledPAYGSpan>
|
||||||
|
Pay-as-You-Go{' '}
|
||||||
|
{isEnterpriseConsumption
|
||||||
|
? 'Consumption'
|
||||||
|
: ''}
|
||||||
|
</StyledPAYGSpan>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</GridRow>
|
</GridRow>
|
||||||
@ -151,6 +159,7 @@ export const BillingPlan = () => {
|
|||||||
<BillingDetails
|
<BillingDetails
|
||||||
instanceStatus={instanceStatus}
|
instanceStatus={instanceStatus}
|
||||||
isPAYG={isPAYG}
|
isPAYG={isPAYG}
|
||||||
|
isEnterpriseConsumption={isEnterpriseConsumption}
|
||||||
/>
|
/>
|
||||||
</StyledPlanBox>
|
</StyledPlanBox>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
@ -39,6 +39,7 @@ export const useInstanceStatus = (): IUseInstanceStatusOutput => {
|
|||||||
refresh,
|
refresh,
|
||||||
isBilling:
|
isBilling:
|
||||||
uiConfig.billing === 'pay-as-you-go' ||
|
uiConfig.billing === 'pay-as-you-go' ||
|
||||||
|
uiConfig.billing === 'enterprise-consumption' ||
|
||||||
billingPlans.includes(data?.plan ?? InstancePlan.UNKNOWN),
|
billingPlans.includes(data?.plan ?? InstancePlan.UNKNOWN),
|
||||||
loading,
|
loading,
|
||||||
error,
|
error,
|
||||||
|
@ -19,7 +19,7 @@ export interface IUiConfig {
|
|||||||
name: string;
|
name: string;
|
||||||
slogan: string;
|
slogan: string;
|
||||||
environment?: string;
|
environment?: string;
|
||||||
billing?: 'subscription' | 'pay-as-you-go';
|
billing?: 'subscription' | 'pay-as-you-go' | 'enterprise-consumption';
|
||||||
unleashUrl?: string;
|
unleashUrl?: string;
|
||||||
version: string;
|
version: string;
|
||||||
versionInfo?: IVersionInfo;
|
versionInfo?: IVersionInfo;
|
||||||
|
Loading…
Reference in New Issue
Block a user