require a minimum number of seats to be purchased to continue.

Этот коммит содержится в:
Conor Macpherson
2023-04-17 15:00:14 -04:00
родитель 5b42689529
Коммит fa01ced588
2 изменённых файлов: 22 добавлений и 12 удалений

Просмотреть файл

@@ -24,7 +24,7 @@ const MAX_TRANSACTION_VALUE = 1_000_000 - 1;
interface Props { interface Props {
canSubmit: boolean; canSubmit: boolean;
licensedSeats: number; licensedSeats: number;
initialSeats: number; minimumSeats: number;
submit: () => void; submit: () => void;
updateSeats: (seats: number) => void; updateSeats: (seats: number) => void;
} }
@@ -34,10 +34,10 @@ export default function SelfHostedExpansionCard(props: Props) {
const license = useSelector(getLicense); const license = useSelector(getLicense);
const startsAt = moment(parseInt(license.StartsAt, 10)).format('MMM. D, YYYY'); const startsAt = moment(parseInt(license.StartsAt, 10)).format('MMM. D, YYYY');
const endsAt = moment(parseInt(license.ExpiresAt, 10)).format('MMM. D, YYYY'); const endsAt = moment(parseInt(license.ExpiresAt, 10)).format('MMM. D, YYYY');
const [additionalSeats, setAdditionalSeats] = useState(props.initialSeats); const [additionalSeats, setAdditionalSeats] = useState(props.minimumSeats);
const [overMaxSeats, setOverMaxSeats] = useState(false); const [overMaxSeats, setOverMaxSeats] = useState(false);
const licenseExpiry = new Date(parseInt(license.ExpiresAt, 10)); const licenseExpiry = new Date(parseInt(license.ExpiresAt, 10));
const invalidAdditionalSeats = additionalSeats === 0 || isNaN(additionalSeats); const invalidAdditionalSeats = additionalSeats === 0 || isNaN(additionalSeats) || additionalSeats < props.minimumSeats;
const [products] = useGetSelfHostedProducts(); const [products] = useGetSelfHostedProducts();
const currentProduct = findSelfHostedProductBySku(products, license.SkuShortName); const currentProduct = findSelfHostedProductBySku(products, license.SkuShortName);
const costPerMonth = currentProduct?.price_per_seat || 0; const costPerMonth = currentProduct?.price_per_seat || 0;
@@ -76,9 +76,9 @@ export default function SelfHostedExpansionCard(props: Props) {
const maxAdditionalSeats = getMaximumAdditionalSeats(); const maxAdditionalSeats = getMaximumAdditionalSeats();
const handleNewSeatsInputChange = (e: React.ChangeEvent<HTMLInputElement>) => { const handleNewSeatsInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const requestedSeats = parseInt(e.target.value, 10); let requestedSeats = parseInt(e.target.value, 10);
if (requestedSeats <= 0) { if (!isNaN(requestedSeats) && requestedSeats <= 0) {
e.preventDefault(); e.preventDefault();
return; return;
} }
@@ -141,12 +141,11 @@ export default function SelfHostedExpansionCard(props: Props) {
type='number' type='number'
value={additionalSeats} value={additionalSeats}
onChange={handleNewSeatsInputChange} onChange={handleNewSeatsInputChange}
error={invalidAdditionalSeats}
disabled={maxAdditionalSeats === 0} disabled={maxAdditionalSeats === 0}
/> />
</div> </div>
<div className='SelfHostedExpansionRHSCard__AddSeatsWarning'> <div className='SelfHostedExpansionRHSCard__AddSeatsWarning'>
{invalidAdditionalSeats && !overMaxSeats && {invalidAdditionalSeats && !overMaxSeats && isNaN(additionalSeats) &&
<FormattedMessage <FormattedMessage
id='self_hosted_expansion_rhs_card_must_add_seats_warning' id='self_hosted_expansion_rhs_card_must_add_seats_warning'
defaultMessage='{warningIcon} You must add a seat to continue' defaultMessage='{warningIcon} You must add a seat to continue'
@@ -155,6 +154,16 @@ export default function SelfHostedExpansionCard(props: Props) {
}} }}
/> />
} }
{invalidAdditionalSeats && additionalSeats < props.minimumSeats &&
<FormattedMessage
id='self_hosted_expansion_rhs_card_must_purchase_enough_seats'
defaultMessage='{warningIcon} You must purchase at least {minimumSeats} seats to be compliant with your license'
values={{
warningIcon: <WarningIcon additionalClassName={'SelfHostedExpansionRHSCard__warning'}/>,
minimumSeats: props.minimumSeats
}}
/>
}
{overMaxSeats && maxAdditionalSeats > 0 && {overMaxSeats && maxAdditionalSeats > 0 &&
<FormattedMessage <FormattedMessage
id='self_hosted_expansion_rhs_card_maximum_seats_warning' id='self_hosted_expansion_rhs_card_maximum_seats_warning'
@@ -203,7 +212,7 @@ export default function SelfHostedExpansionCard(props: Props) {
</div> </div>
<button <button
className='btn btn-primary SelfHostedExpansionRHSCard__CompletePurchaseButton' className='btn btn-primary SelfHostedExpansionRHSCard__CompletePurchaseButton'
disabled={!props.canSubmit || maxAdditionalSeats === 0} disabled={!props.canSubmit || maxAdditionalSeats === 0 || invalidAdditionalSeats}
onClick={props.submit} onClick={props.submit}
> >
<FormattedMessage <FormattedMessage

Просмотреть файл

@@ -175,12 +175,13 @@ export default function SelfHostedExpansionModal() {
const licensedSeats = parseInt(license.Users, 10); const licensedSeats = parseInt(license.Users, 10);
const currentPlan = license.SkuName; const currentPlan = license.SkuName;
const activeUsers = useSelector(getFilteredUsersStats)?.total_users_count || 0; const activeUsers = useSelector(getFilteredUsersStats)?.total_users_count || 0;
const [additionalSeats, setAdditionalSeats] = useState(activeUsers <= licensedSeats ? 1 : activeUsers - licensedSeats); const [minimumSeats] = useState(activeUsers <= licensedSeats ? 1 : activeUsers - licensedSeats);
const [requestedSeats, setRequestedSeats] = useState(minimumSeats)
const [stripeLoadHint, setStripeLoadHint] = useState(Math.random()); const [stripeLoadHint, setStripeLoadHint] = useState(Math.random());
const stripeRef = useLoadStripe(stripeLoadHint); const stripeRef = useLoadStripe(stripeLoadHint);
const initialState = makeInitialState(additionalSeats); const initialState = makeInitialState(requestedSeats);
const [formState, setFormState] = useState<FormState>(initialState); const [formState, setFormState] = useState<FormState>(initialState);
const [show] = useState(true); const [show] = useState(true);
const canRetry = formState.error !== '422'; const canRetry = formState.error !== '422';
@@ -492,12 +493,12 @@ export default function SelfHostedExpansionModal() {
<SelfHostedExpansionCard <SelfHostedExpansionCard
updateSeats={(seats: number) => { updateSeats={(seats: number) => {
setFormState({...formState, seats}); setFormState({...formState, seats});
setAdditionalSeats(seats); setRequestedSeats(seats);
}} }}
canSubmit={canSubmitForm} canSubmit={canSubmitForm}
submit={submit} submit={submit}
licensedSeats={licensedSeats} licensedSeats={licensedSeats}
initialSeats={additionalSeats} minimumSeats={minimumSeats}
/> />
</div> </div>
</div> </div>