diff --git a/apps/web/app/(app)/workspaces/[workspaceId]/components/MainNavigation.tsx b/apps/web/app/(app)/workspaces/[workspaceId]/components/MainNavigation.tsx index 648e4a295e..487ed4bfb5 100644 --- a/apps/web/app/(app)/workspaces/[workspaceId]/components/MainNavigation.tsx +++ b/apps/web/app/(app)/workspaces/[workspaceId]/components/MainNavigation.tsx @@ -41,6 +41,7 @@ import { getAccessFlags } from "@/lib/membership/utils"; import { getFormattedErrorMessage } from "@/lib/utils/helper"; import { useSignOut } from "@/modules/auth/hooks/use-sign-out"; import { TrialAlert } from "@/modules/ee/billing/components/trial-alert"; +import { TRIAL_BASE_RESPONSE_LIMIT, TrialBannerNew } from "@/modules/ee/billing/components/trial-banner-new"; import { CreateOrganizationModal } from "@/modules/organization/components/CreateOrganizationModal"; import { ProfileAvatar } from "@/modules/ui/components/avatars"; import { Badge } from "@/modules/ui/components/badge"; @@ -73,6 +74,8 @@ interface NavigationProps { organizationWorkspacesLimit: number; isLicenseActive: boolean; isAccessControlAllowed: boolean; + responseCount: number; + newTrialBannerVariant: string | boolean; } export const MainNavigation = ({ @@ -87,6 +90,8 @@ export const MainNavigation = ({ organizationWorkspacesLimit, isLicenseActive, isAccessControlAllowed, + responseCount, + newTrialBannerVariant, }: NavigationProps) => { const router = useRouter(); const pathname = usePathname(); @@ -582,13 +587,26 @@ export const MainNavigation = ({ )} {/* Trial Days Remaining */} - {!isCollapsed && isFormbricksCloud && trialDaysRemaining !== null && ( - - - - )} + {!isCollapsed && + isFormbricksCloud && + trialDaysRemaining !== null && + (newTrialBannerVariant === "new-trial-banner" ? ( + + ) : ( + + + + ))}
diff --git a/apps/web/app/(app)/workspaces/[workspaceId]/components/WorkspaceLayout.tsx b/apps/web/app/(app)/workspaces/[workspaceId]/components/WorkspaceLayout.tsx index f478802821..967d6826bb 100644 --- a/apps/web/app/(app)/workspaces/[workspaceId]/components/WorkspaceLayout.tsx +++ b/apps/web/app/(app)/workspaces/[workspaceId]/components/WorkspaceLayout.tsx @@ -4,6 +4,7 @@ import { TopControlBar } from "@/app/(app)/workspaces/[workspaceId]/components/T import { IS_DEVELOPMENT, IS_FORMBRICKS_CLOUD } from "@/lib/constants"; import { getPublicDomain } from "@/lib/getPublicUrl"; import { getAccessFlags } from "@/lib/membership/utils"; +import { getPostHogFeatureFlag } from "@/lib/posthog/get-feature-flag"; import { getTranslate } from "@/lingodotdev/server"; import { getOrganizationWorkspacesLimit } from "@/modules/ee/license-check/lib/utils"; import { LimitsReachedBanner } from "@/modules/ui/components/limits-reached-banner"; @@ -37,6 +38,7 @@ export const WorkspaceLayout = async ({ layoutData, children }: WorkspaceLayoutP const { features, lastChecked, isPendingDowngrade, active, status } = license; const isMultiOrgEnabled = features?.isMultiOrgEnabled ?? false; const organizationWorkspacesLimit = await getOrganizationWorkspacesLimit(organization.id); + const newTrialBannerVariant = await getPostHogFeatureFlag(user.id, "a-b_navigation_rich-trial-banner"); const isOwnerOrManager = isOwner || isManager; // Validate that workspace permission exists for members @@ -71,6 +73,8 @@ export const WorkspaceLayout = async ({ layoutData, children }: WorkspaceLayoutP organizationWorkspacesLimit={organizationWorkspacesLimit} isLicenseActive={active} isAccessControlAllowed={isAccessControlAllowed} + responseCount={responseCount} + newTrialBannerVariant={newTrialBannerVariant} />
{ + const { t, i18n } = useTranslation(); + const locale = i18n.resolvedLanguage ?? i18n.language ?? "en-US"; + + const effectiveLimit = responseLimit ?? baseResponseLimit; + const progressPercent = Math.min((responseCount / effectiveLimit) * 100, 100); + const planLabel = planName.charAt(0).toUpperCase() + planName.slice(1); + + return ( +
+
+ + {trialDaysRemaining > 0 + ? t("common.trial_days_remaining", { count: trialDaysRemaining }) + : t("common.trial_expired")} + + + {t("common.trial_plan_badge", { plan: planLabel })} + +
+ +

+ {responseCount.toLocaleString(locale)} /{" "} + {baseResponseLimit.toLocaleString(locale)}{" "} + {effectiveLimit.toLocaleString(locale)} {t("common.responses")} +

+ +
+
+
+ + {!hasPaymentMethod && ( + + )} +
+ ); +};