Skip to content

Commit

Permalink
feat(billing): show usage for temporarily free products (#23417)
Browse files Browse the repository at this point in the history
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
raquelmsmith and github-actions[bot] authored Jul 2, 2024
1 parent 3813df9 commit aee5a79
Show file tree
Hide file tree
Showing 11 changed files with 301 additions and 2 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
278 changes: 278 additions & 0 deletions frontend/src/scenes/billing/BillingProduct.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,278 @@
import { Meta } from '@storybook/react'

import { mswDecorator, useStorybookMocks } from '~/mocks/browser'
import { billingJson } from '~/mocks/fixtures/_billing'
import preflightJson from '~/mocks/fixtures/_preflight.json'
import { BillingProductV2Type } from '~/types'

import { BillingProduct } from './BillingProduct'

const meta: Meta = {
title: 'Scenes-Other/Billing Product',
parameters: {
layout: 'padded',
viewMode: 'story',
mockDate: '2024-03-10',
},
decorators: [
mswDecorator({
get: {
'/_preflight': {
...preflightJson,
cloud: true,
realm: 'cloud',
},
},
}),
],
}
export default meta

export const BillingProductWithoutAddons = (): JSX.Element => {
useStorybookMocks({
get: {
'/api/billing/': {
...billingJson,
},
},
})

const product = billingJson.products.find((product) => product.type === 'session_replay')

return <BillingProduct product={product as BillingProductV2Type} />
}

export const BillingProductWithAddons = (): JSX.Element => {
useStorybookMocks({
get: {
'/api/billing/': {
...billingJson,
},
},
})

const product = billingJson.products.find((product) => product.type === 'product_analytics')

return <BillingProduct product={product as BillingProductV2Type} />
}

export const BillingProductTemporarilyFree = (): JSX.Element => {
useStorybookMocks({
get: {
'/api/billing/': {
...billingJson,
},
},
})

const product = {
name: 'Data Warehouse',
headline: 'A single source for all your data.',
description: 'Import external data and query it alongside your analytics data.',
price_description: null,
usage_key: 'rows_synced',
image_url: 'https://posthog.com/images/product/product-icons/data-warehouse.svg',
screenshot_url: null,
icon_key: 'IconBuilding',
docs_url: 'https://posthog.com/docs/data-warehouse',
subscribed: false,
plans: [
{
plan_key: 'free-20240530-beta-users-initial',
product_key: 'data_warehouse',
name: 'Free (beta)',
description: 'Import external data and query it alongside your analytics data.',
image_url: 'https://posthog.com/images/product/product-icons/data-warehouse.svg',
docs_url: 'https://posthog.com/docs/data-warehouse',
note: null,
unit: 'row',
flat_rate: false,
free_allocation: null,
features: [
{
key: 'data_warehouse_integrations',
name: 'One-click integrations',
description: 'Sync data from Stripe, Hubspot, Zendesk, Snowflake, Postgres, and more.',
unit: null,
limit: null,
note: null,
is_plan_default: true,
},
{
key: 'data_warehouse_views',
name: 'Custom views',
description: 'Create views to model your data and streamline queries.',
unit: null,
limit: null,
note: null,
is_plan_default: true,
},
{
key: 'data_warehouse_direct_linking',
name: 'Direct linking',
description:
'Link directly to your data sources such as S3, Google Cloud Storage, and Cloudflare R2. Data stays on your servers.',
unit: null,
limit: null,
note: null,
is_plan_default: true,
},
{
key: 'data_warehouse_joins',
name: 'Cross-source joins',
description:
'Join data from any source, including your PostHog analytics data, to easily get the answers you need.',
unit: null,
limit: null,
note: null,
is_plan_default: true,
},
{
key: 'data_warehouse_unified_querying',
name: 'Unified querying',
description: 'Query all your business and product data directly inside PostHog.',
unit: null,
limit: null,
note: null,
is_plan_default: true,
},
{
key: 'data_warehouse_insights_visualization',
name: 'Data visualization',
description:
'Create insights from the data you import and add them to your PostHog dashboards.',
unit: null,
limit: null,
note: null,
is_plan_default: true,
},
{
key: 'data_warehouse_incremental_sync',
name: 'Incremental sync',
description: 'Sync only the data that has changed since the last sync.',
unit: null,
limit: null,
note: null,
is_plan_default: true,
},
{
key: 'data_warehouse_sync_frequency',
name: 'Sync frequency',
description: 'Choose how often you want to sync your data - daily, weekly, or monthly.',
unit: null,
limit: null,
note: null,
is_plan_default: true,
},
],
tiers: null,
current_plan: true,
included_if: null,
contact_support: null,
unit_amount_usd: null,
initial_billing_limit: null,
},
],
type: 'data_warehouse',
free_allocation: 0,
tiers: null,
tiered: false,
unit_amount_usd: null,
current_amount_usd_before_addons: null,
current_amount_usd: null,
current_usage: 2345,
usage_limit: 0,
has_exceeded_limit: false,
percentage_usage: 0,
projected_usage: 76723,
projected_amount_usd: null,
unit: 'row',
addons: [],
contact_support: false,
inclusion_only: false,
features: [
{
key: 'data_warehouse_integrations',
name: 'One-click integrations',
description: 'Sync data from Stripe, Hubspot, Zendesk, Snowflake, Postgres, and more.',
images: null,
icon_key: null,
type: null,
},
{
key: 'data_warehouse_direct_linking',
name: 'Direct linking',
description:
'Link directly to your data sources such as S3, Google Cloud Storage, and Cloudflare R2. Data stays on your servers.',
images: null,
icon_key: null,
type: null,
},
{
key: 'data_warehouse_views',
name: 'Custom views',
description: 'Create views to model your data and streamline queries.',
images: null,
icon_key: null,
type: null,
},
{
key: 'data_warehouse_joins',
name: 'Cross-source joins',
description:
'Join data from any source, including your PostHog analytics data, to easily get the answers you need.',
images: null,
icon_key: null,
type: null,
},
{
key: 'data_warehouse_unified_querying',
name: 'Unified querying',
description: 'Query all your business and product data directly inside PostHog.',
images: null,
icon_key: null,
type: null,
},
{
key: 'data_warehouse_insights_visualization',
name: 'Data visualization',
description: 'Create insights from the data you import and add them to your PostHog dashboards.',
images: null,
icon_key: null,
type: null,
},
{
key: 'data_warehouse_incremental_sync',
name: 'Incremental sync',
description: 'Sync only the data that has changed since the last sync.',
images: null,
icon_key: null,
type: null,
},
{
key: 'data_warehouse_sync_frequency',
name: 'Sync frequency',
description: 'Choose how often you want to sync your data - daily, weekly, or monthly.',
images: null,
icon_key: null,
type: null,
},
],
}

return <BillingProduct product={product as BillingProductV2Type} />
}

export const BillingProductInclusionOnlyWithAddon = (): JSX.Element => {
useStorybookMocks({
get: {
'/api/billing/': {
...billingJson,
},
},
})

const product = billingJson.products.find((product) => product.type === 'platform_and_support')

return <BillingProduct product={product as BillingProductV2Type} />
}
23 changes: 22 additions & 1 deletion frontend/src/scenes/billing/BillingProduct.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { eventUsageLogic } from 'lib/utils/eventUsageLogic'
import { useRef } from 'react'
import { getProductIcon } from 'scenes/products/Products'

import { BillingProductV2AddonType, BillingProductV2Type, BillingTierType } from '~/types'
import { BillingProductV2AddonType, BillingProductV2Type, BillingTierType, ProductKey } from '~/types'

import { convertLargeNumberToWords, getUpgradeProductLink, summarizeUsage } from './billing-utils'
import { BillingGauge } from './BillingGauge'
Expand Down Expand Up @@ -90,6 +90,10 @@ export const BillingProduct = ({ product }: { product: BillingProductV2Type }):
700: 'medium',
})

// Used when a product is offered for free to beta users, so we want to show usage but
// there is no pricing (aka tiers) and no free_allotment
const isTemporaryFreeProduct = !product.tiered && !product.free_allocation && !product.inclusion_only

return (
<div
className={clsx('flex flex-wrap max-w-300 pb-8', {
Expand Down Expand Up @@ -277,6 +281,23 @@ export const BillingProduct = ({ product }: { product: BillingProductV2Type }):
</div>
</Tooltip>
</div>
) : isTemporaryFreeProduct ? (
<div className="grow">
<div className="grow">
<BillingGauge items={billingGaugeItems} product={product} />
</div>
{/* TODO: rms: remove this notice after August 8 2024 */}
{product.type == ProductKey.DATA_WAREHOUSE &&
currentPlan?.plan_key === 'free-20240530-beta-users-initial' &&
new Date() < new Date('2024-08-08') && (
<LemonBanner type="info" className="mb-6">
<p>
Free usage for beta users until August 8, 2024. Then, get 30
million rows free every month.
</p>
</LemonBanner>
)}
</div>
) : null}
</>
)
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1624,7 +1624,7 @@ export interface BillingPlanType {
tiers?: BillingTierType[] | null
unit_amount_usd: string | null
included_if?: 'no_active_subscription' | 'has_subscription' | null
initial_billing_limit?: number
initial_billing_limit?: number | null
contact_support: boolean | null
}

Expand Down

0 comments on commit aee5a79

Please sign in to comment.