From 427ea2f845d3f89fbf44fabd50fdef79a92d1218 Mon Sep 17 00:00:00 2001 From: giancarlo Date: Thu, 18 Apr 2024 19:59:28 +0800 Subject: [PATCH] Update UI styling and add checkout redirect ability This commit does two main things. First, it refactors UI styling in the alert component, changing the location of some utility classes and enhancing color gradients for different alert variants. Second, it introduces the ability to specify whether to redirect to checkout on the pricing page, thereby improving user experience. This adds more flexibility to the 'PricingTable' and 'CheckoutButton' components, allowing for optional redirection and enhanced configurability. --- apps/web/app/(marketing)/page.tsx | 1 + apps/web/app/(marketing)/pricing/page.tsx | 7 ++++- .../gateway/src/components/pricing-table.tsx | 30 +++++++++++++++---- packages/ui/src/shadcn/alert.tsx | 14 ++++----- 4 files changed, 38 insertions(+), 14 deletions(-) diff --git a/apps/web/app/(marketing)/page.tsx b/apps/web/app/(marketing)/page.tsx index bd00a799a..d3770a2a0 100644 --- a/apps/web/app/(marketing)/page.tsx +++ b/apps/web/app/(marketing)/page.tsx @@ -272,6 +272,7 @@ function Home() { config={billingConfig} paths={{ signUp: pathsConfig.auth.signUp, + subscription: pathsConfig.app.personalAccountBilling, }} /> diff --git a/apps/web/app/(marketing)/pricing/page.tsx b/apps/web/app/(marketing)/pricing/page.tsx index 5cdeb23a2..766f3f777 100644 --- a/apps/web/app/(marketing)/pricing/page.tsx +++ b/apps/web/app/(marketing)/pricing/page.tsx @@ -14,6 +14,11 @@ export const generateMetadata = async () => { }; }; +const paths = { + signUp: pathsConfig.auth.signUp, + subscription: pathsConfig.app.personalAccountBilling, +}; + async function PricingPage() { const { t } = await createI18nServerInstance(); @@ -25,7 +30,7 @@ async function PricingPage() { />
- +
); diff --git a/packages/billing/gateway/src/components/pricing-table.tsx b/packages/billing/gateway/src/components/pricing-table.tsx index c4f9145a5..57a0ab342 100644 --- a/packages/billing/gateway/src/components/pricing-table.tsx +++ b/packages/billing/gateway/src/components/pricing-table.tsx @@ -25,18 +25,22 @@ import { LineItemDetails } from './line-item-details'; interface Paths { signUp: string; + subscription: string; } export function PricingTable({ config, paths, CheckoutButtonRenderer, + redirectToCheckout = true, displayPlanDetails = true, }: { config: BillingConfig; paths: Paths; displayPlanDetails?: boolean; + redirectToCheckout?: boolean; + CheckoutButtonRenderer?: React.ComponentType<{ planId: string; highlighted?: boolean; @@ -88,6 +92,7 @@ export function PricingTable({ selectable key={plan.id} plan={plan} + redirectToCheckout={redirectToCheckout} primaryLineItem={primaryLineItem} product={product} paths={paths} @@ -106,14 +111,14 @@ function PricingItem( className?: string; displayPlanDetails: boolean; - paths: { - signUp: string; - }; + paths: Paths; selectable: boolean; primaryLineItem: z.infer; + redirectToCheckout?: boolean; + plan: { id: string; lineItems: z.infer[]; @@ -251,10 +256,11 @@ function PricingItem( condition={props.plan.id && props.CheckoutButton} fallback={ } > @@ -410,12 +416,24 @@ function DefaultCheckoutButton( name: string; }; - signUpPath: string; + paths: Paths; + redirectToCheckout?: boolean; + highlighted?: boolean; }>, ) { + const redirectToCheckoutParam = props.redirectToCheckout + ? '?redirectToCheckout=true' + : ''; + + const planId = props.plan.id; + const signUpPath = props.paths.signUp; + const subscriptionPath = props.paths.subscription; + const linkHref = - props.plan.href ?? `${props.signUpPath}?utm_source=${props.plan.id}` ?? ''; + props.plan.href ?? + `${signUpPath}?plan=${planId}&next=${subscriptionPath}?plan=${planId}${redirectToCheckoutParam}` ?? + ''; const label = props.plan.label ?? 'common:getStartedWithPlan'; diff --git a/packages/ui/src/shadcn/alert.tsx b/packages/ui/src/shadcn/alert.tsx index b72656971..5bd488905 100644 --- a/packages/ui/src/shadcn/alert.tsx +++ b/packages/ui/src/shadcn/alert.tsx @@ -2,21 +2,21 @@ import * as React from 'react'; import { type VariantProps, cva } from 'class-variance-authority'; -import { cn } from '../utils/cn'; +import { cn } from '../utils'; const alertVariants = cva( - 'relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7', + 'relative w-full bg-gradient-to-r rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7', { variants: { variant: { default: 'bg-background text-foreground', destructive: - 'border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive', + 'border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive from-red-50 from-10% via-background to-background dark:from-red-500/10', success: - 'border-green-600/50 text-green-600 dark:border-green-600 [&>svg]:text-green-600', + 'border-green-600/50 text-green-600 dark:border-green-600 [&>svg]:text-green-600 from-green-50 from-10% via-background to-background dark:from-green-500/10', warning: - 'border-orange-600/50 text-orange-600 dark:border-orange-600 [&>svg]:text-orange-600', - info: 'border-blue-600/50 text-blue-600 dark:border-blue-600 [&>svg]:text-blue-600', + 'border-orange-600/50 text-orange-600 dark:border-orange-600 [&>svg]:text-orange-600 from-orange-50 from-10% via-background to-background dark:from-orange-500/10', + info: 'border-blue-600/50 text-blue-600 dark:border-blue-600 [&>svg]:text-blue-600 from-blue-50 from-10% via-background to-background dark:from-blue-500/10', }, }, defaultVariants: { @@ -44,7 +44,7 @@ const AlertTitle = React.forwardRef< >(({ className, ...props }, ref) => (
));