Skip to content

Commit

Permalink
feat: add billing limit max value, improve error handling (#24754)
Browse files Browse the repository at this point in the history
  • Loading branch information
zlwaterfield authored Sep 3, 2024
1 parent 08323a0 commit 6d26bc8
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 31 deletions.
47 changes: 22 additions & 25 deletions frontend/src/scenes/billing/BillingLimit.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { LemonButton, LemonInput } from '@posthog/lemon-ui'
import { useActions, useValues } from 'kea'
import { Field, Form } from 'kea-forms'
import { Form } from 'kea-forms'
import { LemonField } from 'lib/lemon-ui/LemonField'
import { Tooltip } from 'lib/lemon-ui/Tooltip'
import { useRef } from 'react'

Expand Down Expand Up @@ -48,8 +49,8 @@ export const BillingLimit = ({ product }: { product: BillingProductV2Type }): JS
) : (
<Tooltip title="Set a billing limit to control your recurring costs. Some features may stop working and data may be dropped if your usage exceeds your limit.">
<span className="text-sm" data-attr={`billing-limit-set-${product.type}`}>
You have a <b>${customLimitUsd}</b> billing limit set for{' '}
{product?.name?.toLowerCase()}.
You have a <b>${customLimitUsd?.toLocaleString()}</b> billing limit set
for {product?.name?.toLowerCase()}.
</span>
</Tooltip>
)}
Expand Down Expand Up @@ -78,30 +79,26 @@ export const BillingLimit = ({ product }: { product: BillingProductV2Type }): JS
)}{' '}
</div>
) : (
<div className="flex items-center justify-center gap-2.5">
<Field name="input" noStyle>
<div className="flex items-start justify-start gap-2.5">
<LemonField name="input" className="max-w-52">
{({ value, onChange, error }) => (
<Tooltip title={error}>
<div className="max-w-36">
<LemonInput
inputRef={limitInputRef}
type="number"
fullWidth={false}
status={error ? 'danger' : 'default'}
value={value}
data-attr={`billing-limit-input-${product.type}`}
onChange={onChange}
prefix={<b>$</b>}
disabled={billingLoading}
min={0}
step={10}
suffix={<>/ {billing?.billing_period?.interval}</>}
size="small"
/>
</div>
</Tooltip>
<LemonInput
inputRef={limitInputRef}
type="number"
fullWidth={false}
status={error ? 'danger' : 'default'}
value={value}
data-attr={`billing-limit-input-${product.type}`}
onChange={onChange}
prefix={<b>$</b>}
disabled={billingLoading}
min={0}
step={10}
suffix={<>/ {billing?.billing_period?.interval}</>}
size="small"
/>
)}
</Field>
</LemonField>

<LemonButton
loading={billingLoading}
Expand Down
14 changes: 10 additions & 4 deletions frontend/src/scenes/billing/billingLogic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,16 @@ export const billingLogic = kea<billingLogicType>([
},

updateBillingLimits: async (limits: { [key: string]: number | null }) => {
const response = await api.update('api/billing', { custom_limits_usd: limits })

lemonToast.success('Billing limits updated')
return parseBillingResponse(response)
try {
const response = await api.update('api/billing', { custom_limits_usd: limits })
lemonToast.success('Billing limits updated')
return parseBillingResponse(response)
} catch (error: any) {
lemonToast.error(
'There was an error updating your billing limits. Please try again or contact support.'
)
throw error
}
},

deactivateProduct: async (key: string) => {
Expand Down
8 changes: 6 additions & 2 deletions frontend/src/scenes/billing/billingProductLogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,6 @@ export const billingProductLogic = kea<billingProductLogicType>([
const projectedAmount = parseInt(product.projected_amount_usd || '0')
return product.tiers && projectedAmount ? projectedAmount * 1.5 : DEFAULT_BILLING_LIMIT
}

actions.setIsEditingBillingLimit(false)
actions.setBillingLimitInput(
values.hasCustomLimitSet ? values.customLimitUsd : calculateDefaultBillingLimit(props.product)
Expand Down Expand Up @@ -335,7 +334,12 @@ export const billingProductLogic = kea<billingProductLogicType>([
forms(({ actions, props, values }) => ({
billingLimitInput: {
errors: ({ input }) => ({
input: input === null || Number.isInteger(input) ? undefined : 'Please enter a whole number',
input:
input === null || Number.isInteger(input)
? input > 25000
? 'Please enter a number less than 25,000'
: undefined
: 'Please enter a whole number',
}),
submit: async ({ input }) => {
const addonTiers =
Expand Down

0 comments on commit 6d26bc8

Please sign in to comment.