mirror of
https://github.com/formbricks/formbricks.git
synced 2026-05-06 11:20:56 -05:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f356e86729 |
@@ -26,7 +26,7 @@ const Page = async (props: { params: Promise<{ organizationId: string }> }) => {
|
|||||||
const isMultiOrgEnabled = await getIsMultiOrgEnabled();
|
const isMultiOrgEnabled = await getIsMultiOrgEnabled();
|
||||||
|
|
||||||
const membership = await getMembershipByUserIdOrganizationId(session.user.id, organization.id);
|
const membership = await getMembershipByUserIdOrganizationId(session.user.id, organization.id);
|
||||||
const { isMember, isBilling } = getAccessFlags(membership?.role);
|
const { isBilling } = getAccessFlags(membership?.role);
|
||||||
const isMembershipPending = membership?.role === undefined;
|
const isMembershipPending = membership?.role === undefined;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -45,7 +45,6 @@ const Page = async (props: { params: Promise<{ organizationId: string }> }) => {
|
|||||||
isLicenseActive={false}
|
isLicenseActive={false}
|
||||||
isOwnerOrManager={false}
|
isOwnerOrManager={false}
|
||||||
isAccessControlAllowed={false}
|
isAccessControlAllowed={false}
|
||||||
isMember={isMember}
|
|
||||||
isBilling={isBilling}
|
isBilling={isBilling}
|
||||||
isMembershipPending={isMembershipPending}
|
isMembershipPending={isMembershipPending}
|
||||||
environments={[]}
|
environments={[]}
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import { getServerSession } from "next-auth";
|
||||||
|
import { redirect } from "next/navigation";
|
||||||
|
import { EnvironmentLayout } from "@/app/(app)/environments/[environmentId]/components/EnvironmentLayout";
|
||||||
|
import { authOptions } from "@/modules/auth/lib/authOptions";
|
||||||
|
import { getEnvironmentLayoutData } from "@/modules/environments/lib/utils";
|
||||||
|
|
||||||
|
const MainNavLayout = async (props: {
|
||||||
|
params: Promise<{ environmentId: string }>;
|
||||||
|
children: React.ReactNode;
|
||||||
|
}) => {
|
||||||
|
const params = await props.params;
|
||||||
|
const { children } = props;
|
||||||
|
|
||||||
|
const session = await getServerSession(authOptions);
|
||||||
|
if (!session?.user) {
|
||||||
|
return redirect("/auth/login");
|
||||||
|
}
|
||||||
|
|
||||||
|
const layoutData = await getEnvironmentLayoutData(params.environmentId, session.user.id);
|
||||||
|
|
||||||
|
return <EnvironmentLayout layoutData={layoutData}>{children}</EnvironmentLayout>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MainNavLayout;
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { IS_FORMBRICKS_CLOUD } from "@/lib/constants";
|
||||||
|
import { getEnvironmentAuth } from "@/modules/environments/lib/utils";
|
||||||
|
import { SettingsSidebar } from "@/modules/settings/components/settings-sidebar";
|
||||||
|
|
||||||
|
const SettingsLayout = async (props: {
|
||||||
|
params: Promise<{ environmentId: string }>;
|
||||||
|
children: React.ReactNode;
|
||||||
|
}) => {
|
||||||
|
const params = await props.params;
|
||||||
|
const { children } = props;
|
||||||
|
|
||||||
|
const { project, organization, currentUserMembership } = await getEnvironmentAuth(params.environmentId);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex h-screen min-h-screen overflow-hidden">
|
||||||
|
<SettingsSidebar
|
||||||
|
environmentId={params.environmentId}
|
||||||
|
projectName={project.name}
|
||||||
|
organizationName={organization.name}
|
||||||
|
isFormbricksCloud={IS_FORMBRICKS_CLOUD}
|
||||||
|
membershipRole={currentUserMembership?.role}
|
||||||
|
/>
|
||||||
|
<div className="flex flex-1 flex-col overflow-y-auto bg-slate-50">{children}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SettingsLayout;
|
||||||
+139
@@ -0,0 +1,139 @@
|
|||||||
|
import { getServerSession } from "next-auth";
|
||||||
|
import { prisma } from "@formbricks/database";
|
||||||
|
import { AuthenticationError, ResourceNotFoundError } from "@formbricks/types/errors";
|
||||||
|
import { TUserNotificationSettings } from "@formbricks/types/user";
|
||||||
|
import { EditAlerts } from "@/app/(app)/environments/[environmentId]/settings/(account)/notifications/components/EditAlerts";
|
||||||
|
import { IntegrationsTip } from "@/app/(app)/environments/[environmentId]/settings/(account)/notifications/components/IntegrationsTip";
|
||||||
|
import type { Membership } from "@/app/(app)/environments/[environmentId]/settings/(account)/notifications/types";
|
||||||
|
import { SettingsCard } from "@/app/(app)/environments/[environmentId]/settings/components/SettingsCard";
|
||||||
|
import { getUser } from "@/lib/user/service";
|
||||||
|
import { getTranslate } from "@/lingodotdev/server";
|
||||||
|
import { authOptions } from "@/modules/auth/lib/authOptions";
|
||||||
|
import { PageContentWrapper } from "@/modules/ui/components/page-content-wrapper";
|
||||||
|
import { PageHeader } from "@/modules/ui/components/page-header";
|
||||||
|
|
||||||
|
const setCompleteNotificationSettings = (
|
||||||
|
notificationSettings: TUserNotificationSettings,
|
||||||
|
memberships: Membership[]
|
||||||
|
): TUserNotificationSettings => {
|
||||||
|
const newNotificationSettings: TUserNotificationSettings = {
|
||||||
|
alert: {} as Record<string, boolean>,
|
||||||
|
unsubscribedOrganizationIds: notificationSettings.unsubscribedOrganizationIds || [],
|
||||||
|
};
|
||||||
|
for (const membership of memberships) {
|
||||||
|
for (const project of membership.organization.projects) {
|
||||||
|
for (const environment of project.environments) {
|
||||||
|
for (const survey of environment.surveys) {
|
||||||
|
newNotificationSettings.alert[survey.id] =
|
||||||
|
(notificationSettings as unknown as Record<string, Record<string, boolean>>)[survey.id]
|
||||||
|
?.responseFinished ||
|
||||||
|
(notificationSettings.alert && notificationSettings.alert[survey.id]) ||
|
||||||
|
false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newNotificationSettings;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getMemberships = async (userId: string): Promise<Membership[]> => {
|
||||||
|
const memberships = await prisma.membership.findMany({
|
||||||
|
where: {
|
||||||
|
userId,
|
||||||
|
role: { not: "billing" },
|
||||||
|
OR: [
|
||||||
|
{ role: { in: ["owner", "manager"] } },
|
||||||
|
{
|
||||||
|
organization: {
|
||||||
|
projects: {
|
||||||
|
some: {
|
||||||
|
projectTeams: { some: { team: { teamUsers: { some: { userId } } } } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
organization: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
name: true,
|
||||||
|
projects: {
|
||||||
|
where: {
|
||||||
|
OR: [
|
||||||
|
{
|
||||||
|
organization: {
|
||||||
|
memberships: { some: { userId, role: { in: ["owner", "manager"] } } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ projectTeams: { some: { team: { teamUsers: { some: { userId } } } } } },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
name: true,
|
||||||
|
environments: {
|
||||||
|
where: { type: "production" },
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
surveys: { select: { id: true, name: true } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return memberships;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Page = async (props: {
|
||||||
|
params: Promise<{ environmentId: string }>;
|
||||||
|
searchParams: Promise<Record<string, string>>;
|
||||||
|
}) => {
|
||||||
|
const searchParams = await props.searchParams;
|
||||||
|
const params = await props.params;
|
||||||
|
const t = await getTranslate();
|
||||||
|
const session = await getServerSession(authOptions);
|
||||||
|
if (!session) {
|
||||||
|
throw new AuthenticationError(t("common.not_authenticated"));
|
||||||
|
}
|
||||||
|
const autoDisableNotificationType = searchParams["type"];
|
||||||
|
const autoDisableNotificationElementId = searchParams["elementId"];
|
||||||
|
|
||||||
|
const [user, memberships] = await Promise.all([getUser(session.user.id), getMemberships(session.user.id)]);
|
||||||
|
if (!user) {
|
||||||
|
throw new AuthenticationError(t("common.not_authenticated"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!memberships) {
|
||||||
|
throw new ResourceNotFoundError(t("common.membership"), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user?.notificationSettings) {
|
||||||
|
user.notificationSettings = setCompleteNotificationSettings(user.notificationSettings, memberships);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<PageContentWrapper>
|
||||||
|
<PageHeader pageTitle={t("common.account_settings")} />
|
||||||
|
<SettingsCard
|
||||||
|
title={t("environments.settings.notifications.email_alerts_surveys")}
|
||||||
|
description={t(
|
||||||
|
"environments.settings.notifications.set_up_an_alert_to_get_an_email_on_new_responses"
|
||||||
|
)}>
|
||||||
|
<EditAlerts
|
||||||
|
memberships={memberships}
|
||||||
|
user={user}
|
||||||
|
environmentId={params.environmentId}
|
||||||
|
autoDisableNotificationType={autoDisableNotificationType}
|
||||||
|
autoDisableNotificationElementId={autoDisableNotificationElementId}
|
||||||
|
/>
|
||||||
|
</SettingsCard>
|
||||||
|
<IntegrationsTip environmentId={params.environmentId} />
|
||||||
|
</PageContentWrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Page;
|
||||||
+99
@@ -0,0 +1,99 @@
|
|||||||
|
import { AuthenticationError } from "@formbricks/types/errors";
|
||||||
|
import { AccountSecurity } from "@/app/(app)/environments/[environmentId]/settings/(account)/profile/components/AccountSecurity";
|
||||||
|
import { DeleteAccount } from "@/app/(app)/environments/[environmentId]/settings/(account)/profile/components/DeleteAccount";
|
||||||
|
import { EditProfileDetailsForm } from "@/app/(app)/environments/[environmentId]/settings/(account)/profile/components/EditProfileDetailsForm";
|
||||||
|
import { SettingsCard } from "@/app/(app)/environments/[environmentId]/settings/components/SettingsCard";
|
||||||
|
import { EMAIL_VERIFICATION_DISABLED, IS_FORMBRICKS_CLOUD, PASSWORD_RESET_DISABLED } from "@/lib/constants";
|
||||||
|
import { getOrganizationsWhereUserIsSingleOwner } from "@/lib/organization/service";
|
||||||
|
import { getUser } from "@/lib/user/service";
|
||||||
|
import { getTranslate } from "@/lingodotdev/server";
|
||||||
|
import { getIsMultiOrgEnabled, getIsTwoFactorAuthEnabled } from "@/modules/ee/license-check/lib/utils";
|
||||||
|
import { getEnvironmentAuth } from "@/modules/environments/lib/utils";
|
||||||
|
import { IdBadge } from "@/modules/ui/components/id-badge";
|
||||||
|
import { PageContentWrapper } from "@/modules/ui/components/page-content-wrapper";
|
||||||
|
import { PageHeader } from "@/modules/ui/components/page-header";
|
||||||
|
import { UpgradePrompt } from "@/modules/ui/components/upgrade-prompt";
|
||||||
|
|
||||||
|
const Page = async (props: { params: Promise<{ environmentId: string }> }) => {
|
||||||
|
const isTwoFactorAuthEnabled = await getIsTwoFactorAuthEnabled();
|
||||||
|
const isMultiOrgEnabled = await getIsMultiOrgEnabled();
|
||||||
|
const params = await props.params;
|
||||||
|
const t = await getTranslate();
|
||||||
|
const { environmentId } = params;
|
||||||
|
|
||||||
|
const { session } = await getEnvironmentAuth(params.environmentId);
|
||||||
|
|
||||||
|
const organizationsWithSingleOwner = await getOrganizationsWhereUserIsSingleOwner(session.user.id);
|
||||||
|
|
||||||
|
const user = session?.user ? await getUser(session.user.id) : null;
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
throw new AuthenticationError(t("common.not_authenticated"));
|
||||||
|
}
|
||||||
|
|
||||||
|
const isPasswordResetEnabled = !PASSWORD_RESET_DISABLED && user.identityProvider === "email";
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageContentWrapper>
|
||||||
|
<PageHeader pageTitle={t("common.account_settings")} />
|
||||||
|
{user && (
|
||||||
|
<div>
|
||||||
|
<SettingsCard
|
||||||
|
title={t("environments.settings.profile.personal_information")}
|
||||||
|
description={t("environments.settings.profile.update_personal_info")}>
|
||||||
|
<EditProfileDetailsForm
|
||||||
|
user={user}
|
||||||
|
emailVerificationDisabled={EMAIL_VERIFICATION_DISABLED}
|
||||||
|
isPasswordResetEnabled={isPasswordResetEnabled}
|
||||||
|
/>
|
||||||
|
</SettingsCard>
|
||||||
|
{user.identityProvider === "email" && (
|
||||||
|
<SettingsCard
|
||||||
|
title={t("common.security")}
|
||||||
|
description={t("environments.settings.profile.security_description")}>
|
||||||
|
{!isTwoFactorAuthEnabled && !user.twoFactorEnabled ? (
|
||||||
|
<UpgradePrompt
|
||||||
|
title={t("environments.settings.profile.unlock_two_factor_authentication")}
|
||||||
|
description={t("environments.settings.profile.two_factor_authentication_description")}
|
||||||
|
buttons={[
|
||||||
|
{
|
||||||
|
text: IS_FORMBRICKS_CLOUD
|
||||||
|
? t("common.upgrade_plan")
|
||||||
|
: t("common.request_trial_license"),
|
||||||
|
href: IS_FORMBRICKS_CLOUD
|
||||||
|
? `/environments/${environmentId}/settings/organization/billing`
|
||||||
|
: "https://formbricks.com/upgrade-self-hosting-license",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: t("common.learn_more"),
|
||||||
|
href: IS_FORMBRICKS_CLOUD
|
||||||
|
? `/environments/${environmentId}/settings/organization/billing`
|
||||||
|
: "https://formbricks.com/learn-more-self-hosting-license",
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<AccountSecurity user={user} />
|
||||||
|
)}
|
||||||
|
</SettingsCard>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<SettingsCard
|
||||||
|
title={t("environments.settings.profile.delete_account")}
|
||||||
|
description={t("environments.settings.profile.confirm_delete_account")}>
|
||||||
|
<DeleteAccount
|
||||||
|
session={session}
|
||||||
|
IS_FORMBRICKS_CLOUD={IS_FORMBRICKS_CLOUD}
|
||||||
|
user={user}
|
||||||
|
organizationsWithSingleOwner={organizationsWithSingleOwner}
|
||||||
|
isMultiOrgEnabled={isMultiOrgEnabled}
|
||||||
|
/>
|
||||||
|
</SettingsCard>
|
||||||
|
<IdBadge id={user.id} label={t("common.profile_id")} variant="column" />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</PageContentWrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Page;
|
||||||
+43
@@ -0,0 +1,43 @@
|
|||||||
|
import { SettingsCard } from "@/app/(app)/environments/[environmentId]/settings/components/SettingsCard";
|
||||||
|
import { DEFAULT_LOCALE, IS_FORMBRICKS_CLOUD } from "@/lib/constants";
|
||||||
|
import { getUserLocale } from "@/lib/user/service";
|
||||||
|
import { getTranslate } from "@/lingodotdev/server";
|
||||||
|
import { getEnvironmentAuth } from "@/modules/environments/lib/utils";
|
||||||
|
import { ApiKeyList } from "@/modules/organization/settings/api-keys/components/api-key-list";
|
||||||
|
import { getProjectsByOrganizationId } from "@/modules/organization/settings/api-keys/lib/projects";
|
||||||
|
import { PageContentWrapper } from "@/modules/ui/components/page-content-wrapper";
|
||||||
|
import { PageHeader } from "@/modules/ui/components/page-header";
|
||||||
|
|
||||||
|
const Page = async (props: { params: Promise<{ environmentId: string }> }) => {
|
||||||
|
const params = await props.params;
|
||||||
|
const t = await getTranslate();
|
||||||
|
|
||||||
|
const { currentUserMembership, organization, session } = await getEnvironmentAuth(params.environmentId);
|
||||||
|
|
||||||
|
const [projects, locale] = await Promise.all([
|
||||||
|
getProjectsByOrganizationId(organization.id),
|
||||||
|
getUserLocale(session.user.id),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const canAccessApiKeys = currentUserMembership.role === "owner" || currentUserMembership.role === "manager";
|
||||||
|
|
||||||
|
if (!canAccessApiKeys) throw new Error(t("common.not_authorized"));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageContentWrapper>
|
||||||
|
<PageHeader pageTitle={t("environments.settings.general.organization_settings")} />
|
||||||
|
<SettingsCard
|
||||||
|
title={t("common.api_keys")}
|
||||||
|
description={t("environments.settings.api_keys.api_keys_description")}>
|
||||||
|
<ApiKeyList
|
||||||
|
organizationId={organization.id}
|
||||||
|
locale={locale ?? DEFAULT_LOCALE}
|
||||||
|
isReadOnly={!canAccessApiKeys}
|
||||||
|
projects={projects}
|
||||||
|
/>
|
||||||
|
</SettingsCard>
|
||||||
|
</PageContentWrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Page;
|
||||||
+64
@@ -0,0 +1,64 @@
|
|||||||
|
import { notFound } from "next/navigation";
|
||||||
|
import { IS_FORMBRICKS_CLOUD } from "@/lib/constants";
|
||||||
|
import { getMonthlyOrganizationResponseCount } from "@/lib/organization/service";
|
||||||
|
import { getOrganizationProjectsCount } from "@/lib/project/service";
|
||||||
|
import { getTranslate } from "@/lingodotdev/server";
|
||||||
|
import { PricingTable } from "@/modules/ee/billing/components/pricing-table";
|
||||||
|
import { getCloudBillingDisplayContext } from "@/modules/ee/billing/lib/cloud-billing-display";
|
||||||
|
import { getStripeBillingCatalogDisplay } from "@/modules/ee/billing/lib/stripe-billing-catalog";
|
||||||
|
import { getEnvironmentAuth } from "@/modules/environments/lib/utils";
|
||||||
|
import { PageContentWrapper } from "@/modules/ui/components/page-content-wrapper";
|
||||||
|
import { PageHeader } from "@/modules/ui/components/page-header";
|
||||||
|
|
||||||
|
const Page = async (props: { params: Promise<{ environmentId: string }> }) => {
|
||||||
|
const params = await props.params;
|
||||||
|
const t = await getTranslate();
|
||||||
|
|
||||||
|
const { organization, isMember, currentUserMembership } = await getEnvironmentAuth(params.environmentId);
|
||||||
|
|
||||||
|
if (!IS_FORMBRICKS_CLOUD) {
|
||||||
|
notFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
const [cloudBillingDisplayContext, billingCatalog] = await Promise.all([
|
||||||
|
getCloudBillingDisplayContext(organization.id),
|
||||||
|
getStripeBillingCatalogDisplay(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const organizationWithSyncedBilling = {
|
||||||
|
...organization,
|
||||||
|
billing: cloudBillingDisplayContext.billing,
|
||||||
|
};
|
||||||
|
|
||||||
|
const [responseCount, projectCount] = await Promise.all([
|
||||||
|
getMonthlyOrganizationResponseCount(organization.id),
|
||||||
|
getOrganizationProjectsCount(organization.id),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const hasBillingRights = !isMember;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageContentWrapper>
|
||||||
|
<PageHeader pageTitle={t("environments.settings.general.organization_settings")} />
|
||||||
|
|
||||||
|
<PricingTable
|
||||||
|
organization={organizationWithSyncedBilling}
|
||||||
|
environmentId={params.environmentId}
|
||||||
|
responseCount={responseCount}
|
||||||
|
projectCount={projectCount}
|
||||||
|
hasBillingRights={hasBillingRights}
|
||||||
|
currentCloudPlan={cloudBillingDisplayContext.currentCloudPlan}
|
||||||
|
currentBillingInterval={cloudBillingDisplayContext.currentBillingInterval}
|
||||||
|
currentSubscriptionStatus={cloudBillingDisplayContext.currentSubscriptionStatus}
|
||||||
|
pendingChange={cloudBillingDisplayContext.pendingChange}
|
||||||
|
usageCycleStart={cloudBillingDisplayContext.usageCycleStart}
|
||||||
|
usageCycleEnd={cloudBillingDisplayContext.usageCycleEnd}
|
||||||
|
isStripeSetupIncomplete={!organizationWithSyncedBilling.billing.stripeCustomerId}
|
||||||
|
trialDaysRemaining={cloudBillingDisplayContext.trialDaysRemaining}
|
||||||
|
billingCatalog={billingCatalog}
|
||||||
|
/>
|
||||||
|
</PageContentWrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Page;
|
||||||
+65
@@ -0,0 +1,65 @@
|
|||||||
|
import { notFound } from "next/navigation";
|
||||||
|
import { AuthenticationError } from "@formbricks/types/errors";
|
||||||
|
import { PrettyUrlsTable } from "@/app/(app)/environments/[environmentId]/settings/(organization)/domain/components/pretty-urls-table";
|
||||||
|
import { SettingsCard } from "@/app/(app)/environments/[environmentId]/settings/components/SettingsCard";
|
||||||
|
import { IS_FORMBRICKS_CLOUD, IS_STORAGE_CONFIGURED } from "@/lib/constants";
|
||||||
|
import { getTranslate } from "@/lingodotdev/server";
|
||||||
|
import { getWhiteLabelPermission } from "@/modules/ee/license-check/lib/utils";
|
||||||
|
import { FaviconCustomizationSettings } from "@/modules/ee/whitelabel/favicon-customization/components/favicon-customization-settings";
|
||||||
|
import { getEnvironmentAuth } from "@/modules/environments/lib/utils";
|
||||||
|
import { getSurveysWithSlugsByOrganizationId } from "@/modules/survey/lib/slug";
|
||||||
|
import { Alert, AlertDescription } from "@/modules/ui/components/alert";
|
||||||
|
import { PageContentWrapper } from "@/modules/ui/components/page-content-wrapper";
|
||||||
|
import { PageHeader } from "@/modules/ui/components/page-header";
|
||||||
|
|
||||||
|
const Page = async (props: { params: Promise<{ environmentId: string }> }) => {
|
||||||
|
const params = await props.params;
|
||||||
|
const t = await getTranslate();
|
||||||
|
|
||||||
|
if (IS_FORMBRICKS_CLOUD) {
|
||||||
|
return notFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
const { session, currentUserMembership, organization, isOwner, isManager } = await getEnvironmentAuth(
|
||||||
|
params.environmentId
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!session) {
|
||||||
|
throw new AuthenticationError(t("common.not_authenticated"));
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasWhiteLabelPermission = await getWhiteLabelPermission(organization.id);
|
||||||
|
const isOwnerOrManager = isManager || isOwner;
|
||||||
|
|
||||||
|
const surveys = await getSurveysWithSlugsByOrganizationId(organization.id);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageContentWrapper>
|
||||||
|
<PageHeader pageTitle={t("environments.settings.general.organization_settings")} />
|
||||||
|
|
||||||
|
{!IS_STORAGE_CONFIGURED && (
|
||||||
|
<div className="max-w-4xl">
|
||||||
|
<Alert variant="warning">
|
||||||
|
<AlertDescription>{t("common.storage_not_configured")}</AlertDescription>
|
||||||
|
</Alert>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<FaviconCustomizationSettings
|
||||||
|
organization={organization}
|
||||||
|
hasWhiteLabelPermission={hasWhiteLabelPermission}
|
||||||
|
environmentId={params.environmentId}
|
||||||
|
isReadOnly={!isOwnerOrManager}
|
||||||
|
isStorageConfigured={IS_STORAGE_CONFIGURED}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<SettingsCard
|
||||||
|
title={t("environments.settings.domain.title")}
|
||||||
|
description={t("environments.settings.domain.description")}>
|
||||||
|
<PrettyUrlsTable surveys={surveys} />
|
||||||
|
</SettingsCard>
|
||||||
|
</PageContentWrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Page;
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user