mirror of
https://github.com/Unleash/unleash.git
synced 2025-06-27 01:19:00 +02:00
feat: paid users limit in UI (#3210)
This commit is contained in:
parent
46fb1d7886
commit
e209acfa25
@ -12,6 +12,7 @@ import { CreateButton } from 'component/common/CreateButton/CreateButton';
|
|||||||
import { ADMIN } from 'component/providers/AccessProvider/permissions';
|
import { ADMIN } from 'component/providers/AccessProvider/permissions';
|
||||||
import { formatUnknownError } from 'utils/formatUnknownError';
|
import { formatUnknownError } from 'utils/formatUnknownError';
|
||||||
import { GO_BACK } from 'constants/navigate';
|
import { GO_BACK } from 'constants/navigate';
|
||||||
|
import { SeatCostWarning } from './SeatCostWarning/SeatCostWarning';
|
||||||
|
|
||||||
const CreateUser = () => {
|
const CreateUser = () => {
|
||||||
const { setToastApiError } = useToast();
|
const { setToastApiError } = useToast();
|
||||||
@ -86,6 +87,7 @@ const CreateUser = () => {
|
|||||||
documentationLinkLabel="User management documentation"
|
documentationLinkLabel="User management documentation"
|
||||||
formatApiCode={formatApiCode}
|
formatApiCode={formatApiCode}
|
||||||
>
|
>
|
||||||
|
<SeatCostWarning />
|
||||||
<UserForm
|
<UserForm
|
||||||
errors={errors}
|
errors={errors}
|
||||||
handleSubmit={handleSubmit}
|
handleSubmit={handleSubmit}
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
import { VFC } from 'react';
|
||||||
|
import { Alert } from '@mui/material';
|
||||||
|
import { useUsersPlan } from 'hooks/useUsersPlan';
|
||||||
|
import { useUsers } from 'hooks/api/getters/useUsers/useUsers';
|
||||||
|
|
||||||
|
export const SeatCostWarning: VFC = () => {
|
||||||
|
const { users } = useUsers();
|
||||||
|
const { isBillingUsers, seats, planUsers } = useUsersPlan(users);
|
||||||
|
|
||||||
|
if (!isBillingUsers) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Alert severity="info" sx={{ marginBottom: theme => theme.spacing(3) }}>
|
||||||
|
<p>
|
||||||
|
<strong>Heads up!</strong> You are exceeding your allocated free
|
||||||
|
members included in your plan ({planUsers.length} of {seats}).
|
||||||
|
Creating this user will add <strong>$15/month</strong> to your
|
||||||
|
invoice, starting with your next payment.
|
||||||
|
</p>
|
||||||
|
</Alert>
|
||||||
|
);
|
||||||
|
};
|
@ -0,0 +1,37 @@
|
|||||||
|
import { VFC } from 'react';
|
||||||
|
import { Link as RouterLink } from 'react-router-dom';
|
||||||
|
import { Alert, Link } from '@mui/material';
|
||||||
|
import { useUsersPlan } from 'hooks/useUsersPlan';
|
||||||
|
import { useUsers } from 'hooks/api/getters/useUsers/useUsers';
|
||||||
|
|
||||||
|
const userLimit = 20;
|
||||||
|
|
||||||
|
export const UserLimitWarning: VFC = () => {
|
||||||
|
const { users } = useUsers();
|
||||||
|
const { isBillingUsers, planUsers } = useUsersPlan(users);
|
||||||
|
|
||||||
|
if (!isBillingUsers) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (planUsers?.length < userLimit) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Alert severity="info" sx={{ marginBottom: theme => theme.spacing(3) }}>
|
||||||
|
<p>
|
||||||
|
<strong>Heads up!</strong> You have reached your maximum number
|
||||||
|
of registered users for you PRO account (up to max {userLimit}{' '}
|
||||||
|
users). If you need more users please{' '}
|
||||||
|
<Link
|
||||||
|
component={RouterLink}
|
||||||
|
to="https://www.getunleash.io/signup-enterprise"
|
||||||
|
>
|
||||||
|
get in touch with us
|
||||||
|
</Link>
|
||||||
|
.
|
||||||
|
</p>
|
||||||
|
</Alert>
|
||||||
|
);
|
||||||
|
};
|
@ -33,6 +33,7 @@ import { UsersActionsCell } from './UsersActionsCell/UsersActionsCell';
|
|||||||
import { Search } from 'component/common/Search/Search';
|
import { Search } from 'component/common/Search/Search';
|
||||||
import { UserAvatar } from 'component/common/UserAvatar/UserAvatar';
|
import { UserAvatar } from 'component/common/UserAvatar/UserAvatar';
|
||||||
import { useConditionallyHiddenColumns } from 'hooks/useConditionallyHiddenColumns';
|
import { useConditionallyHiddenColumns } from 'hooks/useConditionallyHiddenColumns';
|
||||||
|
import { UserLimitWarning } from './UserLimitWarning/UserLimitWarning';
|
||||||
|
|
||||||
const UsersList = () => {
|
const UsersList = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@ -262,6 +263,7 @@ const UsersList = () => {
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
<UserLimitWarning />
|
||||||
<SearchHighlightProvider value={globalFilter}>
|
<SearchHighlightProvider value={globalFilter}>
|
||||||
<VirtualizedTable
|
<VirtualizedTable
|
||||||
rows={rows}
|
rows={rows}
|
||||||
|
@ -7,6 +7,8 @@ import useUiConfig from './api/getters/useUiConfig/useUiConfig';
|
|||||||
export interface IUsersPlanOutput {
|
export interface IUsersPlanOutput {
|
||||||
planUsers: IUser[];
|
planUsers: IUser[];
|
||||||
isBillingUsers: boolean;
|
isBillingUsers: boolean;
|
||||||
|
seats: number;
|
||||||
|
extraSeats: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useUsersPlan = (users: IUser[]): IUsersPlanOutput => {
|
export const useUsersPlan = (users: IUser[]): IUsersPlanOutput => {
|
||||||
@ -24,7 +26,11 @@ export const useUsersPlan = (users: IUser[]): IUsersPlanOutput => {
|
|||||||
[users, isBillingUsers, seats]
|
[users, isBillingUsers, seats]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const extraSeats = planUsers.filter(user => user.paid).length;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
seats,
|
||||||
|
extraSeats,
|
||||||
planUsers,
|
planUsers,
|
||||||
isBillingUsers,
|
isBillingUsers,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user