From f1934fe76b7be144db958734e277db88330c0664 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Thu, 14 Aug 2025 11:29:02 -0700 Subject: [PATCH] fix(billing): separate client side and server side envvars for billing (#966) --- .../components/settings-navigation/settings-navigation.tsx | 5 ++++- .../sidebar/components/settings-modal/settings-modal.tsx | 5 ++++- .../workspace/[workspaceId]/w/components/sidebar/sidebar.tsx | 5 ++++- apps/sim/lib/env.ts | 4 ++++ 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/settings-navigation/settings-navigation.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/settings-navigation/settings-navigation.tsx index 6f0bc1d22..36d0bef21 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/settings-navigation/settings-navigation.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/settings-navigation/settings-navigation.tsx @@ -8,7 +8,7 @@ import { UserCircle, Users, } from 'lucide-react' -import { isBillingEnabled } from '@/lib/environment' +import { getEnv } from '@/lib/env' import { cn } from '@/lib/utils' import { useSubscriptionStore } from '@/stores/subscription/store' @@ -98,6 +98,9 @@ export function SettingsNavigation({ const { getSubscriptionStatus } = useSubscriptionStore() const subscription = getSubscriptionStatus() + // Get billing status + const isBillingEnabled = getEnv('NEXT_PUBLIC_BILLING_ENABLED') || false + const navigationItems = allNavigationItems.filter((item) => { if (item.hideWhenBillingDisabled && !isBillingEnabled) { return false diff --git a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/settings-modal.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/settings-modal.tsx index d897cb928..bbf156b84 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/settings-modal.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/settings-modal.tsx @@ -3,7 +3,7 @@ import { useEffect, useRef, useState } from 'react' import { X } from 'lucide-react' import { Button, Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui' -import { isBillingEnabled } from '@/lib/environment' +import { getEnv } from '@/lib/env' import { createLogger } from '@/lib/logs/console/logger' import { cn } from '@/lib/utils' import { @@ -44,6 +44,9 @@ export function SettingsModal({ open, onOpenChange }: SettingsModalProps) { const { activeOrganization } = useOrganizationStore() const hasLoadedInitialData = useRef(false) + // Get billing status + const isBillingEnabled = getEnv('NEXT_PUBLIC_BILLING_ENABLED') || false + useEffect(() => { async function loadAllSettings() { if (!open) return diff --git a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/sidebar.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/sidebar.tsx index 4099b71ce..df41903d1 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/sidebar.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/sidebar.tsx @@ -5,7 +5,7 @@ import { HelpCircle, LibraryBig, ScrollText, Search, Settings, Shapes } from 'lu import { useParams, usePathname, useRouter } from 'next/navigation' import { Button, ScrollArea, Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui' import { useSession } from '@/lib/auth-client' -import { isBillingEnabled } from '@/lib/environment' +import { getEnv } from '@/lib/env' import { createLogger } from '@/lib/logs/console/logger' import { generateWorkspaceName } from '@/lib/naming' import { cn } from '@/lib/utils' @@ -195,6 +195,9 @@ export function Sidebar() { const userPermissions = useUserPermissionsContext() const isLoading = workflowsLoading || sessionLoading + // Get billing status + const isBillingEnabled = getEnv('NEXT_PUBLIC_BILLING_ENABLED') || false + // Add state to prevent multiple simultaneous workflow creations const [isCreatingWorkflow, setIsCreatingWorkflow] = useState(false) // Add state to prevent multiple simultaneous workspace creations diff --git a/apps/sim/lib/env.ts b/apps/sim/lib/env.ts index 7eeddb43e..358658e70 100644 --- a/apps/sim/lib/env.ts +++ b/apps/sim/lib/env.ts @@ -179,6 +179,9 @@ export const env = createEnv({ // Asset Storage NEXT_PUBLIC_BLOB_BASE_URL: z.string().url().optional(), // Base URL for Vercel Blob storage (CDN assets) + + // Billing + NEXT_PUBLIC_BILLING_ENABLED: z.boolean().optional(), // Enable billing enforcement and usage tracking (client-side) // Google Services - For client-side Google integrations NEXT_PUBLIC_GOOGLE_CLIENT_ID: z.string().optional(), // Google OAuth client ID for browser auth @@ -216,6 +219,7 @@ export const env = createEnv({ NEXT_PUBLIC_VERCEL_URL: process.env.NEXT_PUBLIC_VERCEL_URL, NEXT_PUBLIC_SENTRY_DSN: process.env.NEXT_PUBLIC_SENTRY_DSN, NEXT_PUBLIC_BLOB_BASE_URL: process.env.NEXT_PUBLIC_BLOB_BASE_URL, + NEXT_PUBLIC_BILLING_ENABLED: process.env.NEXT_PUBLIC_BILLING_ENABLED, NEXT_PUBLIC_GOOGLE_CLIENT_ID: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID, NEXT_PUBLIC_RB2B_KEY: process.env.NEXT_PUBLIC_RB2B_KEY, NEXT_PUBLIC_GOOGLE_API_KEY: process.env.NEXT_PUBLIC_GOOGLE_API_KEY,