mirror of
https://github.com/formbricks/formbricks.git
synced 2026-04-25 20:01:53 -05:00
fix: All roles need insight into consumption (#4242)
Co-authored-by: Piyush Gupta <piyushguptaa2z123@gmail.com>
This commit is contained in:
committed by
GitHub
parent
ade5c3d80e
commit
da6f54eede
@@ -59,15 +59,13 @@ export const EnvironmentLayout = async ({ environmentId, session, children }: En
|
||||
|
||||
const currentUserMembership = await getMembershipByUserIdOrganizationId(session?.user.id, organization.id);
|
||||
const membershipRole = currentUserMembership?.role;
|
||||
const { isOwner, isManager } = getAccessFlags(membershipRole);
|
||||
|
||||
const isOwnerOrManager = isOwner || isManager;
|
||||
const { isMember } = getAccessFlags(membershipRole);
|
||||
|
||||
const { features, lastChecked, isPendingDowngrade, active } = await getEnterpriseLicense();
|
||||
|
||||
const productPermission = await getProductPermissionByUserId(session.user.id, environment.productId);
|
||||
|
||||
if (!isOwnerOrManager && !productPermission) {
|
||||
if (isMember && !productPermission) {
|
||||
throw new Error(t("common.product_permission_not_found"));
|
||||
}
|
||||
|
||||
|
||||
@@ -222,7 +222,7 @@ export const MainNavigation = ({
|
||||
{
|
||||
label: t("common.billing"),
|
||||
href: `/environments/${environment.id}/settings/billing`,
|
||||
hidden: !isFormbricksCloud || isPricingDisabled,
|
||||
hidden: !isFormbricksCloud,
|
||||
icon: CreditCardIcon,
|
||||
},
|
||||
{
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ export const OrganizationSettingsNavbar = ({
|
||||
id: "billing",
|
||||
label: t("common.billing"),
|
||||
href: `/environments/${environmentId}/settings/billing`,
|
||||
hidden: !isFormbricksCloud || isPricingDisabled || loading,
|
||||
hidden: !isFormbricksCloud || loading,
|
||||
current: pathname?.includes("/billing"),
|
||||
},
|
||||
{
|
||||
|
||||
+42
-38
@@ -35,6 +35,7 @@ interface PricingTableProps {
|
||||
SCALE: string;
|
||||
ENTERPRISE: string;
|
||||
};
|
||||
hasBillingRights: boolean;
|
||||
}
|
||||
|
||||
export const PricingTable = ({
|
||||
@@ -44,6 +45,7 @@ export const PricingTable = ({
|
||||
productFeatureKeys,
|
||||
responseCount,
|
||||
stripePriceLookupKeys,
|
||||
hasBillingRights,
|
||||
}: PricingTableProps) => {
|
||||
const t = useTranslations();
|
||||
const [planPeriod, setPlanPeriod] = useState<TOrganizationBillingPeriod>(
|
||||
@@ -220,48 +222,50 @@ export const PricingTable = ({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mx-auto mb-12">
|
||||
<div className="flex gap-x-2">
|
||||
<div className="mb-4 flex w-fit cursor-pointer overflow-hidden rounded-lg border border-slate-200 p-1 lg:mb-0">
|
||||
<div
|
||||
className={`flex-1 rounded-md px-4 py-0.5 text-center ${
|
||||
planPeriod === "monthly" ? "bg-slate-200 font-semibold" : "bg-transparent"
|
||||
}`}
|
||||
onClick={() => handleMonthlyToggle("monthly")}>
|
||||
{t("environments.settings.billing.monthly")}
|
||||
{hasBillingRights && (
|
||||
<div className="mx-auto mb-12">
|
||||
<div className="gap-x-2">
|
||||
<div className="mb-4 flex w-fit cursor-pointer overflow-hidden rounded-lg border border-slate-200 p-1 lg:mb-0">
|
||||
<div
|
||||
className={`flex-1 rounded-md px-4 py-0.5 text-center ${
|
||||
planPeriod === "monthly" ? "bg-slate-200 font-semibold" : "bg-transparent"
|
||||
}`}
|
||||
onClick={() => handleMonthlyToggle("monthly")}>
|
||||
{t("environments.settings.billing.monthly")}
|
||||
</div>
|
||||
<div
|
||||
className={`flex-1 items-center whitespace-nowrap rounded-md py-0.5 pl-4 pr-2 text-center ${
|
||||
planPeriod === "yearly" ? "bg-slate-200 font-semibold" : "bg-transparent"
|
||||
}`}
|
||||
onClick={() => handleMonthlyToggle("yearly")}>
|
||||
{t("environments.settings.billing.annually")}
|
||||
<span className="ml-2 inline-flex items-center rounded-full border border-green-200 bg-green-100 px-2.5 py-0.5 text-xs font-medium text-green-800">
|
||||
{t("environments.settings.billing.get_2_months_free")} 🔥
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={`flex-1 items-center whitespace-nowrap rounded-md py-0.5 pl-4 pr-2 text-center ${
|
||||
planPeriod === "yearly" ? "bg-slate-200 font-semibold" : "bg-transparent"
|
||||
}`}
|
||||
onClick={() => handleMonthlyToggle("yearly")}>
|
||||
{t("environments.settings.billing.annually")}
|
||||
<span className="ml-2 inline-flex items-center rounded-full border border-green-200 bg-green-100 px-2.5 py-0.5 text-xs font-medium text-green-800">
|
||||
{t("environments.settings.billing.get_2_months_free")} 🔥
|
||||
</span>
|
||||
<div className="relative mx-auto grid max-w-md grid-cols-1 gap-y-8 lg:mx-0 lg:-mb-14 lg:max-w-none lg:grid-cols-4">
|
||||
<div
|
||||
className="hidden lg:absolute lg:inset-x-px lg:bottom-0 lg:top-4 lg:block lg:rounded-xl lg:rounded-t-2xl lg:border lg:border-slate-200 lg:bg-slate-100 lg:pb-8 lg:ring-1 lg:ring-white/10"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
{CLOUD_PRICING_DATA.plans.map((plan) => (
|
||||
<PricingCard
|
||||
planPeriod={planPeriod}
|
||||
key={plan.id}
|
||||
plan={plan}
|
||||
onUpgrade={async () => {
|
||||
await onUpgrade(plan.id);
|
||||
}}
|
||||
organization={organization}
|
||||
productFeatureKeys={productFeatureKeys}
|
||||
onManageSubscription={openCustomerPortal}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative mx-auto grid max-w-md grid-cols-1 gap-y-8 lg:mx-0 lg:-mb-14 lg:max-w-none lg:grid-cols-4">
|
||||
<div
|
||||
className="hidden lg:absolute lg:inset-x-px lg:bottom-0 lg:top-4 lg:block lg:rounded-xl lg:rounded-t-2xl lg:border lg:border-slate-200 lg:bg-slate-100 lg:pb-8 lg:ring-1 lg:ring-white/10"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
{CLOUD_PRICING_DATA.plans.map((plan) => (
|
||||
<PricingCard
|
||||
planPeriod={planPeriod}
|
||||
key={plan.id}
|
||||
plan={plan}
|
||||
onUpgrade={async () => {
|
||||
await onUpgrade(plan.id);
|
||||
}}
|
||||
organization={organization}
|
||||
productFeatureKeys={productFeatureKeys}
|
||||
onManageSubscription={openCustomerPortal}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
|
||||
+1
-7
@@ -4,10 +4,7 @@ import { getTranslations } from "next-intl/server";
|
||||
import { notFound } from "next/navigation";
|
||||
import { authOptions } from "@formbricks/lib/authOptions";
|
||||
import { IS_FORMBRICKS_CLOUD } from "@formbricks/lib/constants";
|
||||
import { getMembershipByUserIdOrganizationId } from "@formbricks/lib/membership/service";
|
||||
import { getAccessFlags } from "@formbricks/lib/membership/utils";
|
||||
import { getOrganizationByEnvironmentId } from "@formbricks/lib/organization/service";
|
||||
import { ErrorComponent } from "@formbricks/ui/components/ErrorComponent";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Billing",
|
||||
@@ -29,10 +26,7 @@ const BillingLayout = async ({ children, params }) => {
|
||||
throw new Error(t("common.organization_not_found"));
|
||||
}
|
||||
|
||||
const currentUserMembership = await getMembershipByUserIdOrganizationId(session?.user.id, organization.id);
|
||||
const { isMember } = getAccessFlags(currentUserMembership?.role);
|
||||
|
||||
return <>{!isMember ? <>{children}</> : <ErrorComponent />}</>;
|
||||
return <>{children}</>;
|
||||
};
|
||||
|
||||
export default BillingLayout;
|
||||
|
||||
+4
@@ -6,6 +6,7 @@ import { authOptions } from "@formbricks/lib/authOptions";
|
||||
import { IS_FORMBRICKS_CLOUD } from "@formbricks/lib/constants";
|
||||
import { PRODUCT_FEATURE_KEYS, STRIPE_PRICE_LOOKUP_KEYS } from "@formbricks/lib/constants";
|
||||
import { getMembershipByUserIdOrganizationId } from "@formbricks/lib/membership/service";
|
||||
import { getAccessFlags } from "@formbricks/lib/membership/utils";
|
||||
import {
|
||||
getMonthlyActiveOrganizationPeopleCount,
|
||||
getMonthlyOrganizationResponseCount,
|
||||
@@ -33,6 +34,8 @@ const Page = async ({ params }) => {
|
||||
]);
|
||||
|
||||
const currentUserMembership = await getMembershipByUserIdOrganizationId(session?.user.id, organization.id);
|
||||
const { isMember } = getAccessFlags(currentUserMembership?.role);
|
||||
const hasBillingRights = !isMember;
|
||||
|
||||
const canDoRoleManagement = await getRoleManagementPermission(organization);
|
||||
|
||||
@@ -55,6 +58,7 @@ const Page = async ({ params }) => {
|
||||
responseCount={responseCount}
|
||||
stripePriceLookupKeys={STRIPE_PRICE_LOOKUP_KEYS}
|
||||
productFeatureKeys={PRODUCT_FEATURE_KEYS}
|
||||
hasBillingRights={hasBillingRights}
|
||||
/>
|
||||
</PageContentWrapper>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user