mirror of
https://github.com/formbricks/formbricks.git
synced 2026-03-31 22:03:31 -05:00
Compare commits
12 Commits
fix/licens
...
action-env
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41bc62fb3b | ||
|
|
041f26ab2d | ||
|
|
d03b01cb67 | ||
|
|
c7981fc4d9 | ||
|
|
a1719c2258 | ||
|
|
a5275c2ead | ||
|
|
eec71d9a98 | ||
|
|
d547a70013 | ||
|
|
8870b7d710 | ||
|
|
3c8f6945ba | ||
|
|
e1bd66b009 | ||
|
|
abbd69e355 |
@@ -15,8 +15,7 @@
|
||||
"@formbricks/react-native": "workspace:*",
|
||||
"expo": "51.0.26",
|
||||
"expo-status-bar": "1.12.1",
|
||||
"react": "19.0.0-rc-ed15d500-20241110",
|
||||
"react-dom": "19.0.0-rc-ed15d500-20241110",
|
||||
"react": "18.3.1",
|
||||
"react-native": "0.74.4",
|
||||
"react-native-webview": "13.8.6"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { StatusBar } from "expo-status-bar";
|
||||
import type { JSX } from "react";
|
||||
import { Button, LogBox, StyleSheet, Text, View } from "react-native";
|
||||
import Formbricks, { track } from "@formbricks/react-native";
|
||||
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
"@formbricks/js": "workspace:*",
|
||||
"@formbricks/ui": "workspace:*",
|
||||
"lucide-react": "0.452.0",
|
||||
"next": "15.0.3",
|
||||
"react": "19.0.0-rc-ed15d500-20241110",
|
||||
"react-dom": "19.0.0-rc-ed15d500-20241110"
|
||||
"next": "14.2.16",
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@formbricks/eslint-config": "workspace:*",
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
"@mapbox/rehype-prism": "0.9.0",
|
||||
"@mdx-js/loader": "3.0.1",
|
||||
"@mdx-js/react": "3.0.1",
|
||||
"@next/mdx": "15.0.3",
|
||||
"@next/mdx": "14.2.15",
|
||||
"@paralleldrive/cuid2": "2.2.2",
|
||||
"@sindresorhus/slugify": "2.2.1",
|
||||
"@tailwindcss/typography": "0.5.15",
|
||||
@@ -39,7 +39,7 @@
|
||||
"lucide-react": "0.452.0",
|
||||
"mdast-util-to-string": "4.0.0",
|
||||
"mdx-annotations": "0.1.4",
|
||||
"next": "15.0.3",
|
||||
"next": "14.2.16",
|
||||
"next-plausible": "3.12.2",
|
||||
"next-seo": "6.6.0",
|
||||
"next-sitemap": "4.2.3",
|
||||
@@ -47,8 +47,8 @@
|
||||
"node-fetch": "3.3.2",
|
||||
"prism-react-renderer": "2.4.0",
|
||||
"prismjs": "1.29.0",
|
||||
"react": "19.0.0-rc-ed15d500-20241110",
|
||||
"react-dom": "19.0.0-rc-ed15d500-20241110",
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.3.1",
|
||||
"react-highlight-words": "0.20.0",
|
||||
"react-markdown": "9.0.1",
|
||||
"react-responsive-embed": "2.1.0",
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
"dependencies": {
|
||||
"@formbricks/ui": "workspace:*",
|
||||
"eslint-plugin-react-refresh": "0.4.12",
|
||||
"react": "19.0.0-rc-ed15d500-20241110",
|
||||
"react-dom": "19.0.0-rc-ed15d500-20241110"
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@chromatic-com/storybook": "2.0.2",
|
||||
|
||||
@@ -10,13 +10,12 @@ import { Button } from "@formbricks/ui/components/Button";
|
||||
import { Header } from "@formbricks/ui/components/Header";
|
||||
|
||||
interface InvitePageProps {
|
||||
params: Promise<{
|
||||
params: {
|
||||
environmentId: string;
|
||||
}>;
|
||||
};
|
||||
}
|
||||
|
||||
const Page = async (props: InvitePageProps) => {
|
||||
const params = await props.params;
|
||||
const Page = async ({ params }: InvitePageProps) => {
|
||||
const t = await getTranslations();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session || !session.user) {
|
||||
|
||||
@@ -8,13 +8,12 @@ import { Button } from "@formbricks/ui/components/Button";
|
||||
import { Header } from "@formbricks/ui/components/Header";
|
||||
|
||||
interface ConnectPageProps {
|
||||
params: Promise<{
|
||||
params: {
|
||||
environmentId: string;
|
||||
}>;
|
||||
};
|
||||
}
|
||||
|
||||
const Page = async (props: ConnectPageProps) => {
|
||||
const params = await props.params;
|
||||
const Page = async ({ params }: ConnectPageProps) => {
|
||||
const t = await getTranslations();
|
||||
const environment = await getEnvironment(params.environmentId);
|
||||
|
||||
|
||||
@@ -4,11 +4,7 @@ import { authOptions } from "@formbricks/lib/authOptions";
|
||||
import { hasUserEnvironmentAccess } from "@formbricks/lib/environment/auth";
|
||||
import { AuthorizationError } from "@formbricks/types/errors";
|
||||
|
||||
const OnboardingLayout = async (props) => {
|
||||
const params = await props.params;
|
||||
|
||||
const { children } = props;
|
||||
|
||||
const OnboardingLayout = async ({ children, params }) => {
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session || !session.user) {
|
||||
return redirect(`/auth/login`);
|
||||
|
||||
@@ -11,13 +11,12 @@ import { Button } from "@formbricks/ui/components/Button";
|
||||
import { Header } from "@formbricks/ui/components/Header";
|
||||
|
||||
interface XMTemplatePageProps {
|
||||
params: Promise<{
|
||||
params: {
|
||||
environmentId: string;
|
||||
}>;
|
||||
};
|
||||
}
|
||||
|
||||
const Page = async (props: XMTemplatePageProps) => {
|
||||
const params = await props.params;
|
||||
const Page = async ({ params }: XMTemplatePageProps) => {
|
||||
const session = await getServerSession(authOptions);
|
||||
const environment = await getEnvironment(params.environmentId);
|
||||
const t = await getTranslations();
|
||||
|
||||
@@ -11,7 +11,7 @@ import { ZId } from "@formbricks/types/common";
|
||||
import { DatabaseError } from "@formbricks/types/errors";
|
||||
|
||||
export const getTeamsByOrganizationId = reactCache(
|
||||
async (organizationId: string): Promise<TOrganizationTeam[] | null> =>
|
||||
(organizationId: string): Promise<TOrganizationTeam[] | null> =>
|
||||
cache(
|
||||
async () => {
|
||||
validateInputs([organizationId, ZId]);
|
||||
|
||||
@@ -5,11 +5,7 @@ import { getEnvironments } from "@formbricks/lib/environment/service";
|
||||
import { getMembershipByUserIdOrganizationId } from "@formbricks/lib/membership/service";
|
||||
import { getUserProducts } from "@formbricks/lib/product/service";
|
||||
|
||||
const LandingLayout = async (props) => {
|
||||
const params = await props.params;
|
||||
|
||||
const { children } = props;
|
||||
|
||||
const LandingLayout = async ({ children, params }) => {
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session || !session.user) {
|
||||
return redirect(`/auth/login`);
|
||||
|
||||
@@ -8,8 +8,7 @@ import { getOrganization, getOrganizationsByUserId } from "@formbricks/lib/organ
|
||||
import { getUser } from "@formbricks/lib/user/service";
|
||||
import { Header } from "@formbricks/ui/components/Header";
|
||||
|
||||
const Page = async (props) => {
|
||||
const params = await props.params;
|
||||
const Page = async ({ params }) => {
|
||||
const t = await getTranslations();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session || !session.user) {
|
||||
|
||||
@@ -9,11 +9,7 @@ import { getUser } from "@formbricks/lib/user/service";
|
||||
import { AuthorizationError } from "@formbricks/types/errors";
|
||||
import { ToasterClient } from "@formbricks/ui/components/ToasterClient";
|
||||
|
||||
const ProductOnboardingLayout = async (props) => {
|
||||
const params = await props.params;
|
||||
|
||||
const { children } = props;
|
||||
|
||||
const ProductOnboardingLayout = async ({ children, params }) => {
|
||||
const t = await getTranslations();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session || !session.user) {
|
||||
|
||||
@@ -4,11 +4,7 @@ import { authOptions } from "@formbricks/lib/authOptions";
|
||||
import { getMembershipByUserIdOrganizationId } from "@formbricks/lib/membership/service";
|
||||
import { getAccessFlags } from "@formbricks/lib/membership/utils";
|
||||
|
||||
const OnboardingLayout = async (props) => {
|
||||
const params = await props.params;
|
||||
|
||||
const { children } = props;
|
||||
|
||||
const OnboardingLayout = async ({ children, params }) => {
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session || !session.user) {
|
||||
return redirect(`/auth/login`);
|
||||
|
||||
@@ -9,13 +9,12 @@ import { Button } from "@formbricks/ui/components/Button";
|
||||
import { Header } from "@formbricks/ui/components/Header";
|
||||
|
||||
interface ChannelPageProps {
|
||||
params: Promise<{
|
||||
params: {
|
||||
organizationId: string;
|
||||
}>;
|
||||
};
|
||||
}
|
||||
|
||||
const Page = async (props: ChannelPageProps) => {
|
||||
const params = await props.params;
|
||||
const Page = async ({ params }: ChannelPageProps) => {
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session || !session.user) {
|
||||
return redirect(`/auth/login`);
|
||||
|
||||
@@ -9,13 +9,12 @@ import { Button } from "@formbricks/ui/components/Button";
|
||||
import { Header } from "@formbricks/ui/components/Header";
|
||||
|
||||
interface ModePageProps {
|
||||
params: Promise<{
|
||||
params: {
|
||||
organizationId: string;
|
||||
}>;
|
||||
};
|
||||
}
|
||||
|
||||
const Page = async (props: ModePageProps) => {
|
||||
const params = await props.params;
|
||||
const Page = async ({ params }: ModePageProps) => {
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session || !session.user) {
|
||||
return redirect(`/auth/login`);
|
||||
|
||||
@@ -16,19 +16,17 @@ import { Button } from "@formbricks/ui/components/Button";
|
||||
import { Header } from "@formbricks/ui/components/Header";
|
||||
|
||||
interface ProductSettingsPageProps {
|
||||
params: Promise<{
|
||||
params: {
|
||||
organizationId: string;
|
||||
}>;
|
||||
searchParams: Promise<{
|
||||
};
|
||||
searchParams: {
|
||||
channel?: TProductConfigChannel;
|
||||
industry?: TProductConfigIndustry;
|
||||
mode?: TProductMode;
|
||||
}>;
|
||||
};
|
||||
}
|
||||
|
||||
const Page = async (props: ProductSettingsPageProps) => {
|
||||
const searchParams = await props.searchParams;
|
||||
const params = await props.params;
|
||||
const Page = async ({ params, searchParams }: ProductSettingsPageProps) => {
|
||||
const t = await getTranslations();
|
||||
const session = await getServerSession(authOptions);
|
||||
|
||||
|
||||
@@ -13,11 +13,7 @@ import { AuthorizationError } from "@formbricks/types/errors";
|
||||
import { DevEnvironmentBanner } from "@formbricks/ui/components/DevEnvironmentBanner";
|
||||
import { ToasterClient } from "@formbricks/ui/components/ToasterClient";
|
||||
|
||||
const SurveyEditorEnvironmentLayout = async (props) => {
|
||||
const params = await props.params;
|
||||
|
||||
const { children } = props;
|
||||
|
||||
const SurveyEditorEnvironmentLayout = async ({ children, params }) => {
|
||||
const t = await getTranslations();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session || !session.user) {
|
||||
|
||||
@@ -4,7 +4,7 @@ import { QuestionFormInput } from "@/modules/surveys/components/QuestionFormInpu
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { PlusIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { type JSX, useEffect } from "react";
|
||||
import { useEffect } from "react";
|
||||
import { createI18nString, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { TAttributeClass } from "@formbricks/types/attribute-classes";
|
||||
import { TSurvey, TSurveyAddressQuestion } from "@formbricks/types/surveys/types";
|
||||
|
||||
@@ -4,7 +4,7 @@ import { LocalizedEditor } from "@/modules/ee/multi-language-surveys/components/
|
||||
import { QuestionFormInput } from "@/modules/surveys/components/QuestionFormInput";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { type JSX, useState } from "react";
|
||||
import { useState } from "react";
|
||||
import { TAttributeClass } from "@formbricks/types/attribute-classes";
|
||||
import { TSurvey, TSurveyCTAQuestion } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { QuestionFormInput } from "@/modules/surveys/components/QuestionFormInput";
|
||||
import { PlusIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { type JSX, useEffect, useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { createI18nString, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { TAttributeClass } from "@formbricks/types/attribute-classes";
|
||||
import { TSurvey, TSurveyCalQuestion } from "@formbricks/types/surveys/types";
|
||||
|
||||
@@ -41,8 +41,8 @@ export const CardStylingSettings = ({
|
||||
const surveyTypeDerived = isAppSurvey ? "App" : "Link";
|
||||
const isLogoVisible = !!product.logo?.url;
|
||||
|
||||
const linkCardArrangement = form.watch("cardArrangement.linkSurveys") ?? "straight";
|
||||
const appCardArrangement = form.watch("cardArrangement.appSurveys") ?? "straight";
|
||||
const linkCardArrangement = form.watch("cardArrangement.linkSurveys") ?? "simple";
|
||||
const appCardArrangement = form.watch("cardArrangement.appSurveys") ?? "simple";
|
||||
const roundness = form.watch("roundness") ?? 8;
|
||||
|
||||
const [parent] = useAutoAnimate();
|
||||
|
||||
@@ -87,12 +87,10 @@ export function ConditionalLogic({
|
||||
|
||||
const handleRemoveLogic = (logicItemIdx: number) => {
|
||||
const logicCopy = structuredClone(question.logic ?? []);
|
||||
const isLast = logicCopy.length === 1;
|
||||
logicCopy.splice(logicItemIdx, 1);
|
||||
|
||||
updateQuestion(questionIdx, {
|
||||
logic: logicCopy,
|
||||
logicFallback: isLast ? undefined : question.logicFallback,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { LocalizedEditor } from "@/modules/ee/multi-language-surveys/components/localized-editor";
|
||||
import { QuestionFormInput } from "@/modules/surveys/components/QuestionFormInput";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { type JSX, useState } from "react";
|
||||
import { useState } from "react";
|
||||
import { TAttributeClass } from "@formbricks/types/attribute-classes";
|
||||
import { TSurvey, TSurveyConsentQuestion } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
|
||||
@@ -4,7 +4,7 @@ import { QuestionFormInput } from "@/modules/surveys/components/QuestionFormInpu
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { PlusIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { type JSX, useEffect } from "react";
|
||||
import { useEffect } from "react";
|
||||
import { createI18nString, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { TAttributeClass } from "@formbricks/types/attribute-classes";
|
||||
import { TSurvey, TSurveyContactInfoQuestion } from "@formbricks/types/surveys/types";
|
||||
|
||||
@@ -2,7 +2,6 @@ import { QuestionFormInput } from "@/modules/surveys/components/QuestionFormInpu
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { PlusIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import type { JSX } from "react";
|
||||
import { createI18nString, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { TAttributeClass } from "@formbricks/types/attribute-classes";
|
||||
import { TSurvey, TSurveyDateQuestion } from "@formbricks/types/surveys/types";
|
||||
|
||||
@@ -3,17 +3,13 @@
|
||||
import { EditorCardMenu } from "@/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/EditorCardMenu";
|
||||
import { EndScreenForm } from "@/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/EndScreenForm";
|
||||
import { RedirectUrlForm } from "@/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/RedirectUrlForm";
|
||||
import {
|
||||
findEndingCardUsedInLogic,
|
||||
formatTextWithSlashes,
|
||||
} from "@/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/lib/utils";
|
||||
import { formatTextWithSlashes } from "@/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/lib/utils";
|
||||
import { useSortable } from "@dnd-kit/sortable";
|
||||
import { CSS } from "@dnd-kit/utilities";
|
||||
import { createId } from "@paralleldrive/cuid2";
|
||||
import * as Collapsible from "@radix-ui/react-collapsible";
|
||||
import { GripIcon, Handshake, Undo2 } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import toast from "react-hot-toast";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
import { recallToHeadline } from "@formbricks/lib/utils/recall";
|
||||
import { TAttributeClass } from "@formbricks/types/attribute-classes";
|
||||
@@ -97,14 +93,6 @@ export const EditEndingCard = ({
|
||||
};
|
||||
|
||||
const deleteEndingCard = () => {
|
||||
// checking if this ending card is used in logic
|
||||
const quesIdx = findEndingCardUsedInLogic(localSurvey, endingCard.id);
|
||||
|
||||
if (quesIdx !== -1) {
|
||||
toast.error(t("environments.surveys.edit.ending_card_used_in_logic", { questionIndex: quesIdx + 1 }));
|
||||
return;
|
||||
}
|
||||
|
||||
setLocalSurvey((prevSurvey) => {
|
||||
const updatedEndings = prevSurvey.endings.filter((_, index) => index !== endingCardIndex);
|
||||
return { ...prevSurvey, endings: updatedEndings };
|
||||
|
||||
@@ -6,7 +6,7 @@ import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { PlusIcon, XCircleIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import Link from "next/link";
|
||||
import { type JSX, useMemo, useState } from "react";
|
||||
import { useMemo, useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { createI18nString } from "@formbricks/lib/i18n/utils";
|
||||
|
||||
@@ -2,17 +2,7 @@ import { LogicEditorActions } from "@/app/(app)/(survey-editor)/environments/[en
|
||||
import { LogicEditorConditions } from "@/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/LogicEditorConditions";
|
||||
import { ArrowRightIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { ReactElement, useMemo } from "react";
|
||||
import { getLocalizedValue } from "@formbricks/lib/i18n/utils";
|
||||
import { QUESTIONS_ICON_MAP } from "@formbricks/lib/utils/questions";
|
||||
import { TSurvey, TSurveyLogic, TSurveyQuestion } from "@formbricks/types/surveys/types";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@formbricks/ui/components/Select";
|
||||
|
||||
interface LogicEditorProps {
|
||||
localSurvey: TSurvey;
|
||||
@@ -34,36 +24,6 @@ export function LogicEditor({
|
||||
isLast,
|
||||
}: LogicEditorProps) {
|
||||
const t = useTranslations();
|
||||
|
||||
const fallbackOptions = useMemo(() => {
|
||||
let options: {
|
||||
icon?: ReactElement;
|
||||
label: string;
|
||||
value: string;
|
||||
}[] = [];
|
||||
|
||||
localSurvey.questions.forEach((ques) => {
|
||||
if (ques.id === question.id) return null;
|
||||
options.push({
|
||||
icon: QUESTIONS_ICON_MAP[ques.type],
|
||||
label: getLocalizedValue(ques.headline, "default"),
|
||||
value: ques.id,
|
||||
});
|
||||
});
|
||||
|
||||
localSurvey.endings.forEach((ending) => {
|
||||
options.push({
|
||||
label:
|
||||
ending.type === "endScreen"
|
||||
? getLocalizedValue(ending.headline, "default") || t("environments.surveys.edit.end_screen_card")
|
||||
: ending.label || t("environments.surveys.edit.redirect_thank_you_card"),
|
||||
value: ending.id,
|
||||
});
|
||||
});
|
||||
|
||||
return options;
|
||||
}, [localSurvey.questions, localSurvey.endings, question.id, t]);
|
||||
|
||||
return (
|
||||
<div className="flex w-full grow flex-col gap-4 overflow-x-auto pb-2 text-sm">
|
||||
<LogicEditorConditions
|
||||
@@ -83,36 +43,11 @@ export function LogicEditor({
|
||||
questionIdx={questionIdx}
|
||||
/>
|
||||
{isLast ? (
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="flex flex-wrap items-center space-x-2">
|
||||
<ArrowRightIcon className="h-4 w-4" />
|
||||
<p className="text-nowrap text-slate-700">
|
||||
{t("environments.surveys.edit.all_other_answers_will_continue_to")}
|
||||
<p className="text-slate-700">
|
||||
{t("environments.surveys.edit.all_other_answers_will_continue_to_the_next_question")}
|
||||
</p>
|
||||
<Select
|
||||
autoComplete="true"
|
||||
defaultValue={question.logicFallback || "defaultSelection"}
|
||||
onValueChange={(val) => {
|
||||
updateQuestion(questionIdx, {
|
||||
logicFallback: val === "defaultSelection" ? undefined : val,
|
||||
});
|
||||
}}>
|
||||
<SelectTrigger className="w-auto bg-white">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem key="fallback_default_selection" value={"defaultSelection"}>
|
||||
{t("environments.surveys.edit.next_question")}
|
||||
</SelectItem>
|
||||
{fallbackOptions.map((option) => (
|
||||
<SelectItem key={`fallback_${option.value}`} value={option.value}>
|
||||
<div className="flex items-center gap-2">
|
||||
{option.icon}
|
||||
{option.label}
|
||||
</div>
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
@@ -244,13 +244,7 @@ export function LogicEditorConditions({
|
||||
const conditionOperatorOptions = getConditionOperatorOptions(condition, localSurvey);
|
||||
const { show, options, showInput = false, inputType } = getMatchValueProps(condition, localSurvey, t);
|
||||
|
||||
const allowMultiSelect = [
|
||||
"equalsOneOf",
|
||||
"includesAllOf",
|
||||
"includesOneOf",
|
||||
"doesNotIncludeOneOf",
|
||||
"doesNotIncludeAllOf",
|
||||
].includes(condition.operator);
|
||||
const allowMultiSelect = ["equalsOneOf", "includesAllOf", "includesOneOf"].includes(condition.operator);
|
||||
return (
|
||||
<div key={condition.id} className="flex items-center gap-x-2">
|
||||
<div className="w-10 shrink-0">
|
||||
|
||||
@@ -4,7 +4,6 @@ import { QuestionFormInput } from "@/modules/surveys/components/QuestionFormInpu
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { PlusIcon, TrashIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import type { JSX } from "react";
|
||||
import { createI18nString, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { TAttributeClass } from "@formbricks/types/attribute-classes";
|
||||
import { TI18nString, TSurvey, TSurveyMatrixQuestion } from "@formbricks/types/surveys/types";
|
||||
|
||||
@@ -8,7 +8,7 @@ import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { createId } from "@paralleldrive/cuid2";
|
||||
import { PlusIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { type JSX, useEffect, useRef, useState } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import { createI18nString, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { TAttributeClass } from "@formbricks/types/attribute-classes";
|
||||
|
||||
@@ -4,7 +4,6 @@ import { QuestionFormInput } from "@/modules/surveys/components/QuestionFormInpu
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { PlusIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import type { JSX } from "react";
|
||||
import { createI18nString, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { TAttributeClass } from "@formbricks/types/attribute-classes";
|
||||
import { TSurvey, TSurveyNPSQuestion } from "@formbricks/types/surveys/types";
|
||||
|
||||
@@ -4,7 +4,6 @@ import { QuestionFormInput } from "@/modules/surveys/components/QuestionFormInpu
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { HashIcon, LinkIcon, MailIcon, MessageSquareTextIcon, PhoneIcon, PlusIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import type { JSX } from "react";
|
||||
import { createI18nString, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { TAttributeClass } from "@formbricks/types/attribute-classes";
|
||||
import {
|
||||
|
||||
@@ -3,7 +3,6 @@ import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { createId } from "@paralleldrive/cuid2";
|
||||
import { PlusIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import type { JSX } from "react";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
import { createI18nString, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { TAttributeClass } from "@formbricks/types/attribute-classes";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { PaintbrushIcon, Rows3Icon, SettingsIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { type JSX, useMemo } from "react";
|
||||
import { useMemo } from "react";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
import { TSurveyEditorTabs } from "@formbricks/types/surveys/types";
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { createId } from "@paralleldrive/cuid2";
|
||||
import { PlusIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { type JSX, useEffect, useRef, useState } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { createI18nString, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { TAttributeClass } from "@formbricks/types/attribute-classes";
|
||||
import { TI18nString, TSurvey, TSurveyRankingQuestion } from "@formbricks/types/surveys/types";
|
||||
|
||||
@@ -130,15 +130,21 @@ export const ResponseOptionsCard = ({
|
||||
};
|
||||
|
||||
const handleRunOnDateChange = (date: Date) => {
|
||||
const utcDate = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0, 0));
|
||||
setRunOnDate(utcDate);
|
||||
setLocalSurvey({ ...localSurvey, runOnDate: utcDate ?? null });
|
||||
const equivalentDate = date?.getDate();
|
||||
date?.setUTCHours(0, 0, 0, 0);
|
||||
date?.setDate(equivalentDate);
|
||||
|
||||
setRunOnDate(date);
|
||||
setLocalSurvey({ ...localSurvey, runOnDate: date ?? null });
|
||||
};
|
||||
|
||||
const handleCloseOnDateChange = (date: Date) => {
|
||||
const utcDate = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0, 0));
|
||||
setCloseOnDate(utcDate);
|
||||
setLocalSurvey({ ...localSurvey, closeOnDate: utcDate ?? null });
|
||||
const equivalentDate = date?.getDate();
|
||||
date?.setUTCHours(0, 0, 0, 0);
|
||||
date?.setDate(equivalentDate);
|
||||
|
||||
setCloseOnDate(date);
|
||||
setLocalSurvey({ ...localSurvey, closeOnDate: date ?? null });
|
||||
};
|
||||
|
||||
const handleClosedSurveyMessageChange = ({
|
||||
|
||||
@@ -2,10 +2,12 @@ import { RotateCcwIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import Link from "next/link";
|
||||
import React, { useEffect, useMemo, useState } from "react";
|
||||
import { UseFormReturn, useForm } from "react-hook-form";
|
||||
import { UseFormReturn, useForm, useWatch } from "react-hook-form";
|
||||
import toast from "react-hot-toast";
|
||||
import { COLOR_DEFAULTS } from "@formbricks/lib/styling/constants";
|
||||
import { TEnvironment } from "@formbricks/types/environment";
|
||||
import { TProduct, TProductStyling } from "@formbricks/types/product";
|
||||
import { TBaseStyling } from "@formbricks/types/styling";
|
||||
import { TSurvey, TSurveyStyling } from "@formbricks/types/surveys/types";
|
||||
import { AlertDialog } from "@formbricks/ui/components/AlertDialog";
|
||||
import { Button } from "@formbricks/ui/components/Button";
|
||||
@@ -51,8 +53,50 @@ export const StylingView = ({
|
||||
}: StylingViewProps) => {
|
||||
const t = useTranslations();
|
||||
|
||||
const stylingDefaults: TBaseStyling = useMemo(() => {
|
||||
let stylingDefaults: TBaseStyling;
|
||||
const isOverwriteEnabled = localSurvey.styling?.overwriteThemeStyling ?? false;
|
||||
|
||||
if (isOverwriteEnabled) {
|
||||
const { overwriteThemeStyling, ...baseSurveyStyles } = localSurvey.styling ?? {};
|
||||
stylingDefaults = baseSurveyStyles;
|
||||
} else {
|
||||
const { allowStyleOverwrite, ...baseProductStyles } = product.styling ?? {};
|
||||
stylingDefaults = baseProductStyles;
|
||||
}
|
||||
|
||||
return {
|
||||
brandColor: { light: stylingDefaults.brandColor?.light ?? COLOR_DEFAULTS.brandColor },
|
||||
questionColor: { light: stylingDefaults.questionColor?.light ?? COLOR_DEFAULTS.questionColor },
|
||||
inputColor: { light: stylingDefaults.inputColor?.light ?? COLOR_DEFAULTS.inputColor },
|
||||
inputBorderColor: { light: stylingDefaults.inputBorderColor?.light ?? COLOR_DEFAULTS.inputBorderColor },
|
||||
cardBackgroundColor: {
|
||||
light: stylingDefaults.cardBackgroundColor?.light ?? COLOR_DEFAULTS.cardBackgroundColor,
|
||||
},
|
||||
cardBorderColor: { light: stylingDefaults.cardBorderColor?.light ?? COLOR_DEFAULTS.cardBorderColor },
|
||||
cardShadowColor: { light: stylingDefaults.cardShadowColor?.light ?? COLOR_DEFAULTS.cardShadowColor },
|
||||
highlightBorderColor: stylingDefaults.highlightBorderColor?.light
|
||||
? {
|
||||
light: stylingDefaults.highlightBorderColor.light,
|
||||
}
|
||||
: undefined,
|
||||
isDarkModeEnabled: stylingDefaults.isDarkModeEnabled ?? false,
|
||||
roundness: stylingDefaults.roundness ?? 8,
|
||||
cardArrangement: stylingDefaults.cardArrangement ?? {
|
||||
linkSurveys: "simple",
|
||||
appSurveys: "simple",
|
||||
},
|
||||
background: stylingDefaults.background,
|
||||
hideProgressBar: stylingDefaults.hideProgressBar ?? false,
|
||||
isLogoHidden: stylingDefaults.isLogoHidden ?? false,
|
||||
};
|
||||
}, [localSurvey.styling, product.styling]);
|
||||
|
||||
const form = useForm<TSurveyStyling>({
|
||||
defaultValues: localSurvey.styling ?? product.styling,
|
||||
defaultValues: {
|
||||
...localSurvey.styling,
|
||||
...stylingDefaults,
|
||||
},
|
||||
});
|
||||
|
||||
const overwriteThemeStyling = form.watch("overwriteThemeStyling");
|
||||
@@ -89,17 +133,20 @@ export const StylingView = ({
|
||||
}
|
||||
}, [overwriteThemeStyling]);
|
||||
|
||||
const watchedValues = useWatch({
|
||||
control: form.control,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
form.watch((data: TSurveyStyling) => {
|
||||
setLocalSurvey((prev) => ({
|
||||
...prev,
|
||||
styling: {
|
||||
...prev.styling,
|
||||
...data,
|
||||
},
|
||||
}));
|
||||
});
|
||||
}, [setLocalSurvey]);
|
||||
// @ts-expect-error
|
||||
setLocalSurvey((prev) => ({
|
||||
...prev,
|
||||
styling: {
|
||||
...prev.styling,
|
||||
...watchedValues,
|
||||
},
|
||||
}));
|
||||
}, [watchedValues, setLocalSurvey]);
|
||||
|
||||
const defaultProductStyling = useMemo(() => {
|
||||
const { styling: productStyling } = product;
|
||||
|
||||
@@ -344,7 +344,9 @@ export const SurveyMenuBar = ({
|
||||
<AlertTriangleIcon className="h-5 w-5 text-amber-400" />
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side={"top"} className="lg:hidden">
|
||||
<p className="py-2 text-center text-xs text-slate-500 dark:text-slate-400">{cautionText}</p>
|
||||
<p className="py-2 text-center text-xs text-slate-500 dark:text-slate-400">
|
||||
{t(cautionText)}
|
||||
</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
|
||||
@@ -116,14 +116,6 @@ export const logicRules = {
|
||||
label: "environments.surveys.edit.does_not_equal",
|
||||
value: ZSurveyLogicConditionsOperator.Enum.doesNotEqual,
|
||||
},
|
||||
{
|
||||
label: "environments.surveys.edit.does_not_include_one_of",
|
||||
value: ZSurveyLogicConditionsOperator.Enum.doesNotIncludeOneOf,
|
||||
},
|
||||
{
|
||||
label: "environments.surveys.edit.does_not_include_all_of",
|
||||
value: ZSurveyLogicConditionsOperator.Enum.doesNotIncludeAllOf,
|
||||
},
|
||||
{
|
||||
label: "environments.surveys.edit.includes_all_of",
|
||||
value: ZSurveyLogicConditionsOperator.Enum.includesAllOf,
|
||||
@@ -152,14 +144,6 @@ export const logicRules = {
|
||||
label: "environments.surveys.edit.does_not_equal",
|
||||
value: ZSurveyLogicConditionsOperator.Enum.doesNotEqual,
|
||||
},
|
||||
{
|
||||
label: "environments.surveys.edit.does_not_include_one_of",
|
||||
value: ZSurveyLogicConditionsOperator.Enum.doesNotIncludeOneOf,
|
||||
},
|
||||
{
|
||||
label: "environments.surveys.edit.does_not_include_all_of",
|
||||
value: ZSurveyLogicConditionsOperator.Enum.doesNotIncludeAllOf,
|
||||
},
|
||||
{
|
||||
label: "environments.surveys.edit.includes_all_of",
|
||||
value: ZSurveyLogicConditionsOperator.Enum.includesAllOf,
|
||||
|
||||
@@ -1060,9 +1060,7 @@ export const findQuestionUsedInLogic = (survey: TSurvey, questionId: TSurveyQues
|
||||
};
|
||||
|
||||
return survey.questions.findIndex(
|
||||
(question) =>
|
||||
question.logicFallback === questionId ||
|
||||
(question.id !== questionId && question.logic?.some(isUsedInLogicRule))
|
||||
(question) => question.logic && question.id !== questionId && question.logic.some(isUsedInLogicRule)
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1147,17 +1145,3 @@ export const findHiddenFieldUsedInLogic = (survey: TSurvey, hiddenFieldId: strin
|
||||
|
||||
return survey.questions.findIndex((question) => question.logic?.some(isUsedInLogicRule));
|
||||
};
|
||||
|
||||
export const findEndingCardUsedInLogic = (survey: TSurvey, endingCardId: string): number => {
|
||||
const isUsedInAction = (action: TSurveyLogicAction): boolean => {
|
||||
return action.objective === "jumpToQuestion" && action.target === endingCardId;
|
||||
};
|
||||
|
||||
const isUsedInLogicRule = (logicRule: TSurveyLogic): boolean => {
|
||||
return logicRule.actions.some(isUsedInAction);
|
||||
};
|
||||
|
||||
return survey.questions.findIndex(
|
||||
(question) => question.logicFallback === endingCardId || question.logic?.some(isUsedInLogicRule)
|
||||
);
|
||||
};
|
||||
|
||||
@@ -24,17 +24,14 @@ import { getUserLocale } from "@formbricks/lib/user/service";
|
||||
import { ErrorComponent } from "@formbricks/ui/components/ErrorComponent";
|
||||
import { SurveyEditor } from "./components/SurveyEditor";
|
||||
|
||||
export const generateMetadata = async (props) => {
|
||||
const params = await props.params;
|
||||
export const generateMetadata = async ({ params }) => {
|
||||
const survey = await getSurvey(params.surveyId);
|
||||
return {
|
||||
title: survey?.name ? `${survey?.name} | Editor` : "Editor",
|
||||
};
|
||||
};
|
||||
|
||||
const Page = async (props) => {
|
||||
const searchParams = await props.searchParams;
|
||||
const params = await props.params;
|
||||
const Page = async ({ params, searchParams }) => {
|
||||
const t = await getTranslations();
|
||||
const [
|
||||
survey,
|
||||
|
||||
@@ -14,19 +14,17 @@ import { TTemplateRole } from "@formbricks/types/templates";
|
||||
import { TemplateContainerWithPreview } from "./components/TemplateContainer";
|
||||
|
||||
interface SurveyTemplateProps {
|
||||
params: Promise<{
|
||||
params: {
|
||||
environmentId: string;
|
||||
}>;
|
||||
searchParams: Promise<{
|
||||
};
|
||||
searchParams: {
|
||||
channel?: TProductConfigChannel;
|
||||
industry?: TProductConfigIndustry;
|
||||
role?: TTemplateRole;
|
||||
}>;
|
||||
};
|
||||
}
|
||||
|
||||
const Page = async (props: SurveyTemplateProps) => {
|
||||
const searchParams = await props.searchParams;
|
||||
const params = await props.params;
|
||||
const Page = async ({ params, searchParams }: SurveyTemplateProps) => {
|
||||
const t = await getTranslations();
|
||||
const session = await getServerSession(authOptions);
|
||||
const environmentId = params.environmentId;
|
||||
|
||||
@@ -3,8 +3,7 @@ import { PageContentWrapper } from "@formbricks/ui/components/PageContentWrapper
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
const Page = async (props) => {
|
||||
const searchParams = await props.searchParams;
|
||||
const Page = ({ searchParams }) => {
|
||||
const { environmentId } = searchParams;
|
||||
|
||||
return (
|
||||
|
||||
@@ -21,8 +21,7 @@ export const metadata: Metadata = {
|
||||
title: "Attributes",
|
||||
};
|
||||
|
||||
const Page = async (props) => {
|
||||
const params = await props.params;
|
||||
const Page = async ({ params }) => {
|
||||
let attributeClasses = await getAttributeClasses(params.environmentId);
|
||||
const t = await getTranslations();
|
||||
const product = await getProductByEnvironmentId(params.environmentId);
|
||||
|
||||
@@ -9,11 +9,7 @@ import { getOrganizationByEnvironmentId } from "@formbricks/lib/organization/ser
|
||||
import { getProductByEnvironmentId } from "@formbricks/lib/product/service";
|
||||
import { AuthorizationError } from "@formbricks/types/errors";
|
||||
|
||||
const ConfigLayout = async (props) => {
|
||||
const params = await props.params;
|
||||
|
||||
const { children } = props;
|
||||
|
||||
const ConfigLayout = async ({ children, params }) => {
|
||||
const t = await getTranslations();
|
||||
const [organization, session] = await Promise.all([
|
||||
getOrganizationByEnvironmentId(params.environmentId),
|
||||
|
||||
@@ -54,7 +54,7 @@ export const ResponseSection = async ({
|
||||
|
||||
const productPermission = await getProductPermissionByUserId(session.user.id, product.id);
|
||||
|
||||
const locale = await findMatchingLocale();
|
||||
const locale = findMatchingLocale();
|
||||
|
||||
return (
|
||||
<ResponseTimeline
|
||||
|
||||
@@ -19,8 +19,7 @@ import { getTagsByEnvironmentId } from "@formbricks/lib/tag/service";
|
||||
import { PageContentWrapper } from "@formbricks/ui/components/PageContentWrapper";
|
||||
import { PageHeader } from "@formbricks/ui/components/PageHeader";
|
||||
|
||||
const Page = async (props) => {
|
||||
const params = await props.params;
|
||||
const Page = async ({ params }) => {
|
||||
const t = await getTranslations();
|
||||
const [environment, environmentTags, product, session, organization, person, attributes, attributeClasses] =
|
||||
await Promise.all([
|
||||
|
||||
@@ -16,8 +16,7 @@ import { Button } from "@formbricks/ui/components/Button";
|
||||
import { PageContentWrapper } from "@formbricks/ui/components/PageContentWrapper";
|
||||
import { PageHeader } from "@formbricks/ui/components/PageHeader";
|
||||
|
||||
const Page = async (props: { params: Promise<{ environmentId: string }> }) => {
|
||||
const params = await props.params;
|
||||
const Page = async ({ params }: { params: { environmentId: string } }) => {
|
||||
const t = await getTranslations();
|
||||
const session = await getServerSession(authOptions);
|
||||
|
||||
|
||||
@@ -19,8 +19,7 @@ import { getSegments } from "@formbricks/lib/segment/service";
|
||||
import { PageContentWrapper } from "@formbricks/ui/components/PageContentWrapper";
|
||||
import { PageHeader } from "@formbricks/ui/components/PageHeader";
|
||||
|
||||
const Page = async (props) => {
|
||||
const params = await props.params;
|
||||
const Page = async ({ params }) => {
|
||||
const t = await getTranslations();
|
||||
const [environment, segments, attributeClasses, organization, product] = await Promise.all([
|
||||
getEnvironment(params.environmentId),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { type JSX, useState } from "react";
|
||||
import { useState } from "react";
|
||||
import { TActionClass } from "@formbricks/types/action-classes";
|
||||
import { TEnvironment } from "@formbricks/types/environment";
|
||||
import { ActionDetailModal } from "./ActionDetailModal";
|
||||
|
||||
@@ -23,8 +23,7 @@ export const metadata: Metadata = {
|
||||
title: "Actions",
|
||||
};
|
||||
|
||||
const Page = async (props) => {
|
||||
const params = await props.params;
|
||||
const Page = async ({ params }) => {
|
||||
const session = await getServerSession(authOptions);
|
||||
const t = await getTranslations();
|
||||
const [actionClasses, organization, product] = await Promise.all([
|
||||
@@ -32,7 +31,7 @@ const Page = async (props) => {
|
||||
getOrganizationByEnvironmentId(params.environmentId),
|
||||
getProductByEnvironmentId(params.environmentId),
|
||||
]);
|
||||
const locale = await findMatchingLocale();
|
||||
const locale = findMatchingLocale();
|
||||
|
||||
if (!session) {
|
||||
throw new Error(t("common.session_not_found"));
|
||||
|
||||
@@ -481,11 +481,7 @@ export const MainNavigation = ({
|
||||
{dropdownNavigation.map(
|
||||
(link) =>
|
||||
!link.hidden && (
|
||||
<Link
|
||||
href={link.href}
|
||||
target={link.target}
|
||||
className="flex w-full items-center"
|
||||
key={link.label}>
|
||||
<Link href={link.href} target={link.target} className="flex w-full items-center">
|
||||
<DropdownMenuItem>
|
||||
<link.icon className="mr-2 h-4 w-4" strokeWidth={1.5} />
|
||||
{link.label}
|
||||
|
||||
@@ -21,8 +21,7 @@ import { GoBackButton } from "@formbricks/ui/components/GoBackButton";
|
||||
import { PageContentWrapper } from "@formbricks/ui/components/PageContentWrapper";
|
||||
import { PageHeader } from "@formbricks/ui/components/PageHeader";
|
||||
|
||||
const Page = async (props) => {
|
||||
const params = await props.params;
|
||||
const Page = async ({ params }) => {
|
||||
const t = await getTranslations();
|
||||
const isEnabled = !!AIRTABLE_CLIENT_ID;
|
||||
const [session, surveys, integrations, environment, attributeClasses] = await Promise.all([
|
||||
@@ -54,7 +53,7 @@ const Page = async (props) => {
|
||||
airtableArray = await getAirtableTables(params.environmentId);
|
||||
}
|
||||
|
||||
const locale = await findMatchingLocale();
|
||||
const locale = findMatchingLocale();
|
||||
|
||||
const currentUserMembership = await getMembershipByUserIdOrganizationId(
|
||||
session?.user.id,
|
||||
|
||||
@@ -24,8 +24,7 @@ import { GoBackButton } from "@formbricks/ui/components/GoBackButton";
|
||||
import { PageContentWrapper } from "@formbricks/ui/components/PageContentWrapper";
|
||||
import { PageHeader } from "@formbricks/ui/components/PageHeader";
|
||||
|
||||
const Page = async (props) => {
|
||||
const params = await props.params;
|
||||
const Page = async ({ params }) => {
|
||||
const t = await getTranslations();
|
||||
const isEnabled = !!(GOOGLE_SHEETS_CLIENT_ID && GOOGLE_SHEETS_CLIENT_SECRET && GOOGLE_SHEETS_REDIRECT_URL);
|
||||
const [session, surveys, integrations, environment, attributeClasses] = await Promise.all([
|
||||
@@ -52,7 +51,7 @@ const Page = async (props) => {
|
||||
(integration): integration is TIntegrationGoogleSheets => integration.type === "googleSheets"
|
||||
);
|
||||
|
||||
const locale = await findMatchingLocale();
|
||||
const locale = findMatchingLocale();
|
||||
|
||||
const currentUserMembership = await getMembershipByUserIdOrganizationId(
|
||||
session?.user.id,
|
||||
|
||||
@@ -26,8 +26,7 @@ import { GoBackButton } from "@formbricks/ui/components/GoBackButton";
|
||||
import { PageContentWrapper } from "@formbricks/ui/components/PageContentWrapper";
|
||||
import { PageHeader } from "@formbricks/ui/components/PageHeader";
|
||||
|
||||
const Page = async (props) => {
|
||||
const params = await props.params;
|
||||
const Page = async ({ params }) => {
|
||||
const t = await getTranslations();
|
||||
const enabled = !!(
|
||||
NOTION_OAUTH_CLIENT_ID &&
|
||||
@@ -81,7 +80,7 @@ const Page = async (props) => {
|
||||
return (
|
||||
<PageContentWrapper>
|
||||
<GoBackButton url={`${WEBAPP_URL}/environments/${params.environmentId}/integrations`} />
|
||||
<PageHeader pageTitle={t("environments.integrations.notion.notion_integration")} />
|
||||
<PageHeader pageTitle={"environments.integrations.notion.notion_integration"} />
|
||||
<NotionWrapper
|
||||
enabled={enabled}
|
||||
surveys={surveys}
|
||||
|
||||
@@ -25,8 +25,7 @@ import { Card } from "@formbricks/ui/components/IntegrationCard";
|
||||
import { PageContentWrapper } from "@formbricks/ui/components/PageContentWrapper";
|
||||
import { PageHeader } from "@formbricks/ui/components/PageHeader";
|
||||
|
||||
const Page = async (props) => {
|
||||
const params = await props.params;
|
||||
const Page = async ({ params }) => {
|
||||
const environmentId = params.environmentId;
|
||||
const t = await getTranslations();
|
||||
const [
|
||||
|
||||
@@ -91,7 +91,7 @@ export const ManageIntegration = ({
|
||||
<span className="mr-4 h-4 w-4 rounded-full bg-green-600"></span>
|
||||
<span className="text-slate-500">
|
||||
{t("environments.integrations.slack.connected_with_team", {
|
||||
team: slackIntegration.config.key.team?.name,
|
||||
team: slackIntegration.config.key.team.name,
|
||||
})}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -46,8 +46,7 @@ export const SlackWrapper = ({
|
||||
|
||||
if (
|
||||
getSlackChannelsResponse?.serverError &&
|
||||
(getSlackChannelsResponse.serverError.includes("missing_scope") ||
|
||||
getSlackChannelsResponse.serverError.includes("invalid_auth"))
|
||||
getSlackChannelsResponse.serverError.includes("missing_scope")
|
||||
) {
|
||||
setShowReconnectButton(true);
|
||||
}
|
||||
|
||||
@@ -19,8 +19,7 @@ import { GoBackButton } from "@formbricks/ui/components/GoBackButton";
|
||||
import { PageContentWrapper } from "@formbricks/ui/components/PageContentWrapper";
|
||||
import { PageHeader } from "@formbricks/ui/components/PageHeader";
|
||||
|
||||
const Page = async (props) => {
|
||||
const params = await props.params;
|
||||
const Page = async ({ params }) => {
|
||||
const isEnabled = !!(SLACK_CLIENT_ID && SLACK_CLIENT_SECRET);
|
||||
const t = await getTranslations();
|
||||
const [session, surveys, slackIntegration, environment, attributeClasses] = await Promise.all([
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { WebhookModal } from "@/app/(app)/environments/[environmentId]/integrations/webhooks/components/WebhookDetailModal";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { type JSX, useState } from "react";
|
||||
import { useState } from "react";
|
||||
import { TEnvironment } from "@formbricks/types/environment";
|
||||
import { TSurvey } from "@formbricks/types/surveys/types";
|
||||
import { TWebhook } from "@formbricks/types/webhooks";
|
||||
|
||||
@@ -18,8 +18,7 @@ import { GoBackButton } from "@formbricks/ui/components/GoBackButton";
|
||||
import { PageContentWrapper } from "@formbricks/ui/components/PageContentWrapper";
|
||||
import { PageHeader } from "@formbricks/ui/components/PageHeader";
|
||||
|
||||
const Page = async (props) => {
|
||||
const params = await props.params;
|
||||
const Page = async ({ params }) => {
|
||||
const t = await getTranslations();
|
||||
const [session, organization, webhooksUnsorted, surveys, environment] = await Promise.all([
|
||||
getServerSession(authOptions),
|
||||
|
||||
@@ -15,11 +15,7 @@ import { FormbricksClient } from "../../components/FormbricksClient";
|
||||
import EnvironmentStorageHandler from "./components/EnvironmentStorageHandler";
|
||||
import { PosthogIdentify } from "./components/PosthogIdentify";
|
||||
|
||||
export const EnvLayout = async (props) => {
|
||||
const params = await props.params;
|
||||
|
||||
const { children } = props;
|
||||
|
||||
export const EnvLayout = async ({ children, params }) => {
|
||||
const t = await getTranslations();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session || !session.user) {
|
||||
|
||||
@@ -7,8 +7,7 @@ import { getMembershipByUserIdOrganizationId } from "@formbricks/lib/membership/
|
||||
import { getAccessFlags } from "@formbricks/lib/membership/utils";
|
||||
import { getOrganizationByEnvironmentId } from "@formbricks/lib/organization/service";
|
||||
|
||||
const Page = async (props) => {
|
||||
const params = await props.params;
|
||||
const Page = async ({ params }) => {
|
||||
const session = await getServerSession(authOptions);
|
||||
const t = await getTranslations();
|
||||
const organization = await getOrganizationByEnvironmentId(params.environmentId);
|
||||
|
||||
@@ -12,8 +12,7 @@ import { PageContentWrapper } from "@formbricks/ui/components/PageContentWrapper
|
||||
import { PageHeader } from "@formbricks/ui/components/PageHeader";
|
||||
import { SettingsCard } from "../../../settings/components/SettingsCard";
|
||||
|
||||
const Page = async (props) => {
|
||||
const params = await props.params;
|
||||
const Page = async ({ params }) => {
|
||||
const t = await getTranslations();
|
||||
const [environment, organization] = await Promise.all([
|
||||
getEnvironment(params.environmentId),
|
||||
|
||||
@@ -19,7 +19,7 @@ const LoadingCard = () => {
|
||||
<div className="grid h-12 grid-cols-10 content-center rounded-t-lg bg-slate-100 px-6 text-left text-sm font-semibold text-slate-900">
|
||||
<div className="col-span-4 sm:col-span-2">{t("common.label")}</div>
|
||||
<div className="col-span-4 hidden sm:col-span-5 sm:block">
|
||||
{t("environments.product.api-keys.api_key")}
|
||||
{t("environments.product.api_keys.api_key")}
|
||||
</div>
|
||||
<div className="col-span-4 sm:col-span-2">{t("common.created_at")}</div>
|
||||
</div>
|
||||
|
||||
@@ -17,8 +17,7 @@ import { PageHeader } from "@formbricks/ui/components/PageHeader";
|
||||
import { SettingsCard } from "../../settings/components/SettingsCard";
|
||||
import { ApiKeyList } from "./components/ApiKeyList";
|
||||
|
||||
const Page = async (props) => {
|
||||
const params = await props.params;
|
||||
const Page = async ({ params }) => {
|
||||
const t = await getTranslations();
|
||||
const [session, environment, organization, product] = await Promise.all([
|
||||
getServerSession(authOptions),
|
||||
|
||||
@@ -19,8 +19,7 @@ import { DeleteProduct } from "./components/DeleteProduct";
|
||||
import { EditProductNameForm } from "./components/EditProductNameForm";
|
||||
import { EditWaitingTimeForm } from "./components/EditWaitingTimeForm";
|
||||
|
||||
const Page = async (props: { params: Promise<{ environmentId: string }> }) => {
|
||||
const params = await props.params;
|
||||
const Page = async ({ params }: { params: { environmentId: string } }) => {
|
||||
const t = await getTranslations();
|
||||
const [product, session, organization] = await Promise.all([
|
||||
getProductByEnvironmentId(params.environmentId),
|
||||
|
||||
@@ -16,8 +16,7 @@ import { getUser } from "@formbricks/lib/user/service";
|
||||
import { PageContentWrapper } from "@formbricks/ui/components/PageContentWrapper";
|
||||
import { PageHeader } from "@formbricks/ui/components/PageHeader";
|
||||
|
||||
const Page = async (props: { params: Promise<{ environmentId: string }> }) => {
|
||||
const params = await props.params;
|
||||
const Page = async ({ params }: { params: { environmentId: string } }) => {
|
||||
const t = await getTranslations();
|
||||
const product = await getProductByEnvironmentId(params.environmentId);
|
||||
|
||||
|
||||
@@ -12,11 +12,7 @@ export const metadata: Metadata = {
|
||||
title: "Config",
|
||||
};
|
||||
|
||||
const ConfigLayout = async (props) => {
|
||||
const params = await props.params;
|
||||
|
||||
const { children } = props;
|
||||
|
||||
const ConfigLayout = async ({ children, params }) => {
|
||||
const t = await getTranslations();
|
||||
|
||||
const [organization, session] = await Promise.all([
|
||||
|
||||
@@ -72,8 +72,8 @@ export const ThemeStyling = ({
|
||||
isDarkModeEnabled: product.styling.isDarkModeEnabled ?? false,
|
||||
roundness: product.styling.roundness ?? 8,
|
||||
cardArrangement: product.styling.cardArrangement ?? {
|
||||
linkSurveys: "straight",
|
||||
appSurveys: "straight",
|
||||
linkSurveys: "simple",
|
||||
appSurveys: "simple",
|
||||
},
|
||||
background: product.styling.background,
|
||||
hideProgressBar: product.styling.hideProgressBar ?? false,
|
||||
@@ -119,8 +119,8 @@ export const ThemeStyling = ({
|
||||
},
|
||||
roundness: 8,
|
||||
cardArrangement: {
|
||||
linkSurveys: "straight",
|
||||
appSurveys: "straight",
|
||||
linkSurveys: "simple",
|
||||
appSurveys: "simple",
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -28,9 +28,9 @@ const Loading = () => {
|
||||
<ProductConfigNavigation activeId="look" loading />
|
||||
</PageHeader>
|
||||
<SettingsCard
|
||||
title={t("environments.product.look.theme")}
|
||||
title="environments.product.look.theme"
|
||||
className="max-w-7xl"
|
||||
description={t("environments.product.look.theme_settings_description")}>
|
||||
description="environments.product.look.theme_settings_description">
|
||||
<div className="flex animate-pulse">
|
||||
<div className="w-1/2">
|
||||
<div className="flex flex-col gap-4 pr-6">
|
||||
|
||||
@@ -26,8 +26,7 @@ import { EditFormbricksBranding } from "./components/EditBranding";
|
||||
import { EditPlacementForm } from "./components/EditPlacementForm";
|
||||
import { ThemeStyling } from "./components/ThemeStyling";
|
||||
|
||||
const Page = async (props: { params: Promise<{ environmentId: string }> }) => {
|
||||
const params = await props.params;
|
||||
const Page = async ({ params }: { params: { environmentId: string } }) => {
|
||||
const t = await getTranslations();
|
||||
const [session, organization, product] = await Promise.all([
|
||||
getServerSession(authOptions),
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { redirect } from "next/navigation";
|
||||
|
||||
const Page = async (props) => {
|
||||
const params = await props.params;
|
||||
const Page = ({ params }) => {
|
||||
return redirect(`/environments/${params.environmentId}/product/general`);
|
||||
};
|
||||
|
||||
|
||||
@@ -17,8 +17,7 @@ import { PageContentWrapper } from "@formbricks/ui/components/PageContentWrapper
|
||||
import { PageHeader } from "@formbricks/ui/components/PageHeader";
|
||||
import { EditTagsWrapper } from "./components/EditTagsWrapper";
|
||||
|
||||
const Page = async (props) => {
|
||||
const params = await props.params;
|
||||
const Page = async ({ params }) => {
|
||||
const t = await getTranslations();
|
||||
const environment = await getEnvironment(params.environmentId);
|
||||
if (!environment) {
|
||||
|
||||
@@ -4,11 +4,7 @@ import { authOptions } from "@formbricks/lib/authOptions";
|
||||
import { getOrganizationByEnvironmentId } from "@formbricks/lib/organization/service";
|
||||
import { getProductByEnvironmentId } from "@formbricks/lib/product/service";
|
||||
|
||||
const AccountSettingsLayout = async (props) => {
|
||||
const params = await props.params;
|
||||
|
||||
const { children } = props;
|
||||
|
||||
const AccountSettingsLayout = async ({ children, params }) => {
|
||||
const t = await getTranslations();
|
||||
const [organization, product, session] = await Promise.all([
|
||||
getOrganizationByEnvironmentId(params.environmentId),
|
||||
|
||||
@@ -141,9 +141,7 @@ const getMemberships = async (userId: string): Promise<Membership[]> => {
|
||||
return memberships;
|
||||
};
|
||||
|
||||
const Page = async (props) => {
|
||||
const searchParams = await props.searchParams;
|
||||
const params = await props.params;
|
||||
const Page = async ({ params, searchParams }) => {
|
||||
const t = await getTranslations();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session) {
|
||||
|
||||
@@ -15,8 +15,7 @@ import { DeleteAccount } from "./components/DeleteAccount";
|
||||
import { EditProfileAvatarForm } from "./components/EditProfileAvatarForm";
|
||||
import { EditProfileDetailsForm } from "./components/EditProfileDetailsForm";
|
||||
|
||||
const Page = async (props: { params: Promise<{ environmentId: string }> }) => {
|
||||
const params = await props.params;
|
||||
const Page = async ({ params }: { params: { environmentId: string } }) => {
|
||||
const t = await getTranslations();
|
||||
const { environmentId } = params;
|
||||
const session = await getServerSession(authOptions);
|
||||
|
||||
@@ -13,8 +13,7 @@ import { Button } from "@formbricks/ui/components/Button";
|
||||
import { PageContentWrapper } from "@formbricks/ui/components/PageContentWrapper";
|
||||
import { PageHeader } from "@formbricks/ui/components/PageHeader";
|
||||
|
||||
const Page = async (props) => {
|
||||
const params = await props.params;
|
||||
const Page = async ({ params }) => {
|
||||
const t = await getTranslations();
|
||||
if (IS_FORMBRICKS_CLOUD) {
|
||||
notFound();
|
||||
|
||||
@@ -55,7 +55,7 @@ export const IndividualInviteTab = ({
|
||||
const submitEventClass = async () => {
|
||||
const data = getValues();
|
||||
data.role = data.role || OrganizationRole.owner;
|
||||
onSubmit([data]);
|
||||
await onSubmit([data]);
|
||||
setOpen(false);
|
||||
reset();
|
||||
};
|
||||
|
||||
@@ -13,7 +13,7 @@ import { DatabaseError, UnknownError } from "@formbricks/types/errors";
|
||||
import { TMember, TMembership } from "@formbricks/types/memberships";
|
||||
|
||||
export const getMembersByOrganizationId = reactCache(
|
||||
async (organizationId: string, page?: number): Promise<TMember[]> =>
|
||||
(organizationId: string, page?: number): Promise<TMember[]> =>
|
||||
cache(
|
||||
async () => {
|
||||
validateInputs([organizationId, ZString], [page, ZOptionalNumber]);
|
||||
@@ -135,7 +135,7 @@ export const deleteMembership = async (
|
||||
};
|
||||
|
||||
export const getMembershipsByUserId = reactCache(
|
||||
async (userId: string, page?: number): Promise<TMembership[]> =>
|
||||
(userId: string, page?: number): Promise<TMembership[]> =>
|
||||
cache(
|
||||
async () => {
|
||||
validateInputs([userId, ZString], [page, ZOptionalNumber]);
|
||||
|
||||
@@ -30,8 +30,7 @@ const MembersLoading = () => (
|
||||
</div>
|
||||
);
|
||||
|
||||
const Page = async (props: { params: Promise<{ environmentId: string }> }) => {
|
||||
const params = await props.params;
|
||||
const Page = async ({ params }: { params: { environmentId: string } }) => {
|
||||
const t = await getTranslations();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session) {
|
||||
|
||||
@@ -4,11 +4,7 @@ import { authOptions } from "@formbricks/lib/authOptions";
|
||||
import { getOrganizationByEnvironmentId } from "@formbricks/lib/organization/service";
|
||||
import { getProductByEnvironmentId } from "@formbricks/lib/product/service";
|
||||
|
||||
const Layout = async (props) => {
|
||||
const params = await props.params;
|
||||
|
||||
const { children } = props;
|
||||
|
||||
const Layout = async ({ children, params }) => {
|
||||
const t = await getTranslations();
|
||||
const [organization, product, session] = await Promise.all([
|
||||
getOrganizationByEnvironmentId(params.environmentId),
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { redirect } from "next/navigation";
|
||||
|
||||
const Page = async (props) => {
|
||||
const params = await props.params;
|
||||
const Page = ({ params }) => {
|
||||
return redirect(`/environments/${params.environmentId}/settings/profile`);
|
||||
};
|
||||
|
||||
|
||||
@@ -5,11 +5,10 @@ import { getResponseCountBySurveyId } from "@formbricks/lib/response/service";
|
||||
import { getSurvey } from "@formbricks/lib/survey/service";
|
||||
|
||||
type Props = {
|
||||
params: Promise<{ surveyId: string; environmentId: string }>;
|
||||
params: { surveyId: string; environmentId: string };
|
||||
};
|
||||
|
||||
export const generateMetadata = async (props: Props): Promise<Metadata> => {
|
||||
const params = await props.params;
|
||||
export const generateMetadata = async ({ params }: Props): Promise<Metadata> => {
|
||||
const session = await getServerSession(authOptions);
|
||||
const survey = await getSurvey(params.surveyId);
|
||||
const responseCount = await getResponseCountBySurveyId(params.surveyId);
|
||||
|
||||
@@ -27,8 +27,7 @@ import { findMatchingLocale } from "@formbricks/lib/utils/locale";
|
||||
import { PageContentWrapper } from "@formbricks/ui/components/PageContentWrapper";
|
||||
import { PageHeader } from "@formbricks/ui/components/PageHeader";
|
||||
|
||||
const Page = async (props) => {
|
||||
const params = await props.params;
|
||||
const Page = async ({ params }) => {
|
||||
const t = await getTranslations();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session) {
|
||||
@@ -73,7 +72,7 @@ const Page = async (props) => {
|
||||
|
||||
const isAIEnabled = await getIsAIEnabled(organization);
|
||||
const shouldGenerateInsights = needsInsightsGeneration(survey);
|
||||
const locale = await findMatchingLocale();
|
||||
const locale = findMatchingLocale();
|
||||
|
||||
return (
|
||||
<PageContentWrapper>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { InboxIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import type { JSX } from "react";
|
||||
import { getQuestionTypes } from "@formbricks/lib/utils/questions";
|
||||
import { recallToHeadline } from "@formbricks/lib/utils/recall";
|
||||
import { TAttributeClass } from "@formbricks/types/attribute-classes";
|
||||
|
||||
@@ -11,12 +11,7 @@ import { TInsight } from "@formbricks/types/insights";
|
||||
import { TSurveyQuestionId, ZSurveyQuestionId } from "@formbricks/types/surveys/types";
|
||||
|
||||
export const getInsightsBySurveyIdQuestionId = reactCache(
|
||||
async (
|
||||
surveyId: string,
|
||||
questionId: TSurveyQuestionId,
|
||||
limit?: number,
|
||||
offset?: number
|
||||
): Promise<TInsight[]> =>
|
||||
(surveyId: string, questionId: TSurveyQuestionId, limit?: number, offset?: number): Promise<TInsight[]> =>
|
||||
cache(
|
||||
async () => {
|
||||
validateInputs([surveyId, ZId], [questionId, ZSurveyQuestionId]);
|
||||
|
||||
@@ -119,11 +119,6 @@ const evaluateLogicAndGetNextQuestionId = (
|
||||
}
|
||||
}
|
||||
|
||||
// If no jump target was set, check for a fallback logic
|
||||
if (!firstJumpTarget && currQuesTemp.logicFallback) {
|
||||
firstJumpTarget = currQuesTemp.logicFallback;
|
||||
}
|
||||
|
||||
// Return the first jump target if found, otherwise go to the next question
|
||||
const nextQuestionId = firstJumpTarget || questions[currentQuestionIndex + 1]?.id || undefined;
|
||||
|
||||
@@ -888,7 +883,7 @@ export const getQuestionSummary = async (
|
||||
};
|
||||
|
||||
export const getSurveySummary = reactCache(
|
||||
async (surveyId: string, filterCriteria?: TResponseFilterCriteria): Promise<TSurveySummary> =>
|
||||
(surveyId: string, filterCriteria?: TResponseFilterCriteria): Promise<TSurveySummary> =>
|
||||
cache(
|
||||
async () => {
|
||||
validateInputs([surveyId, ZId], [filterCriteria, ZResponseFilterCriteria.optional()]);
|
||||
|
||||
@@ -28,8 +28,7 @@ import { getUser } from "@formbricks/lib/user/service";
|
||||
import { PageContentWrapper } from "@formbricks/ui/components/PageContentWrapper";
|
||||
import { PageHeader } from "@formbricks/ui/components/PageHeader";
|
||||
|
||||
const Page = async (props) => {
|
||||
const params = await props.params;
|
||||
const Page = async ({ params }) => {
|
||||
const t = await getTranslations();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session) {
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
} from "@/app/(app)/environments/[environmentId]/components/ResponseFilterContext";
|
||||
import { getResponsesDownloadUrlAction } from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/actions";
|
||||
import { getFormattedFilters, getTodayDate } from "@/app/lib/surveys/surveys";
|
||||
import { getFormattedErrorMessage } from "@/lib/utils/helper";
|
||||
import {
|
||||
differenceInDays,
|
||||
endOfMonth,
|
||||
@@ -22,6 +21,7 @@ import {
|
||||
subQuarters,
|
||||
subYears,
|
||||
} from "date-fns";
|
||||
import { getFormattedErrorMessage } from "@/lib/utils/helper";
|
||||
import { ArrowDownToLineIcon, ChevronDown, ChevronUp, DownloadIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useParams } from "next/navigation";
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { redirect } from "next/navigation";
|
||||
|
||||
const Page = async (props) => {
|
||||
const params = await props.params;
|
||||
const Page = ({ params }) => {
|
||||
return redirect(`/environments/${params.environmentId}/surveys/${params.surveyId}/summary`);
|
||||
};
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ export const surveySelect: Prisma.SurveySelect = {
|
||||
};
|
||||
|
||||
export const getSurveys = reactCache(
|
||||
async (
|
||||
(
|
||||
environmentId: string,
|
||||
limit?: number,
|
||||
offset?: number,
|
||||
@@ -87,7 +87,7 @@ export const getSurveys = reactCache(
|
||||
);
|
||||
|
||||
export const getSurveysSortedByRelevance = reactCache(
|
||||
async (
|
||||
(
|
||||
environmentId: string,
|
||||
limit?: number,
|
||||
offset?: number,
|
||||
@@ -173,7 +173,7 @@ export const getSurveysSortedByRelevance = reactCache(
|
||||
);
|
||||
|
||||
export const getSurvey = reactCache(
|
||||
async (surveyId: string): Promise<TSurvey | null> =>
|
||||
(surveyId: string): Promise<TSurvey | null> =>
|
||||
cache(
|
||||
async () => {
|
||||
validateInputs([surveyId, ZId]);
|
||||
|
||||
@@ -27,17 +27,15 @@ export const metadata: Metadata = {
|
||||
};
|
||||
|
||||
interface SurveyTemplateProps {
|
||||
params: Promise<{
|
||||
params: {
|
||||
environmentId: string;
|
||||
}>;
|
||||
searchParams: Promise<{
|
||||
};
|
||||
searchParams: {
|
||||
role?: TTemplateRole;
|
||||
}>;
|
||||
};
|
||||
}
|
||||
|
||||
const Page = async (props: SurveyTemplateProps) => {
|
||||
const searchParams = await props.searchParams;
|
||||
const params = await props.params;
|
||||
const Page = async ({ params, searchParams }: SurveyTemplateProps) => {
|
||||
const session = await getServerSession(authOptions);
|
||||
const product = await getProductByEnvironmentId(params.environmentId);
|
||||
const organization = await getOrganizationByEnvironmentId(params.environmentId);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import { IsPasswordValid } from "@/modules/auth/components/SignupOptions/components/IsPasswordValid";
|
||||
import { XCircleIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useRouter, useSearchParams } from "next/navigation";
|
||||
@@ -9,6 +8,7 @@ import { toast } from "react-hot-toast";
|
||||
import { resetPassword } from "@formbricks/lib/utils/users";
|
||||
import { Button } from "@formbricks/ui/components/Button";
|
||||
import { PasswordInput } from "@formbricks/ui/components/PasswordInput";
|
||||
import { IsPasswordValid } from "@formbricks/ui/components/SignupOptions/components/IsPasswordValid";
|
||||
|
||||
export const ResetPasswordForm = () => {
|
||||
const t = useTranslations();
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { TwoFactor } from "@/modules/auth/components/SigninForm/components/TwoFactor";
|
||||
import { TwoFactorBackup } from "@/modules/auth/components/SigninForm/components/TwoFactorBackup";
|
||||
import { createEmailTokenAction } from "@/modules/auth/components/SignupOptions/actions";
|
||||
import { AzureButton } from "@/modules/auth/components/SignupOptions/components/AzureButton";
|
||||
import { GithubButton } from "@/modules/auth/components/SignupOptions/components/GithubButton";
|
||||
import { GoogleButton } from "@/modules/auth/components/SignupOptions/components/GoogleButton";
|
||||
import { OpenIdButton } from "@/modules/auth/components/SignupOptions/components/OpenIdButton";
|
||||
import { TwoFactor } from "@/app/(auth)/auth/login/components/TwoFactor";
|
||||
import { TwoFactorBackup } from "@/app/(auth)/auth/login/components/TwoFactorBackup";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { XCircleIcon } from "lucide-react";
|
||||
import { signIn } from "next-auth/react";
|
||||
@@ -21,6 +16,10 @@ import { FORMBRICKS_LOGGED_IN_WITH_LS } from "@formbricks/lib/localStorage";
|
||||
import { Button } from "@formbricks/ui/components/Button";
|
||||
import { FormControl, FormError, FormField, FormItem } from "@formbricks/ui/components/Form";
|
||||
import { PasswordInput } from "@formbricks/ui/components/PasswordInput";
|
||||
import { AzureButton } from "@formbricks/ui/components/SignupOptions/components/AzureButton";
|
||||
import { GithubButton } from "@formbricks/ui/components/SignupOptions/components/GithubButton";
|
||||
import { GoogleButton } from "@formbricks/ui/components/SignupOptions/components/GoogleButton";
|
||||
import { OpenIdButton } from "@formbricks/ui/components/SignupOptions/components/OpenIdButton";
|
||||
|
||||
interface TSigninFormState {
|
||||
email: string;
|
||||
@@ -97,12 +96,7 @@ export const SigninForm = ({
|
||||
}
|
||||
|
||||
if (signInResponse?.error === "Email Verification is Pending") {
|
||||
const emailTokenActionResponse = await createEmailTokenAction({ email: data.email });
|
||||
if (emailTokenActionResponse?.serverError) {
|
||||
setSignInError(emailTokenActionResponse.serverError);
|
||||
return;
|
||||
}
|
||||
router.push(`/auth/verification-requested?token=${emailTokenActionResponse?.data}`);
|
||||
router.push(`/auth/verification-requested?email=${data.email}`);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { FormWrapper } from "@/app/(auth)/auth/components/FormWrapper";
|
||||
import { Testimonial } from "@/app/(auth)/auth/components/Testimonial";
|
||||
import { SigninForm } from "@/modules/auth/components/SigninForm";
|
||||
import { SigninForm } from "@/app/(auth)/auth/login/components/SigninForm";
|
||||
import { Metadata } from "next";
|
||||
import { getIsMultiOrgEnabled } from "@formbricks/ee/lib/service";
|
||||
import {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user