diff --git a/apps/web/app/(app)/environments/[environmentId]/settings/billing/components/PricingTable.tsx b/apps/web/app/(app)/environments/[environmentId]/settings/billing/components/PricingTable.tsx index 61b5994b44..c05bfd0ee1 100644 --- a/apps/web/app/(app)/environments/[environmentId]/settings/billing/components/PricingTable.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/settings/billing/components/PricingTable.tsx @@ -93,6 +93,10 @@ export default function PricingTableComponent({ }; const coreAndWebAppSurveyFeatures = [ + { + title: "Remove Formbricks Branding", + comingSoon: false, + }, { title: "Team Roles", comingSoon: false, diff --git a/apps/web/app/(app)/environments/[environmentId]/settings/lookandfeel/page.tsx b/apps/web/app/(app)/environments/[environmentId]/settings/lookandfeel/page.tsx index d36774410f..e78d781335 100644 --- a/apps/web/app/(app)/environments/[environmentId]/settings/lookandfeel/page.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/settings/lookandfeel/page.tsx @@ -1,6 +1,9 @@ import { getServerSession } from "next-auth"; -import { getIsEnterpriseEdition } from "@formbricks/ee/lib/service"; +import { + getRemoveInAppBrandingPermission, + getRemoveLinkBrandingPermission, +} from "@formbricks/ee/lib/service"; import { authOptions } from "@formbricks/lib/authOptions"; import { DEFAULT_BRAND_COLOR, IS_FORMBRICKS_CLOUD } from "@formbricks/lib/constants"; import { getMembershipByUserIdTeamId } from "@formbricks/lib/membership/service"; @@ -33,12 +36,8 @@ export default async function ProfileSettingsPage({ params }: { params: { enviro throw new Error("Team not found"); } - const isEnterpriseEdition = await getIsEnterpriseEdition(); - - const canRemoveLinkBranding = - team.billing.features.linkSurvey.status !== "inactive" || !IS_FORMBRICKS_CLOUD; - const canRemoveInAppBranding = - team.billing.features.inAppSurvey.status !== "inactive" || isEnterpriseEdition; + const canRemoveInAppBranding = getRemoveInAppBrandingPermission(team); + const canRemoveLinkBranding = getRemoveLinkBrandingPermission(team); const currentUserMembership = await getMembershipByUserIdTeamId(session?.user.id, team.id); const { isDeveloper, isViewer } = getAccessFlags(currentUserMembership?.role); diff --git a/apps/web/app/(app)/environments/[environmentId]/settings/members/components/AddMemberModal.tsx b/apps/web/app/(app)/environments/[environmentId]/settings/members/components/AddMemberModal.tsx index 170a79d452..98f61d30c6 100644 --- a/apps/web/app/(app)/environments/[environmentId]/settings/members/components/AddMemberModal.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/settings/members/components/AddMemberModal.tsx @@ -19,10 +19,19 @@ interface MemberModalProps { open: boolean; setOpen: (v: boolean) => void; onSubmit: (data: { name: string; email: string; role: MembershipRole }) => void; - isEnterpriseEdition: boolean; + canDoRoleManagement: boolean; + isFormbricksCloud: boolean; + environmentId: string; } -export default function AddMemberModal({ open, setOpen, onSubmit, isEnterpriseEdition }: MemberModalProps) { +export default function AddMemberModal({ + open, + setOpen, + onSubmit, + canDoRoleManagement, + isFormbricksCloud, + environmentId, +}: MemberModalProps) { const { register, getValues, handleSubmit, reset, control } = useForm<{ name: string; email: string; @@ -47,11 +56,25 @@ export default function AddMemberModal({ open, setOpen, onSubmit, isEnterpriseEd - {!isEnterpriseEdition && ( -
- -
- )} + {!canDoRoleManagement && + (isFormbricksCloud ? ( +
+ +
+ ) : ( +
+ +
+ ))} +
@@ -66,7 +89,7 @@ export default function AddMemberModal({ open, setOpen, onSubmit, isEnterpriseEd
- {isEnterpriseEdition && } + {canDoRoleManagement && }
diff --git a/apps/web/app/(app)/environments/[environmentId]/settings/members/components/EditMemberships/EditMemberships.tsx b/apps/web/app/(app)/environments/[environmentId]/settings/members/components/EditMemberships/EditMemberships.tsx index 7c9d302271..d3e1b42e2f 100644 --- a/apps/web/app/(app)/environments/[environmentId]/settings/members/components/EditMemberships/EditMemberships.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/settings/members/components/EditMemberships/EditMemberships.tsx @@ -1,7 +1,7 @@ import MembersInfo from "@/app/(app)/environments/[environmentId]/settings/members/components/EditMemberships/MembersInfo"; import React from "react"; -import { getIsEnterpriseEdition } from "@formbricks/ee/lib/service"; +import { getRoleManagementPermission } from "@formbricks/ee/lib/service"; import { getInvitesByTeamId } from "@formbricks/lib/invite/service"; import { getMembersByTeamId } from "@formbricks/lib/membership/service"; import { TMembership } from "@formbricks/types/memberships"; @@ -24,7 +24,8 @@ export async function EditMemberships({ const currentUserRole = membership?.role; const isUserAdminOrOwner = membership?.role === "admin" || membership?.role === "owner"; - const isEnterpriseEdition = await getIsEnterpriseEdition(); + const canDoRoleManagement = getRoleManagementPermission(team); + return (
@@ -32,7 +33,7 @@ export async function EditMemberships({
Fullname
Email
- {isEnterpriseEdition &&
Role
} + {canDoRoleManagement &&
Role
}
@@ -44,7 +45,7 @@ export async function EditMemberships({ members={members ?? []} isUserAdminOrOwner={isUserAdminOrOwner} currentUserRole={currentUserRole} - isEnterpriseEdition={isEnterpriseEdition} + canDoRoleManagement={canDoRoleManagement} /> )}
diff --git a/apps/web/app/(app)/environments/[environmentId]/settings/members/components/EditMemberships/MembersInfo.tsx b/apps/web/app/(app)/environments/[environmentId]/settings/members/components/EditMemberships/MembersInfo.tsx index 157f8bf5d7..acd3c23f9f 100644 --- a/apps/web/app/(app)/environments/[environmentId]/settings/members/components/EditMemberships/MembersInfo.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/settings/members/components/EditMemberships/MembersInfo.tsx @@ -16,7 +16,7 @@ type MembersInfoProps = { isUserAdminOrOwner: boolean; currentUserId: string; currentUserRole: TMembershipRole; - isEnterpriseEdition: boolean; + canDoRoleManagement: boolean; }; // Type guard to check if member is an invitee @@ -31,7 +31,7 @@ const MembersInfo = async ({ members, currentUserId, currentUserRole, - isEnterpriseEdition, + canDoRoleManagement, }: MembersInfoProps) => { const allMembers = [...members, ...invites]; @@ -56,7 +56,7 @@ const MembersInfo = async ({
- {isEnterpriseEdition && allMembers?.length > 0 && ( + {canDoRoleManagement && allMembers?.length > 0 && ( ( export default async function MembersSettingsPage({ params }: { params: { environmentId: string } }) { const session = await getServerSession(authOptions); - - const isEnterpriseEdition = await getIsEnterpriseEdition(); - if (!session) { throw new Error("Unauthenticated"); } @@ -55,6 +52,7 @@ export default async function MembersSettingsPage({ params }: { params: { enviro if (!team) { throw new Error("Team not found"); } + const canDoRoleManagement = getRoleManagementPermission(team); const currentUserMembership = await getMembershipByUserIdTeamId(session?.user.id, team.id); const { isOwner, isAdmin } = getAccessFlags(currentUserMembership?.role); @@ -77,7 +75,9 @@ export default async function MembersSettingsPage({ params }: { params: { enviro role={currentUserRole} isLeaveTeamDisabled={isLeaveTeamDisabled} isInviteDisabled={INVITE_DISABLED} - isEnterpriseEdition={isEnterpriseEdition} + canDoRoleManagement={canDoRoleManagement} + isFormbricksCloud={IS_FORMBRICKS_CLOUD} + environmentId={params.environmentId} /> )} diff --git a/packages/ee/lib/service.ts b/packages/ee/lib/service.ts index 67ec254ca4..a65b857a90 100644 --- a/packages/ee/lib/service.ts +++ b/packages/ee/lib/service.ts @@ -1,17 +1,29 @@ import "server-only"; -import { unstable_cache } from "next/cache"; +import { ENTERPRISE_LICENSE_KEY, IS_FORMBRICKS_CLOUD } from "@formbricks/lib/constants"; +import { TTeam } from "@formbricks/types/teams"; -import { ENTERPRISE_LICENSE_KEY } from "@formbricks/lib/constants"; +export const getIsEnterpriseEdition = (): boolean => { + if (ENTERPRISE_LICENSE_KEY) { + return ENTERPRISE_LICENSE_KEY.length > 0; + } + return false; +}; -export const getIsEnterpriseEdition = () => - unstable_cache( - async () => { - if (ENTERPRISE_LICENSE_KEY) { - return ENTERPRISE_LICENSE_KEY?.length > 0; - } - return false; - }, - ["getIsEnterpriseEdition"], - { revalidate: 60 * 60 * 24 } - )(); +export const getRemoveInAppBrandingPermission = (team: TTeam): boolean => { + if (IS_FORMBRICKS_CLOUD) return team.billing.features.inAppSurvey.status !== "inactive"; + else if (!IS_FORMBRICKS_CLOUD) return getIsEnterpriseEdition(); + else return false; +}; + +export const getRemoveLinkBrandingPermission = (team: TTeam): boolean => { + if (IS_FORMBRICKS_CLOUD) return team.billing.features.linkSurvey.status !== "inactive"; + else if (!IS_FORMBRICKS_CLOUD) return true; + else return false; +}; + +export const getRoleManagementPermission = (team: TTeam): boolean => { + if (IS_FORMBRICKS_CLOUD) return team.billing.features.inAppSurvey.status !== "inactive"; + else if (!IS_FORMBRICKS_CLOUD) return getIsEnterpriseEdition(); + else return false; +}; diff --git a/packages/ui/UpgradePlanNotice/index.tsx b/packages/ui/UpgradePlanNotice/index.tsx index ee45d81037..abcaf28033 100644 --- a/packages/ui/UpgradePlanNotice/index.tsx +++ b/packages/ui/UpgradePlanNotice/index.tsx @@ -1,12 +1,26 @@ import { LightBulbIcon } from "@heroicons/react/24/outline"; +import Link from "next/link"; -import { Alert } from "../Alert"; +import { Alert, AlertDescription } from "../Alert"; -export const UpgradePlanNotice = ({ message }: { message: string }) => { +export const UpgradePlanNotice = ({ + message, + url, + textForUrl, +}: { + message: string; + url: string; + textForUrl: string; +}) => { return ( - {message} + + {message} + + {textForUrl} + + ); };