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 && (
+
+ )}
+
+ );
+};