mirror of
https://github.com/formbricks/formbricks.git
synced 2025-12-21 13:40:31 -06:00
feat: tolgee (#4692)
Co-authored-by: pandeymangg <anshuman.pandey9999@gmail.com>
This commit is contained in:
committed by
GitHub
parent
9c33e77755
commit
36378e9c23
39
.github/workflows/tolgee-missing-key-check.yml
vendored
Normal file
39
.github/workflows/tolgee-missing-key-check.yml
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
name: Check Missing Translations
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
jobs:
|
||||
check-missing-translations:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
|
||||
- name: Install Tolgee CLI
|
||||
run: npm install -g @tolgee/cli
|
||||
|
||||
- name: Compare Tolgee Keys
|
||||
id: compare
|
||||
run: |
|
||||
tolgee compare --api-key ${{ secrets.TOLGEE_API_KEY }} > compare_output.txt
|
||||
cat compare_output.txt
|
||||
|
||||
- name: Check for Missing Translations
|
||||
run: |
|
||||
if grep -q "new key found" compare_output.txt; then
|
||||
echo "New keys found that may require translations:"
|
||||
exit 1
|
||||
else
|
||||
echo "No new keys found."
|
||||
fi
|
||||
42
.github/workflows/tolgee.yml
vendored
Normal file
42
.github/workflows/tolgee.yml
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
name: Tolgee Tagging on PR Merge
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
tag-production-keys:
|
||||
name: Tag Production Keys
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18 # Ensure compatibility with your project
|
||||
|
||||
- name: Install Tolgee CLI
|
||||
run: npm install -g @tolgee/cli
|
||||
|
||||
- name: Tag Production Keys
|
||||
run: |
|
||||
BRANCH_NAME=${GITHUB_REF##*/}
|
||||
npx tolgee tag \
|
||||
--api-key ${{ secrets.TOLGEE_API_KEY }} \
|
||||
--filter-extracted \
|
||||
--filter-tag "draft: ${BRANCH_NAME}" \
|
||||
--tag production \
|
||||
--untag "draft: ${BRANCH_NAME}"
|
||||
|
||||
- name: Tag Deprecated Keys
|
||||
run: |
|
||||
npx tolgee tag \
|
||||
--api-key ${{ secrets.TOLGEE_API_KEY }} \
|
||||
--filter-not-extracted --filter-tag production \
|
||||
--tag deprecated --untag production
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -58,4 +58,5 @@ packages/lib/uploads
|
||||
# js compiled assets
|
||||
apps/web/public/js
|
||||
|
||||
|
||||
packages/database/migrations
|
||||
1
.husky/post-checkout
Normal file
1
.husky/post-checkout
Normal file
@@ -0,0 +1 @@
|
||||
echo "{\"branchName\": \"$(git rev-parse --abbrev-ref HEAD)\"}" > ../branch.json
|
||||
1
.husky/post-commit
Normal file
1
.husky/post-commit
Normal file
@@ -0,0 +1 @@
|
||||
echo "{\"branchName\": \"$(git rev-parse --abbrev-ref HEAD)\"}" > ../branch.json
|
||||
@@ -1 +1,3 @@
|
||||
pnpm lint-staged
|
||||
pnpm lint-staged
|
||||
pnpm tolgee-pull || true
|
||||
git add packages/lib/messages/*.json
|
||||
31
.tolgeerc.json
Normal file
31
.tolgeerc.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"$schema": "https://docs.tolgee.io/cli-schema.json",
|
||||
"format": "JSON_TOLGEE",
|
||||
"patterns": ["./apps/web/**/*.ts?(x)"],
|
||||
"projectId": 10304,
|
||||
"pull": {
|
||||
"path": "./packages/lib/messages"
|
||||
},
|
||||
"push": {
|
||||
"files": [
|
||||
{
|
||||
"language": "en-US",
|
||||
"path": "./packages/lib/messages/en-US.json"
|
||||
},
|
||||
{
|
||||
"language": "de-DE",
|
||||
"path": "./packages/lib/messages/de-DE.json"
|
||||
},
|
||||
{
|
||||
"language": "fr-FR",
|
||||
"path": "./packages/lib/messages/fr-FR.json"
|
||||
},
|
||||
{
|
||||
"language": "pt-BR",
|
||||
"path": "./packages/lib/messages/pt-BR.json"
|
||||
}
|
||||
],
|
||||
"forceMode": "OVERRIDE"
|
||||
},
|
||||
"strictNamespace": false
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import { Button } from "@/modules/ui/components/button";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { ArrowRight } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useEffect } from "react";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
@@ -23,7 +23,7 @@ export const ConnectWithFormbricks = ({
|
||||
widgetSetupCompleted,
|
||||
channel,
|
||||
}: ConnectWithFormbricksProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const router = useRouter();
|
||||
const handleFinishOnboarding = async () => {
|
||||
router.push(`/environments/${environment.id}/surveys`);
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Button } from "@/modules/ui/components/button";
|
||||
import { CodeBlock } from "@/modules/ui/components/code-block";
|
||||
import { Html5Icon, NpmIcon } from "@/modules/ui/components/icons";
|
||||
import { TabBar } from "@/modules/ui/components/tab-bar";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import Link from "next/link";
|
||||
import "prismjs/themes/prism.css";
|
||||
import { useState } from "react";
|
||||
@@ -29,7 +29,7 @@ export const OnboardingSetupInstructions = ({
|
||||
channel,
|
||||
widgetSetupCompleted,
|
||||
}: OnboardingSetupInstructionsProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const [activeTab, setActiveTab] = useState(tabs[0].id);
|
||||
const htmlSnippetForAppSurveys = `<!-- START Formbricks Surveys -->
|
||||
<script type="text/javascript">
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { ConnectWithFormbricks } from "@/app/(app)/(onboarding)/environments/[environmentId]/connect/components/ConnectWithFormbricks";
|
||||
import { Button } from "@/modules/ui/components/button";
|
||||
import { Header } from "@/modules/ui/components/header";
|
||||
import { getTranslate } from "@/tolgee/server";
|
||||
import { XIcon } from "lucide-react";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import Link from "next/link";
|
||||
import { WEBAPP_URL } from "@formbricks/lib/constants";
|
||||
import { getEnvironment } from "@formbricks/lib/environment/service";
|
||||
@@ -16,7 +16,7 @@ interface ConnectPageProps {
|
||||
|
||||
const Page = async (props: ConnectPageProps) => {
|
||||
const params = await props.params;
|
||||
const t = await getTranslations();
|
||||
const t = await getTranslate();
|
||||
const environment = await getEnvironment(params.environmentId);
|
||||
|
||||
if (!environment) {
|
||||
|
||||
@@ -5,8 +5,8 @@ import { getXMTemplates } from "@/app/(app)/(onboarding)/environments/[environme
|
||||
import { OnboardingOptionsContainer } from "@/app/(app)/(onboarding)/organizations/components/OnboardingOptionsContainer";
|
||||
import { getFormattedErrorMessage } from "@/lib/utils/helper";
|
||||
import { createSurveyAction } from "@/modules/surveys/components/TemplateList/actions";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { ActivityIcon, ShoppingCartIcon, SmileIcon, StarIcon, ThumbsUpIcon, UsersIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
@@ -23,7 +23,7 @@ interface XMTemplateListProps {
|
||||
|
||||
export const XMTemplateList = ({ project, user, environmentId }: XMTemplateListProps) => {
|
||||
const [activeTemplateId, setActiveTemplateId] = useState<number | null>(null);
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const router = useRouter();
|
||||
|
||||
const createSurvey = async (activeTemplate: TXMTemplate) => {
|
||||
@@ -47,7 +47,7 @@ export const XMTemplateList = ({ project, user, environmentId }: XMTemplateListP
|
||||
|
||||
const handleTemplateClick = (templateIdx: number) => {
|
||||
setActiveTemplateId(templateIdx);
|
||||
const template = getXMTemplates(user.locale)[templateIdx];
|
||||
const template = getXMTemplates(t)[templateIdx];
|
||||
const newTemplate = replacePresetPlaceholders(template, project);
|
||||
createSurvey(newTemplate);
|
||||
};
|
||||
|
||||
@@ -5,7 +5,7 @@ import { TXMTemplate } from "@formbricks/types/templates";
|
||||
// replace all occurences of projectName with the actual project name in the current template
|
||||
export const replacePresetPlaceholders = (template: TXMTemplate, project: TProject) => {
|
||||
const survey = structuredClone(template);
|
||||
survey.name = survey.name.replace("{{projectName}}", project.name);
|
||||
survey.name = survey.name.replace("$[projectName]", project.name);
|
||||
survey.questions = survey.questions.map((question) => {
|
||||
return replaceQuestionPresetPlaceholders(question, project);
|
||||
});
|
||||
|
||||
@@ -1,25 +1,18 @@
|
||||
import { getDefaultEndingCard } from "@/app/lib/templates";
|
||||
import { createId } from "@paralleldrive/cuid2";
|
||||
import { getDefaultEndingCard, translate } from "@formbricks/lib/templates";
|
||||
import { TFnType } from "@tolgee/react";
|
||||
import { TSurveyQuestionTypeEnum } from "@formbricks/types/surveys/types";
|
||||
import { TXMTemplate } from "@formbricks/types/templates";
|
||||
|
||||
function validateLocale(locale: string): boolean {
|
||||
// Add logic to validate the locale, e.g., check against a list of supported locales
|
||||
return typeof locale === "string" && locale.length > 0;
|
||||
}
|
||||
|
||||
function logError(error: Error, context: string) {
|
||||
console.error(`Error in ${context}:`, error);
|
||||
}
|
||||
|
||||
export const getXMSurveyDefault = (locale: string): TXMTemplate => {
|
||||
export const getXMSurveyDefault = (t: TFnType): TXMTemplate => {
|
||||
try {
|
||||
if (!validateLocale(locale)) {
|
||||
throw new Error("Invalid locale");
|
||||
}
|
||||
return {
|
||||
name: "",
|
||||
endings: [getDefaultEndingCard([], locale)],
|
||||
endings: [getDefaultEndingCard([], t)],
|
||||
questions: [],
|
||||
styling: {
|
||||
overwriteThemeStyling: true,
|
||||
@@ -31,24 +24,24 @@ export const getXMSurveyDefault = (locale: string): TXMTemplate => {
|
||||
}
|
||||
};
|
||||
|
||||
const NPSSurvey = (locale: string): TXMTemplate => {
|
||||
const npsSurvey = (t: TFnType): TXMTemplate => {
|
||||
return {
|
||||
...getXMSurveyDefault(locale),
|
||||
name: translate("nps_survey_name", locale),
|
||||
...getXMSurveyDefault(t),
|
||||
name: t("templates.nps_survey_name"),
|
||||
questions: [
|
||||
{
|
||||
id: createId(),
|
||||
type: TSurveyQuestionTypeEnum.NPS,
|
||||
headline: { default: translate("nps_survey_question_1_headline", locale) },
|
||||
headline: { default: t("templates.nps_survey_question_1_headline") },
|
||||
required: true,
|
||||
lowerLabel: { default: translate("nps_survey_question_1_lower_label", locale) },
|
||||
upperLabel: { default: translate("nps_survey_question_1_upper_label", locale) },
|
||||
lowerLabel: { default: t("templates.nps_survey_question_1_lower_label") },
|
||||
upperLabel: { default: t("templates.nps_survey_question_1_upper_label") },
|
||||
isColorCodingEnabled: true,
|
||||
},
|
||||
{
|
||||
id: createId(),
|
||||
type: TSurveyQuestionTypeEnum.OpenText,
|
||||
headline: { default: translate("nps_survey_question_2_headline", locale) },
|
||||
headline: { default: t("templates.nps_survey_question_2_headline") },
|
||||
required: false,
|
||||
inputType: "text",
|
||||
charLimit: {
|
||||
@@ -58,7 +51,7 @@ const NPSSurvey = (locale: string): TXMTemplate => {
|
||||
{
|
||||
id: createId(),
|
||||
type: TSurveyQuestionTypeEnum.OpenText,
|
||||
headline: { default: translate("nps_survey_question_3_headline", locale) },
|
||||
headline: { default: t("templates.nps_survey_question_3_headline") },
|
||||
required: false,
|
||||
inputType: "text",
|
||||
charLimit: {
|
||||
@@ -69,13 +62,13 @@ const NPSSurvey = (locale: string): TXMTemplate => {
|
||||
};
|
||||
};
|
||||
|
||||
const StarRatingSurvey = (locale: string): TXMTemplate => {
|
||||
const starRatingSurvey = (t: TFnType): TXMTemplate => {
|
||||
const reusableQuestionIds = [createId(), createId(), createId()];
|
||||
const defaultSurvey = getXMSurveyDefault(locale);
|
||||
const defaultSurvey = getXMSurveyDefault(t);
|
||||
|
||||
return {
|
||||
...defaultSurvey,
|
||||
name: translate("star_rating_survey_name", locale),
|
||||
name: t("templates.star_rating_survey_name"),
|
||||
questions: [
|
||||
{
|
||||
id: reusableQuestionIds[0],
|
||||
@@ -112,15 +105,15 @@ const StarRatingSurvey = (locale: string): TXMTemplate => {
|
||||
],
|
||||
range: 5,
|
||||
scale: "number",
|
||||
headline: { default: translate("star_rating_survey_question_1_headline", locale) },
|
||||
headline: { default: t("templates.star_rating_survey_question_1_headline") },
|
||||
required: true,
|
||||
lowerLabel: { default: translate("star_rating_survey_question_1_lower_label", locale) },
|
||||
upperLabel: { default: translate("star_rating_survey_question_1_upper_label", locale) },
|
||||
lowerLabel: { default: t("templates.star_rating_survey_question_1_lower_label") },
|
||||
upperLabel: { default: t("templates.star_rating_survey_question_1_upper_label") },
|
||||
isColorCodingEnabled: false,
|
||||
},
|
||||
{
|
||||
id: reusableQuestionIds[1],
|
||||
html: { default: translate("star_rating_survey_question_2_html", locale) },
|
||||
html: { default: t("templates.star_rating_survey_question_2_html") },
|
||||
type: TSurveyQuestionTypeEnum.CTA,
|
||||
logic: [
|
||||
{
|
||||
@@ -148,20 +141,20 @@ const StarRatingSurvey = (locale: string): TXMTemplate => {
|
||||
],
|
||||
},
|
||||
],
|
||||
headline: { default: translate("star_rating_survey_question_2_headline", locale) },
|
||||
headline: { default: t("templates.star_rating_survey_question_2_headline") },
|
||||
required: true,
|
||||
buttonUrl: "https://formbricks.com/github",
|
||||
buttonLabel: { default: translate("star_rating_survey_question_2_button_label", locale) },
|
||||
buttonLabel: { default: t("templates.star_rating_survey_question_2_button_label") },
|
||||
buttonExternal: true,
|
||||
},
|
||||
{
|
||||
id: reusableQuestionIds[2],
|
||||
type: TSurveyQuestionTypeEnum.OpenText,
|
||||
headline: { default: "Sorry to hear! What is ONE thing we can do better?" },
|
||||
headline: { default: t("templates.star_rating_survey_question_3_headline") },
|
||||
required: true,
|
||||
subheader: { default: "Help us improve your experience." },
|
||||
buttonLabel: { default: "Send" },
|
||||
placeholder: { default: "Type your answer here..." },
|
||||
subheader: { default: t("templates.star_rating_survey_question_3_subheader") },
|
||||
buttonLabel: { default: t("templates.star_rating_survey_question_3_button_label") },
|
||||
placeholder: { default: t("templates.star_rating_survey_question_3_placeholder") },
|
||||
inputType: "text",
|
||||
charLimit: {
|
||||
enabled: false,
|
||||
@@ -171,13 +164,13 @@ const StarRatingSurvey = (locale: string): TXMTemplate => {
|
||||
};
|
||||
};
|
||||
|
||||
const CSATSurvey = (locale: string): TXMTemplate => {
|
||||
const csatSurvey = (t: TFnType): TXMTemplate => {
|
||||
const reusableQuestionIds = [createId(), createId(), createId()];
|
||||
const defaultSurvey = getXMSurveyDefault(locale);
|
||||
const defaultSurvey = getXMSurveyDefault(t);
|
||||
|
||||
return {
|
||||
...defaultSurvey,
|
||||
name: translate("csat_survey_name", locale),
|
||||
name: t("templates.csat_survey_name"),
|
||||
questions: [
|
||||
{
|
||||
id: reusableQuestionIds[0],
|
||||
@@ -214,10 +207,10 @@ const CSATSurvey = (locale: string): TXMTemplate => {
|
||||
],
|
||||
range: 5,
|
||||
scale: "smiley",
|
||||
headline: { default: translate("csat_survey_question_1_headline", locale) },
|
||||
headline: { default: t("templates.csat_survey_question_1_headline") },
|
||||
required: true,
|
||||
lowerLabel: { default: translate("csat_survey_question_1_lower_label", locale) },
|
||||
upperLabel: { default: translate("csat_survey_question_1_upper_label", locale) },
|
||||
lowerLabel: { default: t("templates.csat_survey_question_1_lower_label") },
|
||||
upperLabel: { default: t("templates.csat_survey_question_1_upper_label") },
|
||||
isColorCodingEnabled: false,
|
||||
},
|
||||
{
|
||||
@@ -249,9 +242,9 @@ const CSATSurvey = (locale: string): TXMTemplate => {
|
||||
],
|
||||
},
|
||||
],
|
||||
headline: { default: translate("csat_survey_question_2_headline", locale) },
|
||||
headline: { default: t("templates.csat_survey_question_2_headline") },
|
||||
required: false,
|
||||
placeholder: { default: translate("csat_survey_question_2_placeholder", locale) },
|
||||
placeholder: { default: t("templates.csat_survey_question_2_placeholder") },
|
||||
inputType: "text",
|
||||
charLimit: {
|
||||
enabled: false,
|
||||
@@ -260,9 +253,9 @@ const CSATSurvey = (locale: string): TXMTemplate => {
|
||||
{
|
||||
id: reusableQuestionIds[2],
|
||||
type: TSurveyQuestionTypeEnum.OpenText,
|
||||
headline: { default: translate("csat_survey_question_3_headline", locale) },
|
||||
headline: { default: t("templates.csat_survey_question_3_headline") },
|
||||
required: false,
|
||||
placeholder: { default: translate("csat_survey_question_3_placeholder", locale) },
|
||||
placeholder: { default: t("templates.csat_survey_question_3_placeholder") },
|
||||
inputType: "text",
|
||||
charLimit: {
|
||||
enabled: false,
|
||||
@@ -272,28 +265,28 @@ const CSATSurvey = (locale: string): TXMTemplate => {
|
||||
};
|
||||
};
|
||||
|
||||
const CESSurvey = (locale: string): TXMTemplate => {
|
||||
const cessSurvey = (t: TFnType): TXMTemplate => {
|
||||
return {
|
||||
...getXMSurveyDefault(locale),
|
||||
name: translate("cess_survey_name", locale),
|
||||
...getXMSurveyDefault(t),
|
||||
name: t("templates.cess_survey_name"),
|
||||
questions: [
|
||||
{
|
||||
id: createId(),
|
||||
type: TSurveyQuestionTypeEnum.Rating,
|
||||
range: 5,
|
||||
scale: "number",
|
||||
headline: { default: translate("cess_survey_question_1_headline", locale) },
|
||||
headline: { default: t("templates.cess_survey_question_1_headline") },
|
||||
required: true,
|
||||
lowerLabel: { default: translate("cess_survey_question_1_lower_label", locale) },
|
||||
upperLabel: { default: translate("cess_survey_question_1_upper_label", locale) },
|
||||
lowerLabel: { default: t("templates.cess_survey_question_1_lower_label") },
|
||||
upperLabel: { default: t("templates.cess_survey_question_1_upper_label") },
|
||||
isColorCodingEnabled: false,
|
||||
},
|
||||
{
|
||||
id: createId(),
|
||||
type: TSurveyQuestionTypeEnum.OpenText,
|
||||
headline: { default: translate("cess_survey_question_2_headline", locale) },
|
||||
headline: { default: t("templates.cess_survey_question_2_headline") },
|
||||
required: true,
|
||||
placeholder: { default: translate("cess_survey_question_2_placeholder", locale) },
|
||||
placeholder: { default: t("templates.cess_survey_question_2_placeholder") },
|
||||
inputType: "text",
|
||||
charLimit: {
|
||||
enabled: false,
|
||||
@@ -303,13 +296,13 @@ const CESSurvey = (locale: string): TXMTemplate => {
|
||||
};
|
||||
};
|
||||
|
||||
const SmileysRatingSurvey = (locale: string): TXMTemplate => {
|
||||
const smileysRatingSurvey = (t: TFnType): TXMTemplate => {
|
||||
const reusableQuestionIds = [createId(), createId(), createId()];
|
||||
const defaultSurvey = getXMSurveyDefault(locale);
|
||||
const defaultSurvey = getXMSurveyDefault(t);
|
||||
|
||||
return {
|
||||
...defaultSurvey,
|
||||
name: translate("smileys_survey_name", locale),
|
||||
name: t("templates.smileys_survey_name"),
|
||||
questions: [
|
||||
{
|
||||
id: reusableQuestionIds[0],
|
||||
@@ -346,15 +339,15 @@ const SmileysRatingSurvey = (locale: string): TXMTemplate => {
|
||||
],
|
||||
range: 5,
|
||||
scale: "smiley",
|
||||
headline: { default: translate("smileys_survey_question_1_headline", locale) },
|
||||
headline: { default: t("templates.smileys_survey_question_1_headline") },
|
||||
required: true,
|
||||
lowerLabel: { default: translate("smileys_survey_question_1_lower_label", locale) },
|
||||
upperLabel: { default: translate("smileys_survey_question_1_upper_label", locale) },
|
||||
lowerLabel: { default: t("templates.smileys_survey_question_1_lower_label") },
|
||||
upperLabel: { default: t("templates.smileys_survey_question_1_upper_label") },
|
||||
isColorCodingEnabled: false,
|
||||
},
|
||||
{
|
||||
id: reusableQuestionIds[1],
|
||||
html: { default: translate("smileys_survey_question_2_html", locale) },
|
||||
html: { default: t("templates.smileys_survey_question_2_html") },
|
||||
type: TSurveyQuestionTypeEnum.CTA,
|
||||
logic: [
|
||||
{
|
||||
@@ -382,20 +375,20 @@ const SmileysRatingSurvey = (locale: string): TXMTemplate => {
|
||||
],
|
||||
},
|
||||
],
|
||||
headline: { default: translate("smileys_survey_question_2_headline", locale) },
|
||||
headline: { default: t("templates.smileys_survey_question_2_headline") },
|
||||
required: true,
|
||||
buttonUrl: "https://formbricks.com/github",
|
||||
buttonLabel: { default: translate("smileys_survey_question_2_button_label", locale) },
|
||||
buttonLabel: { default: t("templates.smileys_survey_question_2_button_label") },
|
||||
buttonExternal: true,
|
||||
},
|
||||
{
|
||||
id: reusableQuestionIds[2],
|
||||
type: TSurveyQuestionTypeEnum.OpenText,
|
||||
headline: { default: translate("smileys_survey_question_3_headline", locale) },
|
||||
headline: { default: t("templates.smileys_survey_question_3_headline") },
|
||||
required: true,
|
||||
subheader: { default: translate("smileys_survey_question_3_subheader", locale) },
|
||||
buttonLabel: { default: translate("smileys_survey_question_3_button_label", locale) },
|
||||
placeholder: { default: translate("smileys_survey_question_3_placeholder", locale) },
|
||||
subheader: { default: t("templates.smileys_survey_question_3_subheader") },
|
||||
buttonLabel: { default: t("templates.smileys_survey_question_3_button_label") },
|
||||
placeholder: { default: t("templates.smileys_survey_question_3_placeholder") },
|
||||
inputType: "text",
|
||||
charLimit: {
|
||||
enabled: false,
|
||||
@@ -405,26 +398,26 @@ const SmileysRatingSurvey = (locale: string): TXMTemplate => {
|
||||
};
|
||||
};
|
||||
|
||||
const eNPSSurvey = (locale: string): TXMTemplate => {
|
||||
const enpsSurvey = (t: TFnType): TXMTemplate => {
|
||||
return {
|
||||
...getXMSurveyDefault(locale),
|
||||
name: translate("enps_survey_name", locale),
|
||||
...getXMSurveyDefault(t),
|
||||
name: t("templates.enps_survey_name"),
|
||||
questions: [
|
||||
{
|
||||
id: createId(),
|
||||
type: TSurveyQuestionTypeEnum.NPS,
|
||||
headline: {
|
||||
default: translate("enps_survey_question_1_headline", locale),
|
||||
default: t("templates.enps_survey_question_1_headline"),
|
||||
},
|
||||
required: false,
|
||||
lowerLabel: { default: translate("enps_survey_question_1_lower_label", locale) },
|
||||
upperLabel: { default: translate("enps_survey_question_1_upper_label", locale) },
|
||||
lowerLabel: { default: t("templates.enps_survey_question_1_lower_label") },
|
||||
upperLabel: { default: t("templates.enps_survey_question_1_upper_label") },
|
||||
isColorCodingEnabled: true,
|
||||
},
|
||||
{
|
||||
id: createId(),
|
||||
type: TSurveyQuestionTypeEnum.OpenText,
|
||||
headline: { default: translate("enps_survey_question_2_headline", locale) },
|
||||
headline: { default: t("templates.enps_survey_question_2_headline") },
|
||||
required: false,
|
||||
inputType: "text",
|
||||
charLimit: {
|
||||
@@ -434,7 +427,7 @@ const eNPSSurvey = (locale: string): TXMTemplate => {
|
||||
{
|
||||
id: createId(),
|
||||
type: TSurveyQuestionTypeEnum.OpenText,
|
||||
headline: { default: translate("enps_survey_question_3_headline", locale) },
|
||||
headline: { default: t("templates.enps_survey_question_3_headline") },
|
||||
required: false,
|
||||
inputType: "text",
|
||||
charLimit: {
|
||||
@@ -445,18 +438,15 @@ const eNPSSurvey = (locale: string): TXMTemplate => {
|
||||
};
|
||||
};
|
||||
|
||||
export const getXMTemplates = (locale: string): TXMTemplate[] => {
|
||||
export const getXMTemplates = (t: TFnType): TXMTemplate[] => {
|
||||
try {
|
||||
if (!validateLocale(locale)) {
|
||||
throw new Error("Invalid locale");
|
||||
}
|
||||
return [
|
||||
NPSSurvey(locale),
|
||||
StarRatingSurvey(locale),
|
||||
CSATSurvey(locale),
|
||||
CESSurvey(locale),
|
||||
SmileysRatingSurvey(locale),
|
||||
eNPSSurvey(locale),
|
||||
npsSurvey(t),
|
||||
starRatingSurvey(t),
|
||||
csatSurvey(t),
|
||||
cessSurvey(t),
|
||||
smileysRatingSurvey(t),
|
||||
enpsSurvey(t),
|
||||
];
|
||||
} catch (error) {
|
||||
logError(error, "getXMTemplates");
|
||||
|
||||
@@ -3,9 +3,9 @@ import { getOrganizationIdFromEnvironmentId } from "@/lib/utils/helper";
|
||||
import { authOptions } from "@/modules/auth/lib/authOptions";
|
||||
import { Button } from "@/modules/ui/components/button";
|
||||
import { Header } from "@/modules/ui/components/header";
|
||||
import { getTranslate } from "@/tolgee/server";
|
||||
import { XIcon } from "lucide-react";
|
||||
import { getServerSession } from "next-auth";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import Link from "next/link";
|
||||
import { getEnvironment } from "@formbricks/lib/environment/service";
|
||||
import { getProjectByEnvironmentId, getUserProjects } from "@formbricks/lib/project/service";
|
||||
@@ -21,7 +21,7 @@ const Page = async (props: XMTemplatePageProps) => {
|
||||
const params = await props.params;
|
||||
const session = await getServerSession(authOptions);
|
||||
const environment = await getEnvironment(params.environmentId);
|
||||
const t = await getTranslations();
|
||||
const t = await getTranslate();
|
||||
if (!session) {
|
||||
throw new Error(t("common.session_not_found"));
|
||||
}
|
||||
|
||||
@@ -17,9 +17,9 @@ import {
|
||||
DropdownMenuSubTrigger,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/modules/ui/components/dropdown-menu";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { ArrowUpRightIcon, ChevronRightIcon, LogOutIcon, PlusIcon } from "lucide-react";
|
||||
import { signOut } from "next-auth/react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/navigation";
|
||||
@@ -44,7 +44,7 @@ export const LandingSidebar = ({
|
||||
}: LandingSidebarProps) => {
|
||||
const [openCreateOrganizationModal, setOpenCreateOrganizationModal] = useState<boolean>(false);
|
||||
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
|
||||
@@ -2,15 +2,15 @@ import { LandingSidebar } from "@/app/(app)/(onboarding)/organizations/[organiza
|
||||
import { authOptions } from "@/modules/auth/lib/authOptions";
|
||||
import { getEnterpriseLicense } from "@/modules/ee/license-check/lib/utils";
|
||||
import { Header } from "@/modules/ui/components/header";
|
||||
import { getTranslate } from "@/tolgee/server";
|
||||
import { getServerSession } from "next-auth";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import { notFound, redirect } from "next/navigation";
|
||||
import { getOrganization, getOrganizationsByUserId } from "@formbricks/lib/organization/service";
|
||||
import { getUser } from "@formbricks/lib/user/service";
|
||||
|
||||
const Page = async (props) => {
|
||||
const params = await props.params;
|
||||
const t = await getTranslations();
|
||||
const t = await getTranslate();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session || !session.user) {
|
||||
return redirect(`/auth/login`);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { PosthogIdentify } from "@/app/(app)/environments/[environmentId]/components/PosthogIdentify";
|
||||
import { authOptions } from "@/modules/auth/lib/authOptions";
|
||||
import { ToasterClient } from "@/modules/ui/components/toaster-client";
|
||||
import { getTranslate } from "@/tolgee/server";
|
||||
import { getServerSession } from "next-auth";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import { redirect } from "next/navigation";
|
||||
import { canUserAccessOrganization } from "@formbricks/lib/organization/auth";
|
||||
import { getOrganization } from "@formbricks/lib/organization/service";
|
||||
@@ -14,7 +14,7 @@ const ProjectOnboardingLayout = async (props) => {
|
||||
|
||||
const { children } = props;
|
||||
|
||||
const t = await getTranslations();
|
||||
const t = await getTranslate();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session || !session.user) {
|
||||
return redirect(`/auth/login`);
|
||||
|
||||
@@ -2,9 +2,9 @@ import { OnboardingOptionsContainer } from "@/app/(app)/(onboarding)/organizatio
|
||||
import { authOptions } from "@/modules/auth/lib/authOptions";
|
||||
import { Button } from "@/modules/ui/components/button";
|
||||
import { Header } from "@/modules/ui/components/header";
|
||||
import { getTranslate } from "@/tolgee/server";
|
||||
import { PictureInPicture2Icon, SendIcon, XIcon } from "lucide-react";
|
||||
import { getServerSession } from "next-auth";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import Link from "next/link";
|
||||
import { redirect } from "next/navigation";
|
||||
import { getUserProjects } from "@formbricks/lib/project/service";
|
||||
@@ -22,7 +22,7 @@ const Page = async (props: ChannelPageProps) => {
|
||||
return redirect(`/auth/login`);
|
||||
}
|
||||
|
||||
const t = await getTranslations();
|
||||
const t = await getTranslate();
|
||||
const channelOptions = [
|
||||
{
|
||||
title: t("organizations.projects.new.channel.link_and_email_surveys"),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { authOptions } from "@/modules/auth/lib/authOptions";
|
||||
import { getOrganizationProjectsLimit } from "@/modules/ee/license-check/lib/utils";
|
||||
import { getTranslate } from "@/tolgee/server";
|
||||
import { getServerSession } from "next-auth";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import { notFound, redirect } from "next/navigation";
|
||||
import { getMembershipByUserIdOrganizationId } from "@formbricks/lib/membership/service";
|
||||
import { getAccessFlags } from "@formbricks/lib/membership/utils";
|
||||
@@ -12,7 +12,7 @@ const OnboardingLayout = async (props) => {
|
||||
const params = await props.params;
|
||||
|
||||
const { children } = props;
|
||||
const t = await getTranslations();
|
||||
const t = await getTranslate();
|
||||
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session || !session.user) {
|
||||
|
||||
@@ -2,9 +2,9 @@ import { OnboardingOptionsContainer } from "@/app/(app)/(onboarding)/organizatio
|
||||
import { authOptions } from "@/modules/auth/lib/authOptions";
|
||||
import { Button } from "@/modules/ui/components/button";
|
||||
import { Header } from "@/modules/ui/components/header";
|
||||
import { getTranslate } from "@/tolgee/server";
|
||||
import { HeartIcon, ListTodoIcon, XIcon } from "lucide-react";
|
||||
import { getServerSession } from "next-auth";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import Link from "next/link";
|
||||
import { redirect } from "next/navigation";
|
||||
import { getUserProjects } from "@formbricks/lib/project/service";
|
||||
@@ -22,7 +22,7 @@ const Page = async (props: ModePageProps) => {
|
||||
return redirect(`/auth/login`);
|
||||
}
|
||||
|
||||
const t = await getTranslations();
|
||||
const t = await getTranslate();
|
||||
const channelOptions = [
|
||||
{
|
||||
title: t("organizations.projects.new.mode.formbricks_surveys"),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { createProjectAction } from "@/app/(app)/environments/[environmentId]/actions";
|
||||
import { previewSurvey } from "@/app/lib/templates";
|
||||
import { getFormattedErrorMessage } from "@/lib/utils/helper";
|
||||
import { TOrganizationTeam } from "@/modules/ee/teams/project-teams/types/team";
|
||||
import { CreateTeamModal } from "@/modules/ee/teams/team-list/components/create-team-modal";
|
||||
@@ -19,14 +20,13 @@ import { Input } from "@/modules/ui/components/input";
|
||||
import { MultiSelect } from "@/modules/ui/components/multi-select";
|
||||
import { SurveyInline } from "@/modules/ui/components/survey";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import Image from "next/image";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { FORMBRICKS_SURVEYS_FILTERS_KEY_LS } from "@formbricks/lib/localStorage";
|
||||
import { getPreviewSurvey } from "@formbricks/lib/styling/constants";
|
||||
import {
|
||||
TProjectConfigChannel,
|
||||
TProjectConfigIndustry,
|
||||
@@ -43,7 +43,6 @@ interface ProjectSettingsProps {
|
||||
defaultBrandColor: string;
|
||||
organizationTeams: TOrganizationTeam[];
|
||||
canDoRoleManagement: boolean;
|
||||
locale: string;
|
||||
userProjectsCount: number;
|
||||
}
|
||||
|
||||
@@ -55,13 +54,12 @@ export const ProjectSettings = ({
|
||||
defaultBrandColor,
|
||||
organizationTeams,
|
||||
canDoRoleManagement = false,
|
||||
locale,
|
||||
userProjectsCount,
|
||||
}: ProjectSettingsProps) => {
|
||||
const [createTeamModalOpen, setCreateTeamModalOpen] = useState(false);
|
||||
|
||||
const router = useRouter();
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const addProject = async (data: TProjectUpdateInput) => {
|
||||
try {
|
||||
const createProjectResponse = await createProjectAction({
|
||||
@@ -233,7 +231,7 @@ export const ProjectSettings = ({
|
||||
<p className="text-sm text-slate-400">{t("common.preview")}</p>
|
||||
<div className="z-0 h-3/4 w-3/4">
|
||||
<SurveyInline
|
||||
survey={getPreviewSurvey(locale, projectName || "my Product")}
|
||||
survey={previewSurvey(projectName || "my Product", t)}
|
||||
styling={{ brandColor: { light: brandColor } }}
|
||||
isBrandingEnabled={false}
|
||||
languageCode="default"
|
||||
|
||||
@@ -4,15 +4,14 @@ import { authOptions } from "@/modules/auth/lib/authOptions";
|
||||
import { getRoleManagementPermission } from "@/modules/ee/license-check/lib/utils";
|
||||
import { Button } from "@/modules/ui/components/button";
|
||||
import { Header } from "@/modules/ui/components/header";
|
||||
import { getTranslate } from "@/tolgee/server";
|
||||
import { XIcon } from "lucide-react";
|
||||
import { getServerSession } from "next-auth";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import Link from "next/link";
|
||||
import { redirect } from "next/navigation";
|
||||
import { DEFAULT_BRAND_COLOR, DEFAULT_LOCALE } from "@formbricks/lib/constants";
|
||||
import { DEFAULT_BRAND_COLOR } from "@formbricks/lib/constants";
|
||||
import { getOrganization } from "@formbricks/lib/organization/service";
|
||||
import { getUserProjects } from "@formbricks/lib/project/service";
|
||||
import { getUserLocale } from "@formbricks/lib/user/service";
|
||||
import { TProjectConfigChannel, TProjectConfigIndustry, TProjectMode } from "@formbricks/types/project";
|
||||
|
||||
interface ProjectSettingsPageProps {
|
||||
@@ -29,7 +28,7 @@ interface ProjectSettingsPageProps {
|
||||
const Page = async (props: ProjectSettingsPageProps) => {
|
||||
const searchParams = await props.searchParams;
|
||||
const params = await props.params;
|
||||
const t = await getTranslations();
|
||||
const t = await getTranslate();
|
||||
const session = await getServerSession(authOptions);
|
||||
|
||||
if (!session || !session.user) {
|
||||
@@ -39,7 +38,6 @@ const Page = async (props: ProjectSettingsPageProps) => {
|
||||
const channel = searchParams.channel || null;
|
||||
const industry = searchParams.industry || null;
|
||||
const mode = searchParams.mode || "surveys";
|
||||
const locale = session?.user.id ? await getUserLocale(session.user.id) : undefined;
|
||||
const projects = await getUserProjects(session.user.id, params.organizationId);
|
||||
|
||||
const organizationTeams = await getTeamsByOrganizationId(params.organizationId);
|
||||
@@ -70,7 +68,6 @@ const Page = async (props: ProjectSettingsPageProps) => {
|
||||
defaultBrandColor={DEFAULT_BRAND_COLOR}
|
||||
organizationTeams={organizationTeams}
|
||||
canDoRoleManagement={canDoRoleManagement}
|
||||
locale={locale ?? DEFAULT_LOCALE}
|
||||
userProjectsCount={projects.length}
|
||||
/>
|
||||
{projects.length >= 1 && (
|
||||
|
||||
@@ -4,8 +4,8 @@ import { ResponseFilterProvider } from "@/app/(app)/environments/[environmentId]
|
||||
import { authOptions } from "@/modules/auth/lib/authOptions";
|
||||
import { DevEnvironmentBanner } from "@/modules/ui/components/dev-environment-banner";
|
||||
import { ToasterClient } from "@/modules/ui/components/toaster-client";
|
||||
import { getTranslate } from "@/tolgee/server";
|
||||
import { getServerSession } from "next-auth";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import { redirect } from "next/navigation";
|
||||
import { hasUserEnvironmentAccess } from "@formbricks/lib/environment/auth";
|
||||
import { getEnvironment } from "@formbricks/lib/environment/service";
|
||||
@@ -18,7 +18,7 @@ const SurveyEditorEnvironmentLayout = async (props) => {
|
||||
|
||||
const { children } = props;
|
||||
|
||||
const t = await getTranslations();
|
||||
const t = await getTranslate();
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session || !session.user) {
|
||||
return redirect(`/auth/login`);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { ModalWithTabs } from "@/modules/ui/components/modal-with-tabs";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { TActionClass } from "@formbricks/types/action-classes";
|
||||
import { TSurvey } from "@formbricks/types/surveys/types";
|
||||
import { CreateNewActionTab } from "./CreateNewActionTab";
|
||||
@@ -28,7 +28,7 @@ export const AddActionModal = ({
|
||||
isReadOnly,
|
||||
environmentId,
|
||||
}: AddActionModalProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const tabs = [
|
||||
{
|
||||
title: t("environments.surveys.edit.select_saved_action"),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { PlusIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { TSurvey } from "@formbricks/types/surveys/types";
|
||||
|
||||
interface AddEndingCardButtonProps {
|
||||
@@ -11,7 +11,7 @@ interface AddEndingCardButtonProps {
|
||||
}
|
||||
|
||||
export const AddEndingCardButton = ({ localSurvey, addEndingCard }: AddEndingCardButtonProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
return (
|
||||
<div
|
||||
className="group inline-flex rounded-lg border border-slate-300 bg-slate-50 hover:cursor-pointer hover:bg-white"
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { createId } from "@paralleldrive/cuid2";
|
||||
import * as Collapsible from "@radix-ui/react-collapsible";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { PlusIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useState } from "react";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
import {
|
||||
@@ -19,14 +19,13 @@ interface AddQuestionButtonProps {
|
||||
addQuestion: (question: any) => void;
|
||||
project: TProject;
|
||||
isCxMode: boolean;
|
||||
locale: string;
|
||||
}
|
||||
|
||||
export const AddQuestionButton = ({ addQuestion, project, isCxMode, locale }: AddQuestionButtonProps) => {
|
||||
const t = useTranslations();
|
||||
export const AddQuestionButton = ({ addQuestion, project, isCxMode }: AddQuestionButtonProps) => {
|
||||
const { t } = useTranslate();
|
||||
const [open, setOpen] = useState(false);
|
||||
const [hoveredQuestionId, setHoveredQuestionId] = useState<string | null>(null);
|
||||
const availableQuestionTypes = isCxMode ? getCXQuestionTypes(locale) : getQuestionTypes(locale);
|
||||
const availableQuestionTypes = isCxMode ? getCXQuestionTypes(t) : getQuestionTypes(t);
|
||||
const [parent] = useAutoAnimate();
|
||||
|
||||
return (
|
||||
@@ -60,7 +59,7 @@ export const AddQuestionButton = ({ addQuestion, project, isCxMode, locale }: Ad
|
||||
onClick={() => {
|
||||
addQuestion({
|
||||
...universalQuestionPresets,
|
||||
...getQuestionDefaults(questionType.id, project, locale),
|
||||
...getQuestionDefaults(questionType.id, project, t),
|
||||
id: createId(),
|
||||
type: questionType.id,
|
||||
});
|
||||
|
||||
@@ -4,8 +4,8 @@ import { QuestionFormInput } from "@/modules/surveys/components/QuestionFormInpu
|
||||
import { Button } from "@/modules/ui/components/button";
|
||||
import { QuestionToggleTable } from "@/modules/ui/components/question-toggle-table";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { PlusIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { type JSX, useEffect } from "react";
|
||||
import { createI18nString, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { TSurvey, TSurveyAddressQuestion } from "@formbricks/types/surveys/types";
|
||||
@@ -34,7 +34,7 @@ export const AddressQuestionForm = ({
|
||||
locale,
|
||||
}: AddressQuestionFormProps): JSX.Element => {
|
||||
const surveyLanguageCodes = extractLanguageCodes(localSurvey.languages ?? []);
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const fields = [
|
||||
{
|
||||
id: "addressLine1",
|
||||
|
||||
@@ -5,8 +5,8 @@ import { FormControl, FormDescription, FormField, FormItem, FormLabel } from "@/
|
||||
import { Slider } from "@/modules/ui/components/slider";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import * as Collapsible from "@radix-ui/react-collapsible";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { CheckIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { UseFormReturn } from "react-hook-form";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
import { TProjectStyling } from "@formbricks/types/project";
|
||||
@@ -34,7 +34,7 @@ export const BackgroundStylingCard = ({
|
||||
isUnsplashConfigured,
|
||||
form,
|
||||
}: BackgroundStylingCardProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const [parent] = useAutoAnimate();
|
||||
|
||||
return (
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Input } from "@/modules/ui/components/input";
|
||||
import { Label } from "@/modules/ui/components/label";
|
||||
import { OptionsSwitch } from "@/modules/ui/components/options-switch";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { type JSX, useState } from "react";
|
||||
import { TSurvey, TSurveyCTAQuestion } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
@@ -34,7 +34,7 @@ export const CTAQuestionForm = ({
|
||||
setSelectedLanguageCode,
|
||||
locale,
|
||||
}: CTAQuestionFormProps): JSX.Element => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const options = [
|
||||
{
|
||||
value: "internal",
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
"use client";
|
||||
|
||||
import { QuestionFormInput } from "@/modules/surveys/components/QuestionFormInput";
|
||||
import { AdvancedOptionToggle } from "@/modules/ui/components/advanced-option-toggle";
|
||||
import { Button } from "@/modules/ui/components/button";
|
||||
import { Input } from "@/modules/ui/components/input";
|
||||
import { Label } from "@/modules/ui/components/label";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { PlusIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { type JSX, useEffect, useState } from "react";
|
||||
import { createI18nString, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { TSurvey, TSurveyCalQuestion } from "@formbricks/types/surveys/types";
|
||||
@@ -34,7 +36,7 @@ export const CalQuestionForm = ({
|
||||
}: CalQuestionFormProps): JSX.Element => {
|
||||
const surveyLanguageCodes = extractLanguageCodes(localSurvey.languages);
|
||||
const [isCalHostEnabled, setIsCalHostEnabled] = useState(!!question.calHost);
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
useEffect(() => {
|
||||
if (!isCalHostEnabled) {
|
||||
updateQuestion(questionIdx, { calHost: undefined });
|
||||
|
||||
@@ -8,8 +8,8 @@ import { Slider } from "@/modules/ui/components/slider";
|
||||
import { Switch } from "@/modules/ui/components/switch";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import * as Collapsible from "@radix-ui/react-collapsible";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { CheckIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import React from "react";
|
||||
import { UseFormReturn } from "react-hook-form";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
@@ -36,7 +36,7 @@ export const CardStylingSettings = ({
|
||||
setOpen,
|
||||
form,
|
||||
}: CardStylingSettingsProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const isAppSurvey = surveyType === "app";
|
||||
const surveyTypeDerived = isAppSurvey ? "App" : "Link";
|
||||
const isLogoVisible = !!project.logo?.url;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import { LogicEditor } from "@/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/LogicEditor";
|
||||
import {
|
||||
getDefaultOperatorForQuestion,
|
||||
@@ -13,6 +15,7 @@ import {
|
||||
import { Label } from "@/modules/ui/components/label";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { createId } from "@paralleldrive/cuid2";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import {
|
||||
ArrowDownIcon,
|
||||
ArrowUpIcon,
|
||||
@@ -22,7 +25,6 @@ import {
|
||||
SplitIcon,
|
||||
TrashIcon,
|
||||
} from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useMemo } from "react";
|
||||
import { duplicateLogicItem } from "@formbricks/lib/surveyLogic/utils";
|
||||
import { replaceHeadlineRecall } from "@formbricks/lib/utils/recall";
|
||||
@@ -41,7 +43,7 @@ export function ConditionalLogic({
|
||||
questionIdx,
|
||||
updateQuestion,
|
||||
}: ConditionalLogicProps) {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const transformedSurvey = useMemo(() => {
|
||||
let modifiedSurvey = replaceHeadlineRecall(localSurvey, "default");
|
||||
modifiedSurvey = replaceEndingCardHeadlineRecall(modifiedSurvey, "default");
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { LocalizedEditor } from "@/modules/ee/multi-language-surveys/components/localized-editor";
|
||||
import { QuestionFormInput } from "@/modules/surveys/components/QuestionFormInput";
|
||||
import { Label } from "@/modules/ui/components/label";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { type JSX, useState } from "react";
|
||||
import { TSurvey, TSurveyConsentQuestion } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
@@ -30,7 +30,7 @@ export const ConsentQuestionForm = ({
|
||||
locale,
|
||||
}: ConsentQuestionFormProps): JSX.Element => {
|
||||
const [firstRender, setFirstRender] = useState(true);
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
return (
|
||||
<form>
|
||||
<QuestionFormInput
|
||||
|
||||
@@ -4,8 +4,8 @@ import { QuestionFormInput } from "@/modules/surveys/components/QuestionFormInpu
|
||||
import { Button } from "@/modules/ui/components/button";
|
||||
import { QuestionToggleTable } from "@/modules/ui/components/question-toggle-table";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { PlusIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { type JSX, useEffect } from "react";
|
||||
import { createI18nString, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { TSurvey, TSurveyContactInfoQuestion } from "@formbricks/types/surveys/types";
|
||||
@@ -33,7 +33,7 @@ export const ContactInfoQuestionForm = ({
|
||||
setSelectedLanguageCode,
|
||||
locale,
|
||||
}: ContactInfoQuestionFormProps): JSX.Element => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const surveyLanguageCodes = extractLanguageCodes(localSurvey.languages ?? []);
|
||||
|
||||
const fields = [
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import { isValidCssSelector } from "@/app/lib/actionClass/actionClass";
|
||||
import { Button } from "@/modules/ui/components/button";
|
||||
import { CodeActionForm } from "@/modules/ui/components/code-action-form";
|
||||
@@ -7,7 +9,7 @@ import { Label } from "@/modules/ui/components/label";
|
||||
import { NoCodeActionForm } from "@/modules/ui/components/no-code-action-form";
|
||||
import { TabToggle } from "@/modules/ui/components/tab-toggle";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { useMemo } from "react";
|
||||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import toast from "react-hot-toast";
|
||||
@@ -38,7 +40,7 @@ export const CreateNewActionTab = ({
|
||||
setLocalSurvey,
|
||||
environmentId,
|
||||
}: CreateNewActionTabProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const actionClassNames = useMemo(
|
||||
() => actionClasses.map((actionClass) => actionClass.name),
|
||||
[actionClasses]
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
"use client";
|
||||
|
||||
import { QuestionFormInput } from "@/modules/surveys/components/QuestionFormInput";
|
||||
import { Button } from "@/modules/ui/components/button";
|
||||
import { Label } from "@/modules/ui/components/label";
|
||||
import { OptionsSwitch } from "@/modules/ui/components/options-switch";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { useTranslate } from "@tolgee/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 { TSurvey, TSurveyDateQuestion } from "@formbricks/types/surveys/types";
|
||||
@@ -48,7 +50,7 @@ export const DateQuestionForm = ({
|
||||
locale,
|
||||
}: IDateQuestionFormProps): JSX.Element => {
|
||||
const surveyLanguageCodes = extractLanguageCodes(localSurvey.languages);
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const [parent] = useAutoAnimate();
|
||||
return (
|
||||
<form>
|
||||
|
||||
@@ -14,8 +14,8 @@ 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 { useTranslate } from "@tolgee/react";
|
||||
import { GripIcon, Handshake, Undo2 } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
@@ -59,7 +59,7 @@ export const EditEndingCard = ({
|
||||
locale,
|
||||
}: EditEndingCardProps) => {
|
||||
const endingCard = localSurvey.endings[endingCardIndex];
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const isRedirectToUrlDisabled = isFormbricksCloud
|
||||
? plan === "free" && endingCard.type !== "redirectToUrl"
|
||||
: false;
|
||||
@@ -231,7 +231,6 @@ export const EditEndingCard = ({
|
||||
updateCard={() => {}}
|
||||
addCard={addEndingCard}
|
||||
cardType="ending"
|
||||
locale={locale}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,8 +6,8 @@ import { FileInput } from "@/modules/ui/components/file-input";
|
||||
import { Label } from "@/modules/ui/components/label";
|
||||
import { Switch } from "@/modules/ui/components/switch";
|
||||
import * as Collapsible from "@radix-ui/react-collapsible";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { Hand } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
@@ -35,7 +35,7 @@ export const EditWelcomeCard = ({
|
||||
setSelectedLanguageCode,
|
||||
locale,
|
||||
}: EditWelcomeCardProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const [firstRender, setFirstRender] = useState(true);
|
||||
const path = usePathname();
|
||||
const environmentId = path?.split("/environments/")[1]?.split("/")[0];
|
||||
|
||||
@@ -13,13 +13,13 @@ import {
|
||||
} from "@/modules/ui/components/dropdown-menu";
|
||||
import { TooltipRenderer } from "@/modules/ui/components/tooltip";
|
||||
import { createId } from "@paralleldrive/cuid2";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { ArrowDownIcon, ArrowUpIcon, CopyIcon, EllipsisIcon, TrashIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useState } from "react";
|
||||
import {
|
||||
QUESTIONS_ICON_MAP,
|
||||
getCXQuestionNameMap,
|
||||
getQuestionDefaults,
|
||||
getQuestionIconMap,
|
||||
getQuestionNameMap,
|
||||
} from "@formbricks/lib/utils/questions";
|
||||
import { TProject } from "@formbricks/types/project";
|
||||
@@ -44,7 +44,6 @@ interface EditorCardMenuProps {
|
||||
cardType: "question" | "ending";
|
||||
project?: TProject;
|
||||
isCxMode?: boolean;
|
||||
locale: string;
|
||||
}
|
||||
|
||||
export const EditorCardMenu = ({
|
||||
@@ -60,9 +59,9 @@ export const EditorCardMenu = ({
|
||||
addCard,
|
||||
cardType,
|
||||
isCxMode = false,
|
||||
locale,
|
||||
}: EditorCardMenuProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const QUESTIONS_ICON_MAP = getQuestionIconMap(t);
|
||||
const [logicWarningModal, setLogicWarningModal] = useState(false);
|
||||
const [changeToType, setChangeToType] = useState(() => {
|
||||
if (card.type !== "endScreen" && card.type !== "redirectToUrl") {
|
||||
@@ -76,7 +75,7 @@ export const EditorCardMenu = ({
|
||||
? survey.questions.length === 1
|
||||
: survey.type === "link" && survey.endings.length === 1;
|
||||
|
||||
const availableQuestionTypes = isCxMode ? getCXQuestionNameMap(locale) : getQuestionNameMap(locale);
|
||||
const availableQuestionTypes = isCxMode ? getCXQuestionNameMap(t) : getQuestionNameMap(t);
|
||||
|
||||
const changeQuestionType = (type?: TSurveyQuestionTypeEnum) => {
|
||||
if (!type) return;
|
||||
@@ -84,7 +83,7 @@ export const EditorCardMenu = ({
|
||||
const { headline, required, subheader, imageUrl, videoUrl, buttonLabel, backButtonLabel } =
|
||||
card as TSurveyQuestion;
|
||||
|
||||
const questionDefaults = getQuestionDefaults(type, project, locale);
|
||||
const questionDefaults = getQuestionDefaults(type, project, t);
|
||||
|
||||
if (
|
||||
(type === TSurveyQuestionTypeEnum.MultipleChoiceSingle &&
|
||||
@@ -123,7 +122,7 @@ export const EditorCardMenu = ({
|
||||
};
|
||||
|
||||
const addQuestionCardBelow = (type: TSurveyQuestionTypeEnum) => {
|
||||
const questionDefaults = getQuestionDefaults(type, project, locale);
|
||||
const questionDefaults = getQuestionDefaults(type, project, t);
|
||||
|
||||
addCard(
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@ import { RecallWrapper } from "@/modules/surveys/components/QuestionFormInput/co
|
||||
import { Input } from "@/modules/ui/components/input";
|
||||
import { Label } from "@/modules/ui/components/label";
|
||||
import { Switch } from "@/modules/ui/components/switch";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { useState } from "react";
|
||||
import { useRef } from "react";
|
||||
import { getLocalizedValue } from "@formbricks/lib/i18n/utils";
|
||||
@@ -34,7 +34,7 @@ export const EndScreenForm = ({
|
||||
endingCard,
|
||||
locale,
|
||||
}: EndScreenFormProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
const [showEndingCardCTA, setshowEndingCardCTA] = useState<boolean>(
|
||||
endingCard.type === "endScreen" &&
|
||||
|
||||
@@ -6,8 +6,8 @@ import { Button } from "@/modules/ui/components/button";
|
||||
import { Input } from "@/modules/ui/components/input";
|
||||
import { useGetBillingInfo } from "@/modules/utils/hooks/useGetBillingInfo";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { useTranslate } from "@tolgee/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 { toast } from "react-hot-toast";
|
||||
@@ -45,7 +45,7 @@ export const FileUploadQuestionForm = ({
|
||||
locale,
|
||||
}: FileUploadFormProps): JSX.Element => {
|
||||
const [extension, setExtension] = useState("");
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const [isMaxSizeError, setMaxSizeError] = useState(false);
|
||||
const {
|
||||
billingInfo,
|
||||
@@ -227,7 +227,7 @@ export const FileUploadQuestionForm = ({
|
||||
className="underline"
|
||||
target="_blank"
|
||||
href={`/environments/${localSurvey.environmentId}/settings/billing`}>
|
||||
{t("environments.surveys.edit.upgrade_your_plan")}
|
||||
{t("common.please_upgrade_your_plan")}
|
||||
</Link>
|
||||
</p>
|
||||
)}
|
||||
|
||||
@@ -5,8 +5,8 @@ import { ColorPicker } from "@/modules/ui/components/color-picker";
|
||||
import { FormControl, FormDescription, FormField, FormItem, FormLabel } from "@/modules/ui/components/form";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import * as Collapsible from "@radix-ui/react-collapsible";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { CheckIcon, SparklesIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import React from "react";
|
||||
import { UseFormReturn } from "react-hook-form";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
@@ -30,7 +30,7 @@ export const FormStylingSettings = ({
|
||||
setOpen,
|
||||
form,
|
||||
}: FormStylingSettingsProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const brandColor = form.watch("brandColor.light") || COLOR_DEFAULTS.brandColor;
|
||||
const background = form.watch("background");
|
||||
const highlightBorderColor = form.watch("highlightBorderColor");
|
||||
|
||||
@@ -8,8 +8,8 @@ import { Switch } from "@/modules/ui/components/switch";
|
||||
import { Tag } from "@/modules/ui/components/tag";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import * as Collapsible from "@radix-ui/react-collapsible";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { EyeOff } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
@@ -32,7 +32,7 @@ export const HiddenFieldsCard = ({
|
||||
}: HiddenFieldsCardProps) => {
|
||||
const open = activeQuestionId == "hidden";
|
||||
const [hiddenField, setHiddenField] = useState<string>("");
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const setOpen = (open: boolean) => {
|
||||
if (open) {
|
||||
setActiveQuestionId("hidden");
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
"use client";
|
||||
|
||||
import { getDefaultEndingCard } from "@/app/lib/templates";
|
||||
import { Badge } from "@/modules/ui/components/badge";
|
||||
import { Label } from "@/modules/ui/components/label";
|
||||
import { RadioGroup, RadioGroupItem } from "@/modules/ui/components/radio-group";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import * as Collapsible from "@radix-ui/react-collapsible";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { AlertCircleIcon, CheckIcon, LinkIcon, MonitorIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import Link from "next/link";
|
||||
import { useEffect, useState } from "react";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
import { getDefaultEndingCard } from "@formbricks/lib/templates";
|
||||
import { TEnvironment } from "@formbricks/types/environment";
|
||||
import { TSegment } from "@formbricks/types/segment";
|
||||
import { TSurvey, TSurveyType } from "@formbricks/types/surveys/types";
|
||||
@@ -19,13 +19,12 @@ interface HowToSendCardProps {
|
||||
localSurvey: TSurvey;
|
||||
setLocalSurvey: (survey: TSurvey | ((TSurvey: TSurvey) => TSurvey)) => void;
|
||||
environment: TEnvironment;
|
||||
locale: string;
|
||||
}
|
||||
|
||||
export const HowToSendCard = ({ localSurvey, setLocalSurvey, environment, locale }: HowToSendCardProps) => {
|
||||
export const HowToSendCard = ({ localSurvey, setLocalSurvey, environment }: HowToSendCardProps) => {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [appSetupCompleted, setAppSetupCompleted] = useState(false);
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
useEffect(() => {
|
||||
if (environment) {
|
||||
setAppSetupCompleted(environment.appSetupCompleted);
|
||||
@@ -35,7 +34,7 @@ export const HowToSendCard = ({ localSurvey, setLocalSurvey, environment, locale
|
||||
const setSurveyType = (type: TSurveyType) => {
|
||||
const endingsTemp = localSurvey.endings;
|
||||
if (type === "link" && localSurvey.endings.length === 0) {
|
||||
endingsTemp.push(getDefaultEndingCard(localSurvey.languages, locale));
|
||||
endingsTemp.push(getDefaultEndingCard(localSurvey.languages, t));
|
||||
}
|
||||
setLocalSurvey((prevSurvey) => ({
|
||||
...prevSurvey,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import { LogicEditorActions } from "@/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/LogicEditorActions";
|
||||
import { LogicEditorConditions } from "@/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/LogicEditorConditions";
|
||||
import {
|
||||
@@ -7,11 +9,11 @@ import {
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/modules/ui/components/select";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
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 { getQuestionIconMap } from "@formbricks/lib/utils/questions";
|
||||
import { TSurvey, TSurveyLogic, TSurveyQuestion } from "@formbricks/types/surveys/types";
|
||||
|
||||
interface LogicEditorProps {
|
||||
@@ -33,8 +35,8 @@ export function LogicEditor({
|
||||
logicIdx,
|
||||
isLast,
|
||||
}: LogicEditorProps) {
|
||||
const t = useTranslations();
|
||||
|
||||
const { t } = useTranslate();
|
||||
const QUESTIONS_ICON_MAP = getQuestionIconMap(t);
|
||||
const fallbackOptions = useMemo(() => {
|
||||
let options: {
|
||||
icon?: ReactElement;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
getActionObjectiveOptions,
|
||||
getActionOperatorOptions,
|
||||
@@ -14,8 +16,8 @@ import {
|
||||
} from "@/modules/ui/components/dropdown-menu";
|
||||
import { InputCombobox } from "@/modules/ui/components/input-combo-box";
|
||||
import { createId } from "@paralleldrive/cuid2";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { CopyIcon, CornerDownRightIcon, EllipsisVerticalIcon, PlusIcon, TrashIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { getUpdatedActionBody } from "@formbricks/lib/surveyLogic/utils";
|
||||
import {
|
||||
TActionNumberVariableCalculateOperator,
|
||||
@@ -46,7 +48,7 @@ export function LogicEditorActions({
|
||||
questionIdx,
|
||||
}: LogicEditorActions) {
|
||||
const actions = logicItem.actions;
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const handleActionsChange = (
|
||||
operation: "remove" | "addBelow" | "duplicate" | "update",
|
||||
actionIdx: number,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
getConditionOperatorOptions,
|
||||
getConditionValueOptions,
|
||||
@@ -13,8 +15,8 @@ import {
|
||||
import { InputCombobox, TComboboxOption } from "@/modules/ui/components/input-combo-box";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { createId } from "@paralleldrive/cuid2";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { CopyIcon, EllipsisVerticalIcon, PlusIcon, TrashIcon, WorkflowIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
import {
|
||||
addConditionBelow,
|
||||
@@ -54,7 +56,7 @@ export function LogicEditorConditions({
|
||||
updateQuestion,
|
||||
depth = 0,
|
||||
}: LogicEditorConditionsProps) {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const [parent] = useAutoAnimate();
|
||||
|
||||
const handleAddConditionBelow = (resourceId: string) => {
|
||||
|
||||
@@ -6,8 +6,8 @@ import { Label } from "@/modules/ui/components/label";
|
||||
import { ShuffleOptionSelect } from "@/modules/ui/components/shuffle-option-select";
|
||||
import { TooltipRenderer } from "@/modules/ui/components/tooltip";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { useTranslate } from "@tolgee/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 { TI18nString, TSurvey, TSurveyMatrixQuestion } from "@formbricks/types/surveys/types";
|
||||
@@ -37,7 +37,7 @@ export const MatrixQuestionForm = ({
|
||||
locale,
|
||||
}: MatrixQuestionFormProps): JSX.Element => {
|
||||
const languageCodes = extractLanguageCodes(localSurvey.languages);
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
// Function to add a new Label input field
|
||||
const handleAddLabel = (type: "row" | "column") => {
|
||||
if (type === "row") {
|
||||
|
||||
@@ -9,8 +9,8 @@ import { DndContext } from "@dnd-kit/core";
|
||||
import { SortableContext, verticalListSortingStrategy } from "@dnd-kit/sortable";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { createId } from "@paralleldrive/cuid2";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { PlusIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { type JSX, useEffect, useRef, useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import { createI18nString, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
@@ -46,7 +46,7 @@ export const MultipleChoiceQuestionForm = ({
|
||||
setSelectedLanguageCode,
|
||||
locale,
|
||||
}: MultipleChoiceQuestionFormProps): JSX.Element => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const lastChoiceRef = useRef<HTMLInputElement>(null);
|
||||
const [isNew, setIsNew] = useState(true);
|
||||
const [isInvalidValue, setisInvalidValue] = useState<string | null>(null);
|
||||
|
||||
@@ -4,8 +4,8 @@ import { QuestionFormInput } from "@/modules/surveys/components/QuestionFormInpu
|
||||
import { AdvancedOptionToggle } from "@/modules/ui/components/advanced-option-toggle";
|
||||
import { Button } from "@/modules/ui/components/button";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { useTranslate } from "@tolgee/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 { TSurvey, TSurveyNPSQuestion } from "@formbricks/types/surveys/types";
|
||||
@@ -34,7 +34,7 @@ export const NPSQuestionForm = ({
|
||||
setSelectedLanguageCode,
|
||||
locale,
|
||||
}: NPSQuestionFormProps): JSX.Element => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const surveyLanguageCodes = extractLanguageCodes(localSurvey.languages);
|
||||
// Auto animate
|
||||
const [parent] = useAutoAnimate();
|
||||
|
||||
@@ -7,8 +7,8 @@ import { Input } from "@/modules/ui/components/input";
|
||||
import { Label } from "@/modules/ui/components/label";
|
||||
import { OptionsSwitch } from "@/modules/ui/components/options-switch";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { HashIcon, LinkIcon, MailIcon, MessageSquareTextIcon, PhoneIcon, PlusIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { JSX, useEffect, useState } from "react";
|
||||
import { createI18nString, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import {
|
||||
@@ -40,7 +40,7 @@ export const OpenQuestionForm = ({
|
||||
setSelectedLanguageCode,
|
||||
locale,
|
||||
}: OpenQuestionFormProps): JSX.Element => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const questionTypes = [
|
||||
{ value: "text", label: t("common.text"), icon: <MessageSquareTextIcon className="h-4 w-4" /> },
|
||||
{ value: "email", label: t("common.email"), icon: <MailIcon className="h-4 w-4" /> },
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import { QuestionFormInput } from "@/modules/surveys/components/QuestionFormInput";
|
||||
import { Button } from "@/modules/ui/components/button";
|
||||
import { FileInput } from "@/modules/ui/components/file-input";
|
||||
@@ -5,8 +7,8 @@ import { Label } from "@/modules/ui/components/label";
|
||||
import { Switch } from "@/modules/ui/components/switch";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { createId } from "@paralleldrive/cuid2";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
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";
|
||||
@@ -37,7 +39,7 @@ export const PictureSelectionForm = ({
|
||||
}: PictureSelectionFormProps): JSX.Element => {
|
||||
const environmentId = localSurvey.environmentId;
|
||||
const surveyLanguageCodes = extractLanguageCodes(localSurvey.languages);
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const handleChoiceDeletion = (choiceValue: string) => {
|
||||
// Filter out the deleted choice from the choices array
|
||||
const newChoices = question.choices?.filter((choice) => choice.id !== choiceValue) || [];
|
||||
|
||||
@@ -3,18 +3,10 @@
|
||||
import { Label } from "@/modules/ui/components/label";
|
||||
import { getPlacementStyle } from "@/modules/ui/components/preview-survey/lib/utils";
|
||||
import { RadioGroup, RadioGroupItem } from "@/modules/ui/components/radio-group";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
import { TPlacement } from "@formbricks/types/common";
|
||||
|
||||
const placements = [
|
||||
{ name: "common.bottom_right", value: "bottomRight", disabled: false },
|
||||
{ name: "common.top_right", value: "topRight", disabled: false },
|
||||
{ name: "common.top_left", value: "topLeft", disabled: false },
|
||||
{ name: "common.bottom_left", value: "bottomLeft", disabled: false },
|
||||
{ name: "common.centered_modal", value: "center", disabled: false },
|
||||
];
|
||||
|
||||
interface TPlacementProps {
|
||||
currentPlacement: TPlacement;
|
||||
setCurrentPlacement: (placement: TPlacement) => void;
|
||||
@@ -32,7 +24,14 @@ export const Placement = ({
|
||||
setClickOutsideClose,
|
||||
clickOutsideClose,
|
||||
}: TPlacementProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const placements = [
|
||||
{ name: t("common.bottom_right"), value: "bottomRight", disabled: false },
|
||||
{ name: t("common.top_right"), value: "topRight", disabled: false },
|
||||
{ name: t("common.top_left"), value: "topLeft", disabled: false },
|
||||
{ name: t("common.bottom_left"), value: "bottomLeft", disabled: false },
|
||||
{ name: t("common.centered_modal"), value: "center", disabled: false },
|
||||
];
|
||||
const overlayStyle =
|
||||
currentPlacement === "center" && overlay === "dark" ? "bg-slate-700/80" : "bg-slate-200";
|
||||
return (
|
||||
|
||||
@@ -10,11 +10,11 @@ import { useSortable } from "@dnd-kit/sortable";
|
||||
import { CSS } from "@dnd-kit/utilities";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import * as Collapsible from "@radix-ui/react-collapsible";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { ChevronDownIcon, ChevronRightIcon, GripIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useState } from "react";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
import { QUESTIONS_ICON_MAP, getTSurveyQuestionTypeEnumName } from "@formbricks/lib/utils/questions";
|
||||
import { getQuestionIconMap, getTSurveyQuestionTypeEnumName } from "@formbricks/lib/utils/questions";
|
||||
import { recallToHeadline } from "@formbricks/lib/utils/recall";
|
||||
import { TProject } from "@formbricks/types/project";
|
||||
import {
|
||||
@@ -84,7 +84,8 @@ export const QuestionCard = ({
|
||||
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
|
||||
id: question.id,
|
||||
});
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const QUESTIONS_ICON_MAP = getQuestionIconMap(t);
|
||||
const open = activeQuestionId === question.id;
|
||||
const [openAdvanced, setOpenAdvanced] = useState(question.logic && question.logic.length > 0);
|
||||
const [parent] = useAutoAnimate();
|
||||
@@ -225,7 +226,7 @@ export const QuestionCard = ({
|
||||
selectedLanguageCode
|
||||
] ?? ""
|
||||
)
|
||||
: getTSurveyQuestionTypeEnumName(question.type, locale)}
|
||||
: getTSurveyQuestionTypeEnumName(question.type, t)}
|
||||
</p>
|
||||
{!open && (
|
||||
<p className="mt-1 truncate text-xs text-slate-500">
|
||||
@@ -251,7 +252,6 @@ export const QuestionCard = ({
|
||||
addCard={addQuestion}
|
||||
cardType="question"
|
||||
isCxMode={isCxMode}
|
||||
locale={locale}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
"use client";
|
||||
|
||||
import { QuestionFormInput } from "@/modules/surveys/components/QuestionFormInput";
|
||||
import { Button } from "@/modules/ui/components/button";
|
||||
import { TooltipRenderer } from "@/modules/ui/components/tooltip";
|
||||
import { useSortable } from "@dnd-kit/sortable";
|
||||
import { CSS } from "@dnd-kit/utilities";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { GripVerticalIcon, PlusIcon, TrashIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
import { createI18nString } from "@formbricks/lib/i18n/utils";
|
||||
import {
|
||||
@@ -56,7 +58,7 @@ export const QuestionOptionChoice = ({
|
||||
updateQuestion,
|
||||
locale,
|
||||
}: ChoiceProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const isDragDisabled = choice.id === "other";
|
||||
const { attributes, listeners, setNodeRef, transform, transition } = useSortable({
|
||||
id: choice.id,
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import { AddEndingCardButton } from "@/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/AddEndingCardButton";
|
||||
import { SurveyVariablesCard } from "@/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/SurveyVariablesCard";
|
||||
import { findQuestionUsedInLogic } from "@/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/lib/utils";
|
||||
import { getDefaultEndingCard } from "@/app/lib/templates";
|
||||
import { MultiLanguageCard } from "@/modules/ee/multi-language-surveys/components/multi-language-card";
|
||||
import {
|
||||
DndContext,
|
||||
@@ -15,13 +16,12 @@ import {
|
||||
import { SortableContext, verticalListSortingStrategy } from "@dnd-kit/sortable";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { createId } from "@paralleldrive/cuid2";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import React, { SetStateAction, useEffect, useMemo } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import { addMultiLanguageLabels, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { structuredClone } from "@formbricks/lib/pollyfills/structuredClone";
|
||||
import { isConditionGroup } from "@formbricks/lib/surveyLogic/utils";
|
||||
import { getDefaultEndingCard } from "@formbricks/lib/templates";
|
||||
import { checkForEmptyFallBackValue, extractRecallInfo } from "@formbricks/lib/utils/recall";
|
||||
import { TOrganizationBillingPlan } from "@formbricks/types/organizations";
|
||||
import { TProject } from "@formbricks/types/project";
|
||||
@@ -80,7 +80,7 @@ export const QuestionsView = ({
|
||||
isCxMode,
|
||||
locale,
|
||||
}: QuestionsViewProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const internalQuestionIdMap = useMemo(() => {
|
||||
return localSurvey.questions.reduce((acc, question) => {
|
||||
acc[question.id] = createId();
|
||||
@@ -338,7 +338,7 @@ export const QuestionsView = ({
|
||||
|
||||
const addEndingCard = (index: number) => {
|
||||
const updatedSurvey = structuredClone(localSurvey);
|
||||
const newEndingCard = getDefaultEndingCard(localSurvey.languages, locale);
|
||||
const newEndingCard = getDefaultEndingCard(localSurvey.languages, t);
|
||||
|
||||
updatedSurvey.endings.splice(index, 0, newEndingCard);
|
||||
setActiveQuestionId(newEndingCard.id);
|
||||
@@ -461,7 +461,7 @@ export const QuestionsView = ({
|
||||
/>
|
||||
</DndContext>
|
||||
|
||||
<AddQuestionButton addQuestion={addQuestion} project={project} isCxMode={isCxMode} locale={locale} />
|
||||
<AddQuestionButton addQuestion={addQuestion} project={project} isCxMode={isCxMode} />
|
||||
<div className="mt-5 flex flex-col gap-5" ref={parent}>
|
||||
<hr className="border-t border-dashed" />
|
||||
<DndContext
|
||||
|
||||
@@ -8,8 +8,8 @@ import { DndContext } from "@dnd-kit/core";
|
||||
import { SortableContext, verticalListSortingStrategy } from "@dnd-kit/sortable";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { createId } from "@paralleldrive/cuid2";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { PlusIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { type JSX, useEffect, useRef, useState } from "react";
|
||||
import { createI18nString, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { TI18nString, TSurvey, TSurveyRankingQuestion } from "@formbricks/types/surveys/types";
|
||||
@@ -38,7 +38,7 @@ export const RankingQuestionForm = ({
|
||||
setSelectedLanguageCode,
|
||||
locale,
|
||||
}: RankingQuestionFormProps): JSX.Element => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const lastChoiceRef = useRef<HTMLInputElement>(null);
|
||||
const [isInvalidValue, setIsInvalidValue] = useState<string | null>(null);
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
"use client";
|
||||
|
||||
import { QuestionFormInput } from "@/modules/surveys/components/QuestionFormInput";
|
||||
import { AdvancedOptionToggle } from "@/modules/ui/components/advanced-option-toggle";
|
||||
import { Button } from "@/modules/ui/components/button";
|
||||
import { Label } from "@/modules/ui/components/label";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { HashIcon, PlusIcon, SmileIcon, StarIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { createI18nString, extractLanguageCodes } from "@formbricks/lib/i18n/utils";
|
||||
import { TSurvey, TSurveyRatingQuestion } from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
@@ -32,7 +34,7 @@ export const RatingQuestionForm = ({
|
||||
setSelectedLanguageCode,
|
||||
locale,
|
||||
}: RatingQuestionFormProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const surveyLanguageCodes = extractLanguageCodes(localSurvey.languages);
|
||||
const [parent] = useAutoAnimate();
|
||||
return (
|
||||
|
||||
@@ -6,10 +6,10 @@ import { Label } from "@/modules/ui/components/label";
|
||||
import { RadioGroup, RadioGroupItem } from "@/modules/ui/components/radio-group";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import * as Collapsible from "@radix-ui/react-collapsible";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { CheckIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import Link from "next/link";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { TSurvey } from "@formbricks/types/surveys/types";
|
||||
|
||||
interface DisplayOption {
|
||||
@@ -18,29 +18,6 @@ interface DisplayOption {
|
||||
description: string;
|
||||
}
|
||||
|
||||
const displayOptions: DisplayOption[] = [
|
||||
{
|
||||
id: "displayOnce",
|
||||
name: "environments.surveys.edit.show_only_once",
|
||||
description: "environments.surveys.edit.the_survey_will_be_shown_once_even_if_person_doesnt_respond",
|
||||
},
|
||||
{
|
||||
id: "displaySome",
|
||||
name: "environments.surveys.edit.show_multiple_times",
|
||||
description: "environments.surveys.edit.the_survey_will_be_shown_multiple_times_until_they_respond",
|
||||
},
|
||||
{
|
||||
id: "displayMultiple",
|
||||
name: "environments.surveys.edit.until_they_submit_a_response",
|
||||
description: "environments.surveys.edit.if_you_really_want_that_answer_ask_until_you_get_it",
|
||||
},
|
||||
{
|
||||
id: "respondMultiple",
|
||||
name: "environments.surveys.edit.keep_showing_while_conditions_match",
|
||||
description: "environments.surveys.edit.even_after_they_submitted_a_response_e_g_feedback_box",
|
||||
},
|
||||
];
|
||||
|
||||
interface RecontactOptionsCardProps {
|
||||
localSurvey: TSurvey;
|
||||
setLocalSurvey: (survey: TSurvey) => void;
|
||||
@@ -52,7 +29,38 @@ export const RecontactOptionsCard = ({
|
||||
setLocalSurvey,
|
||||
environmentId,
|
||||
}: RecontactOptionsCardProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
|
||||
const displayOptions: DisplayOption[] = useMemo(
|
||||
() => [
|
||||
{
|
||||
id: "displayOnce",
|
||||
name: t("environments.surveys.edit.show_only_once"),
|
||||
description: t(
|
||||
"environments.surveys.edit.the_survey_will_be_shown_once_even_if_person_doesnt_respond"
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "displaySome",
|
||||
name: t("environments.surveys.edit.show_multiple_times"),
|
||||
description: t(
|
||||
"environments.surveys.edit.the_survey_will_be_shown_multiple_times_until_they_respond"
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "displayMultiple",
|
||||
name: t("environments.surveys.edit.until_they_submit_a_response"),
|
||||
description: t("environments.surveys.edit.if_you_really_want_that_answer_ask_until_you_get_it"),
|
||||
},
|
||||
{
|
||||
id: "respondMultiple",
|
||||
name: t("environments.surveys.edit.keep_showing_while_conditions_match"),
|
||||
description: t("environments.surveys.edit.even_after_they_submitted_a_response_e_g_feedback_box"),
|
||||
},
|
||||
],
|
||||
[t]
|
||||
);
|
||||
|
||||
const [open, setOpen] = useState(false);
|
||||
const ignoreWaiting = localSurvey.recontactDays !== null;
|
||||
const [inputDays, setInputDays] = useState(
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import { RecallWrapper } from "@/modules/surveys/components/QuestionFormInput/components/RecallWrapper";
|
||||
import { Input } from "@/modules/ui/components/input";
|
||||
import { Label } from "@/modules/ui/components/label";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { useRef } from "react";
|
||||
import { headlineToRecall, recallToHeadline } from "@formbricks/lib/utils/recall";
|
||||
import { TSurvey, TSurveyRedirectUrlCard } from "@formbricks/types/surveys/types";
|
||||
@@ -14,7 +16,7 @@ interface RedirectUrlFormProps {
|
||||
|
||||
export const RedirectUrlForm = ({ localSurvey, endingCard, updateSurvey }: RedirectUrlFormProps) => {
|
||||
const selectedLanguageCode = "default";
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
return (
|
||||
|
||||
@@ -7,8 +7,8 @@ import { Label } from "@/modules/ui/components/label";
|
||||
import { Switch } from "@/modules/ui/components/switch";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import * as Collapsible from "@radix-ui/react-collapsible";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { ArrowUpRight, CheckIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import Link from "next/link";
|
||||
import { KeyboardEventHandler, useEffect, useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
@@ -26,7 +26,7 @@ export const ResponseOptionsCard = ({
|
||||
setLocalSurvey,
|
||||
responseCount,
|
||||
}: ResponseOptionsCardProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const [open, setOpen] = useState(localSurvey.type === "link" ? true : false);
|
||||
const autoComplete = localSurvey.autoComplete !== null;
|
||||
const [runOnDateToggle, setRunOnDateToggle] = useState(false);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import { Input } from "@/modules/ui/components/input";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { Code2Icon, MousePointerClickIcon, SparklesIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useState } from "react";
|
||||
import { TActionClass } from "@formbricks/types/action-classes";
|
||||
import { TSurvey } from "@formbricks/types/surveys/types";
|
||||
@@ -18,7 +20,7 @@ export const SavedActionsTab = ({
|
||||
setLocalSurvey,
|
||||
setOpen,
|
||||
}: SavedActionsTabProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const availableActions = actionClasses.filter(
|
||||
(actionClass) => !localSurvey.triggers.some((trigger) => trigger.actionClass.id === actionClass.id)
|
||||
);
|
||||
|
||||
@@ -23,7 +23,6 @@ interface SettingsViewProps {
|
||||
responseCount: number;
|
||||
membershipRole?: TOrganizationRole;
|
||||
isUserTargetingAllowed?: boolean;
|
||||
locale: string;
|
||||
projectPermission: TTeamPermission | null;
|
||||
isFormbricksCloud: boolean;
|
||||
}
|
||||
@@ -38,7 +37,6 @@ export const SettingsView = ({
|
||||
responseCount,
|
||||
membershipRole,
|
||||
isUserTargetingAllowed = false,
|
||||
locale,
|
||||
projectPermission,
|
||||
isFormbricksCloud,
|
||||
}: SettingsViewProps) => {
|
||||
@@ -46,12 +44,7 @@ export const SettingsView = ({
|
||||
|
||||
return (
|
||||
<div className="mt-12 space-y-3 p-5">
|
||||
<HowToSendCard
|
||||
localSurvey={localSurvey}
|
||||
setLocalSurvey={setLocalSurvey}
|
||||
environment={environment}
|
||||
locale={locale}
|
||||
/>
|
||||
<HowToSendCard localSurvey={localSurvey} setLocalSurvey={setLocalSurvey} environment={environment} />
|
||||
|
||||
{localSurvey.type === "app" ? (
|
||||
<div>
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import { AlertDialog } from "@/modules/ui/components/alert-dialog";
|
||||
import { Button } from "@/modules/ui/components/button";
|
||||
import {
|
||||
@@ -9,8 +11,8 @@ import {
|
||||
FormProvider,
|
||||
} from "@/modules/ui/components/form";
|
||||
import { Switch } from "@/modules/ui/components/switch";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
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";
|
||||
@@ -50,7 +52,7 @@ export const StylingView = ({
|
||||
isUnsplashConfigured,
|
||||
isCxMode,
|
||||
}: StylingViewProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
|
||||
const form = useForm<TSurveyStyling>({
|
||||
defaultValues: { ...defaultStyling, ...project.styling, ...localSurvey.styling },
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import { TabBar } from "@/modules/ui/components/tab-bar";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { AnimatedSurveyBg } from "./AnimatedSurveyBg";
|
||||
import { ColorSurveyBg } from "./ColorSurveyBg";
|
||||
@@ -25,7 +27,7 @@ export const SurveyBgSelectorTab = ({
|
||||
isUnsplashConfigured,
|
||||
}: SurveyBgSelectorTabProps) => {
|
||||
const [activeTab, setActiveTab] = useState(bgType || "color");
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const [parent] = useAutoAnimate();
|
||||
const [colorBackground, setColorBackground] = useState(bg);
|
||||
const [animationBackground, setAnimationBackground] = useState(bg);
|
||||
|
||||
@@ -217,7 +217,6 @@ export const SurveyEditor = ({
|
||||
responseCount={responseCount}
|
||||
membershipRole={membershipRole}
|
||||
isUserTargetingAllowed={isUserTargetingAllowed}
|
||||
locale={locale}
|
||||
projectPermission={projectPermission}
|
||||
isFormbricksCloud={isFormbricksCloud}
|
||||
/>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import { ProBadge } from "@/modules/ui/components/pro-badge";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { MailIcon, PaintbrushIcon, Rows3Icon, SettingsIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { type JSX, useMemo } from "react";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
import { TSurveyEditorTabs } from "@formbricks/types/surveys/types";
|
||||
@@ -27,27 +29,27 @@ export const SurveyEditorTabs = ({
|
||||
isCxMode,
|
||||
isSurveyFollowUpsAllowed = false,
|
||||
}: SurveyEditorTabsProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const tabsComputed = useMemo(() => {
|
||||
const tabs: Tab[] = [
|
||||
{
|
||||
id: "questions",
|
||||
label: "common.questions",
|
||||
label: t("common.questions"),
|
||||
icon: <Rows3Icon className="h-5 w-5" />,
|
||||
},
|
||||
{
|
||||
id: "styling",
|
||||
label: "common.styling",
|
||||
label: t("common.styling"),
|
||||
icon: <PaintbrushIcon className="h-5 w-5" />,
|
||||
},
|
||||
{
|
||||
id: "settings",
|
||||
label: "common.settings",
|
||||
label: t("common.settings"),
|
||||
icon: <SettingsIcon className="h-5 w-5" />,
|
||||
},
|
||||
{
|
||||
id: "followUps",
|
||||
label: "environments.surveys.edit.follow_ups",
|
||||
label: t("environments.surveys.edit.follow_ups"),
|
||||
icon: <MailIcon className="h-5 w-5" />,
|
||||
isPro: !isSurveyFollowUpsAllowed,
|
||||
},
|
||||
@@ -78,7 +80,7 @@ export const SurveyEditorTabs = ({
|
||||
)}
|
||||
aria-current={tab.id === activeId ? "page" : undefined}>
|
||||
{tab.icon && <div className="mr-2 h-5 w-5">{tab.icon}</div>}
|
||||
{t(tab.label)}
|
||||
{tab.label}
|
||||
{tab.isPro && <ProBadge />}
|
||||
</button>
|
||||
))}
|
||||
|
||||
@@ -6,9 +6,9 @@ import { AlertDialog } from "@/modules/ui/components/alert-dialog";
|
||||
import { Button } from "@/modules/ui/components/button";
|
||||
import { Input } from "@/modules/ui/components/input";
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/modules/ui/components/tooltip";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { isEqual } from "lodash";
|
||||
import { AlertTriangleIcon, ArrowLeftIcon, SettingsIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
@@ -57,7 +57,7 @@ export const SurveyMenuBar = ({
|
||||
isCxMode,
|
||||
locale,
|
||||
}: SurveyMenuBarProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const router = useRouter();
|
||||
const [audiencePrompt, setAudiencePrompt] = useState(true);
|
||||
const [isLinkSurvey, setIsLinkSurvey] = useState(true);
|
||||
|
||||
@@ -4,8 +4,8 @@ import { Label } from "@/modules/ui/components/label";
|
||||
import { Switch } from "@/modules/ui/components/switch";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import * as Collapsible from "@radix-ui/react-collapsible";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { CheckIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import Link from "next/link";
|
||||
import { useState } from "react";
|
||||
import { TPlacement } from "@formbricks/types/common";
|
||||
@@ -23,7 +23,7 @@ export const SurveyPlacementCard = ({
|
||||
setLocalSurvey,
|
||||
environmentId,
|
||||
}: SurveyPlacementCardProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
const { projectOverwrites } = localSurvey ?? {};
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import * as Collapsible from "@radix-ui/react-collapsible";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { FileDigitIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
import { TSurvey, TSurveyQuestionId } from "@formbricks/types/surveys/types";
|
||||
import { SurveyVariablesCardItem } from "./SurveyVariablesCardItem";
|
||||
@@ -24,7 +24,7 @@ export const SurveyVariablesCard = ({
|
||||
setActiveQuestionId,
|
||||
}: SurveyVariablesCardProps) => {
|
||||
const open = activeQuestionId === variablesCardId;
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const [parent] = useAutoAnimate();
|
||||
|
||||
const setOpenState = (state: boolean) => {
|
||||
|
||||
@@ -13,8 +13,8 @@ import {
|
||||
SelectValue,
|
||||
} from "@/modules/ui/components/select";
|
||||
import { createId } from "@paralleldrive/cuid2";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { TrashIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import React, { useCallback, useEffect } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import toast from "react-hot-toast";
|
||||
@@ -34,7 +34,7 @@ export const SurveyVariablesCardItem = ({
|
||||
setLocalSurvey,
|
||||
mode,
|
||||
}: SurveyVariablesCardItemProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const form = useForm<TSurveyVariable>({
|
||||
defaultValues: variable ?? {
|
||||
id: createId(),
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import { UpgradePrompt } from "@/modules/ui/components/upgrade-prompt";
|
||||
import * as Collapsible from "@radix-ui/react-collapsible";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { LockIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useState } from "react";
|
||||
|
||||
interface TargetingLockedCardProps {
|
||||
@@ -10,7 +12,7 @@ interface TargetingLockedCardProps {
|
||||
}
|
||||
|
||||
export const TargetingLockedCard = ({ isFormbricksCloud, environmentId }: TargetingLockedCardProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
import { Button } from "@/modules/ui/components/button";
|
||||
import { Input } from "@/modules/ui/components/input";
|
||||
import { LoadingSpinner } from "@/modules/ui/components/loading-spinner";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { debounce } from "lodash";
|
||||
import { SearchIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import UnsplashImage from "next/image";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
@@ -121,7 +121,7 @@ const defaultImages = [
|
||||
];
|
||||
|
||||
export const ImageFromUnsplashSurveyBg = ({ handleBgChange }: ImageFromUnsplashSurveyBgProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const inputFocus = useRef<HTMLInputElement>(null);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [query, setQuery] = useState("");
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { Button } from "@/modules/ui/components/button";
|
||||
import { Input } from "@/modules/ui/components/input";
|
||||
import { Label } from "@/modules/ui/components/label";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import { TSurvey, TSurveyQuestion } from "@formbricks/types/surveys/types";
|
||||
@@ -22,7 +22,7 @@ export const UpdateQuestionId = ({
|
||||
questionIdx,
|
||||
updateQuestion,
|
||||
}: UpdateQuestionIdProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const [currentValue, setCurrentValue] = useState(question.id);
|
||||
const [prevValue, setPrevValue] = useState(question.id);
|
||||
const [isInputInvalid, setIsInputInvalid] = useState(
|
||||
|
||||
@@ -7,6 +7,7 @@ import { Button } from "@/modules/ui/components/button";
|
||||
import { Input } from "@/modules/ui/components/input";
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import * as Collapsible from "@radix-ui/react-collapsible";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import {
|
||||
CheckIcon,
|
||||
Code2Icon,
|
||||
@@ -15,7 +16,6 @@ import {
|
||||
SparklesIcon,
|
||||
Trash2Icon,
|
||||
} from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { getAccessFlags } from "@formbricks/lib/membership/utils";
|
||||
import { TActionClass } from "@formbricks/types/action-classes";
|
||||
@@ -40,7 +40,7 @@ export const WhenToSendCard = ({
|
||||
membershipRole,
|
||||
projectPermission,
|
||||
}: WhenToSendCardProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const [open, setOpen] = useState(localSurvey.type === "app" ? true : false);
|
||||
const [isAddActionModalOpen, setAddActionModalOpen] = useState(false);
|
||||
const [actionClasses, setActionClasses] = useState<TActionClass[]>(propActionClasses);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { TFnType } from "@tolgee/react";
|
||||
import { TSurveyQuestionTypeEnum, ZSurveyLogicConditionsOperator } from "@formbricks/types/surveys/types";
|
||||
|
||||
export const getLogicRules = (t: (key: string) => string) => {
|
||||
export const getLogicRules = (t: TFnType) => {
|
||||
return {
|
||||
question: {
|
||||
[`${TSurveyQuestionTypeEnum.OpenText}.text`]: {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { TComboboxGroupedOption, TComboboxOption } from "@/modules/ui/components/input-combo-box";
|
||||
import { TFnType } from "@tolgee/react";
|
||||
import { EyeOffIcon, FileDigitIcon, FileType2Icon } from "lucide-react";
|
||||
import { HTMLInputTypeAttribute } from "react";
|
||||
import { getLocalizedValue } from "@formbricks/lib/i18n/utils";
|
||||
import { isConditionGroup } from "@formbricks/lib/surveyLogic/utils";
|
||||
import { translate } from "@formbricks/lib/templates";
|
||||
import { getQuestionTypes } from "@formbricks/lib/utils/questions";
|
||||
import { recallToHeadline } from "@formbricks/lib/utils/recall";
|
||||
import {
|
||||
@@ -21,7 +21,6 @@ import {
|
||||
TSurveyQuestionTypeEnum,
|
||||
TSurveyVariable,
|
||||
} from "@formbricks/types/surveys/types";
|
||||
import { TUserLocale } from "@formbricks/types/user";
|
||||
import { TLogicRuleOption, getLogicRules } from "./logicRuleEngine";
|
||||
|
||||
// formats the text to highlight specific parts of the text with slashes
|
||||
@@ -43,18 +42,19 @@ export const formatTextWithSlashes = (text: string) => {
|
||||
});
|
||||
};
|
||||
|
||||
const questionIconMapping = getQuestionTypes("en-US").reduce(
|
||||
(prev, curr) => ({
|
||||
...prev,
|
||||
[curr.id]: curr.icon,
|
||||
}),
|
||||
{}
|
||||
);
|
||||
const getQuestionIconMapping = (t: TFnType) =>
|
||||
getQuestionTypes(t).reduce(
|
||||
(prev, curr) => ({
|
||||
...prev,
|
||||
[curr.id]: curr.icon,
|
||||
}),
|
||||
{}
|
||||
);
|
||||
|
||||
export const getConditionValueOptions = (
|
||||
localSurvey: TSurvey,
|
||||
currQuestionIdx: number,
|
||||
t: (key: string) => string
|
||||
t: TFnType
|
||||
): TComboboxGroupedOption[] => {
|
||||
const hiddenFields = localSurvey.hiddenFields?.fieldIds ?? [];
|
||||
const variables = localSurvey.variables ?? [];
|
||||
@@ -65,7 +65,7 @@ export const getConditionValueOptions = (
|
||||
.filter((_, idx) => idx <= currQuestionIdx)
|
||||
.map((question) => {
|
||||
return {
|
||||
icon: questionIconMapping[question.type],
|
||||
icon: getQuestionIconMapping(t)[question.type],
|
||||
label: getLocalizedValue(question.headline, "default"),
|
||||
value: question.id,
|
||||
meta: {
|
||||
@@ -133,7 +133,7 @@ export const replaceEndingCardHeadlineRecall = (survey: TSurvey, language: strin
|
||||
return modifiedSurvey;
|
||||
};
|
||||
|
||||
export const getActionObjectiveOptions = (t: (key: string) => string): TComboboxOption[] => [
|
||||
export const getActionObjectiveOptions = (t: TFnType): TComboboxOption[] => [
|
||||
{ label: t("environments.surveys.edit.calculate"), value: "calculate" },
|
||||
{ label: t("environments.surveys.edit.require_answer"), value: "requireAnswer" },
|
||||
{ label: t("environments.surveys.edit.jump_to_question"), value: "jumpToQuestion" },
|
||||
@@ -143,10 +143,7 @@ export const hasJumpToQuestionAction = (actions: TSurveyLogicActions): boolean =
|
||||
return actions.some((action) => action.objective === "jumpToQuestion");
|
||||
};
|
||||
|
||||
const getQuestionOperatorOptions = (
|
||||
question: TSurveyQuestion,
|
||||
t: (key: string) => string
|
||||
): TComboboxOption[] => {
|
||||
const getQuestionOperatorOptions = (question: TSurveyQuestion, t: TFnType): TComboboxOption[] => {
|
||||
let options: TLogicRuleOption;
|
||||
|
||||
if (question.type === "openText") {
|
||||
@@ -165,7 +162,7 @@ const getQuestionOperatorOptions = (
|
||||
|
||||
export const getDefaultOperatorForQuestion = (
|
||||
question: TSurveyQuestion,
|
||||
t: (key: string) => string
|
||||
t: TFnType
|
||||
): TSurveyLogicConditionsOperator => {
|
||||
const options = getQuestionOperatorOptions(question, t);
|
||||
|
||||
@@ -175,7 +172,7 @@ export const getDefaultOperatorForQuestion = (
|
||||
export const getConditionOperatorOptions = (
|
||||
condition: TSingleCondition,
|
||||
localSurvey: TSurvey,
|
||||
t: (key: string) => string
|
||||
t: TFnType
|
||||
): TComboboxOption[] => {
|
||||
if (condition.leftOperand.type === "variable") {
|
||||
const variables = localSurvey.variables ?? [];
|
||||
@@ -199,7 +196,7 @@ export const getMatchValueProps = (
|
||||
condition: TSingleCondition,
|
||||
localSurvey: TSurvey,
|
||||
questionIdx: number,
|
||||
t: (key: string) => string
|
||||
t: TFnType
|
||||
): {
|
||||
show?: boolean;
|
||||
showInput?: boolean;
|
||||
@@ -257,7 +254,7 @@ export const getMatchValueProps = (
|
||||
|
||||
const questionOptions = allowedQuestions.map((question) => {
|
||||
return {
|
||||
icon: questionIconMapping[question.type],
|
||||
icon: getQuestionIconMapping(t)[question.type],
|
||||
label: getLocalizedValue(question.headline, "default"),
|
||||
value: question.id,
|
||||
meta: {
|
||||
@@ -460,7 +457,7 @@ export const getMatchValueProps = (
|
||||
|
||||
const questionOptions = openTextQuestions.map((question) => {
|
||||
return {
|
||||
icon: questionIconMapping[question.type],
|
||||
icon: getQuestionIconMapping(t)[question.type],
|
||||
label: getLocalizedValue(question.headline, "default"),
|
||||
value: question.id,
|
||||
meta: {
|
||||
@@ -541,7 +538,7 @@ export const getMatchValueProps = (
|
||||
|
||||
const questionOptions = allowedQuestions.map((question) => {
|
||||
return {
|
||||
icon: questionIconMapping[question.type],
|
||||
icon: getQuestionIconMapping(t)[question.type],
|
||||
label: getLocalizedValue(question.headline, "default"),
|
||||
value: question.id,
|
||||
meta: {
|
||||
@@ -615,7 +612,7 @@ export const getMatchValueProps = (
|
||||
|
||||
const questionOptions = allowedQuestions.map((question) => {
|
||||
return {
|
||||
icon: questionIconMapping[question.type],
|
||||
icon: getQuestionIconMapping(t)[question.type],
|
||||
label: getLocalizedValue(question.headline, "default"),
|
||||
value: question.id,
|
||||
meta: {
|
||||
@@ -695,7 +692,7 @@ export const getMatchValueProps = (
|
||||
|
||||
const questionOptions = allowedQuestions.map((question) => {
|
||||
return {
|
||||
icon: questionIconMapping[question.type],
|
||||
icon: getQuestionIconMapping(t)[question.type],
|
||||
label: getLocalizedValue(question.headline, "default"),
|
||||
value: question.id,
|
||||
meta: {
|
||||
@@ -769,7 +766,7 @@ export const getActionTargetOptions = (
|
||||
action: TSurveyLogicAction,
|
||||
localSurvey: TSurvey,
|
||||
currQuestionIdx: number,
|
||||
t: (key: string) => string
|
||||
t: TFnType
|
||||
): TComboboxOption[] => {
|
||||
let questions = localSurvey.questions.filter((_, idx) => idx > currQuestionIdx);
|
||||
|
||||
@@ -779,7 +776,7 @@ export const getActionTargetOptions = (
|
||||
|
||||
const questionOptions = questions.map((question) => {
|
||||
return {
|
||||
icon: questionIconMapping[question.type],
|
||||
icon: getQuestionIconMapping(t)[question.type],
|
||||
label: getLocalizedValue(question.headline, "default"),
|
||||
value: question.id,
|
||||
};
|
||||
@@ -816,7 +813,7 @@ export const getActionVariableOptions = (localSurvey: TSurvey): TComboboxOption[
|
||||
};
|
||||
|
||||
export const getActionOperatorOptions = (
|
||||
t: (key: string) => string,
|
||||
t: TFnType,
|
||||
variableType?: TSurveyVariable["type"]
|
||||
): TComboboxOption[] => {
|
||||
if (variableType === "number") {
|
||||
@@ -861,7 +858,7 @@ export const getActionValueOptions = (
|
||||
variableId: string,
|
||||
localSurvey: TSurvey,
|
||||
questionIdx: number,
|
||||
t: (key: string) => string
|
||||
t: TFnType
|
||||
): TComboboxGroupedOption[] => {
|
||||
const hiddenFields = localSurvey.hiddenFields?.fieldIds ?? [];
|
||||
let variables = localSurvey.variables ?? [];
|
||||
@@ -897,7 +894,7 @@ export const getActionValueOptions = (
|
||||
|
||||
const questionOptions = allowedQuestions.map((question) => {
|
||||
return {
|
||||
icon: questionIconMapping[question.type],
|
||||
icon: getQuestionIconMapping(t)[question.type],
|
||||
label: getLocalizedValue(question.headline, "default"),
|
||||
value: question.id,
|
||||
meta: {
|
||||
@@ -955,7 +952,7 @@ export const getActionValueOptions = (
|
||||
|
||||
const questionOptions = allowedQuestions.map((question) => {
|
||||
return {
|
||||
icon: questionIconMapping[question.type],
|
||||
icon: getQuestionIconMapping(t)[question.type],
|
||||
label: getLocalizedValue(question.headline, "default"),
|
||||
value: question.id,
|
||||
meta: {
|
||||
@@ -1157,8 +1154,8 @@ export const findHiddenFieldUsedInLogic = (survey: TSurvey, hiddenFieldId: strin
|
||||
return survey.questions.findIndex((question) => question.logic?.some(isUsedInLogicRule));
|
||||
};
|
||||
|
||||
export const getSurveyFollowUpActionDefaultBody = (locale: TUserLocale) => {
|
||||
return translate("follow_ups_modal_action_body", locale) as string;
|
||||
export const getSurveyFollowUpActionDefaultBody = (t: TFnType) => {
|
||||
return t("templates.follow_ups_modal_action_body") as string;
|
||||
};
|
||||
|
||||
export const findEndingCardUsedInLogic = (survey: TSurvey, endingCardId: string): number => {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// extend this object in order to add more validation rules
|
||||
import { TFnType } from "@tolgee/react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { z } from "zod";
|
||||
import { extractLanguageCodes, getLocalizedValue } from "@formbricks/lib/i18n/utils";
|
||||
@@ -227,7 +228,7 @@ export const isEndingCardValid = (
|
||||
}
|
||||
};
|
||||
|
||||
export const isSurveyValid = (survey: TSurvey, selectedLanguageCode: string, t: (key: string) => string) => {
|
||||
export const isSurveyValid = (survey: TSurvey, selectedLanguageCode: string, t: TFnType) => {
|
||||
const questionWithEmptyFallback = checkForEmptyFallBackValue(survey, selectedLanguageCode);
|
||||
if (questionWithEmptyFallback) {
|
||||
toast.error(t("environments.surveys.edit.fallback_missing"));
|
||||
|
||||
@@ -7,8 +7,8 @@ import { getProjectPermissionByUserId } from "@/modules/ee/teams/lib/roles";
|
||||
import { getTeamPermissionFlags } from "@/modules/ee/teams/utils/teams";
|
||||
import { getSurveyFollowUpsPermission } from "@/modules/survey-follow-ups/lib/utils";
|
||||
import { ErrorComponent } from "@/modules/ui/components/error-component";
|
||||
import { getTranslate } from "@/tolgee/server";
|
||||
import { getServerSession } from "next-auth";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import { getActionClasses } from "@formbricks/lib/actionClass/service";
|
||||
import {
|
||||
DEFAULT_LOCALE,
|
||||
@@ -38,7 +38,7 @@ export const generateMetadata = async (props) => {
|
||||
const Page = async (props) => {
|
||||
const searchParams = await props.searchParams;
|
||||
const params = await props.params;
|
||||
const t = await getTranslations();
|
||||
const t = await getTranslate();
|
||||
const [
|
||||
survey,
|
||||
project,
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { getDefaultEndingCard, getDefaultWelcomeCard } from "@formbricks/lib/templates";
|
||||
import { getDefaultEndingCard, getDefaultWelcomeCard } from "@/app/lib/templates";
|
||||
import { TFnType } from "@tolgee/react";
|
||||
import { TSurvey } from "@formbricks/types/surveys/types";
|
||||
|
||||
export const getMinimalSurvey = (locale: string): TSurvey => ({
|
||||
export const getMinimalSurvey = (t: TFnType): TSurvey => ({
|
||||
id: "someUniqueId1",
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
@@ -15,9 +16,9 @@ export const getMinimalSurvey = (locale: string): TSurvey => ({
|
||||
triggers: [],
|
||||
recontactDays: null,
|
||||
displayLimit: null,
|
||||
welcomeCard: getDefaultWelcomeCard(locale),
|
||||
welcomeCard: getDefaultWelcomeCard(t),
|
||||
questions: [],
|
||||
endings: [getDefaultEndingCard([], locale)],
|
||||
endings: [getDefaultEndingCard([], t)],
|
||||
hiddenFields: {
|
||||
enabled: false,
|
||||
},
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
"use client";
|
||||
|
||||
import { Button } from "@/modules/ui/components/button";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { ArrowLeftIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
export const BackButton = () => {
|
||||
const router = useRouter();
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
return (
|
||||
<Button
|
||||
variant="secondary"
|
||||
|
||||
@@ -12,8 +12,8 @@ import {
|
||||
CardTitle,
|
||||
} from "@/modules/ui/components/card";
|
||||
import { Textarea } from "@/modules/ui/components/textarea";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { Sparkles } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
@@ -23,7 +23,7 @@ interface FormbricksAICardProps {
|
||||
}
|
||||
|
||||
export const FormbricksAICard = ({ environmentId }: FormbricksAICardProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const router = useRouter();
|
||||
const [aiPrompt, setAiPrompt] = useState("");
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
@@ -52,14 +52,14 @@ export const FormbricksAICard = ({ environmentId }: FormbricksAICardProps) => {
|
||||
<Card className="mx-auto w-full bg-gradient-to-tr from-slate-100 to-slate-200">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-2xl font-bold">Formbricks AI</CardTitle>
|
||||
<CardDescription>{t("environments.surveys.templates.formbricks_ai_description")}</CardDescription>
|
||||
<CardDescription>{t("environments.surveys.edit.formbricks_ai_description")}</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<form onSubmit={handleSubmit} className="space-y-4">
|
||||
<Textarea
|
||||
className="bg-slate-50"
|
||||
id="ai-prompt"
|
||||
placeholder={t("environments.surveys.templates.formbricks_ai_prompt_placeholder")}
|
||||
placeholder={t("environments.surveys.edit.formbricks_ai_prompt_placeholder")}
|
||||
value={aiPrompt}
|
||||
onChange={(e) => setAiPrompt(e.target.value)}
|
||||
required
|
||||
@@ -75,7 +75,7 @@ export const FormbricksAICard = ({ environmentId }: FormbricksAICardProps) => {
|
||||
variant="secondary"
|
||||
loading={isLoading}>
|
||||
<Sparkles className="mr-2 h-4 w-4" />
|
||||
{t("environments.surveys.templates.formbricks_ai_generate")}
|
||||
{t("environments.surveys.edit.formbricks_ai_generate")}
|
||||
</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
import { FormbricksAICard } from "@/app/(app)/(survey-editor)/environments/[environmentId]/surveys/templates/components/FormbricksAICard";
|
||||
import { MenuBar } from "@/app/(app)/(survey-editor)/environments/[environmentId]/surveys/templates/components/MenuBar";
|
||||
import { customSurveyTemplate } from "@/app/lib/templates";
|
||||
import { TemplateList } from "@/modules/surveys/components/TemplateList";
|
||||
import { PreviewSurvey } from "@/modules/ui/components/preview-survey";
|
||||
import { SearchBar } from "@/modules/ui/components/search-bar";
|
||||
import { Separator } from "@/modules/ui/components/separator";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { useState } from "react";
|
||||
import { getCustomSurveyTemplate } from "@formbricks/lib/templates";
|
||||
import type { TEnvironment } from "@formbricks/types/environment";
|
||||
import type { TProject, TProjectConfigChannel, TProjectConfigIndustry } from "@formbricks/types/project";
|
||||
import type { TTemplate, TTemplateRole } from "@formbricks/types/templates";
|
||||
@@ -31,8 +31,8 @@ export const TemplateContainerWithPreview = ({
|
||||
prefilledFilters,
|
||||
isAIEnabled,
|
||||
}: TemplateContainerWithPreviewProps) => {
|
||||
const t = useTranslations();
|
||||
const initialTemplate = getCustomSurveyTemplate(user.locale);
|
||||
const { t } = useTranslate();
|
||||
const initialTemplate = customSurveyTemplate(t);
|
||||
const [activeTemplate, setActiveTemplate] = useState<TTemplate>(initialTemplate);
|
||||
const [activeQuestionId, setActiveQuestionId] = useState<string>(initialTemplate.preset.questions[0].id);
|
||||
const [templateSearch, setTemplateSearch] = useState<string | null>(null);
|
||||
@@ -80,7 +80,7 @@ export const TemplateContainerWithPreview = ({
|
||||
<aside className="group hidden flex-1 flex-shrink-0 items-center justify-center overflow-hidden border-l border-slate-100 bg-slate-50 md:flex md:flex-col">
|
||||
{activeTemplate && (
|
||||
<PreviewSurvey
|
||||
survey={{ ...getMinimalSurvey(user.locale), ...activeTemplate.preset }}
|
||||
survey={{ ...getMinimalSurvey(t), ...activeTemplate.preset }}
|
||||
questionId={activeQuestionId}
|
||||
project={project}
|
||||
environment={environment}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { authOptions } from "@/modules/auth/lib/authOptions";
|
||||
import { getProjectPermissionByUserId } from "@/modules/ee/teams/lib/roles";
|
||||
import { getTeamPermissionFlags } from "@/modules/ee/teams/utils/teams";
|
||||
import { getTranslate } from "@/tolgee/server";
|
||||
import { getServerSession } from "next-auth";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import { redirect } from "next/navigation";
|
||||
import { getEnvironment } from "@formbricks/lib/environment/service";
|
||||
import { getMembershipByUserIdOrganizationId } from "@formbricks/lib/membership/service";
|
||||
@@ -27,7 +27,7 @@ interface SurveyTemplateProps {
|
||||
const Page = async (props: SurveyTemplateProps) => {
|
||||
const searchParams = await props.searchParams;
|
||||
const params = await props.params;
|
||||
const t = await getTranslations();
|
||||
const t = await getTranslate();
|
||||
const session = await getServerSession(authOptions);
|
||||
const environmentId = params.environmentId;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { Button } from "@/modules/ui/components/button";
|
||||
import { Confetti } from "@/modules/ui/components/confetti";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import Link from "next/link";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
@@ -11,7 +11,7 @@ interface ConfirmationPageProps {
|
||||
}
|
||||
|
||||
export const ConfirmationPage = ({ environmentId }: ConfirmationPageProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const [showConfetti, setShowConfetti] = useState(false);
|
||||
useEffect(() => {
|
||||
setShowConfetti(true);
|
||||
|
||||
@@ -6,8 +6,8 @@ import { Button } from "@/modules/ui/components/button";
|
||||
import { ErrorComponent } from "@/modules/ui/components/error-component";
|
||||
import { Label } from "@/modules/ui/components/label";
|
||||
import { LoadingSpinner } from "@/modules/ui/components/loading-spinner";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { Code2Icon, MousePointerClickIcon, SparklesIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import { convertDateTimeStringShort } from "@formbricks/lib/time";
|
||||
@@ -33,7 +33,7 @@ export const ActionActivityTab = ({
|
||||
environment,
|
||||
isReadOnly,
|
||||
}: ActivityTabProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const [activeSurveys, setActiveSurveys] = useState<string[] | undefined>();
|
||||
const [inactiveSurveys, setInactiveSurveys] = useState<string[] | undefined>();
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import { ModalWithTabs } from "@/modules/ui/components/modal-with-tabs";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { Code2Icon, MousePointerClickIcon, SparklesIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { TActionClass } from "@formbricks/types/action-classes";
|
||||
import { TEnvironment } from "@formbricks/types/environment";
|
||||
import { ActionActivityTab } from "./ActionActivityTab";
|
||||
@@ -29,7 +31,7 @@ export const ActionDetailModal = ({
|
||||
otherEnvActionClasses,
|
||||
otherEnvironment,
|
||||
}: ActionDetailModalProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const tabs = [
|
||||
{
|
||||
title: t("common.activity"),
|
||||
|
||||
@@ -12,8 +12,8 @@ import { FormControl, FormError, FormField, FormItem, FormLabel } from "@/module
|
||||
import { Input } from "@/modules/ui/components/input";
|
||||
import { NoCodeActionForm } from "@/modules/ui/components/no-code-action-form";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { TrashIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useMemo, useState } from "react";
|
||||
@@ -38,7 +38,7 @@ export const ActionSettingsTab = ({
|
||||
const { createdAt, updatedAt, id, ...restActionClass } = actionClass;
|
||||
const router = useRouter();
|
||||
const [openDeleteDialog, setOpenDeleteDialog] = useState(false);
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const [isUpdatingAction, setIsUpdatingAction] = useState(false);
|
||||
const [isDeletingAction, setIsDeletingAction] = useState(false);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import { getTranslate } from "@/tolgee/server";
|
||||
|
||||
export const ActionTableHeading = async () => {
|
||||
const t = await getTranslations();
|
||||
const t = await getTranslate();
|
||||
return (
|
||||
<>
|
||||
<div className="grid h-12 grid-cols-6 content-center border-b border-slate-200 text-left text-sm font-semibold text-slate-900">
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
import { CreateNewActionTab } from "@/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/CreateNewActionTab";
|
||||
import { Button } from "@/modules/ui/components/button";
|
||||
import { Modal } from "@/modules/ui/components/modal";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { MousePointerClickIcon, PlusIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useState } from "react";
|
||||
import { TActionClass } from "@formbricks/types/action-classes";
|
||||
|
||||
@@ -15,7 +15,7 @@ interface AddActionModalProps {
|
||||
}
|
||||
|
||||
export const AddActionModal = ({ environmentId, actionClasses, isReadOnly }: AddActionModalProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
const [newActionClasses, setNewActionClasses] = useState<TActionClass[]>(actionClasses);
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
"use client";
|
||||
|
||||
import { PageContentWrapper } from "@/modules/ui/components/page-content-wrapper";
|
||||
import { PageHeader } from "@/modules/ui/components/page-header";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
|
||||
const Loading = () => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
return (
|
||||
<>
|
||||
<PageContentWrapper>
|
||||
|
||||
@@ -7,9 +7,9 @@ import { getProjectPermissionByUserId } from "@/modules/ee/teams/lib/roles";
|
||||
import { getTeamPermissionFlags } from "@/modules/ee/teams/utils/teams";
|
||||
import { PageContentWrapper } from "@/modules/ui/components/page-content-wrapper";
|
||||
import { PageHeader } from "@/modules/ui/components/page-header";
|
||||
import { getTranslate } from "@/tolgee/server";
|
||||
import { Metadata } from "next";
|
||||
import { getServerSession } from "next-auth";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import { redirect } from "next/navigation";
|
||||
import { getActionClasses } from "@formbricks/lib/actionClass/service";
|
||||
import { getEnvironments } from "@formbricks/lib/environment/service";
|
||||
@@ -26,7 +26,7 @@ export const metadata: Metadata = {
|
||||
const Page = async (props) => {
|
||||
const params = await props.params;
|
||||
const session = await getServerSession(authOptions);
|
||||
const t = await getTranslations();
|
||||
const t = await getTranslate();
|
||||
const [actionClasses, organization, project] = await Promise.all([
|
||||
getActionClasses(params.environmentId),
|
||||
getOrganizationByEnvironmentId(params.environmentId),
|
||||
|
||||
@@ -5,8 +5,8 @@ import { getProjectPermissionByUserId } from "@/modules/ee/teams/lib/roles";
|
||||
import { DevEnvironmentBanner } from "@/modules/ui/components/dev-environment-banner";
|
||||
import { LimitsReachedBanner } from "@/modules/ui/components/limits-reached-banner";
|
||||
import { PendingDowngradeBanner } from "@/modules/ui/components/pending-downgrade-banner";
|
||||
import { getTranslate } from "@/tolgee/server";
|
||||
import type { Session } from "next-auth";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import { IS_FORMBRICKS_CLOUD } from "@formbricks/lib/constants";
|
||||
import { getEnvironment, getEnvironments } from "@formbricks/lib/environment/service";
|
||||
import { getMembershipByUserIdOrganizationId } from "@formbricks/lib/membership/service";
|
||||
@@ -27,7 +27,7 @@ interface EnvironmentLayoutProps {
|
||||
}
|
||||
|
||||
export const EnvironmentLayout = async ({ environmentId, session, children }: EnvironmentLayoutProps) => {
|
||||
const t = await getTranslations();
|
||||
const t = await getTranslate();
|
||||
const [user, environment, organizations, organization] = await Promise.all([
|
||||
getUser(session.user.id),
|
||||
getEnvironment(environmentId),
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { Label } from "@/modules/ui/components/label";
|
||||
import { Switch } from "@/modules/ui/components/switch";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
@@ -14,7 +14,7 @@ interface EnvironmentSwitchProps {
|
||||
}
|
||||
|
||||
export const EnvironmentSwitch = ({ environment, environments }: EnvironmentSwitchProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const router = useRouter();
|
||||
const [isEnvSwitchChecked, setIsEnvSwitchChecked] = useState(environment?.type === "development");
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
DropdownMenuSubTrigger,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/modules/ui/components/dropdown-menu";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import {
|
||||
ArrowUpRightIcon,
|
||||
BlocksIcon,
|
||||
@@ -40,7 +41,6 @@ import {
|
||||
UsersIcon,
|
||||
} from "lucide-react";
|
||||
import { signOut } from "next-auth/react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { usePathname, useRouter } from "next/navigation";
|
||||
@@ -82,7 +82,7 @@ export const MainNavigation = ({
|
||||
}: NavigationProps) => {
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const [currentOrganizationName, setCurrentOrganizationName] = useState("");
|
||||
const [currentOrganizationId, setCurrentOrganizationId] = useState("");
|
||||
const [showCreateOrganizationModal, setShowCreateOrganizationModal] = useState(false);
|
||||
|
||||
@@ -5,8 +5,8 @@ import { TTeamPermission } from "@/modules/ee/teams/project-teams/types/team";
|
||||
import { getTeamPermissionFlags } from "@/modules/ee/teams/utils/teams";
|
||||
import { Button } from "@/modules/ui/components/button";
|
||||
import { TooltipRenderer } from "@/modules/ui/components/tooltip";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { CircleUserIcon, MessageCircleQuestionIcon, PlusIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useRouter } from "next/navigation";
|
||||
import formbricks from "@formbricks/js";
|
||||
import { getAccessFlags } from "@formbricks/lib/membership/utils";
|
||||
@@ -28,7 +28,7 @@ export const TopControlButtons = ({
|
||||
membershipRole,
|
||||
projectPermission,
|
||||
}: TopControlButtonsProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const router = useRouter();
|
||||
|
||||
const { isMember, isBilling } = getAccessFlags(membershipRole);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { AlertTriangleIcon, CheckIcon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
import { TEnvironment } from "@formbricks/types/environment";
|
||||
|
||||
@@ -8,7 +10,7 @@ interface WidgetStatusIndicatorProps {
|
||||
}
|
||||
|
||||
export const WidgetStatusIndicator = ({ environment }: WidgetStatusIndicatorProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const stati = {
|
||||
notImplemented: {
|
||||
icon: AlertTriangleIcon,
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/modules/ui/components/select";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import Image from "next/image";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useEffect, useState } from "react";
|
||||
@@ -59,7 +59,7 @@ export type IntegrationModalInputs = {
|
||||
};
|
||||
|
||||
const NoBaseFoundError = () => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
return (
|
||||
<Alert>
|
||||
<AlertTitle>{t("environments.integrations.airtable.no_bases_found")}</AlertTitle>
|
||||
@@ -78,7 +78,7 @@ export const AddIntegrationModal = ({
|
||||
isEditMode,
|
||||
defaultData,
|
||||
}: AddIntegrationModalProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const router = useRouter();
|
||||
const [tables, setTables] = useState<TIntegrationAirtableTables["tables"]>([]);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import { Label } from "@/modules/ui/components/label";
|
||||
import {
|
||||
Select,
|
||||
@@ -6,7 +8,7 @@ import {
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/modules/ui/components/select";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { Control, Controller, UseFormSetValue } from "react-hook-form";
|
||||
import { TIntegrationItem } from "@formbricks/types/integration";
|
||||
import { IntegrationModalInputs } from "./AddIntegrationModal";
|
||||
@@ -28,7 +30,7 @@ export const BaseSelectDropdown = ({
|
||||
setValue,
|
||||
defaultValue,
|
||||
}: BaseSelectProps) => {
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
return (
|
||||
<div className="flex w-full flex-col">
|
||||
<Label htmlFor="base">{t("environments.integrations.airtable.airtable_base")}</Label>
|
||||
|
||||
@@ -9,8 +9,8 @@ import { getFormattedErrorMessage } from "@/lib/utils/helper";
|
||||
import { Button } from "@/modules/ui/components/button";
|
||||
import { DeleteDialog } from "@/modules/ui/components/delete-dialog";
|
||||
import { EmptySpaceFiller } from "@/modules/ui/components/empty-space-filler";
|
||||
import { useTranslate } from "@tolgee/react";
|
||||
import { Trash2Icon } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { timeSince } from "@formbricks/lib/time";
|
||||
@@ -39,7 +39,7 @@ const tableHeaders = [
|
||||
|
||||
export const ManageIntegration = (props: ManageIntegrationProps) => {
|
||||
const { airtableIntegration, environment, environmentId, setIsConnected, surveys, airtableArray } = props;
|
||||
const t = useTranslations();
|
||||
const { t } = useTranslate();
|
||||
const [isDeleting, setisDeleting] = useState(false);
|
||||
const [isDeleteIntegrationModalOpen, setIsDeleteIntegrationModalOpen] = useState(false);
|
||||
const [defaultValues, setDefaultValues] = useState<(IntegrationModalInputs & { index: number }) | null>(
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user