diff --git a/apps/web/app/(dashboard)/home/(user)/billing/_components/personal-account-checkout-form.tsx b/apps/web/app/(dashboard)/home/(user)/billing/_components/personal-account-checkout-form.tsx index 6c10c6a7a..0a462d17c 100644 --- a/apps/web/app/(dashboard)/home/(user)/billing/_components/personal-account-checkout-form.tsx +++ b/apps/web/app/(dashboard)/home/(user)/billing/_components/personal-account-checkout-form.tsx @@ -20,11 +20,16 @@ import billingConfig from '~/config/billing.config'; import { createPersonalAccountCheckoutSession } from '../server-actions'; -export function PersonalAccountCheckoutForm() { +export function PersonalAccountCheckoutForm(props: { + customerId: string | null | undefined; +}) { const [pending, startTransition] = useTransition(); const [error, setError] = useState(false); const [checkoutToken, setCheckoutToken] = useState(); + // only allow trial if the user is not already a customer + const canStartTrial = !props.customerId; + // If the checkout token is set, render the embedded checkout component if (checkoutToken) { return ( @@ -40,10 +45,12 @@ export function PersonalAccountCheckoutForm() {
- Manage your Plan + + + - You can change your plan at any time. + @@ -55,6 +62,7 @@ export function PersonalAccountCheckoutForm() { { startTransition(async () => { try { diff --git a/apps/web/app/(dashboard)/home/(user)/billing/page.tsx b/apps/web/app/(dashboard)/home/(user)/billing/page.tsx index d7de63492..b06f959ff 100644 --- a/apps/web/app/(dashboard)/home/(user)/billing/page.tsx +++ b/apps/web/app/(dashboard)/home/(user)/billing/page.tsx @@ -42,7 +42,7 @@ async function PersonalAccountBillingPage() {
} + fallback={} > {(subscription) => ( (null); @@ -33,6 +36,9 @@ export function TeamAccountCheckoutForm(params: { accountId: string }) { ); } + // only allow trial if the user is not already a customer + const canStartTrial = !params.customerId; + // Otherwise, render the plan picker component return ( @@ -50,6 +56,7 @@ export function TeamAccountCheckoutForm(params: { accountId: string }) { { startTransition(async () => { const slug = routeParams.account as string; diff --git a/apps/web/app/(dashboard)/home/[account]/billing/page.tsx b/apps/web/app/(dashboard)/home/[account]/billing/page.tsx index 13be1ea7a..e889d4033 100644 --- a/apps/web/app/(dashboard)/home/[account]/billing/page.tsx +++ b/apps/web/app/(dashboard)/home/[account]/billing/page.tsx @@ -57,7 +57,10 @@ async function TeamAccountBillingPage({ params }: Params) { condition={subscription} fallback={ - + } > @@ -89,6 +92,7 @@ function CannotManageBillingAlert() { + diff --git a/apps/web/config/billing.config.ts b/apps/web/config/billing.config.ts index e3954ccce..a43e45f91 100644 --- a/apps/web/config/billing.config.ts +++ b/apps/web/config/billing.config.ts @@ -28,22 +28,6 @@ export default createBillingSchema({ cost: 9.99, type: 'base', }, - { - id: 'price_1NNwYHI1i3VnbZTqI2UzaHIe6', - name: 'Per Seat', - description: 'Add-on plan', - cost: 1.99, - type: 'per-seat', - }, - { - id: 'price_1NNwYHI1i3VnbZTqI2UzaHIe7', - name: 'Metered', - description: 'Metered plan', - cost: 0.99, - type: 'metered', - unit: 'GB', - included: 10, - }, ], }, { diff --git a/apps/web/public/locales/en/billing.json b/apps/web/public/locales/en/billing.json index 3843dc1b3..b7ead8855 100644 --- a/apps/web/public/locales/en/billing.json +++ b/apps/web/public/locales/en/billing.json @@ -20,6 +20,23 @@ "cannotManageBillingAlertDescription": "You do not have permissions to manage billing. Please contact your organization owner.", "manageTeamPlan": "Manage your Team Plan", "manageTeamPlanDescription": "Choose a plan that fits your team's needs. You can upgrade or downgrade your plan at any time.", + "flatSubscription": "Flat Subscription", + "billingInterval": { + "label": "Choose your billing interval", + "month": "Billed monthly", + "year": "Billed yearly" + }, + "trialPeriod": "{{period}} day trial", + "perPeriod": "per {{period}}", + "processing": "Processing...", + "proceedToPayment": "Proceed to Payment", + "startTrial": "Start Trial", + "perTeamMember": "Per team member", + "perUnitIncluded": "({{included}} included)", + "featuresLabel": "Features", + "detailsLabel": "Details", + "planPickerLabel": "Pick your preferred plan", + "planCardLabel": "Manage your Plan", "status": { "free": { "badge": "Free Plan", diff --git a/apps/web/public/locales/en/common.json b/apps/web/public/locales/en/common.json index 4efdbf74e..af9599120 100644 --- a/apps/web/public/locales/en/common.json +++ b/apps/web/public/locales/en/common.json @@ -57,9 +57,5 @@ "label": "Member", "description": "Cannot invite members or change settings" } - }, - "billingInterval": { - "month": "Billed monthly", - "year": "Billed yearly" } } diff --git a/packages/billing-gateway/src/components/plan-picker.tsx b/packages/billing-gateway/src/components/plan-picker.tsx index 29a57d298..77d837927 100644 --- a/packages/billing-gateway/src/components/plan-picker.tsx +++ b/packages/billing-gateway/src/components/plan-picker.tsx @@ -5,6 +5,7 @@ import { useMemo } from 'react'; import { zodResolver } from '@hookform/resolvers/zod'; import { ArrowRight, CheckCircle } from 'lucide-react'; import { useForm } from 'react-hook-form'; +import { useTranslation } from 'react-i18next'; import { z } from 'zod'; import { @@ -32,7 +33,6 @@ import { RadioGroupItem, RadioGroupItemLabel, } from '@kit/ui/radio-group'; -import { Separator } from '@kit/ui/separator'; import { Trans } from '@kit/ui/trans'; import { cn } from '@kit/ui/utils'; @@ -40,6 +40,7 @@ export function PlanPicker( props: React.PropsWithChildren<{ config: BillingConfig; onSubmit: (data: { planId: string; productId: string }) => void; + canStartTrial?: boolean; pending?: boolean; }>, ) { @@ -94,6 +95,8 @@ export function PlanPicker( } }, [props.config, planId]); + const { t } = useTranslation(`billing`); + return (
- Choose your billing interval + @@ -148,7 +151,7 @@ export function PlanPicker( @@ -167,7 +170,9 @@ export function PlanPicker( name={'planId'} render={({ field }) => ( - Pick your preferred plan + + + @@ -215,10 +220,18 @@ export function PlanPicker( 'flex flex-col justify-center space-y-2' } > - {product.name} + + + - {product.description} + @@ -227,10 +240,19 @@ export function PlanPicker( 'flex items-center space-x-4 text-right' } > - +
- {plan.trialPeriod} day trial +
@@ -247,7 +269,12 @@ export function PlanPicker(
- per {selectedInterval} +
@@ -267,14 +294,14 @@ export function PlanPicker(