diff --git a/frontend/__snapshots__/scenes-other-billing-product--billing-product-inclusion-only-with-addon--dark.png b/frontend/__snapshots__/scenes-other-billing-product--billing-product-inclusion-only-with-addon--dark.png
new file mode 100644
index 0000000000000..7da9dd9c65935
Binary files /dev/null and b/frontend/__snapshots__/scenes-other-billing-product--billing-product-inclusion-only-with-addon--dark.png differ
diff --git a/frontend/__snapshots__/scenes-other-billing-product--billing-product-inclusion-only-with-addon--light.png b/frontend/__snapshots__/scenes-other-billing-product--billing-product-inclusion-only-with-addon--light.png
new file mode 100644
index 0000000000000..7ba9c28aa3b0b
Binary files /dev/null and b/frontend/__snapshots__/scenes-other-billing-product--billing-product-inclusion-only-with-addon--light.png differ
diff --git a/frontend/__snapshots__/scenes-other-billing-product--billing-product-temporarily-free--dark.png b/frontend/__snapshots__/scenes-other-billing-product--billing-product-temporarily-free--dark.png
new file mode 100644
index 0000000000000..bbcde2e8024f1
Binary files /dev/null and b/frontend/__snapshots__/scenes-other-billing-product--billing-product-temporarily-free--dark.png differ
diff --git a/frontend/__snapshots__/scenes-other-billing-product--billing-product-temporarily-free--light.png b/frontend/__snapshots__/scenes-other-billing-product--billing-product-temporarily-free--light.png
new file mode 100644
index 0000000000000..29e522091393c
Binary files /dev/null and b/frontend/__snapshots__/scenes-other-billing-product--billing-product-temporarily-free--light.png differ
diff --git a/frontend/__snapshots__/scenes-other-billing-product--billing-product-with-addons--dark.png b/frontend/__snapshots__/scenes-other-billing-product--billing-product-with-addons--dark.png
new file mode 100644
index 0000000000000..e462988a9b075
Binary files /dev/null and b/frontend/__snapshots__/scenes-other-billing-product--billing-product-with-addons--dark.png differ
diff --git a/frontend/__snapshots__/scenes-other-billing-product--billing-product-with-addons--light.png b/frontend/__snapshots__/scenes-other-billing-product--billing-product-with-addons--light.png
new file mode 100644
index 0000000000000..2f875002c176b
Binary files /dev/null and b/frontend/__snapshots__/scenes-other-billing-product--billing-product-with-addons--light.png differ
diff --git a/frontend/__snapshots__/scenes-other-billing-product--billing-product-without-addons--dark.png b/frontend/__snapshots__/scenes-other-billing-product--billing-product-without-addons--dark.png
new file mode 100644
index 0000000000000..da4e9805d838d
Binary files /dev/null and b/frontend/__snapshots__/scenes-other-billing-product--billing-product-without-addons--dark.png differ
diff --git a/frontend/__snapshots__/scenes-other-billing-product--billing-product-without-addons--light.png b/frontend/__snapshots__/scenes-other-billing-product--billing-product-without-addons--light.png
new file mode 100644
index 0000000000000..8c584a081ba68
Binary files /dev/null and b/frontend/__snapshots__/scenes-other-billing-product--billing-product-without-addons--light.png differ
diff --git a/frontend/src/scenes/billing/BillingProduct.stories.tsx b/frontend/src/scenes/billing/BillingProduct.stories.tsx
new file mode 100644
index 0000000000000..e5d2fde651a36
--- /dev/null
+++ b/frontend/src/scenes/billing/BillingProduct.stories.tsx
@@ -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
+}
+
+export const BillingProductWithAddons = (): JSX.Element => {
+ useStorybookMocks({
+ get: {
+ '/api/billing/': {
+ ...billingJson,
+ },
+ },
+ })
+
+ const product = billingJson.products.find((product) => product.type === 'product_analytics')
+
+ return
+}
+
+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
+}
+
+export const BillingProductInclusionOnlyWithAddon = (): JSX.Element => {
+ useStorybookMocks({
+ get: {
+ '/api/billing/': {
+ ...billingJson,
+ },
+ },
+ })
+
+ const product = billingJson.products.find((product) => product.type === 'platform_and_support')
+
+ return
+}
diff --git a/frontend/src/scenes/billing/BillingProduct.tsx b/frontend/src/scenes/billing/BillingProduct.tsx
index 8654f18d72c17..8281bae289f1e 100644
--- a/frontend/src/scenes/billing/BillingProduct.tsx
+++ b/frontend/src/scenes/billing/BillingProduct.tsx
@@ -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'
@@ -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 (
+ ) : isTemporaryFreeProduct ? (
+
+
+
+
+ {/* 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') && (
+
+
+ Free usage for beta users until August 8, 2024. Then, get 30
+ million rows free every month.
+
+
+ )}
+
) : null}
>
)
diff --git a/frontend/src/types.ts b/frontend/src/types.ts
index fdf011a2e8e19..3c79ab23a81a7 100644
--- a/frontend/src/types.ts
+++ b/frontend/src/types.ts
@@ -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
}