Compare commits

..

10 Commits

Author SHA1 Message Date
Johannes
0851e65a9a Merge branch 'main' of https://github.com/formbricks/formbricks into simplify-stripe 2025-10-28 09:11:23 +01:00
Johannes
7df0e8e9b9 Merge branch 'main' of https://github.com/formbricks/formbricks into simplify-stripe 2025-10-27 13:57:53 +01:00
Johannes
e3679d4a2d clean up locale files 2025-10-27 11:53:58 +01:00
Johannes
9bdbe50a83 add logs 2025-10-27 10:43:36 +01:00
Johannes
01e8333acd bring back monthly reset 2025-10-27 10:23:09 +01:00
Johannes
db2823504f fix code rabbit issue 2025-10-27 09:55:25 +01:00
Johannes
95bbe24109 remove not needed migration 2025-10-23 19:34:03 +02:00
Johannes
07a1b687f8 final tweaks 2025-10-23 19:33:02 +02:00
Johannes
e8636ceacb Merge branch 'main' of https://github.com/formbricks/formbricks into simplify-stripe 2025-10-22 17:32:38 +02:00
Johannes
8e30564103 refactor: simplify Stripe integration and rename enterprise to custom
BREAKING CHANGES:
- Remove SCALE plan from PROJECT_FEATURE_KEYS enum
- Rename PROJECT_FEATURE_KEYS.ENTERPRISE to PROJECT_FEATURE_KEYS.CUSTOM
- Update trial period from 30 to 15 days
- Remove invoice.finalized and subscription.created/updated webhook handlers

FEATURES:
- Hardcode billing limits instead of syncing from Stripe metadata
- Simplify checkout handler to always use hardcoded Startup plan limits
- Simplify subscription creation flow (single code path)
- Create database migration to rename existing enterprise plans to custom

REMOVED:
- subscription-created-or-updated.ts (125 lines of complex metadata parsing)
- invoice-finalized.ts (no longer needed)

FILES CHANGED:
- Remove SCALE plan from constants and billing limits
- Update type definitions to use custom instead of enterprise
- Simplify webhook handlers (4 → 2 handlers)
- Update all UI components to reference custom plan
- Create database migration for plan renaming
- Update all tests to reference custom instead of enterprise

IMPACT:
- Reduces Stripe integration complexity by ~80%
- Eliminates metadata sync failures
- Makes billing more predictable and maintainable
- Aligns code naming with UI (custom vs enterprise)
- Reduces trial period from 30 to 15 days

Refs: #simplify-stripe-integration
2025-10-20 18:55:22 +02:00
59 changed files with 3741 additions and 6601 deletions

View File

@@ -52,22 +52,15 @@ export const EnvironmentContextWrapper = ({
organization,
children,
}: EnvironmentContextWrapperProps) => {
const environmentContextValue = useMemo(() => {
if (!environment?.id || !project?.id || !organization?.id) {
return null;
}
return {
const environmentContextValue = useMemo(
() => ({
environment,
project,
organization,
organizationId: project.organizationId,
};
}, [environment, project, organization]);
if (!environmentContextValue) {
return null;
}
}),
[environment, project, organization]
);
return (
<EnvironmentContext.Provider value={environmentContextValue}>{children}</EnvironmentContext.Provider>

View File

@@ -1,6 +1,5 @@
import { getServerSession } from "next-auth";
import { notFound, redirect } from "next/navigation";
import { AuthorizationError } from "@formbricks/types/errors";
import { redirect } from "next/navigation";
import { EnvironmentLayout } from "@/app/(app)/environments/[environmentId]/components/EnvironmentLayout";
import { EnvironmentContextWrapper } from "@/app/(app)/environments/[environmentId]/context/environment-context";
import { authOptions } from "@/modules/auth/lib/authOptions";
@@ -21,18 +20,8 @@ const EnvLayout = async (props: {
return redirect(`/auth/login`);
}
// Handle AuthorizationError gracefully during rapid navigation
let layoutData;
try {
layoutData = await getEnvironmentLayoutData(params.environmentId, session.user.id);
} catch (error) {
// If user doesn't have access, show not found instead of crashing
if (error instanceof AuthorizationError) {
return notFound();
}
// Re-throw other errors
throw error;
}
// Single consolidated data fetch (replaces ~12 individual fetches)
const layoutData = await getEnvironmentLayoutData(params.environmentId, session.user.id);
return (
<EnvironmentIdBaseLayout

View File

@@ -1,11 +0,0 @@
"use client";
import { LoadingSpinner } from "@/modules/ui/components/loading-spinner";
export default function EnvironmentLoading() {
return (
<div className="flex h-screen min-h-screen items-center justify-center">
<LoadingSpinner className="h-8 w-8" />
</div>
);
}

View File

@@ -96,6 +96,7 @@ export const SurveyAnalysisCTA = ({
const duplicateSurveyAndRoute = async (surveyId: string) => {
setLoading(true);
const duplicatedSurveyResponse = await copySurveyToOtherEnvironmentAction({
environmentId: environment.id,
surveyId: surveyId,
targetEnvironmentId: environment.id,
});

View File

@@ -0,0 +1,3 @@
import { LinkSurveyLoading } from "@/modules/survey/link/loading";
export default LinkSurveyLoading;

View File

@@ -7,7 +7,7 @@
},
"locale": {
"source": "en-US",
"targets": ["de-DE", "fr-FR", "ja-JP", "pt-BR", "pt-PT", "ro-RO", "zh-Hans-CN", "zh-Hant-TW", "nl-NL"]
"targets": ["de-DE", "fr-FR", "ja-JP", "pt-BR", "pt-PT", "ro-RO", "zh-Hans-CN", "zh-Hant-TW"]
},
"version": 1.8
}

View File

@@ -721,14 +721,14 @@ checksums:
environments/project/api_keys/secret: f041e5eb96121c8b4f2b8af7e0f83a9b
environments/project/api_keys/unable_to_delete_api_key: 1fd76d9a22c5f5f8c241c4891fca8295
environments/project/app-connection/app_connection: 778d2305e1a9c8efe91c2c7b4af37ae4
environments/project/app-connection/app_connection_description: dde226414bd2265cbd0daf6635efcfdd
environments/project/app-connection/app_connection_description: 01327bfae3da950d796890b6605afed2
environments/project/app-connection/cache_update_delay_description: 1cb2c46fdb6762ccb348d21086063a4f
environments/project/app-connection/cache_update_delay_title: fef7f99f0228f9e30093574ac7770e7e
environments/project/app-connection/environment_id: 3dba898b081c18cd4cae131765ef411f
environments/project/app-connection/environment_id_description: 8b4a763d069b000cfa1a2025a13df80c
environments/project/app-connection/formbricks_sdk_connected: 29e8a40ad6a7fdb5af5ee9451a70a9aa
environments/project/app-connection/formbricks_sdk_not_connected: 557c534e665750978ba6edb0eacb428e
environments/project/app-connection/formbricks_sdk_not_connected_description: 4ddbacae084238bd0cefeded0fe9dbb9
environments/project/app-connection/formbricks_sdk_not_connected_description: 666b2b25f06e76554cc2d60f925bcd4b
environments/project/app-connection/how_to_setup: 3bad40037f280b47fe6418fcbeb4c717
environments/project/app-connection/how_to_setup_description: 2ae5cd9456a8acd3986e3d3678e70ed2
environments/project/app-connection/receiving_data: 9f2a48c0b0278861add70b526061264c
@@ -745,7 +745,7 @@ checksums:
environments/project/general/project_deleted_successfully: dbedf0f0739b822f3951de4aeb2fc26f
environments/project/general/project_name_settings_description: 079c6380ad539543a9aa8772bc1b0fa2
environments/project/general/project_name_updated_successfully: f95f70f4a49d451dc0441a51d05a3aa3
environments/project/general/recontact_waiting_time: 0566dc710b4b9644e276e311b419c4c0
environments/project/general/recontact_waiting_time: 9c5ebb18960dec73def053de89e63272
environments/project/general/recontact_waiting_time_settings_description: 8922cde1f95777f9a2747fb4bed57ab5
environments/project/general/this_action_cannot_be_undone: 3d8b13374ffd3cefc0f3f7ce077bd9c9
environments/project/general/wait_x_days_before_showing_next_survey: d96228788d32ec23dc0d8c8ba77150a6
@@ -915,12 +915,15 @@ checksums:
environments/settings/billing/manage_subscription: 31cafd367fc70d656d8dd979d537dc96
environments/settings/billing/monthly: 818f1192e32bb855597f930d3e78806e
environments/settings/billing/monthly_identified_users: 0795735f6b241d31edac576a77dd7e55
environments/settings/billing/per_month: 64e96490ee2d7811496cf04adae30aa4
environments/settings/billing/per_year: bf02408d157486e53c15a521a5645617
environments/settings/billing/plan_upgraded_successfully: 52e2a258cc9ca8a512c288bf6f18cf37
environments/settings/billing/premium_support_with_slas: 2e33d4442c16bfececa6cae7b2081e5d
environments/settings/billing/remove_branding: 88b6b818750e478bfa153b33dd658280
environments/settings/billing/startup: 4c4ac5a0b9dc62100bca6c6465f31c4c
environments/settings/billing/startup_description: 964fcb2c77f49b80266c94606e3f4506
environments/settings/billing/switch_plan: fb3e1941051a4273ca29224803570f4b
environments/settings/billing/switch_plan_confirmation_text: 910a6df56964619975c6ed5651a55db7
environments/settings/billing/team_access_roles: 1cc4af14e589f6c09ab92a4f21958049
environments/settings/billing/unable_to_upgrade_plan: 50fc725609411d139e534c85eeb2879e
environments/settings/billing/unlimited_miu: 29c3f5bd01c2a09fdf1d3601665ce90f
@@ -1141,6 +1144,7 @@ checksums:
environments/surveys/edit/allow_multi_select: 7b4b83f7a0205e2a0a8971671a69a174
environments/surveys/edit/allow_multiple_files: dbd99f9d1026e4f7c5a5d03f71ba379d
environments/surveys/edit/allow_users_to_select_more_than_one_image: d683e0b538d1366400292a771f3fbd08
environments/surveys/edit/always_show_survey: b0ae6a873ce2eeb0aea2e6d4cb04c540
environments/surveys/edit/and_launch_surveys_in_your_website_or_app: a3edcdb4aea792a27d90aad1930f001a
environments/surveys/edit/animation: 66a18eacfb92fc9fc9db188d2dde4f81
environments/surveys/edit/app_survey_description: bdfacfce478e97f70b700a1382dfa687
@@ -1223,7 +1227,8 @@ checksums:
environments/surveys/edit/custom_hostname: bc2b1c8de3f9b8ef145b45aeba6ab429
environments/surveys/edit/darken_or_lighten_background_of_your_choice: 304a64a8050ebf501d195e948cd25b6f
environments/surveys/edit/date_format: e95dfc41ac944874868487457ddc057a
environments/surveys/edit/days_before_showing_this_survey_again: 354fb28c5ff076f022d82a20c749ee46
environments/surveys/edit/days_before_showing_this_survey_again: 8b4623eab862615fa60064400008eb23
environments/surveys/edit/decide_how_often_people_can_answer_this_survey: 58427b0f0a7a258c24fa2acd9913e95e
environments/surveys/edit/delete_choice: fd750208d414b9ad8c980c161a0199e1
environments/surveys/edit/disable_the_visibility_of_survey_progress: 2af631010114307ac2a91612559c9618
environments/surveys/edit/display_an_estimate_of_completion_time_for_survey: 03f0a816569399c1c61d08dbc913de06
@@ -1251,7 +1256,7 @@ checksums:
environments/surveys/edit/equals_one_of: 369a451add4b79bc003f952f0e1bfcc9
environments/surveys/edit/error_publishing_survey: bf9fab1d8ea7132a2e9b4b7b09f18b1f
environments/surveys/edit/error_saving_changes: b75aa9e4e42e1d43c8f9c33c2b7dc9a7
environments/surveys/edit/even_after_they_submitted_a_response_e_g_feedback_box: 7b99f30397dcde76f65e1ab64bdbd113
environments/surveys/edit/even_after_they_submitted_a_response_e_g_feedback_box: c6668f9cf127fd922bec695dc548fe12
environments/surveys/edit/everyone: 2112aa71b568773e8e8a792c63f4d413
environments/surveys/edit/external_urls_paywall_tooltip: 0dbb62557e8a6fa817f0e74709eeb3d2
environments/surveys/edit/fallback_missing: 43dbedbe1a178d455e5f80783a7b6722
@@ -1322,9 +1327,8 @@ checksums:
environments/surveys/edit/hostname: 9bdaa7692869999df51bb60d58d9ef62
environments/surveys/edit/how_funky_do_you_want_your_cards_in_survey_type_derived_surveys: 3cb16b37510c01af20a80f51b598346e
environments/surveys/edit/if_you_need_more_please: a7d208c283caf6b93800b809fca80768
environments/surveys/edit/if_you_really_want_that_answer_ask_until_you_get_it: 31c18a8c7c578db2ba49eed663d1739f
environments/surveys/edit/ignore_global_waiting_time: 1e7f1465aeb6d26c325ad7f135b207a8
environments/surveys/edit/ignore_global_waiting_time_description: 37d173a4d537622de40677389238d859
environments/surveys/edit/if_you_really_want_that_answer_ask_until_you_get_it: 33f0320ec85067a06198a841348e9fc6
environments/surveys/edit/ignore_waiting_time_between_surveys: 8145b6aef535fde5ee54dea63e66f64a
environments/surveys/edit/image: 048ba7a239de0fbd883ade8558415830
environments/surveys/edit/includes_all_of: ec72f90c0839d4c3bb518deb03894031
environments/surveys/edit/includes_one_of: 6d5be5d7c2494179e88bd7302b247884
@@ -1391,10 +1395,9 @@ checksums:
environments/surveys/edit/optional: 396fb9a0472daf401c392bdc3e248943
environments/surveys/edit/options: 59156082418d80acb211f973b1218f11
environments/surveys/edit/override_theme_with_individual_styles_for_this_survey: edffc97f5d3372419fe0444de0a5aa3f
environments/surveys/edit/overwrite_global_waiting_time: 7bc23bd502b6bd048356b67acd956d9d
environments/surveys/edit/overwrite_global_waiting_time_description: 795cf6e93d4c01d2e43aa0ebab601c6e
environments/surveys/edit/overwrite_placement: d7278be243e52c5091974e0fc4a7c342
environments/surveys/edit/overwrite_the_global_placement_of_the_survey: 874075712254b1ce92e099d89f675a48
environments/surveys/edit/overwrites_waiting_period_between_surveys_to_x_days: 8d5596b024cbe8c82b021dcf6c73ba05
environments/surveys/edit/pick_a_background_from_our_library_or_upload_your_own: b83bcbdc8131fc9524d272ff5dede754
environments/surveys/edit/picture_idx: 55e053ad1ade5d17c582406706036028
environments/surveys/edit/pin_can_only_contain_numbers: 417c854d44620a7229ebd9ab8cbb3613
@@ -1451,8 +1454,7 @@ checksums:
environments/surveys/edit/range: 1fad969ecf3de1c21df046b93053c422
environments/surveys/edit/recall_data: 39beabd626c0af15316885cff5d5d9b8
environments/surveys/edit/recall_information_from: 884cfd143456fab1a91f0744cc92f0c8
environments/surveys/edit/recontact_options_section: 57a23e1bcab6baa484b27b615e6c906a
environments/surveys/edit/recontact_options_section_description: 1e04011440c339a3b5cfff12d55b7f12
environments/surveys/edit/recontact_options: 0f570378a531da60448fde37abd50214
environments/surveys/edit/redirect_thank_you_card: 09f721c4b62e2584e40a53507092ea83
environments/surveys/edit/redirect_to_url: f17d726bbc3391561447b3f4010635cf
environments/surveys/edit/remove_description: b52de820b4bbcb354eb62246c4112a9a
@@ -1461,8 +1463,6 @@ checksums:
environments/surveys/edit/required: 04d7fb6f37ffe0a6ca97d49e2a8b6eb5
environments/surveys/edit/reset_to_theme_styles: f9edc3970ec23d6c4d2d7accc292ef3a
environments/surveys/edit/reset_to_theme_styles_main_text: d86fb2213d3b2efbd0361526dc6cb27b
environments/surveys/edit/respect_global_waiting_time: 850e7e64ec890c591b2d07741ef26e11
environments/surveys/edit/respect_global_waiting_time_description: 5235fee102d619cb391c5aa2c75b61be
environments/surveys/edit/response_limit_can_t_be_set_to_0: 278664873ee3b1046dbcb58848efc12a
environments/surveys/edit/response_limit_needs_to_exceed_number_of_received_responses: 9a9c223c0918ded716ddfaa84fbaa8d9
environments/surveys/edit/response_limits_redirections_and_more: e4f1cf94e56ad0e1b08701158d688802
@@ -1487,7 +1487,7 @@ checksums:
environments/surveys/edit/show_advanced_settings: b6f5bbbb84f34e51cd72ccd332e9613e
environments/surveys/edit/show_button: 6b364aac9d7ac71f34a438607c9693bc
environments/surveys/edit/show_language_switch: b6915a7f26d7079f2d4d844d74440413
environments/surveys/edit/show_multiple_times: 05239c532c9c05ef5d2990ba6ce12f60
environments/surveys/edit/show_multiple_times: 5e6e0244c20feca78723c79aa1ddcf62
environments/surveys/edit/show_only_once: 31858baf60ebcf193c7e35d9084af0af
environments/surveys/edit/show_survey_maximum_of: 721ed61b01a9fc8ce4becb72823bb72e
environments/surveys/edit/show_survey_to_users: d5e90fd17babfea978fce826e9df89b0
@@ -1517,12 +1517,13 @@ checksums:
environments/surveys/edit/switch_multi_lanugage_on_to_get_started: d2ca06684af26bd6b5121a4656bb6458
environments/surveys/edit/targeted: ca615f1fc3b490d5a2187b27fb4a2073
environments/surveys/edit/ten_points: a1317b82003859f77fb3138c55450d63
environments/surveys/edit/the_survey_will_be_shown_multiple_times_until_they_respond: 2d8d7d2351bd7533eb3788cce228c654
environments/surveys/edit/the_survey_will_be_shown_once_even_if_person_doesnt_respond: 6062aaa5cf8e58e79b75b6b588ae9598
environments/surveys/edit/the_survey_will_be_shown_multiple_times_until_they_respond: 219b15081cbafaa391e266bd2cc4c9d4
environments/surveys/edit/the_survey_will_be_shown_once_even_if_person_doesnt_respond: c145b7be481ae1fe6f66298d9a5cf838
environments/surveys/edit/then: 5e941fb7dd51a18651fcfb865edd5ba6
environments/surveys/edit/this_action_will_remove_all_the_translations_from_this_survey: 3340c89696f10bdc01b9a1047ff0b987
environments/surveys/edit/this_extension_is_already_added: 201d636539836c95958e28cecd8f3240
environments/surveys/edit/this_file_type_is_not_supported: f365b9a2e05aa062ab0bc1af61f642e2
environments/surveys/edit/this_setting_overwrites_your: 6f980149a5a4adc2cfe3dac4f367e7e5
environments/surveys/edit/three_points: d7f299aec752d7d690ef0ab6373327ae
environments/surveys/edit/times: 5ab156c13df6bfd75c0b17ad0a92c78a
environments/surveys/edit/to_keep_the_placement_over_all_surveys_consistent_you_can: 7a078e6a39d4c30b465137d2b6ef3e67
@@ -1533,7 +1534,7 @@ checksums:
environments/surveys/edit/unlock_targeting_description: 8e315dc41c2849754839a1460643c5fb
environments/surveys/edit/unlock_targeting_title: 6098caf969cac64cd54e217471ae42d4
environments/surveys/edit/unsaved_changes_warning: a164f276c9f7344022aa4640b32abcf9
environments/surveys/edit/until_they_submit_a_response: 2a0fd5dcc6cc40a72ed9b974f22eaf68
environments/surveys/edit/until_they_submit_a_response: c980c520f5b5883ed46f2e1c006082b5
environments/surveys/edit/upgrade_notice_description: 32b66a4f257ad8d38bc38dcc95fe23c4
environments/surveys/edit/upgrade_notice_title: 40866066ebc558ad0c92a4f19f12090c
environments/surveys/edit/upload: 4a6c84aa16db0f4e5697f49b45257bc7
@@ -1541,6 +1542,7 @@ checksums:
environments/surveys/edit/upper_label: 1fa48bce3fade6ffc1a52d9fdddf9e17
environments/surveys/edit/url_filters: e524879d2eb74463d7fd06a7e0f53421
environments/surveys/edit/url_not_supported: af8a753467c617b596aadef1aaaed664
environments/surveys/edit/use_with_caution: 7c35d3ad68dd001e53cbd9d57c96af91
environments/surveys/edit/variable_is_used_in_logic_of_question_please_remove_it_from_logic_first: bd9d9c7cf0be671c4e8cf67e2ae6659e
environments/surveys/edit/variable_is_used_in_quota_please_remove_it_from_quota_first: 0d36e5b2713f5450fe346e0af0aaa29c
environments/surveys/edit/variable_name_is_already_taken_please_choose_another: 6da42fe8733c6379158bce9a176f76d7
@@ -1550,13 +1552,11 @@ checksums:
environments/surveys/edit/variable_used_in_recall_welcome: 60321b2f40ae01cd10f99ed77bb986ba
environments/surveys/edit/verify_email_before_submission: c05d345dc35f2d33839e4cfd72d11eb2
environments/surveys/edit/verify_email_before_submission_description: 434ab3ee6134367513b633a9d4f7d772
environments/surveys/edit/visibility_and_recontact: c27cb4ff3a4262266902a335c3ad5d84
environments/surveys/edit/visibility_and_recontact_description: 2969ab679e1f6111dd96e95cee26e219
environments/surveys/edit/wait: 014d18ade977bf08d75b995076596708
environments/surveys/edit/wait_a_few_seconds_after_the_trigger_before_showing_the_survey: 13d5521cf73be5afeba71f5db5847919
environments/surveys/edit/waiting_time_across_surveys: 5c5a7653d797c86c4008f13a40434ad8
environments/surveys/edit/waiting_time_across_surveys_description: 1bbee2fee49f842056547c336f8fd788
environments/surveys/edit/waiting_period: 21775d12b2cb831134b1f47450eaf1f3
environments/surveys/edit/welcome_message: 986a434e3895c8ee0b267df95cc40051
environments/surveys/edit/when_conditions_match_waiting_time_will_be_ignored_and_survey_shown: e7fe9c56664da4670e52e38656d8705d
environments/surveys/edit/without_a_filter_all_of_your_users_can_be_surveyed: 451990569c61f25d01044cc45b1ce122
environments/surveys/edit/you_have_not_created_a_segment_yet: c6658bd1cee9c5c957c675db044708dd
environments/surveys/edit/you_need_to_have_two_or_more_languages_set_up_in_your_project_to_work_with_translations: b12b28699e02ff9ba69bcbae838ba5da

View File

@@ -19,7 +19,8 @@ export const ENCRYPTION_KEY = env.ENCRYPTION_KEY;
// Other
export const CRON_SECRET = env.CRON_SECRET;
export const DEFAULT_BRAND_COLOR = "#64748b";
export const FB_LOGO_URL = `${WEBAPP_URL}/logo-transparent.png`;
export const FB_LOGO_URL =
"https://s3.eu-central-1.amazonaws.com/listmonk-formbricks/Formbricks-Light-transparent.png";
export const PRIVACY_URL = env.PRIVACY_URL;
export const TERMS_URL = env.TERMS_URL;
@@ -169,7 +170,6 @@ export const AVAILABLE_LOCALES: TUserLocale[] = [
"de-DE",
"pt-BR",
"fr-FR",
"nl-NL",
"zh-Hant-TW",
"pt-PT",
"ro-RO",

View File

@@ -137,7 +137,6 @@ export const appLanguages = [
"ro-RO": "Engleză (SUA)",
"ja-JP": "英語(米国)",
"zh-Hans-CN": "英语(美国)",
"nl-NL": "Engels (VS)",
},
},
{
@@ -152,7 +151,6 @@ export const appLanguages = [
"ro-RO": "Germană",
"ja-JP": "ドイツ語",
"zh-Hans-CN": "德语",
"nl-NL": "Duits",
},
},
{
@@ -167,7 +165,6 @@ export const appLanguages = [
"ro-RO": "Portugheză (Brazilia)",
"ja-JP": "ポルトガル語(ブラジル)",
"zh-Hans-CN": "葡萄牙语(巴西)",
"nl-NL": "Portugees (Brazilië)",
},
},
{
@@ -182,7 +179,6 @@ export const appLanguages = [
"ro-RO": "Franceză",
"ja-JP": "フランス語",
"zh-Hans-CN": "法语",
"nl-NL": "Frans",
},
},
{
@@ -197,7 +193,6 @@ export const appLanguages = [
"ro-RO": "Chineză (Tradicională)",
"ja-JP": "中国語(繁体字)",
"zh-Hans-CN": "繁体中文",
"nl-NL": "Chinees (Traditioneel)",
},
},
{
@@ -212,7 +207,6 @@ export const appLanguages = [
"ro-RO": "Portugheză (Portugalia)",
"ja-JP": "ポルトガル語(ポルトガル)",
"zh-Hans-CN": "葡萄牙语(葡萄牙)",
"nl-NL": "Portugees (Portugal)",
},
},
{
@@ -227,7 +221,6 @@ export const appLanguages = [
"ro-RO": "Română",
"ja-JP": "ルーマニア語",
"zh-Hans-CN": "罗马尼亚语",
"nl-NL": "Roemeens",
},
},
{
@@ -242,7 +235,6 @@ export const appLanguages = [
"ro-RO": "Japoneză",
"ja-JP": "日本語",
"zh-Hans-CN": "日语",
"nl-NL": "Japans",
},
},
{
@@ -257,22 +249,6 @@ export const appLanguages = [
"ro-RO": "Chineză (Simplificată)",
"ja-JP": "中国語(簡体字)",
"zh-Hans-CN": "简体中文",
"nl-NL": "Chinees (Vereenvoudigd)",
},
},
{
code: "nl-NL",
label: {
"en-US": "Dutch",
"de-DE": "Niederländisch",
"pt-BR": "Holandês",
"fr-FR": "Néerlandais",
"zh-Hant-TW": "荷蘭語",
"pt-PT": "Holandês",
"ro-RO": "Olandeză",
"ja-JP": "オランダ語",
"zh-Hans-CN": "荷兰语",
"nl-NL": "Nederlands",
},
},
];

View File

@@ -1,5 +1,5 @@
import { formatDistance, intlFormat } from "date-fns";
import { de, enUS, fr, ja, nl, pt, ptBR, ro, zhCN, zhTW } from "date-fns/locale";
import { de, enUS, fr, ja, pt, ptBR, ro, zhCN, zhTW } from "date-fns/locale";
import { TUserLocale } from "@formbricks/types/user";
export const convertDateString = (dateString: string | null) => {
@@ -91,8 +91,6 @@ const getLocaleForTimeSince = (locale: TUserLocale) => {
return ptBR;
case "fr-FR":
return fr;
case "nl-NL":
return nl;
case "zh-Hant-TW":
return zhTW;
case "pt-PT":

View File

@@ -53,9 +53,9 @@ export const I18nProvider = ({ children, language, defaultLanguage }: I18nProvid
initializeI18n();
}, [locale, defaultLanguage]);
// Don't render children until i18n is ready to prevent race conditions
// Don't render children until i18n is ready to prevent hydration issues
if (!isReady) {
return null;
return <div style={{ visibility: "hidden" }}>{children}</div>;
}
return (

View File

@@ -774,14 +774,14 @@
},
"app-connection": {
"app_connection": "App-Verbindung",
"app_connection_description": "Verbinde deine App oder Website mit Formbricks.",
"app_connection_description": "Verbinde deine App mit Formbricks.",
"cache_update_delay_description": "Wenn du Aktualisierungen an Umfragen, Kontakten, Aktionen oder anderen Daten vornimmst, kann es bis zu 5 Minuten dauern, bis diese Änderungen in deiner lokalen App, die das Formbricks SDK verwendet, angezeigt werden. Diese Verzögerung ist auf eine Einschränkung unseres aktuellen Caching-Systems zurückzuführen. Wir arbeiten aktiv an einer Überarbeitung des Cache und werden in Formbricks 4.0 eine Lösung veröffentlichen.",
"cache_update_delay_title": "Änderungen werden aufgrund von Caching nach 5 Minuten angezeigt",
"environment_id": "Deine Umgebungs-ID",
"environment_id_description": "Diese ID identifiziert eindeutig diese Formbricks Umgebung.",
"formbricks_sdk_connected": "Formbricks SDK ist verbunden",
"formbricks_sdk_not_connected": "Formbricks SDK ist noch nicht verbunden.",
"formbricks_sdk_not_connected_description": "Füge das Formbricks SDK zu deiner Website oder App hinzu, um sie mit Formbricks zu verbinden",
"formbricks_sdk_not_connected_description": "Verbinde deine Website oder App mit Formbricks",
"how_to_setup": "Wie einrichten",
"how_to_setup_description": "Befolge diese Schritte, um das Formbricks Widget in deiner App einzurichten.",
"receiving_data": "Daten werden empfangen 💃🕺",
@@ -800,7 +800,7 @@
"project_deleted_successfully": "Projekt erfolgreich gelöscht",
"project_name_settings_description": "Ändere den Namen deines Projekts.",
"project_name_updated_successfully": "Projektname erfolgreich aktualisiert",
"recontact_waiting_time": "Projektweite Wartezeit zwischen Umfragen",
"recontact_waiting_time": "Wartezeit für erneuten Kontakt",
"recontact_waiting_time_settings_description": "Steuere, wie oft Nutzer in allen App-Umfragen eine Umfrage angezeigt bekommen können.",
"this_action_cannot_be_undone": "Diese Aktion kann nicht rückgängig gemacht werden.",
"wait_x_days_before_showing_next_survey": "Warte X Tage, bevor die nächste Umfrage angezeigt wird:",
@@ -1226,6 +1226,7 @@
"allow_multi_select": "Mehrfachauswahl erlauben",
"allow_multiple_files": "Mehrere Dateien zulassen",
"allow_users_to_select_more_than_one_image": "Erlaube Nutzern, mehr als ein Bild auszuwählen",
"always_show_survey": "Umfrage immer anzeigen",
"and_launch_surveys_in_your_website_or_app": "und Umfragen auf deiner Website oder App starten.",
"animation": "Animation",
"app_survey_description": "Bette eine Umfrage in deine Web-App oder Website ein, um Antworten zu sammeln.",
@@ -1308,7 +1309,8 @@
"custom_hostname": "Benutzerdefinierter Hostname",
"darken_or_lighten_background_of_your_choice": "Hintergrund deiner Wahl abdunkeln oder aufhellen.",
"date_format": "Datumsformat",
"days_before_showing_this_survey_again": "Tage nachdem eine beliebige Umfrage angezeigt wurde, bevor diese Umfrage erscheinen kann.",
"days_before_showing_this_survey_again": "Tage, bevor diese Umfrage erneut angezeigt wird.",
"decide_how_often_people_can_answer_this_survey": "Entscheide, wie oft Leute diese Umfrage beantworten können.",
"delete_choice": "Auswahl löschen",
"disable_the_visibility_of_survey_progress": "Deaktiviere die Sichtbarkeit des Umfragefortschritts.",
"display_an_estimate_of_completion_time_for_survey": "Zeige eine Schätzung der Fertigstellungszeit für die Umfrage an",
@@ -1336,7 +1338,7 @@
"equals_one_of": "Entspricht einem von",
"error_publishing_survey": "Beim Veröffentlichen der Umfrage ist ein Fehler aufgetreten.",
"error_saving_changes": "Fehler beim Speichern der Änderungen",
"even_after_they_submitted_a_response_e_g_feedback_box": "Mehrfachantworten erlauben; weiterhin anzeigen, auch nach einer Antwort (z.B. Feedback-Box).",
"even_after_they_submitted_a_response_e_g_feedback_box": "Sogar nachdem sie eine Antwort eingereicht haben (z.B. Feedback-Box)",
"everyone": "Jeder",
"external_urls_paywall_tooltip": "Bitte aktualisieren, um die externe URL anzupassen. Phishing-Prävention.",
"fallback_missing": "Fehlender Fallback",
@@ -1407,9 +1409,8 @@
"hostname": "Hostname",
"how_funky_do_you_want_your_cards_in_survey_type_derived_surveys": "Wie funky sollen deine Karten in {surveyTypeDerived} Umfragen sein",
"if_you_need_more_please": "Wenn Du mehr brauchst, bitte",
"if_you_really_want_that_answer_ask_until_you_get_it": "Weiterhin anzeigen, wenn ausgelöst, bis eine Antwort abgegeben wird.",
"ignore_global_waiting_time": "Projektweite Wartezeit ignorieren",
"ignore_global_waiting_time_description": "Diese Umfrage kann angezeigt werden, wenn ihre Bedingungen erfüllt sind, auch wenn kürzlich eine andere Umfrage angezeigt wurde.",
"if_you_really_want_that_answer_ask_until_you_get_it": "Wenn Du diese Antwort brauchst, frag so lange, bis Du sie bekommst.",
"ignore_waiting_time_between_surveys": "Wartezeit zwischen Umfragen ignorieren",
"image": "Bild",
"includes_all_of": "Enthält alles von",
"includes_one_of": "Enthält eines von",
@@ -1476,10 +1477,9 @@
"optional": "Optional",
"options": "Optionen",
"override_theme_with_individual_styles_for_this_survey": "Styling für diese Umfrage überschreiben.",
"overwrite_global_waiting_time": "Benutzerdefinierte Wartezeit festlegen",
"overwrite_global_waiting_time_description": "Die Projektkonfiguration nur für diese Umfrage überschreiben.",
"overwrite_placement": "Platzierung überschreiben",
"overwrite_the_global_placement_of_the_survey": "Platzierung für diese Umfrage überschreiben",
"overwrites_waiting_period_between_surveys_to_x_days": "Überschreibt die Wartezeit zwischen Umfragen auf {days} Tag(e).",
"pick_a_background_from_our_library_or_upload_your_own": "Wähle einen Hintergrund aus oder lade deinen eigenen hoch.",
"picture_idx": "Bild {idx}",
"pin_can_only_contain_numbers": "PIN darf nur Zahlen enthalten.",
@@ -1538,8 +1538,7 @@
"range": "Reichweite",
"recall_data": "Daten abrufen",
"recall_information_from": "Information abrufen von ...",
"recontact_options_section": "Optionen zur erneuten Kontaktaufnahme",
"recontact_options_section_description": "Wenn die Wartezeit es erlaubt, wählen Sie aus, wie oft diese Umfrage einer Person angezeigt werden kann.",
"recontact_options": "Optionen zur erneuten Kontaktaufnahme",
"redirect_thank_you_card": "Weiterleitung anlegen",
"redirect_to_url": "Zu URL weiterleiten",
"remove_description": "Beschreibung entfernen",
@@ -1548,8 +1547,6 @@
"required": "Erforderlich",
"reset_to_theme_styles": "Styling zurücksetzen",
"reset_to_theme_styles_main_text": "Bist Du sicher, dass Du das Styling auf die Themenstile zurücksetzen möchtest? Dadurch wird jegliches benutzerdefinierte Styling entfernt.",
"respect_global_waiting_time": "Projektweite Wartezeit verwenden",
"respect_global_waiting_time_description": "Diese Umfrage folgt der in der Projektkonfiguration festgelegten Wartezeit. Sie wird nur angezeigt, wenn in diesem Zeitraum keine andere Umfrage erschienen ist.",
"response_limit_can_t_be_set_to_0": "Das Antwortlimit kann nicht auf 0 gesetzt werden",
"response_limit_needs_to_exceed_number_of_received_responses": "Antwortlimit muss die Anzahl der erhaltenen Antworten ({responseCount}) überschreiten.",
"response_limits_redirections_and_more": "Antwort Limits, Weiterleitungen und mehr.",
@@ -1574,7 +1571,7 @@
"show_advanced_settings": "Erweiterte Einstellungen anzeigen",
"show_button": "Button anzeigen",
"show_language_switch": "Sprachwechsel anzeigen",
"show_multiple_times": "Begrenzte Anzahl von Malen anzeigen",
"show_multiple_times": "Mehrfach anzeigen",
"show_only_once": "Nur einmal anzeigen",
"show_survey_maximum_of": "Umfrage maximal anzeigen von",
"show_survey_to_users": "Umfrage % der Nutzer anzeigen",
@@ -1604,12 +1601,13 @@
"switch_multi_lanugage_on_to_get_started": "Schalte Mehrsprachigkeit ein, um loszulegen 👉",
"targeted": "Gezielt",
"ten_points": "10 Punkte",
"the_survey_will_be_shown_multiple_times_until_they_respond": "Höchstens die angegebene Anzahl von Malen anzeigen oder bis sie antworten (je nachdem, was zuerst eintritt).",
"the_survey_will_be_shown_once_even_if_person_doesnt_respond": "Einmal anzeigen, auch wenn sie nicht antworten.",
"the_survey_will_be_shown_multiple_times_until_they_respond": "Die Umfrage wird mehrmals angezeigt, bis Du antwortest",
"the_survey_will_be_shown_once_even_if_person_doesnt_respond": "Die Umfrage wird einmal angezeigt, auch wenn die Person nicht antwortet.",
"then": "dann",
"this_action_will_remove_all_the_translations_from_this_survey": "Diese Aktion entfernt alle Übersetzungen aus dieser Umfrage.",
"this_extension_is_already_added": "Diese Erweiterung ist bereits hinzugefügt.",
"this_file_type_is_not_supported": "Dieser Dateityp wird nicht unterstützt.",
"this_setting_overwrites_your": "Diese Einstellung überschreibt deine",
"three_points": "3 Punkte",
"times": "Zeiten",
"to_keep_the_placement_over_all_surveys_consistent_you_can": "Um die Platzierung über alle Umfragen hinweg konsistent zu halten, kannst du",
@@ -1620,7 +1618,7 @@
"unlock_targeting_description": "Spezifische Nutzergruppen basierend auf Attributen oder Geräteinformationen ansprechen",
"unlock_targeting_title": "Targeting mit einem höheren Plan freischalten",
"unsaved_changes_warning": "Du hast ungespeicherte Änderungen in deiner Umfrage. Möchtest Du sie speichern, bevor Du gehst?",
"until_they_submit_a_response": "Fragen, bis sie eine Antwort abgeben",
"until_they_submit_a_response": "Bis sie eine Antwort einreichen",
"upgrade_notice_description": "Erstelle mehrsprachige Umfragen und entdecke viele weitere Funktionen",
"upgrade_notice_title": "Schalte mehrsprachige Umfragen mit einem höheren Plan frei",
"upload": "Hochladen",
@@ -1628,6 +1626,7 @@
"upper_label": "Oberes Label",
"url_filters": "URL-Filter",
"url_not_supported": "URL nicht unterstützt",
"use_with_caution": "Mit Vorsicht verwenden",
"variable_is_used_in_logic_of_question_please_remove_it_from_logic_first": "{variable} wird in der Logik der Frage {questionIndex} verwendet. Bitte entferne es zuerst aus der Logik.",
"variable_is_used_in_quota_please_remove_it_from_quota_first": "Variable \"{variableName}\" wird in der \"{quotaName}\" Quote verwendet",
"variable_name_is_already_taken_please_choose_another": "Variablenname ist bereits vergeben, bitte wähle einen anderen.",
@@ -1637,13 +1636,11 @@
"variable_used_in_recall_welcome": "Variable \"{variable}\" wird in der Willkommenskarte abgerufen.",
"verify_email_before_submission": "E-Mail vor dem Absenden überprüfen",
"verify_email_before_submission_description": "Lass nur Leute mit einer echten E-Mail antworten.",
"visibility_and_recontact": "Sichtbarkeit & erneute Kontaktaufnahme",
"visibility_and_recontact_description": "Steuern Sie, wann diese Umfrage erscheinen kann und wie oft sie erneut erscheinen kann.",
"wait": "Warte",
"wait_a_few_seconds_after_the_trigger_before_showing_the_survey": "Warte ein paar Sekunden nach dem Auslöser, bevor Du die Umfrage anzeigst",
"waiting_time_across_surveys": "Projektweite Wartezeit",
"waiting_time_across_surveys_description": "Um Umfragemüdigkeit zu vermeiden, wählen Sie aus, wie diese Umfrage mit der projektweiten Wartezeit interagiert.",
"waiting_period": "Wartezeit",
"welcome_message": "Willkommensnachricht",
"when_conditions_match_waiting_time_will_be_ignored_and_survey_shown": "Wenn die Bedingungen übereinstimmen, wird die Wartezeit ignoriert und die Umfrage angezeigt.",
"without_a_filter_all_of_your_users_can_be_surveyed": "Ohne Filter können alle deine Nutzer befragt werden.",
"you_have_not_created_a_segment_yet": "Du hast noch keinen Segment erstellt.",
"you_need_to_have_two_or_more_languages_set_up_in_your_project_to_work_with_translations": "Du musst zwei oder mehr Sprachen in deinem Projekt einrichten, um mit Übersetzungen zu arbeiten.",

View File

@@ -774,14 +774,14 @@
},
"app-connection": {
"app_connection": "App Connection",
"app_connection_description": "Connect your app or website to Formbricks.",
"app_connection_description": "Connect your app to Formbricks.",
"cache_update_delay_description": "When you make updates to surveys, contacts, actions, or other data, it can take up to 5 minutes for those changes to appear in your local app running the Formbricks SDK. This delay is due to a limitation in our current caching system. Were actively reworking the cache and will release a fix in Formbricks 4.0.",
"cache_update_delay_title": "Changes will be reflected after 5 minutes due to caching",
"environment_id": "Your Environment ID",
"environment_id_description": "This id uniquely identifies this Formbricks environment.",
"formbricks_sdk_connected": "Formbricks SDK is connected",
"formbricks_sdk_not_connected": "Formbricks SDK is not yet connected.",
"formbricks_sdk_not_connected_description": "Add the Formbricks SDK to your website or app to connect it with Formbricks",
"formbricks_sdk_not_connected_description": "Connect your website or app with Formbricks",
"how_to_setup": "How to setup",
"how_to_setup_description": "Follow these steps to setup the Formbricks widget within your app.",
"receiving_data": "Receiving data \uD83D\uDC83\uD83D\uDD7A",
@@ -800,7 +800,7 @@
"project_deleted_successfully": "Project deleted successfully",
"project_name_settings_description": "Change your projects name.",
"project_name_updated_successfully": "Project name updated successfully",
"recontact_waiting_time": "Project-wide Waiting Time Between Surveys",
"recontact_waiting_time": "Recontact Waiting Time",
"recontact_waiting_time_settings_description": "Control how frequently users can be surveyed across all app surveys.",
"this_action_cannot_be_undone": "This action cannot be undone.",
"wait_x_days_before_showing_next_survey": "Wait X days before showing next survey:",
@@ -1226,6 +1226,7 @@
"allow_multi_select": "Allow multi-select",
"allow_multiple_files": "Allow multiple files",
"allow_users_to_select_more_than_one_image": "Allow users to select more than one image",
"always_show_survey": "Always show survey",
"and_launch_surveys_in_your_website_or_app": "and launch surveys in your website or app.",
"animation": "Animation",
"app_survey_description": "Embed a survey in your web app or website to collect responses.",
@@ -1308,7 +1309,8 @@
"custom_hostname": "Custom hostname",
"darken_or_lighten_background_of_your_choice": "Darken or lighten background of your choice.",
"date_format": "Date format",
"days_before_showing_this_survey_again": "days after any survey is shown before this survey can appear.",
"days_before_showing_this_survey_again": "days before showing this survey again.",
"decide_how_often_people_can_answer_this_survey": "Decide how often people can answer this survey.",
"delete_choice": "Delete choice",
"disable_the_visibility_of_survey_progress": "Disable the visibility of survey progress.",
"display_an_estimate_of_completion_time_for_survey": "Display an estimate of completion time for survey",
@@ -1336,7 +1338,7 @@
"equals_one_of": "Equals one of",
"error_publishing_survey": "An error occured while publishing the survey.",
"error_saving_changes": "Error saving changes",
"even_after_they_submitted_a_response_e_g_feedback_box": "Allow multiple responses; continue showing even after a response (e.g., Feedback Box).",
"even_after_they_submitted_a_response_e_g_feedback_box": "Even after they submitted a response (e.g. Feedback Box)",
"everyone": "Everyone",
"external_urls_paywall_tooltip": "Please upgrade to customize external URL. Phishing prevention.",
"fallback_missing": "Fallback missing",
@@ -1407,9 +1409,8 @@
"hostname": "Hostname",
"how_funky_do_you_want_your_cards_in_survey_type_derived_surveys": "How funky do you want your cards in {surveyTypeDerived} Surveys",
"if_you_need_more_please": "If you need more, please",
"if_you_really_want_that_answer_ask_until_you_get_it": "Keep showing whenever triggered until a response is submitted.",
"ignore_global_waiting_time": "Ignore project-wide waiting time",
"ignore_global_waiting_time_description": "This survey can show whenever its conditions are met, even if another survey was shown recently.",
"if_you_really_want_that_answer_ask_until_you_get_it": "If you really want that answer, ask until you get it.",
"ignore_waiting_time_between_surveys": "Ignore waiting time between surveys",
"image": "Image",
"includes_all_of": "Includes all of",
"includes_one_of": "Includes one of",
@@ -1476,10 +1477,9 @@
"optional": "Optional",
"options": "Options",
"override_theme_with_individual_styles_for_this_survey": "Override the theme with individual styles for this survey.",
"overwrite_global_waiting_time": "Set custom waiting time",
"overwrite_global_waiting_time_description": "Override the project configuration for this survey only.",
"overwrite_placement": "Overwrite placement",
"overwrite_the_global_placement_of_the_survey": "Overwrite the global placement of the survey",
"overwrites_waiting_period_between_surveys_to_x_days": "Overwrites waiting period between surveys to {days} day(s).",
"pick_a_background_from_our_library_or_upload_your_own": "Pick a background from our library or upload your own.",
"picture_idx": "Picture {idx}",
"pin_can_only_contain_numbers": "PIN can only contain numbers.",
@@ -1538,8 +1538,7 @@
"range": "Range",
"recall_data": "Recall data",
"recall_information_from": "Recall information from ...",
"recontact_options_section": "Recontact options",
"recontact_options_section_description": "If the waiting time allows, choose how often this survey can be shown to a person.",
"recontact_options": "Recontact Options",
"redirect_thank_you_card": "Redirect thank you card",
"redirect_to_url": "Redirect to Url",
"remove_description": "Remove description",
@@ -1548,8 +1547,6 @@
"required": "Required",
"reset_to_theme_styles": "Reset to theme styles",
"reset_to_theme_styles_main_text": "Are you sure you want to reset the styling to the theme styles? This will remove all custom styling.",
"respect_global_waiting_time": "Use project-wide waiting time",
"respect_global_waiting_time_description": "This survey follows the waiting time set in project configuration. It only shows if no other survey has appeared during that period.",
"response_limit_can_t_be_set_to_0": "Response limit can't be set to 0",
"response_limit_needs_to_exceed_number_of_received_responses": "Response limit needs to exceed number of received responses ({responseCount}).",
"response_limits_redirections_and_more": "Response limits, redirections and more.",
@@ -1574,7 +1571,7 @@
"show_advanced_settings": "Show Advanced settings",
"show_button": "Show Button",
"show_language_switch": "Show language switch",
"show_multiple_times": "Show a limited number of times",
"show_multiple_times": "Show multiple times",
"show_only_once": "Show only once",
"show_survey_maximum_of": "Show survey maximum of",
"show_survey_to_users": "Show survey to % of users",
@@ -1604,12 +1601,13 @@
"switch_multi_lanugage_on_to_get_started": "Switch multi-lanugage on to get started \uD83D\uDC49",
"targeted": "Targeted",
"ten_points": "10 points",
"the_survey_will_be_shown_multiple_times_until_they_respond": "Show at most the specified number of times, or until they respond (whichever comes first).",
"the_survey_will_be_shown_once_even_if_person_doesnt_respond": "Show a single time, even if they don't respond.",
"the_survey_will_be_shown_multiple_times_until_they_respond": "The survey will be shown multiple times until they respond",
"the_survey_will_be_shown_once_even_if_person_doesnt_respond": "The survey will be shown once, even if person doesn't respond.",
"then": "Then",
"this_action_will_remove_all_the_translations_from_this_survey": "This action will remove all the translations from this survey.",
"this_extension_is_already_added": "This extension is already added.",
"this_file_type_is_not_supported": "This file type is not supported.",
"this_setting_overwrites_your": "This setting overwrites your",
"three_points": "3 points",
"times": "times",
"to_keep_the_placement_over_all_surveys_consistent_you_can": "To keep the placement over all surveys consistent, you can",
@@ -1620,7 +1618,7 @@
"unlock_targeting_description": "Target specific user groups based on attributes or device information",
"unlock_targeting_title": "Unlock targeting with a higher plan",
"unsaved_changes_warning": "You have unsaved changes in your survey. Would you like to save them before leaving?",
"until_they_submit_a_response": "Ask until they submit a response",
"until_they_submit_a_response": "Until they submit a response",
"upgrade_notice_description": "Create multilingual surveys and unlock many more features",
"upgrade_notice_title": "Unlock multi-language surveys with a higher plan",
"upload": "Upload",
@@ -1628,6 +1626,7 @@
"upper_label": "Upper Label",
"url_filters": "URL Filters",
"url_not_supported": "URL not supported",
"use_with_caution": "Use with caution",
"variable_is_used_in_logic_of_question_please_remove_it_from_logic_first": "{variable} is used in logic of question {questionIndex}. Please remove it from logic first.",
"variable_is_used_in_quota_please_remove_it_from_quota_first": "Variable \"{variableName}\" is being used in \"{quotaName}\" quota",
"variable_name_is_already_taken_please_choose_another": "Variable name is already taken, please choose another.",
@@ -1637,13 +1636,11 @@
"variable_used_in_recall_welcome": "Variable \"{variable}\" is being recalled in Welcome Card.",
"verify_email_before_submission": "Verify email before submission",
"verify_email_before_submission_description": "Only let people with a real email respond.",
"visibility_and_recontact": "Visibility & Recontact",
"visibility_and_recontact_description": "Control when this survey can appear and how often it can reappear.",
"wait": "Wait",
"wait_a_few_seconds_after_the_trigger_before_showing_the_survey": "Wait a few seconds after the trigger before showing the survey",
"waiting_time_across_surveys": "Project-wide waiting time",
"waiting_time_across_surveys_description": "To prevent survey fatigue, choose how this survey interacts with the project-wide waiting time.",
"waiting_period": "waiting period",
"welcome_message": "Welcome message",
"when_conditions_match_waiting_time_will_be_ignored_and_survey_shown": "When conditions match, waiting time will be ignored and survey shown.",
"without_a_filter_all_of_your_users_can_be_surveyed": "Without a filter, all of your users can be surveyed.",
"you_have_not_created_a_segment_yet": "You have not created a segment yet",
"you_need_to_have_two_or_more_languages_set_up_in_your_project_to_work_with_translations": "You need to have two or more languages set up in your project to work with translations.",

View File

@@ -774,14 +774,14 @@
},
"app-connection": {
"app_connection": "Connexion d'une application",
"app_connection_description": "Connectez votre application ou site web à Formbricks.",
"app_connection_description": "Vous pouvez connecter une application à Formbricks.",
"cache_update_delay_description": "Lorsque vous effectuez des mises à jour sur les sondages, contacts, actions ou autres données, cela peut prendre jusqu'à 5 minutes pour que ces modifications apparaissent dans votre application locale exécutant le SDK Formbricks. Ce délai est dû à une limitation de notre système de mise en cache actuel. Nous retravaillons activement le cache et publierons une correction dans Formbricks 4.0.",
"cache_update_delay_title": "Les modifications seront reflétées après 5 minutes en raison de la mise en cache",
"environment_id": "Identifiant de votre environnement",
"environment_id_description": "Cet identifiant unique est attribué à votre environnement Formbricks.",
"formbricks_sdk_connected": "Le SDK Formbricks est connecté",
"formbricks_sdk_not_connected": "Le SDK Formbricks n'est pas encore connecté.",
"formbricks_sdk_not_connected_description": "Ajoutez le SDK Formbricks à votre site web ou application pour le connecter à Formbricks",
"formbricks_sdk_not_connected_description": "Connectez votre site Web ou votre application à Formbricks.",
"how_to_setup": "Comment configurer",
"how_to_setup_description": "Suivez ces étapes pour configurer le widget Formbricks dans votre application.",
"receiving_data": "Réception des données 💃🕺",
@@ -800,7 +800,7 @@
"project_deleted_successfully": "Projet supprimé avec succès",
"project_name_settings_description": "Vous pouvez modifier le nom de votre projet.",
"project_name_updated_successfully": "Le nom du projet a été mis à jour avec succès.",
"recontact_waiting_time": "Temps d'attente entre les enquêtes à l'échelle du projet",
"recontact_waiting_time": "Délai avant nouveau contact",
"recontact_waiting_time_settings_description": "Vous pouvez contrôler la fréquence à laquelle les utilisateurs sont sollicités pour répondre aux enquêtes.",
"this_action_cannot_be_undone": "Cette action ne peut pas être annulée.",
"wait_x_days_before_showing_next_survey": "Nombre de jours devant s'écouler avant une nouvelle sollicitation :",
@@ -1226,6 +1226,7 @@
"allow_multi_select": "Autoriser la sélection multiple",
"allow_multiple_files": "Autoriser plusieurs fichiers",
"allow_users_to_select_more_than_one_image": "Permettre aux utilisateurs de sélectionner plusieurs images",
"always_show_survey": "Afficher toujours l'enquête",
"and_launch_surveys_in_your_website_or_app": "et lancez des enquêtes sur votre site web ou votre application.",
"animation": "Animation",
"app_survey_description": "Intégrez une enquête dans votre application web ou votre site web pour collecter des réponses.",
@@ -1308,7 +1309,8 @@
"custom_hostname": "Nom d'hôte personnalisé",
"darken_or_lighten_background_of_your_choice": "Assombrir ou éclaircir l'arrière-plan de votre choix.",
"date_format": "Format de date",
"days_before_showing_this_survey_again": "jours après qu'une enquête soit affichée avant que cette enquête puisse apparaître.",
"days_before_showing_this_survey_again": "jours avant de montrer à nouveau cette enquête.",
"decide_how_often_people_can_answer_this_survey": "Décidez à quelle fréquence les gens peuvent répondre à cette enquête.",
"delete_choice": "Supprimer l'option",
"disable_the_visibility_of_survey_progress": "Désactiver la visibilité de la progression du sondage.",
"display_an_estimate_of_completion_time_for_survey": "Afficher une estimation du temps de complétion pour l'enquête.",
@@ -1336,7 +1338,7 @@
"equals_one_of": "Égal à l'un de",
"error_publishing_survey": "Une erreur est survenue lors de la publication de l'enquête.",
"error_saving_changes": "Erreur lors de l'enregistrement des modifications",
"even_after_they_submitted_a_response_e_g_feedback_box": "Autoriser plusieurs réponses; continuer à afficher même après une réponse (par exemple, boîte de commentaires).",
"even_after_they_submitted_a_response_e_g_feedback_box": "Même après avoir soumis une réponse (par exemple, la boîte de feedback)",
"everyone": "Tout le monde",
"external_urls_paywall_tooltip": "Veuillez passer à la version supérieure pour personnaliser l'URL externe. Prévention contre l'hameçonnage.",
"fallback_missing": "Fallback manquant",
@@ -1407,9 +1409,8 @@
"hostname": "Nom d'hôte",
"how_funky_do_you_want_your_cards_in_survey_type_derived_surveys": "À quel point voulez-vous que vos cartes soient funky dans les enquêtes {surveyTypeDerived}",
"if_you_need_more_please": "Si vous en avez besoin de plus, s'il vous plaît",
"if_you_really_want_that_answer_ask_until_you_get_it": "Continuer à afficher à chaque déclenchement jusqu'à ce qu'une réponse soit soumise.",
"ignore_global_waiting_time": "Ignorer le temps d'attente à l'échelle du projet",
"ignore_global_waiting_time_description": "Cette enquête peut s'afficher chaque fois que ses conditions sont remplies, même si une autre enquête a été affichée récemment.",
"if_you_really_want_that_answer_ask_until_you_get_it": "Si tu veux vraiment cette réponse, demande jusqu'à ce que tu l'obtiennes.",
"ignore_waiting_time_between_surveys": "Ignorer le temps d'attente entre les enquêtes",
"image": "Image",
"includes_all_of": "Comprend tous les",
"includes_one_of": "Comprend un de",
@@ -1476,10 +1477,9 @@
"optional": "Optionnel",
"options": "Options",
"override_theme_with_individual_styles_for_this_survey": "Override the theme with individual styles for this survey.",
"overwrite_global_waiting_time": "Définir un temps d'attente personnalisé",
"overwrite_global_waiting_time_description": "Remplacer la configuration du projet pour cette enquête uniquement.",
"overwrite_placement": "Surcharge de placement",
"overwrite_the_global_placement_of_the_survey": "Surcharger le placement global de l'enquête",
"overwrites_waiting_period_between_surveys_to_x_days": "Remplace la période d'attente entre les enquêtes par {days} jour(s).",
"pick_a_background_from_our_library_or_upload_your_own": "Choisissez un arrière-plan dans notre bibliothèque ou téléchargez le vôtre.",
"picture_idx": "Image {idx}",
"pin_can_only_contain_numbers": "Le code PIN ne peut contenir que des chiffres.",
@@ -1538,8 +1538,7 @@
"range": "Plage",
"recall_data": "Rappel des données",
"recall_information_from": "Rappeler les informations de ...",
"recontact_options_section": "Options de recontact",
"recontact_options_section_description": "Si le temps d'attente le permet, choisissez la fréquence à laquelle cette enquête peut être présentée à une personne.",
"recontact_options": "Options de recontact",
"redirect_thank_you_card": "Carte de remerciement de redirection",
"redirect_to_url": "Rediriger vers l'URL",
"remove_description": "Supprimer la description",
@@ -1548,8 +1547,6 @@
"required": "Requis",
"reset_to_theme_styles": "Réinitialiser aux styles de thème",
"reset_to_theme_styles_main_text": "Êtes-vous sûr de vouloir réinitialiser le style aux styles du thème ? Cela supprimera tous les styles personnalisés.",
"respect_global_waiting_time": "Utiliser le temps d'attente à l'échelle du projet",
"respect_global_waiting_time_description": "Cette enquête respecte le temps d'attente défini dans la configuration du projet. Elle ne s'affiche que si aucune autre enquête n'est apparue pendant cette période.",
"response_limit_can_t_be_set_to_0": "La limite de réponse ne peut pas être fixée à 0.",
"response_limit_needs_to_exceed_number_of_received_responses": "La limite de réponses doit dépasser le nombre de réponses reçues ({responseCount}).",
"response_limits_redirections_and_more": "Limites de réponse, redirections et plus.",
@@ -1574,7 +1571,7 @@
"show_advanced_settings": "Afficher les paramètres avancés",
"show_button": "Afficher le bouton",
"show_language_switch": "Afficher le changement de langue",
"show_multiple_times": "Afficher un nombre limité de fois",
"show_multiple_times": "Afficher plusieurs fois",
"show_only_once": "Afficher une seule fois",
"show_survey_maximum_of": "Afficher le maximum du sondage de",
"show_survey_to_users": "Afficher l'enquête à % des utilisateurs",
@@ -1604,12 +1601,13 @@
"switch_multi_lanugage_on_to_get_started": "Activez le multilingue pour commencer 👉",
"targeted": "Ciblé",
"ten_points": "10 points",
"the_survey_will_be_shown_multiple_times_until_they_respond": "Afficher au maximum le nombre de fois spécifié, ou jusqu'à ce qu'ils répondent (selon la première éventualité).",
"the_survey_will_be_shown_once_even_if_person_doesnt_respond": "Afficher une seule fois, même si la personne ne répond pas.",
"the_survey_will_be_shown_multiple_times_until_they_respond": "L'enquête sera affichée plusieurs fois jusqu'à ce qu'ils répondent.",
"the_survey_will_be_shown_once_even_if_person_doesnt_respond": "L'enquête sera affichée une fois, même si la personne ne répond pas.",
"then": "Alors",
"this_action_will_remove_all_the_translations_from_this_survey": "Cette action supprimera toutes les traductions de cette enquête.",
"this_extension_is_already_added": "Cette extension est déjà ajoutée.",
"this_file_type_is_not_supported": "Ce type de fichier n'est pas pris en charge.",
"this_setting_overwrites_your": "Ce paramètre écrase votre",
"three_points": "3 points",
"times": "fois",
"to_keep_the_placement_over_all_surveys_consistent_you_can": "Pour maintenir la cohérence du placement sur tous les sondages, vous pouvez",
@@ -1620,7 +1618,7 @@
"unlock_targeting_description": "Cibler des groupes d'utilisateurs spécifiques en fonction des attributs ou des informations sur l'appareil",
"unlock_targeting_title": "Débloquez le ciblage avec un plan supérieur.",
"unsaved_changes_warning": "Vous avez des modifications non enregistrées dans votre enquête. Souhaitez-vous les enregistrer avant de partir ?",
"until_they_submit_a_response": "Demander jusqu'à ce qu'ils soumettent une réponse",
"until_they_submit_a_response": "Jusqu'à ce qu'ils soumettent une réponse",
"upgrade_notice_description": "Créez des sondages multilingues et débloquez de nombreuses autres fonctionnalités",
"upgrade_notice_title": "Débloquez les sondages multilingues avec un plan supérieur",
"upload": "Télécharger",
@@ -1628,6 +1626,7 @@
"upper_label": "Étiquette supérieure",
"url_filters": "Filtres d'URL",
"url_not_supported": "URL non supportée",
"use_with_caution": "À utiliser avec précaution",
"variable_is_used_in_logic_of_question_please_remove_it_from_logic_first": "{variable} est utilisé dans la logique de la question {questionIndex}. Veuillez d'abord le supprimer de la logique.",
"variable_is_used_in_quota_please_remove_it_from_quota_first": "La variable \"{variableName}\" est utilisée dans le quota \"{quotaName}\"",
"variable_name_is_already_taken_please_choose_another": "Le nom de la variable est déjà pris, veuillez en choisir un autre.",
@@ -1637,13 +1636,11 @@
"variable_used_in_recall_welcome": "La variable \"{variable}\" est rappelée dans la carte de bienvenue.",
"verify_email_before_submission": "Vérifiez l'email avant la soumission",
"verify_email_before_submission_description": "Ne laissez répondre que les personnes ayant une véritable adresse e-mail.",
"visibility_and_recontact": "Visibilité et recontact",
"visibility_and_recontact_description": "Contrôlez quand cette enquête peut apparaître et à quelle fréquence elle peut réapparaître.",
"wait": "Attendre",
"wait_a_few_seconds_after_the_trigger_before_showing_the_survey": "Attendez quelques secondes après le déclencheur avant de montrer l'enquête.",
"waiting_time_across_surveys": "Temps d'attente à l'échelle du projet",
"waiting_time_across_surveys_description": "Pour éviter la lassitude face aux enquêtes, choisissez comment cette enquête interagit avec le temps d'attente à l'échelle du projet.",
"waiting_period": "période d'attente",
"welcome_message": "Message de bienvenue",
"when_conditions_match_waiting_time_will_be_ignored_and_survey_shown": "Lorsque les conditions correspondent, le temps d'attente sera ignoré et l'enquête sera affichée.",
"without_a_filter_all_of_your_users_can_be_surveyed": "Sans filtre, tous vos utilisateurs peuvent être sondés.",
"you_have_not_created_a_segment_yet": "Tu n'as pas encore créé de segment.",
"you_need_to_have_two_or_more_languages_set_up_in_your_project_to_work_with_translations": "Vous devez avoir deux langues ou plus configurées dans votre projet pour travailler avec des traductions.",

View File

@@ -774,14 +774,14 @@
},
"app-connection": {
"app_connection": "アプリ接続",
"app_connection_description": "アプリやウェブサイトをFormbricksに接続します。",
"app_connection_description": "あなたのアプリをFormbricksに接続します。",
"cache_update_delay_description": "フォーム・連絡先・アクションなどを更新してから、Formbricks SDK を実行中のローカルアプリに反映されるまで最大5分かかる場合があります。これは現在のキャッシュ方式の制限によるものです。私たちはキャッシュを改修中で、Formbricks 4.0 で修正を提供予定です。",
"cache_update_delay_title": "キャッシュのため変更の反映に最大5分かかります",
"environment_id": "あなたのEnvironmentId",
"environment_id_description": "このIDはこのFormbricks環境を一意に識別します。",
"formbricks_sdk_connected": "Formbricks SDK は接続されています",
"formbricks_sdk_not_connected": "Formbricks SDK はまだ接続されていません。",
"formbricks_sdk_not_connected_description": "FormbricksSDKをウェブサイトやアプリに追加して、Formbricks接続してください",
"formbricks_sdk_not_connected_description": "あなたのウェブサイトまたはアプリをFormbricks接続してください",
"how_to_setup": "セットアップ方法",
"how_to_setup_description": "アプリ内でFormbricksウィジェットを設定する手順に従ってください。",
"receiving_data": "データ受信中 💃🕺",
@@ -800,7 +800,7 @@
"project_deleted_successfully": "プロジェクトを削除しました",
"project_name_settings_description": "プロジェクト名を変更します。",
"project_name_updated_successfully": "プロジェクト名を更新しました",
"recontact_waiting_time": "フォーム間のプロジェクト全体の待機時間",
"recontact_waiting_time": "再接触の待機時間",
"recontact_waiting_time_settings_description": "アプリ内フォーム全体で、ユーザーにどの頻度で表示するかを制御します。",
"this_action_cannot_be_undone": "この操作は取り消せません。",
"wait_x_days_before_showing_next_survey": "次のフォームを表示するまでの待機日数:",
@@ -1226,6 +1226,7 @@
"allow_multi_select": "複数選択を許可",
"allow_multiple_files": "複数のファイルを許可",
"allow_users_to_select_more_than_one_image": "ユーザーが複数の画像を選択できるようにする",
"always_show_survey": "常にフォームを表示",
"and_launch_surveys_in_your_website_or_app": "ウェブサイトやアプリでフォームを公開できます。",
"animation": "アニメーション",
"app_survey_description": "回答を収集するために、ウェブアプリまたはウェブサイトにフォームを埋め込みます。",
@@ -1308,7 +1309,8 @@
"custom_hostname": "カスタムホスト名",
"darken_or_lighten_background_of_your_choice": "お好みの背景を暗くしたり明るくしたりします。",
"date_format": "日付形式",
"days_before_showing_this_survey_again": "任意のフォームが表示された後、このフォームが再表示されるまでの日数。",
"days_before_showing_this_survey_again": "日後にこのフォームを再度表示します。",
"decide_how_often_people_can_answer_this_survey": "このフォームに人々が何回回答できるかを決定します。",
"delete_choice": "選択肢を削除",
"disable_the_visibility_of_survey_progress": "フォームの進捗状況の表示を無効にする。",
"display_an_estimate_of_completion_time_for_survey": "フォームの完了時間の目安を表示",
@@ -1336,7 +1338,7 @@
"equals_one_of": "のいずれかと等しい",
"error_publishing_survey": "フォームの公開中にエラーが発生しました。",
"error_saving_changes": "変更の保存中にエラーが発生しました",
"even_after_they_submitted_a_response_e_g_feedback_box": "複数の回答を許可;回答後も表示を継続(例:フィードボックス)",
"even_after_they_submitted_a_response_e_g_feedback_box": "回答を送信した後でも(例:フィードバックボックス)",
"everyone": "全員",
"external_urls_paywall_tooltip": "外部 URL をカスタマイズするにはアップグレードしてください 。 フィッシング防止 。",
"fallback_missing": "フォールバックがありません",
@@ -1407,9 +1409,8 @@
"hostname": "ホスト名",
"how_funky_do_you_want_your_cards_in_survey_type_derived_surveys": "{surveyTypeDerived} フォームのカードをどれくらいユニークにしますか",
"if_you_need_more_please": "さらに必要な場合は、",
"if_you_really_want_that_answer_ask_until_you_get_it": "回答が提出されるまで、トリガーされるたびに表示し続けます。",
"ignore_global_waiting_time": "プロジェクト全体の待機時間を無視する",
"ignore_global_waiting_time_description": "このフォームは、最近別のフォームが表示されていても、条件が満たされればいつでも表示できます。",
"if_you_really_want_that_answer_ask_until_you_get_it": "本当にその回答が欲しいなら、それを得るまで尋ねてください。",
"ignore_waiting_time_between_surveys": "フォーム間の待機時間を無視する",
"image": "画像",
"includes_all_of": "のすべてを含む",
"includes_one_of": "のいずれかを含む",
@@ -1476,10 +1477,9 @@
"optional": "オプション",
"options": "オプション",
"override_theme_with_individual_styles_for_this_survey": "このフォームの個別のスタイルでテーマを上書きします。",
"overwrite_global_waiting_time": "カスタム待機時間を設定する",
"overwrite_global_waiting_time_description": "このフォームのみプロジェクト設定を上書きします。",
"overwrite_placement": "配置を上書き",
"overwrite_the_global_placement_of_the_survey": "フォームのグローバルな配置を上書き",
"overwrites_waiting_period_between_surveys_to_x_days": "フォーム間の待機期間を {days} 日に上書きします。",
"pick_a_background_from_our_library_or_upload_your_own": "ライブラリから背景を選択するか、独自にアップロードしてください。",
"picture_idx": "写真 {idx}",
"pin_can_only_contain_numbers": "PINは数字のみでなければなりません。",
@@ -1538,8 +1538,7 @@
"range": "範囲",
"recall_data": "データを呼び出す",
"recall_information_from": "... からの情報を呼び戻す",
"recontact_options_section": "再接触オプション",
"recontact_options_section_description": "待機時間が許可する場合、このフォームを一人の人にどれくらいの頻度で表示できるかを選択します。",
"recontact_options": "再接触オプション",
"redirect_thank_you_card": "サンクスクカードをリダイレクト",
"redirect_to_url": "URLにリダイレクト",
"remove_description": "説明を削除",
@@ -1548,8 +1547,6 @@
"required": "必須",
"reset_to_theme_styles": "テーマのスタイルにリセット",
"reset_to_theme_styles_main_text": "スタイルをテーマのスタイルにリセットしてもよろしいですか?これにより、すべてのカスタムスタイルが削除されます。",
"respect_global_waiting_time": "プロジェクト全体の待機時間を使用する",
"respect_global_waiting_time_description": "このフォームはプロジェクト設定で設定された待機時間に従います。その期間中に他のフォームが表示されていない場合にのみ表示されます。",
"response_limit_can_t_be_set_to_0": "回答数の上限を0に設定することはできません",
"response_limit_needs_to_exceed_number_of_received_responses": "回答数の上限は、受信済みの回答数 ({responseCount}) を超える必要があります。",
"response_limits_redirections_and_more": "回答数の上限、リダイレクトなど。",
@@ -1574,7 +1571,7 @@
"show_advanced_settings": "詳細設定を表示",
"show_button": "ボタンを表示",
"show_language_switch": "言語切り替えを表示",
"show_multiple_times": "限られた回数表示する",
"show_multiple_times": "複数回表示",
"show_only_once": "一度だけ表示",
"show_survey_maximum_of": "フォームの最大表示回数",
"show_survey_to_users": "ユーザーの {percentage}% にフォームを表示",
@@ -1604,12 +1601,13 @@
"switch_multi_lanugage_on_to_get_started": "始めるには多言語をオンにしてください 👉",
"targeted": "ターゲット",
"ten_points": "10点",
"the_survey_will_be_shown_multiple_times_until_they_respond": "指定された回数まで、または回答があるまで表示します(どちらか先に達した方)。",
"the_survey_will_be_shown_once_even_if_person_doesnt_respond": "回答なくても1回だけ表示します。",
"the_survey_will_be_shown_multiple_times_until_they_respond": "回答するまで複数回フォームが表示されます",
"the_survey_will_be_shown_once_even_if_person_doesnt_respond": "回答なくても、一度だけフォームが表示されます。",
"then": "その後",
"this_action_will_remove_all_the_translations_from_this_survey": "このアクションは、このフォームからすべての翻訳を削除します。",
"this_extension_is_already_added": "この拡張機能はすでに追加されています。",
"this_file_type_is_not_supported": "このファイルタイプはサポートされていません。",
"this_setting_overwrites_your": "この設定はあなたの",
"three_points": "3点",
"times": "回",
"to_keep_the_placement_over_all_surveys_consistent_you_can": "すべてのフォームの配置を一貫させるために、",
@@ -1620,7 +1618,7 @@
"unlock_targeting_description": "属性またはデバイス情報に基づいて、特定のユーザーグループをターゲットにします",
"unlock_targeting_title": "上位プランでターゲティングをアンロック",
"unsaved_changes_warning": "フォームに未保存の変更があります。離れる前に保存しますか?",
"until_they_submit_a_response": "回答が提出されるまで質問する",
"until_they_submit_a_response": "回答を送信するまで",
"upgrade_notice_description": "多言語フォームを作成し、さらに多くの機能をアンロック",
"upgrade_notice_title": "上位プランで多言語フォームをアンロック",
"upload": "アップロード",
@@ -1628,6 +1626,7 @@
"upper_label": "上限ラベル",
"url_filters": "URLフィルター",
"url_not_supported": "URLはサポートされていません",
"use_with_caution": "注意して使用",
"variable_is_used_in_logic_of_question_please_remove_it_from_logic_first": "{variable} は質問 {questionIndex} のロジックで使用されています。まず、ロジックから削除してください。",
"variable_is_used_in_quota_please_remove_it_from_quota_first": "変数 \"{variableName}\" は \"{quotaName}\" クォータ で使用されています",
"variable_name_is_already_taken_please_choose_another": "変数名はすでに使用されています。別の名前を選択してください。",
@@ -1637,13 +1636,11 @@
"variable_used_in_recall_welcome": "変数 \"{variable}\" が ウェルカム カード で 呼び出され て います。",
"verify_email_before_submission": "送信前にメールアドレスを認証",
"verify_email_before_submission_description": "有効なメールアドレスを持つ人のみが回答できるようにする",
"visibility_and_recontact": "表示と再接触",
"visibility_and_recontact_description": "このフォームがいつ表示され、どのくらいの頻度で再表示できるかをコントロールします。",
"wait": "待つ",
"wait_a_few_seconds_after_the_trigger_before_showing_the_survey": "トリガーから数秒待ってからフォームを表示します",
"waiting_time_across_surveys": "プロジェクト全体の待機間",
"waiting_time_across_surveys_description": "フォーム疲れを防ぐため、このフォームがプロジェクト全体の待機時間とどのように相互作用するかを選択します。",
"waiting_period": "待機間",
"welcome_message": "ウェルカムメッセージ",
"when_conditions_match_waiting_time_will_be_ignored_and_survey_shown": "条件が一致すると、待機時間は無視され、フォームが表示されます。",
"without_a_filter_all_of_your_users_can_be_surveyed": "フィルターがなければ、すべてのユーザーがフォームに回答できます。",
"you_have_not_created_a_segment_yet": "まだセグメントを作成していません",
"you_need_to_have_two_or_more_languages_set_up_in_your_project_to_work_with_translations": "翻訳を操作するには、プロジェクトで2つ以上の言語を設定する必要があります。",

File diff suppressed because it is too large Load Diff

View File

@@ -774,14 +774,14 @@
},
"app-connection": {
"app_connection": "Conexão do App",
"app_connection_description": "Conecte seu app ou site ao Formbricks.",
"app_connection_description": "Conecte seu app ao Formbricks.",
"cache_update_delay_description": "Quando você faz atualizações em pesquisas, contatos, ações ou outros dados, pode levar até 5 minutos para que essas mudanças apareçam no seu app local rodando o SDK do Formbricks. Esse atraso é devido a uma limitação no nosso sistema de cache atual. Estamos ativamente retrabalhando o cache e planejamos lançar uma correção no Formbricks 4.0.",
"cache_update_delay_title": "As mudanças serão refletidas após 5 minutos devido ao cache",
"environment_id": "Seu Id do Ambiente",
"environment_id_description": "Este ID identifica exclusivamente este ambiente do Formbricks.",
"formbricks_sdk_connected": "O SDK do Formbricks está conectado",
"formbricks_sdk_not_connected": "O SDK do Formbricks ainda não está conectado.",
"formbricks_sdk_not_connected_description": "Adicione o SDK do Formbricks ao seu site ou app para conectá-lo ao Formbricks",
"formbricks_sdk_not_connected_description": "Conecte seu site ou app com o Formbricks",
"how_to_setup": "Como configurar",
"how_to_setup_description": "Siga esses passos para configurar o widget do Formbricks no seu app.",
"receiving_data": "Recebendo dados 💃🕺",
@@ -800,7 +800,7 @@
"project_deleted_successfully": "Projeto deletado com sucesso",
"project_name_settings_description": "Mude o nome do seu projeto.",
"project_name_updated_successfully": "Nome do projeto atualizado com sucesso",
"recontact_waiting_time": "Tempo de espera entre pesquisas em todo o projeto",
"recontact_waiting_time": "Tempo de Espera para Recontato",
"recontact_waiting_time_settings_description": "Controle com que frequência os usuários podem ser pesquisados em todas as pesquisas do app.",
"this_action_cannot_be_undone": "Essa ação não pode ser desfeita.",
"wait_x_days_before_showing_next_survey": "Espere X dias antes de mostrar a próxima pesquisa:",
@@ -1226,6 +1226,7 @@
"allow_multi_select": "Permitir seleção múltipla",
"allow_multiple_files": "Permitir vários arquivos",
"allow_users_to_select_more_than_one_image": "Permitir que os usuários selecionem mais de uma imagem",
"always_show_survey": "Mostrar pesquisa sempre",
"and_launch_surveys_in_your_website_or_app": "e lançar pesquisas no seu site ou app.",
"animation": "animação",
"app_survey_description": "Embuta uma pesquisa no seu app ou site para coletar respostas.",
@@ -1308,7 +1309,8 @@
"custom_hostname": "Hostname personalizado",
"darken_or_lighten_background_of_your_choice": "Escureça ou clareie o fundo da sua escolha.",
"date_format": "Formato de data",
"days_before_showing_this_survey_again": "dias após qualquer pesquisa ser mostrada antes que esta pesquisa possa aparecer.",
"days_before_showing_this_survey_again": "dias antes de mostrar essa pesquisa de novo.",
"decide_how_often_people_can_answer_this_survey": "Decida com que frequência as pessoas podem responder a essa pesquisa.",
"delete_choice": "Deletar opção",
"disable_the_visibility_of_survey_progress": "Desativar a visibilidade do progresso da pesquisa.",
"display_an_estimate_of_completion_time_for_survey": "Mostrar uma estimativa de tempo de conclusão da pesquisa",
@@ -1336,7 +1338,7 @@
"equals_one_of": "É igual a um de",
"error_publishing_survey": "Ocorreu um erro ao publicar a pesquisa.",
"error_saving_changes": "Erro ao salvar alterações",
"even_after_they_submitted_a_response_e_g_feedback_box": "Permitir múltiplas respostas; continuar mostrando mesmo após uma resposta (ex.: caixa de feedback).",
"even_after_they_submitted_a_response_e_g_feedback_box": "Mesmo depois de eles enviarem uma resposta (por exemplo, Caixa de Feedback)",
"everyone": "Todo mundo",
"external_urls_paywall_tooltip": "Por favor, faça upgrade para personalizar o URL externo. Prevenção de phishing.",
"fallback_missing": "Faltando alternativa",
@@ -1407,9 +1409,8 @@
"hostname": "nome do host",
"how_funky_do_you_want_your_cards_in_survey_type_derived_surveys": "Quão descoladas você quer suas cartas em Pesquisas {surveyTypeDerived}",
"if_you_need_more_please": "Se você precisar de mais, por favor",
"if_you_really_want_that_answer_ask_until_you_get_it": "Continuar mostrando sempre que acionada até que uma resposta seja enviada.",
"ignore_global_waiting_time": "Ignorar tempo de espera do projeto",
"ignore_global_waiting_time_description": "Esta pesquisa pode ser mostrada sempre que suas condições forem atendidas, mesmo que outra pesquisa tenha sido mostrada recentemente.",
"if_you_really_want_that_answer_ask_until_you_get_it": "Se você realmente quer essa resposta, pergunte até conseguir.",
"ignore_waiting_time_between_surveys": "Ignorar tempo de espera entre pesquisas",
"image": "imagem",
"includes_all_of": "Inclui tudo de",
"includes_one_of": "Inclui um de",
@@ -1476,10 +1477,9 @@
"optional": "Opcional",
"options": "Opções",
"override_theme_with_individual_styles_for_this_survey": "Substitua o tema com estilos individuais para essa pesquisa.",
"overwrite_global_waiting_time": "Definir tempo de espera personalizado",
"overwrite_global_waiting_time_description": "Substituir a configuração do projeto apenas para esta pesquisa.",
"overwrite_placement": "Substituir posicionamento",
"overwrite_the_global_placement_of_the_survey": "Substituir a posição global da pesquisa",
"overwrites_waiting_period_between_surveys_to_x_days": "Substitui o período de espera entre as pesquisas para {days} dia(s).",
"pick_a_background_from_our_library_or_upload_your_own": "Escolha um fundo da nossa biblioteca ou faça upload do seu próprio.",
"picture_idx": "Imagem {idx}",
"pin_can_only_contain_numbers": "O PIN só pode conter números.",
@@ -1538,8 +1538,7 @@
"range": "alcance",
"recall_data": "Lembrar dados",
"recall_information_from": "Recuperar informações de ...",
"recontact_options_section": "Opções de recontato",
"recontact_options_section_description": "Se o tempo de espera permitir, escolha com que frequência esta pesquisa pode ser mostrada a uma pessoa.",
"recontact_options": "Opções de Recontato",
"redirect_thank_you_card": "Redirecionar cartão de agradecimento",
"redirect_to_url": "Redirecionar para URL",
"remove_description": "Remover descrição",
@@ -1548,8 +1547,6 @@
"required": "Obrigatório",
"reset_to_theme_styles": "Redefinir para estilos do tema",
"reset_to_theme_styles_main_text": "Tem certeza de que quer redefinir o estilo para o tema padrão? Isso vai remover todas as personalizações.",
"respect_global_waiting_time": "Usar tempo de espera do projeto",
"respect_global_waiting_time_description": "Esta pesquisa segue o tempo de espera definido na configuração do projeto. Ela só é mostrada se nenhuma outra pesquisa tiver aparecido durante esse período.",
"response_limit_can_t_be_set_to_0": "Limite de resposta não pode ser 0",
"response_limit_needs_to_exceed_number_of_received_responses": "O limite de respostas precisa exceder o número de respostas recebidas ({responseCount}).",
"response_limits_redirections_and_more": "Limites de resposta, redirecionamentos e mais.",
@@ -1574,7 +1571,7 @@
"show_advanced_settings": "Mostrar configurações avançadas",
"show_button": "Mostrar Botão",
"show_language_switch": "Mostrar troca de idioma",
"show_multiple_times": "Mostrar um número limitado de vezes",
"show_multiple_times": "Mostrar várias vezes",
"show_only_once": "Mostrar só uma vez",
"show_survey_maximum_of": "Mostrar no máximo",
"show_survey_to_users": "Mostrar pesquisa para % dos usuários",
@@ -1604,12 +1601,13 @@
"switch_multi_lanugage_on_to_get_started": "Ative o modo multilíngue para começar 👉",
"targeted": "direcionado",
"ten_points": "10 pontos",
"the_survey_will_be_shown_multiple_times_until_they_respond": "Mostrar no máximo o número especificado de vezes, ou até que respondam (o que ocorrer primeiro).",
"the_survey_will_be_shown_once_even_if_person_doesnt_respond": "Mostrar uma única vez, mesmo que não respondam.",
"the_survey_will_be_shown_multiple_times_until_they_respond": "A pesquisa vai ser mostrada várias vezes até eles responderem",
"the_survey_will_be_shown_once_even_if_person_doesnt_respond": "A pesquisa será mostrada uma vez, mesmo se a pessoa não responder.",
"then": "Então",
"this_action_will_remove_all_the_translations_from_this_survey": "Essa ação vai remover todas as traduções dessa pesquisa.",
"this_extension_is_already_added": "Essa extensão já foi adicionada.",
"this_file_type_is_not_supported": "Esse tipo de arquivo não é suportado.",
"this_setting_overwrites_your": "Essa configuração sobrescreve seu",
"three_points": "3 pontos",
"times": "times",
"to_keep_the_placement_over_all_surveys_consistent_you_can": "Para manter a colocação consistente em todas as pesquisas, você pode",
@@ -1620,7 +1618,7 @@
"unlock_targeting_description": "Direcione grupos específicos de usuários com base em atributos ou informações do dispositivo",
"unlock_targeting_title": "Desbloqueie o direcionamento com um plano superior",
"unsaved_changes_warning": "Você tem alterações não salvas na sua pesquisa. Quer salvar antes de sair?",
"until_they_submit_a_response": "Perguntar até que enviem uma resposta",
"until_they_submit_a_response": "Até eles enviarem uma resposta",
"upgrade_notice_description": "Crie pesquisas multilíngues e desbloqueie muitas outras funcionalidades",
"upgrade_notice_title": "Desbloqueie pesquisas multilíngues com um plano superior",
"upload": "Enviar",
@@ -1628,6 +1626,7 @@
"upper_label": "Etiqueta Superior",
"url_filters": "Filtros de URL",
"url_not_supported": "URL não suportada",
"use_with_caution": "Use com cuidado",
"variable_is_used_in_logic_of_question_please_remove_it_from_logic_first": "{variable} está sendo usado na lógica da pergunta {questionIndex}. Por favor, remova-o da lógica primeiro.",
"variable_is_used_in_quota_please_remove_it_from_quota_first": "Variável \"{variableName}\" está sendo usada na cota \"{quotaName}\"",
"variable_name_is_already_taken_please_choose_another": "O nome da variável já está em uso, por favor escolha outro.",
@@ -1637,13 +1636,11 @@
"variable_used_in_recall_welcome": "Variável \"{variable}\" está sendo recordada no Card de Boas-Vindas.",
"verify_email_before_submission": "Verifique o e-mail antes de enviar",
"verify_email_before_submission_description": "Deixe só quem tem um email real responder.",
"visibility_and_recontact": "Visibilidade e recontato",
"visibility_and_recontact_description": "Controle quando esta pesquisa pode aparecer e com que frequência pode reaparecer.",
"wait": "Espera",
"wait_a_few_seconds_after_the_trigger_before_showing_the_survey": "Espera alguns segundos depois do gatilho antes de mostrar a pesquisa",
"waiting_time_across_surveys": "Tempo de espera em todo o projeto",
"waiting_time_across_surveys_description": "Para evitar fadiga de pesquisas, escolha como esta pesquisa interage com o tempo de espera em todo o projeto.",
"waiting_period": "período de espera",
"welcome_message": "Mensagem de boas-vindas",
"when_conditions_match_waiting_time_will_be_ignored_and_survey_shown": "Quando as condições forem atendidas, o tempo de espera será ignorado e a pesquisa será exibida.",
"without_a_filter_all_of_your_users_can_be_surveyed": "Sem um filtro, todos os seus usuários podem ser pesquisados.",
"you_have_not_created_a_segment_yet": "Você ainda não criou um segmento.",
"you_need_to_have_two_or_more_languages_set_up_in_your_project_to_work_with_translations": "Você precisa ter dois ou mais idiomas configurados no seu projeto para trabalhar com traduções.",

View File

@@ -774,14 +774,14 @@
},
"app-connection": {
"app_connection": "Conexão de aplicação",
"app_connection_description": "Ligue a sua aplicação ou website ao Formbricks.",
"app_connection_description": "Conecte a sua aplicação ao Formbricks",
"cache_update_delay_description": "Quando fizer atualizações para inquéritos, contactos, ações ou outros dados, pode demorar até 5 minutos para que essas alterações apareçam na sua aplicação local a correr o SDK do Formbricks. Este atraso deve-se a uma limitação no nosso atual sistema de cache. Estamos a trabalhar ativamente na reformulação da cache e lançaremos uma correção no Formbricks 4.0.",
"cache_update_delay_title": "As alterações serão refletidas após 5 minutos devido ao armazenamento em cache.",
"environment_id": "O seu identificador",
"environment_id_description": "Este id identifica o seu espaço Formbricks.",
"formbricks_sdk_connected": "O SDK do Formbricks está conectado",
"formbricks_sdk_not_connected": "O Formbricks SDK ainda não está conectado",
"formbricks_sdk_not_connected_description": "Adicione o SDK do Formbricks ao seu website ou aplicação para o ligar ao Formbricks",
"formbricks_sdk_not_connected_description": "Ligue o seu website ou aplicação ao Formbricks",
"how_to_setup": "Como configurar",
"how_to_setup_description": "Siga estes passos para configurar o widget Formbricks na sua aplicação.",
"receiving_data": "A receber dados 💃🕺",
@@ -800,7 +800,7 @@
"project_deleted_successfully": "Projeto eliminado com sucesso",
"project_name_settings_description": "Altere o nome dos seus projetos.",
"project_name_updated_successfully": "Nome do projeto atualizado com sucesso",
"recontact_waiting_time": "Tempo de Espera Entre Inquéritos em Todo o Projeto",
"recontact_waiting_time": "Tempo de espera de recontacto",
"recontact_waiting_time_settings_description": "Controle a regularidade com que os utilizadores podem ser inquiridos em todos os inquéritos da aplicação.",
"this_action_cannot_be_undone": "Esta ação não pode ser desfeita.",
"wait_x_days_before_showing_next_survey": "Dias de espera:",
@@ -1226,6 +1226,7 @@
"allow_multi_select": "Permitir seleção múltipla",
"allow_multiple_files": "Permitir vários ficheiros",
"allow_users_to_select_more_than_one_image": "Permitir aos utilizadores selecionar mais do que uma imagem",
"always_show_survey": "Mostrar sempre o inquérito",
"and_launch_surveys_in_your_website_or_app": "e lance inquéritos no seu site ou aplicação.",
"animation": "Animação",
"app_survey_description": "Incorpore um inquérito na sua aplicação web ou site para recolher respostas.",
@@ -1308,7 +1309,8 @@
"custom_hostname": "Nome do host personalizado",
"darken_or_lighten_background_of_your_choice": "Escurecer ou clarear o fundo da sua escolha.",
"date_format": "Formato da data",
"days_before_showing_this_survey_again": "dias após qualquer inquérito ser mostrado antes que este inquérito possa aparecer.",
"days_before_showing_this_survey_again": "dias antes de mostrar este inquérito novamente.",
"decide_how_often_people_can_answer_this_survey": "Decida com que frequência as pessoas podem responder a este inquérito.",
"delete_choice": "Eliminar escolha",
"disable_the_visibility_of_survey_progress": "Desativar a visibilidade do progresso da pesquisa.",
"display_an_estimate_of_completion_time_for_survey": "Mostrar uma estimativa do tempo de conclusão do inquérito",
@@ -1336,7 +1338,7 @@
"equals_one_of": "Igual a um de",
"error_publishing_survey": "Ocorreu um erro ao publicar o questionário.",
"error_saving_changes": "Erro ao guardar alterações",
"even_after_they_submitted_a_response_e_g_feedback_box": "Permitir múltiplas respostas; continuar a mostrar mesmo após uma resposta (por exemplo, Caixa de Feedback).",
"even_after_they_submitted_a_response_e_g_feedback_box": "Mesmo depois de terem enviado uma resposta (por exemplo, Caixa de Feedback)",
"everyone": "Todos",
"external_urls_paywall_tooltip": "Por favor, atualize para personalizar o URL externo. Prevenção contra phishing.",
"fallback_missing": "Substituição em falta",
@@ -1407,9 +1409,8 @@
"hostname": "Nome do host",
"how_funky_do_you_want_your_cards_in_survey_type_derived_surveys": "Quão extravagantes quer os seus cartões em Inquéritos {surveyTypeDerived}",
"if_you_need_more_please": "Se precisar de mais, por favor",
"if_you_really_want_that_answer_ask_until_you_get_it": "Continuar a mostrar sempre que acionado até que uma resposta seja submetida.",
"ignore_global_waiting_time": "Ignorar tempo de espera de todo o projeto",
"ignore_global_waiting_time_description": "Este inquérito pode ser mostrado sempre que as suas condições forem cumpridas, mesmo que outro inquérito tenha sido mostrado recentemente.",
"if_you_really_want_that_answer_ask_until_you_get_it": "Se realmente quiser essa resposta, pergunte até obtê-la.",
"ignore_waiting_time_between_surveys": "Ignorar tempo de espera entre inquéritos",
"image": "Imagem",
"includes_all_of": "Inclui todos de",
"includes_one_of": "Inclui um de",
@@ -1476,10 +1477,9 @@
"optional": "Opcional",
"options": "Opções",
"override_theme_with_individual_styles_for_this_survey": "Substituir o tema com estilos individuais para este inquérito.",
"overwrite_global_waiting_time": "Definir tempo de espera personalizado",
"overwrite_global_waiting_time_description": "Substituir a configuração do projeto apenas para este inquérito.",
"overwrite_placement": "Substituir colocação",
"overwrite_the_global_placement_of_the_survey": "Substituir a colocação global do inquérito",
"overwrites_waiting_period_between_surveys_to_x_days": "Substitui o período de espera entre inquéritos para {days} dia(s).",
"pick_a_background_from_our_library_or_upload_your_own": "Escolha um fundo da nossa biblioteca ou carregue o seu próprio.",
"picture_idx": "Imagem {idx}",
"pin_can_only_contain_numbers": "O PIN só pode conter números.",
@@ -1538,8 +1538,7 @@
"range": "Intervalo",
"recall_data": "Recuperar dados",
"recall_information_from": "Recordar informação de ...",
"recontact_options_section": "Opções de recontacto",
"recontact_options_section_description": "Se o tempo de espera permitir, escolha com que frequência este inquérito pode ser mostrado a uma pessoa.",
"recontact_options": "Opções de Recontacto",
"redirect_thank_you_card": "Redirecionar cartão de agradecimento",
"redirect_to_url": "Redirecionar para Url",
"remove_description": "Remover descrição",
@@ -1548,8 +1547,6 @@
"required": "Obrigatório",
"reset_to_theme_styles": "Repor para estilos do tema",
"reset_to_theme_styles_main_text": "Tem a certeza de que deseja repor o estilo para os estilos do tema? Isto irá remover todos os estilos personalizados.",
"respect_global_waiting_time": "Usar tempo de espera de todo o projeto",
"respect_global_waiting_time_description": "Este inquérito segue o tempo de espera definido na configuração do projeto. Só é mostrado se nenhum outro inquérito tiver aparecido durante esse período.",
"response_limit_can_t_be_set_to_0": "O limite de respostas não pode ser definido como 0",
"response_limit_needs_to_exceed_number_of_received_responses": "O limite de respostas precisa exceder o número de respostas recebidas ({responseCount}).",
"response_limits_redirections_and_more": "Limites de resposta, redirecionamentos e mais.",
@@ -1574,7 +1571,7 @@
"show_advanced_settings": "Mostrar definições avançadas",
"show_button": "Mostrar Botão",
"show_language_switch": "Mostrar alternador de idioma",
"show_multiple_times": "Mostrar um número limitado de vezes",
"show_multiple_times": "Mostrar várias vezes",
"show_only_once": "Mostrar apenas uma vez",
"show_survey_maximum_of": "Mostrar inquérito máximo de",
"show_survey_to_users": "Mostrar inquérito a % dos utilizadores",
@@ -1604,12 +1601,13 @@
"switch_multi_lanugage_on_to_get_started": "Ative o modo multilingue para começar 👉",
"targeted": "Alvo",
"ten_points": "10 pontos",
"the_survey_will_be_shown_multiple_times_until_they_respond": "Mostrar no máximo o número especificado de vezes, ou até que respondam (o que ocorrer primeiro).",
"the_survey_will_be_shown_once_even_if_person_doesnt_respond": "Mostrar uma única vez, mesmo que não respondam.",
"the_survey_will_be_shown_multiple_times_until_they_respond": "O inquérito será mostrado várias vezes até que respondam",
"the_survey_will_be_shown_once_even_if_person_doesnt_respond": "O inquérito será mostrado uma vez, mesmo que a pessoa não responda.",
"then": "Então",
"this_action_will_remove_all_the_translations_from_this_survey": "Esta ação irá remover todas as traduções deste inquérito.",
"this_extension_is_already_added": "Esta extensão já está adicionada.",
"this_file_type_is_not_supported": "Este tipo de ficheiro não é suportado.",
"this_setting_overwrites_your": "Esta configuração substitui o seu",
"three_points": "3 pontos",
"times": "tempos",
"to_keep_the_placement_over_all_surveys_consistent_you_can": "Para manter a colocação consistente em todos os questionários, pode",
@@ -1620,7 +1618,7 @@
"unlock_targeting_description": "Alvo de grupos de utilizadores específicos com base em atributos ou informações do dispositivo",
"unlock_targeting_title": "Desbloqueie a segmentação com um plano superior",
"unsaved_changes_warning": "Tem alterações não guardadas no seu inquérito. Gostaria de as guardar antes de sair?",
"until_they_submit_a_response": "Perguntar até que submetam uma resposta",
"until_they_submit_a_response": "Até que enviem uma resposta",
"upgrade_notice_description": "Crie inquéritos multilingues e desbloqueie muitas mais funcionalidades",
"upgrade_notice_title": "Desbloqueie inquéritos multilingues com um plano superior",
"upload": "Carregar",
@@ -1628,6 +1626,7 @@
"upper_label": "Etiqueta Superior",
"url_filters": "Filtros de URL",
"url_not_supported": "URL não suportado",
"use_with_caution": "Usar com cautela",
"variable_is_used_in_logic_of_question_please_remove_it_from_logic_first": "{variable} é usada na lógica da pergunta {questionIndex}. Por favor, remova-a da lógica primeiro.",
"variable_is_used_in_quota_please_remove_it_from_quota_first": "Variável \"{variableName}\" está a ser utilizada na quota \"{quotaName}\"",
"variable_name_is_already_taken_please_choose_another": "O nome da variável já está em uso, por favor escolha outro.",
@@ -1637,13 +1636,11 @@
"variable_used_in_recall_welcome": "Variável \"{variable}\" está a ser recordada no cartão de boas-vindas.",
"verify_email_before_submission": "Verificar email antes da submissão",
"verify_email_before_submission_description": "Permitir apenas que pessoas com um email real respondam.",
"visibility_and_recontact": "Visibilidade e Recontacto",
"visibility_and_recontact_description": "Controlar quando este inquérito pode aparecer e com que frequência pode reaparecer.",
"wait": "Aguardar",
"wait_a_few_seconds_after_the_trigger_before_showing_the_survey": "Aguarde alguns segundos após o gatilho antes de mostrar o inquérito",
"waiting_time_across_surveys": "Tempo de espera em todo o projeto",
"waiting_time_across_surveys_description": "Para evitar a fadiga de inquéritos, escolha como este inquérito interage com o tempo de espera em todo o projeto.",
"waiting_period": "período de espera",
"welcome_message": "Mensagem de boas-vindas",
"when_conditions_match_waiting_time_will_be_ignored_and_survey_shown": "Quando as condições corresponderem, o tempo de espera será ignorado e o inquérito será mostrado.",
"without_a_filter_all_of_your_users_can_be_surveyed": "Sem um filtro, todos os seus utilizadores podem ser pesquisados.",
"you_have_not_created_a_segment_yet": "Ainda não criou um segmento",
"you_need_to_have_two_or_more_languages_set_up_in_your_project_to_work_with_translations": "Precisa de ter duas ou mais línguas configuradas no seu projeto para trabalhar com traduções.",

View File

@@ -774,14 +774,14 @@
},
"app-connection": {
"app_connection": "Conectare aplicație",
"app_connection_description": "Conectează-ți aplicația sau site-ul la Formbricks.",
"app_connection_description": "Conectează aplicația ta la Formbricks.",
"cache_update_delay_description": "Când faci actualizări la sondaje, contacte, acțiuni sau alte date, poate dura până la 5 minute pentru ca aceste modificări să apară în aplicația locală care rulează SDK Formbricks. Această întârziere se datorează unei limitări în sistemul nostru actual de caching. Revedem activ cache-ul și vom lansa o soluție în Formbricks 4.0.",
"cache_update_delay_title": "Modificările vor fi reflectate după 5 minute datorită memorării în cache",
"environment_id": "ID-ul mediului tău",
"environment_id_description": "Acest id identifică în mod unic acest mediu Formbricks.",
"formbricks_sdk_connected": "SDK Formbricks este conectat",
"formbricks_sdk_not_connected": "Formbricks SDK nu este încă conectat.",
"formbricks_sdk_not_connected_description": "Adaugă SDK-ul Formbricks pe site-ul sau în aplicația ta pentru a-l conecta la Formbricks.",
"formbricks_sdk_not_connected_description": "Conectează-ți site-ul sau aplicația cu Formbricks",
"how_to_setup": "Cum să configurezi",
"how_to_setup_description": "Urmează acești pași pentru a configura widget-ul Formbricks în aplicația ta.",
"receiving_data": "Recepționare date 💃🕺",
@@ -800,7 +800,7 @@
"project_deleted_successfully": "Proiect șters cu succes!",
"project_name_settings_description": "Schimbați numele proiectului.",
"project_name_updated_successfully": "Numele proiectului actualizat cu succes",
"recontact_waiting_time": "Timp de așteptare la nivel de proiect între sondaje",
"recontact_waiting_time": "Timp de așteptare până la recontactare",
"recontact_waiting_time_settings_description": "Controlează cât de des pot fi utilizatorii chestionați în toate sondajele din aplicație.",
"this_action_cannot_be_undone": "Această acțiune nu poate fi anulată.",
"wait_x_days_before_showing_next_survey": "Așteaptă X zile înainte de a afișa următorul sondaj:",
@@ -1226,6 +1226,7 @@
"allow_multi_select": "Permite selectare multiplă",
"allow_multiple_files": "Permite fișiere multiple",
"allow_users_to_select_more_than_one_image": "Permite utilizatorilor să selecteze mai mult de o imagine",
"always_show_survey": "Arată întotdeauna sondajul",
"and_launch_surveys_in_your_website_or_app": "și lansați chestionare pe site-ul sau în aplicația dvs.",
"animation": "Animație",
"app_survey_description": "Incorporați un chestionar în aplicația web sau pe site-ul dvs. pentru a colecta răspunsuri.",
@@ -1308,7 +1309,8 @@
"custom_hostname": "Gazdă personalizată",
"darken_or_lighten_background_of_your_choice": "Întunecați sau luminați fundalul după preferințe.",
"date_format": "Format dată",
"days_before_showing_this_survey_again": "zile după afișarea oricărui sondaj înainte ca acest sondaj să poată apărea din nou.",
"days_before_showing_this_survey_again": "zile înainte de a afișa din nou acest sondaj.",
"decide_how_often_people_can_answer_this_survey": "Decide cât de des pot răspunde oamenii la acest sondaj",
"delete_choice": "Șterge alegerea",
"disable_the_visibility_of_survey_progress": "Dezactivați vizibilitatea progresului sondajului",
"display_an_estimate_of_completion_time_for_survey": "Afișează o estimare a timpului de finalizare pentru sondaj",
@@ -1336,7 +1338,7 @@
"equals_one_of": "Egal unu dintre",
"error_publishing_survey": "A apărut o eroare în timpul publicării sondajului.",
"error_saving_changes": "Eroare la salvarea modificărilor",
"even_after_they_submitted_a_response_e_g_feedback_box": "Permite răspunsuri multiple; continuă afișarea chiar și după un răspuns (de exemplu, Caseta de Feedback).",
"even_after_they_submitted_a_response_e_g_feedback_box": "Chiar și după ce au furnizat un răspuns (de ex. Cutia de Feedback)",
"everyone": "Toată lumea",
"external_urls_paywall_tooltip": "Vă rugăm să faceți upgrade pentru a personaliza URL-ul extern. Prevenire phishing.",
"fallback_missing": "Rezerva lipsă",
@@ -1407,9 +1409,8 @@
"hostname": "Nume gazdă",
"how_funky_do_you_want_your_cards_in_survey_type_derived_surveys": "Cât de funky doriți să fie cardurile dumneavoastră în sondajele de tip {surveyTypeDerived}",
"if_you_need_more_please": "Dacă aveți nevoie de mai multe, vă rugăm să",
"if_you_really_want_that_answer_ask_until_you_get_it": "Continuă afișarea ori de câte ori este declanșat până când se trimite un răspuns.",
"ignore_global_waiting_time": "Ignoră timpul de așteptare la nivel de proiect",
"ignore_global_waiting_time_description": "Acest sondaj poate fi afișat ori de câte ori condițiile sale sunt îndeplinite, chiar dacă un alt sondaj a fost afișat recent.",
"if_you_really_want_that_answer_ask_until_you_get_it": "Dacă într-adevăr îți dorești acel răspuns, întreabă până îl primești.",
"ignore_waiting_time_between_surveys": "Ignoră perioada de așteptare între sondaje",
"image": "Imagine",
"includes_all_of": "Include toate\",\"contextDescription\":\"Part of a survey completion screen referencing conditions met when all items are included\"}",
"includes_one_of": "Include una dintre",
@@ -1476,10 +1477,9 @@
"optional": "Opțional",
"options": "Opțiuni",
"override_theme_with_individual_styles_for_this_survey": "Suprascrie tema cu stiluri individuale pentru acest sondaj.",
"overwrite_global_waiting_time": "Setează un timp de așteptare personalizat",
"overwrite_global_waiting_time_description": "Suprascrie configurația proiectului doar pentru acest sondaj.",
"overwrite_placement": "Suprascriere amplasare",
"overwrite_the_global_placement_of_the_survey": "Suprascrie amplasarea globală a sondajului",
"overwrites_waiting_period_between_surveys_to_x_days": "Suprascrie perioada de așteptare dintre sondaje la {days} zi(le).",
"pick_a_background_from_our_library_or_upload_your_own": "Alege un fundal din biblioteca noastră sau încarcă unul propriu.",
"picture_idx": "Poză {idx}",
"pin_can_only_contain_numbers": "PIN-ul poate conține doar numere.",
@@ -1538,8 +1538,7 @@
"range": "Interval",
"recall_data": "Reamintiți datele",
"recall_information_from": "Reamintiți informațiile din ...",
"recontact_options_section": "Opțiuni de recontactare",
"recontact_options_section_description": "Dacă timpul de așteptare permite, alege cât de des poate fi afișat acest sondaj unei persoane.",
"recontact_options": "Opțiuni de recontactare",
"redirect_thank_you_card": "Redirecționează cardul de mulțumire",
"redirect_to_url": "Redirecționează către URL",
"remove_description": "Eliminați descrierea",
@@ -1548,8 +1547,6 @@
"required": "Obligatoriu",
"reset_to_theme_styles": "Resetare la stilurile temei",
"reset_to_theme_styles_main_text": "Sigur doriți să resetați stilul la stilurile de temă? Acest lucru va elimina toate stilizările personalizate.",
"respect_global_waiting_time": "Folosește timpul de așteptare la nivel de proiect",
"respect_global_waiting_time_description": "Acest sondaj respectă timpul de așteptare setat în configurația proiectului. Este afișat doar dacă niciun alt sondaj nu a apărut în acea perioadă.",
"response_limit_can_t_be_set_to_0": "Limitul de răspunsuri nu poate fi setat la 0",
"response_limit_needs_to_exceed_number_of_received_responses": "Limita răspunsurilor trebuie să depășească numărul de răspunsuri primite ({responseCount}).",
"response_limits_redirections_and_more": "Limite de răspunsuri, redirecționări și altele.",
@@ -1604,12 +1601,13 @@
"switch_multi_lanugage_on_to_get_started": "Comutați pe modul multilingv pentru a începe 👉",
"targeted": "Ţintite",
"ten_points": "10 puncte",
"the_survey_will_be_shown_multiple_times_until_they_respond": "Afișează de cel mult numărul specificat de ori sau până când răspund (oricare dintre acestea survine prima).",
"the_survey_will_be_shown_once_even_if_person_doesnt_respond": "Afișează o singură dată, chiar dacă persoana nu răspunde.",
"the_survey_will_be_shown_multiple_times_until_they_respond": "Sondajul va fi afișat de mai multe ori până când vor răspunde",
"the_survey_will_be_shown_once_even_if_person_doesnt_respond": "Sondajul va fi afișat o singură dată, chiar dacă persoana nu răspunde.",
"then": "Apoi",
"this_action_will_remove_all_the_translations_from_this_survey": "Această acțiune va elimina toate traducerile din acest sondaj.",
"this_extension_is_already_added": "Această extensie este deja adăugată.",
"this_file_type_is_not_supported": "Acest tip de fișier nu este acceptat.",
"this_setting_overwrites_your": "Această setare suprascrie",
"three_points": "3 puncte",
"times": "ori",
"to_keep_the_placement_over_all_surveys_consistent_you_can": "Pentru a menține amplasarea consecventă pentru toate sondajele, puteți",
@@ -1620,7 +1618,7 @@
"unlock_targeting_description": "Vizează grupuri specifice de utilizatori pe baza atributelor sau a informațiilor despre dispozitiv",
"unlock_targeting_title": "Deblocați țintirea cu un plan superior",
"unsaved_changes_warning": "Aveți modificări nesalvate în sondajul dumneavoastră. Doriți să le salvați înainte de a pleca?",
"until_they_submit_a_response": "Întreabă până când trimit un răspuns",
"until_they_submit_a_response": "Până când vor furniza un răspuns",
"upgrade_notice_description": "Creați sondaje multilingve și deblocați multe alte caracteristici",
"upgrade_notice_title": "Deblocați sondajele multilingve cu un plan superior",
"upload": "Încărcați",
@@ -1628,6 +1626,7 @@
"upper_label": "Etichetă superioară",
"url_filters": "Filtre URL",
"url_not_supported": "URL nesuportat",
"use_with_caution": "Folosește cu precauție",
"variable_is_used_in_logic_of_question_please_remove_it_from_logic_first": "{variable} este folosit în logica întrebării {questionIndex}. Vă rugăm să-l eliminați din logică mai întâi.",
"variable_is_used_in_quota_please_remove_it_from_quota_first": "Variabila \"{variableName}\" este folosită în cota \"{quotaName}\"",
"variable_name_is_already_taken_please_choose_another": "Numele variabilei este deja utilizat, vă rugăm să alegeți altul.",
@@ -1637,13 +1636,11 @@
"variable_used_in_recall_welcome": "Variabila \"{variable}\" este reamintită în cardul de bun venit.",
"verify_email_before_submission": "Verifică emailul înainte de trimitere",
"verify_email_before_submission_description": "Permite doar persoanelor cu un email real să răspundă.",
"visibility_and_recontact": "Vizibilitate și recontactare",
"visibility_and_recontact_description": "Controlează când poate apărea acest sondaj și cât de des poate reapărea.",
"wait": "Așteptați",
"wait_a_few_seconds_after_the_trigger_before_showing_the_survey": "Așteptați câteva secunde după declanșare înainte de a afișa sondajul",
"waiting_time_across_surveys": "Timp de așteptare la nivel de proiect",
"waiting_time_across_surveys_description": "Pentru a preveni oboseala cauzată de sondaje, alege cum interacționează acest sondaj cu timpul de așteptare la nivel de proiect.",
"waiting_period": "perioada de așteptare",
"welcome_message": "Mesaj de bun venit",
"when_conditions_match_waiting_time_will_be_ignored_and_survey_shown": "Când condițiile se potrivesc, timpul de așteptare va fi ignorat și sondajul va fi afișat.",
"without_a_filter_all_of_your_users_can_be_surveyed": "Fără un filtru, toți utilizatorii pot fi chestionați.",
"you_have_not_created_a_segment_yet": "Nu ai creat încă un segment",
"you_need_to_have_two_or_more_languages_set_up_in_your_project_to_work_with_translations": "Trebuie să aveți două sau mai multe limbi configurate în proiectul dvs. pentru a lucra cu traducerile.",

View File

@@ -774,14 +774,14 @@
},
"app-connection": {
"app_connection": "应用程序 连接",
"app_connection_description": "将您的应用或网站连接到 Formbricks。",
"app_connection_description": "连接 您 的 应用 与 Formbricks。",
"cache_update_delay_description": "当 你 对 调查 、 联系人 、 操作 或 其他 数据 进行 更新 时 可能 需要 最多 5 分钟 更改 才能 显示 在 你 本地 运行 Formbricks SDK 的 应用程序 中 。 这个 延迟 是 由于 我们 当前 缓存 系统 的 限制 。 我们 正在 积极 重新设计 缓存 并 将 在 Formbricks 4.0 中 发布 修复 。",
"cache_update_delay_title": "更改 将 在 5 分钟 后 由于 缓存 而 显示",
"environment_id": "你的 环境 ID",
"environment_id_description": "这个 id 独特地 标识 这个 Formbricks 环境。",
"formbricks_sdk_connected": "Formbricks SDK 已连接",
"formbricks_sdk_not_connected": "Formbricks SDK 尚未连接。",
"formbricks_sdk_not_connected_description": "将 Formbricks SDK 添加到您的网站或应用,以将其连接到 Formbricks",
"formbricks_sdk_not_connected_description": "连接 您 的 网站 或 应用 与 Formbricks",
"how_to_setup": "如何设置",
"how_to_setup_description": "遵循这些步骤在你的应用中设置 Formbricks 小部件。",
"receiving_data": "接收 数据 💃🕺",
@@ -800,7 +800,7 @@
"project_deleted_successfully": "项目 删除 成功",
"project_name_settings_description": "更改 您 的 项目 名称。",
"project_name_updated_successfully": "项目 名称 更新 成功",
"recontact_waiting_time": "项目范围内的调查等待时间",
"recontact_waiting_time": "再联系 等待 时间",
"recontact_waiting_time_settings_description": "控制用户可以通过所有应用程序 调查 的 频率。",
"this_action_cannot_be_undone": "此 操作 无法 撤消。",
"wait_x_days_before_showing_next_survey": "等待 X 天后再显示下一个 调查:",
@@ -1226,6 +1226,7 @@
"allow_multi_select": "允许 多选",
"allow_multiple_files": "允许 多 个 文件",
"allow_users_to_select_more_than_one_image": "允许 用户 选择 多于 一个 图片",
"always_show_survey": "始终 显示 调查",
"and_launch_surveys_in_your_website_or_app": "并 在 你 的 网站 或 应用 中 启动 问卷 。",
"animation": "动画",
"app_survey_description": "在 你的 网络 应用 或 网站 中 嵌入 问卷 收集 反馈 。",
@@ -1308,7 +1309,8 @@
"custom_hostname": "自 定 义 主 机 名",
"darken_or_lighten_background_of_your_choice": "根据 您 的 选择 暗化 或 亮化 背景。",
"date_format": "日期格式",
"days_before_showing_this_survey_again": "显示调查之前,需等待的天数。",
"days_before_showing_this_survey_again": "显示调查 之前天数。",
"decide_how_often_people_can_answer_this_survey": "决定 人 可以 回答 这份 调查 的 频率 。",
"delete_choice": "删除 选择",
"disable_the_visibility_of_survey_progress": "禁用问卷 进度 的可见性。",
"display_an_estimate_of_completion_time_for_survey": "显示 调查 预计 完成 时间",
@@ -1336,7 +1338,7 @@
"equals_one_of": "等于 其中 一个",
"error_publishing_survey": "发布调查时发生了错误",
"error_saving_changes": "保存 更改 时 出错",
"even_after_they_submitted_a_response_e_g_feedback_box": "允许多次回应;即使已提交回应,仍会继续显示(例如反馈框)",
"even_after_they_submitted_a_response_e_g_feedback_box": "即使 他们 提交 了 回复(例如 反馈框)",
"everyone": "所有 人",
"external_urls_paywall_tooltip": "请升级 以自定义 外部 URL 。 网络钓鱼 预防 。",
"fallback_missing": "备用 缺失",
@@ -1407,9 +1409,8 @@
"hostname": "主 机 名",
"how_funky_do_you_want_your_cards_in_survey_type_derived_surveys": "在 {surveyTypeDerived} 调查 中,您 想要 卡片 多么 有趣",
"if_you_need_more_please": "如果你需要更多,请",
"if_you_really_want_that_answer_ask_until_you_get_it": "每次触发时都会显示,直到提交回应为止。",
"ignore_global_waiting_time": "忽略项目范围内的等待时间",
"ignore_global_waiting_time_description": "只要满足条件,此调查即可显示,即使最近刚显示过其他调查。",
"if_you_really_want_that_answer_ask_until_you_get_it": "如果 你 真想 要 那个 答案,就 不断 询问 直到 得到。",
"ignore_waiting_time_between_surveys": "忽略 调查 之间 的 等待 时间",
"image": "图片",
"includes_all_of": "包括所有 ",
"includes_one_of": "包括一 个",
@@ -1476,10 +1477,9 @@
"optional": "可选",
"options": "选项",
"override_theme_with_individual_styles_for_this_survey": "使用 个性化 样式 替代 这份 问卷 的 主题。",
"overwrite_global_waiting_time": "设置自定义等待时间",
"overwrite_global_waiting_time_description": "仅为此调查覆盖项目配置。",
"overwrite_placement": "覆盖 放置",
"overwrite_the_global_placement_of_the_survey": "覆盖 全局 调查 放置",
"overwrites_waiting_period_between_surveys_to_x_days": "将 调查 之间 的 等待期 覆盖 为 {days} 天。",
"pick_a_background_from_our_library_or_upload_your_own": "从我们的库中选择一种 背景 或 上传您自己的。",
"picture_idx": "图片 {idx}",
"pin_can_only_contain_numbers": "PIN 只能包含数字。",
@@ -1538,8 +1538,7 @@
"range": "范围",
"recall_data": "调用 数据",
"recall_information_from": "从 ... 召回信息",
"recontact_options_section": "重新联系选项",
"recontact_options_section_description": "如果等待时间允许,请选择此调查可以向某人显示的频率。",
"recontact_options": "重新 联系 选项",
"redirect_thank_you_card": "重定向感谢卡",
"redirect_to_url": "重定向到 URL",
"remove_description": "移除 描述",
@@ -1548,8 +1547,6 @@
"required": "必需的",
"reset_to_theme_styles": "重置 为 主题 风格",
"reset_to_theme_styles_main_text": "您 确定 要 将 样式 重置 为 主题 样式吗?这 将 删除 所有 自定义 样式。",
"respect_global_waiting_time": "使用项目范围内的等待时间",
"respect_global_waiting_time_description": "此调查遵循项目配置中设置的等待时间。仅在该期间未显示其他调查时才会显示。",
"response_limit_can_t_be_set_to_0": "不 能 将 响应 限制 设置 为 0",
"response_limit_needs_to_exceed_number_of_received_responses": "限制 响应 需要 超过 收到 的 响应 数量 {responseCount})。",
"response_limits_redirections_and_more": "响应 限制 、 重定向 和 更多 。",
@@ -1574,7 +1571,7 @@
"show_advanced_settings": "显示 高级设置",
"show_button": "显示 按钮",
"show_language_switch": "显示 语言 切换",
"show_multiple_times": "显示有限次数",
"show_multiple_times": "显示 多次",
"show_only_once": "仅 显示 一次",
"show_survey_maximum_of": "显示 调查 最大 一次",
"show_survey_to_users": "显示 问卷 给 % 的 用户",
@@ -1604,12 +1601,13 @@
"switch_multi_lanugage_on_to_get_started": "打开多语言以开始 👉",
"targeted": "定位",
"ten_points": "10 分",
"the_survey_will_be_shown_multiple_times_until_they_respond": "最多显示指定次数,或直到他们回应(以先到者为准)。",
"the_survey_will_be_shown_once_even_if_person_doesnt_respond": "显示一次,即使他们未回应。",
"the_survey_will_be_shown_multiple_times_until_they_respond": "调查 将 显示 多次 直到 他们 回复",
"the_survey_will_be_shown_once_even_if_person_doesnt_respond": "调查 将 显示 一次,即使 你 不 回复。",
"then": "然后",
"this_action_will_remove_all_the_translations_from_this_survey": "此操作将删除该调查中的所有翻译。",
"this_extension_is_already_added": "此扩展已经添加。",
"this_file_type_is_not_supported": "此 文件 类型 不 支持。",
"this_setting_overwrites_your": "此 设置 覆盖 你的",
"three_points": "3 分",
"times": "次数",
"to_keep_the_placement_over_all_surveys_consistent_you_can": "为了 保持 所有 调查 的 放置 一致,您 可以",
@@ -1620,7 +1618,7 @@
"unlock_targeting_description": "根据 属性 或 设备信息 定位 特定 用户组",
"unlock_targeting_title": "通过 更 高级 划解锁 定位",
"unsaved_changes_warning": "您在调查中有未保存的更改。离开前是否要保存?",
"until_they_submit_a_response": "持续显示直到提交回应",
"until_they_submit_a_response": "直到 他们 提交 回复",
"upgrade_notice_description": "创建 多语言 调查 并 解锁 更多 功能",
"upgrade_notice_title": "解锁 更高 计划 中 的 多语言 调查",
"upload": "上传",
@@ -1628,6 +1626,7 @@
"upper_label": "上限标签",
"url_filters": "URL 过滤器",
"url_not_supported": "URL 不支持",
"use_with_caution": "谨慎 使用",
"variable_is_used_in_logic_of_question_please_remove_it_from_logic_first": "\"{variable} 在 问题 {questionIndex} 的 逻辑 中 使用。请 先 从 逻辑 中 删除 它。\"",
"variable_is_used_in_quota_please_remove_it_from_quota_first": "变量 \"{variableName}\" 正在 被 \"{quotaName}\" 配额 使用",
"variable_name_is_already_taken_please_choose_another": "变量名已被占用,请选择其他。",
@@ -1637,13 +1636,11 @@
"variable_used_in_recall_welcome": "变量 \"{variable}\" 正在召回于欢迎 卡 。",
"verify_email_before_submission": "提交 之前 验证电子邮件",
"verify_email_before_submission_description": "仅允许 拥有 有效 电子邮件 的 人 回应。",
"visibility_and_recontact": "可见性与重新联系",
"visibility_and_recontact_description": "控制此调查何时可以显示以及可以重新显示的频率。",
"wait": "等待",
"wait_a_few_seconds_after_the_trigger_before_showing_the_survey": "触发后等待几秒再显示问卷",
"waiting_time_across_surveys": "项目范围内的等待时间",
"waiting_time_across_surveys_description": "为防止调查疲劳,请选择此调查如何与项目范围内的等待时间交互。",
"waiting_period": "等待期",
"welcome_message": "欢迎 信息",
"when_conditions_match_waiting_time_will_be_ignored_and_survey_shown": "当 条件 匹配 时,等待 时间 将 被 忽略 并 显示 调查。",
"without_a_filter_all_of_your_users_can_be_surveyed": "没有 过滤器 时 ,所有 用户 都可以 被 调查 。",
"you_have_not_created_a_segment_yet": "您 还没有 创建 段落",
"you_need_to_have_two_or_more_languages_set_up_in_your_project_to_work_with_translations": "您 需要在您的项目中设置两种或更多语言才能进行翻译。",

View File

@@ -774,14 +774,14 @@
},
"app-connection": {
"app_connection": "應用程式連線",
"app_connection_description": "將您的應用程式或網站連接到 Formbricks。",
"app_connection_description": "將您的應用程式連線至 Formbricks。",
"cache_update_delay_description": "當您對調查、聯絡人、操作或其他資料進行更新時,可能需要長達 5 分鐘這些變更才能顯示在執行 Formbricks SDK 的本地應用程式中。此延遲是因我們目前快取系統的限制。我們正積極重新設計快取,並將在 Formbricks 4.0 中發佈修補程式。",
"cache_update_delay_title": "更改將於 5 分鐘後因快取而反映",
"environment_id": "您的 EnvironmentId",
"environment_id_description": "此 ID 可唯一識別此 Formbricks 環境。",
"formbricks_sdk_connected": "Formbricks SDK 已連線",
"formbricks_sdk_not_connected": "Formbricks SDK 尚未連線。",
"formbricks_sdk_not_connected_description": "將 Formbricks SDK 添加到您的網站或應用程式,以連接到 Formbricks",
"formbricks_sdk_not_connected_description": "將您的網站或應用程式 Formbricks 連線",
"how_to_setup": "如何設定",
"how_to_setup_description": "請按照這些步驟在您的應用程式中設定 Formbricks 小工具。",
"receiving_data": "正在接收資料 💃🕺",
@@ -800,7 +800,7 @@
"project_deleted_successfully": "專案已成功刪除",
"project_name_settings_description": "變更您的專案名稱。",
"project_name_updated_successfully": "專案名稱已成功更新",
"recontact_waiting_time": "專案範圍內的問卷等待時間",
"recontact_waiting_time": "重新聯絡等待時間",
"recontact_waiting_time_settings_description": "控制使用者在所有應用程式問卷中可以被調查的頻率。",
"this_action_cannot_be_undone": "此操作無法復原。",
"wait_x_days_before_showing_next_survey": "在顯示下一個問卷之前等待 X 天:",
@@ -1226,6 +1226,7 @@
"allow_multi_select": "允許多重選取",
"allow_multiple_files": "允許上傳多個檔案",
"allow_users_to_select_more_than_one_image": "允許使用者選取多張圖片",
"always_show_survey": "始終顯示問卷",
"and_launch_surveys_in_your_website_or_app": "並在您的網站或應用程式中啟動問卷。",
"animation": "動畫",
"app_survey_description": "將問卷嵌入您的 Web 應用程式或網站中以收集回應。",
@@ -1308,7 +1309,8 @@
"custom_hostname": "自訂主機名稱",
"darken_or_lighten_background_of_your_choice": "變暗或變亮您選擇的背景。",
"date_format": "日期格式",
"days_before_showing_this_survey_again": "顯示此問卷之前,需等待其他問卷顯示後的天數。",
"days_before_showing_this_survey_again": "天後再次顯示此問卷。",
"decide_how_often_people_can_answer_this_survey": "決定人們可以回答此問卷的頻率。",
"delete_choice": "刪除選項",
"disable_the_visibility_of_survey_progress": "停用問卷進度的可見性。",
"display_an_estimate_of_completion_time_for_survey": "顯示問卷的估計完成時間",
@@ -1336,7 +1338,7 @@
"equals_one_of": "等於其中之一",
"error_publishing_survey": "發布問卷時發生錯誤。",
"error_saving_changes": "儲存變更時發生錯誤",
"even_after_they_submitted_a_response_e_g_feedback_box": "允許多次回應;即使已提交回應仍繼續顯示(例如意見回饋框)。",
"even_after_they_submitted_a_response_e_g_feedback_box": "即使他們提交回應之後(例如意見反應方塊)",
"everyone": "所有人",
"external_urls_paywall_tooltip": "請升級以自訂 external URL 。 Phishing 預防。",
"fallback_missing": "遺失的回退",
@@ -1407,9 +1409,8 @@
"hostname": "主機名稱",
"how_funky_do_you_want_your_cards_in_survey_type_derived_surveys": "您希望 '{'surveyTypeDerived'}' 問卷中的卡片有多酷炫",
"if_you_need_more_please": "如果您需要更多,請",
"if_you_really_want_that_answer_ask_until_you_get_it": "每次觸發時都顯示,直到提交回應為止。",
"ignore_global_waiting_time": "忽略專案範圍內的等待時間",
"ignore_global_waiting_time_description": "此問卷在符合條件時即可顯示,即使最近已顯示過其他問卷。",
"if_you_really_want_that_answer_ask_until_you_get_it": "如果您真的想要該答案,請詢問直到您獲得它。",
"ignore_waiting_time_between_surveys": "忽略問卷之間的等待時間",
"image": "圖片",
"includes_all_of": "包含全部",
"includes_one_of": "包含其中之一",
@@ -1476,10 +1477,9 @@
"optional": "選填",
"options": "選項",
"override_theme_with_individual_styles_for_this_survey": "使用此問卷的個別樣式覆寫主題。",
"overwrite_global_waiting_time": "設定自訂等待時間",
"overwrite_global_waiting_time_description": "僅覆蓋此問卷的專案設定。",
"overwrite_placement": "覆寫位置",
"overwrite_the_global_placement_of_the_survey": "覆寫問卷的整體位置",
"overwrites_waiting_period_between_surveys_to_x_days": "將問卷之間的等待時間覆寫為 '{'days'}' 天。",
"pick_a_background_from_our_library_or_upload_your_own": "從我們的媒體庫中選取背景或上傳您自己的背景。",
"picture_idx": "圖片 '{'idx'}'",
"pin_can_only_contain_numbers": "PIN 碼只能包含數字。",
@@ -1538,8 +1538,7 @@
"range": "範圍",
"recall_data": "回憶數據",
"recall_information_from": "從 ... 獲取 信息",
"recontact_options_section": "重新聯絡選項",
"recontact_options_section_description": "如果等待時間允許,選擇此問卷可以向同一人顯示的頻率。",
"recontact_options": "重新聯絡選項",
"redirect_thank_you_card": "重新導向感謝卡片",
"redirect_to_url": "重新導向至網址",
"remove_description": "移除描述",
@@ -1548,8 +1547,6 @@
"required": "必填",
"reset_to_theme_styles": "重設為主題樣式",
"reset_to_theme_styles_main_text": "您確定要將樣式重設為主題樣式嗎?這將移除所有自訂樣式。",
"respect_global_waiting_time": "使用專案範圍內的等待時間",
"respect_global_waiting_time_description": "此問卷遵循專案設定的等待時間。僅在該期間內未顯示其他問卷時才會顯示。",
"response_limit_can_t_be_set_to_0": "回應限制不能設定為 0",
"response_limit_needs_to_exceed_number_of_received_responses": "回應限制必須超過收到的回應數 ('{'responseCount'}')。",
"response_limits_redirections_and_more": "回應限制、重新導向等。",
@@ -1574,7 +1571,7 @@
"show_advanced_settings": "顯示進階設定",
"show_button": "顯示按鈕",
"show_language_switch": "顯示語言切換",
"show_multiple_times": "顯示有限次數",
"show_multiple_times": "多次顯示",
"show_only_once": "僅顯示一次",
"show_survey_maximum_of": "最多顯示問卷",
"show_survey_to_users": "將問卷顯示給 % 的使用者",
@@ -1604,12 +1601,13 @@
"switch_multi_lanugage_on_to_get_started": "開啟多語言以開始使用 👉",
"targeted": "目標",
"ten_points": "10 分",
"the_survey_will_be_shown_multiple_times_until_they_respond": "最多顯示指定次數,或直到他們回應(以先達成者為準)。",
"the_survey_will_be_shown_once_even_if_person_doesnt_respond": "僅顯示一次,即使他們未回應。",
"the_survey_will_be_shown_multiple_times_until_they_respond": "將多次顯示問卷,直到他們回應",
"the_survey_will_be_shown_once_even_if_person_doesnt_respond": "即使使用者沒有回應,也只會顯示一次問卷。",
"then": "然後",
"this_action_will_remove_all_the_translations_from_this_survey": "此操作將從此問卷中移除所有翻譯。",
"this_extension_is_already_added": "已新增此擴充功能。",
"this_file_type_is_not_supported": "不支援此檔案類型。",
"this_setting_overwrites_your": "此設定會覆寫您的",
"three_points": "3 分",
"times": "次",
"to_keep_the_placement_over_all_surveys_consistent_you_can": "若要保持所有問卷的位置一致,您可以",
@@ -1620,7 +1618,7 @@
"unlock_targeting_description": "根據屬性或裝置資訊鎖定特定使用者群組",
"unlock_targeting_title": "使用更高等級的方案解鎖目標設定",
"unsaved_changes_warning": "您的問卷中有未儲存的變更。您要先儲存它們再離開嗎?",
"until_they_submit_a_response": "持續詢問直到提交回應",
"until_they_submit_a_response": "直到他們提交回應",
"upgrade_notice_description": "建立多語言問卷並解鎖更多功能",
"upgrade_notice_title": "使用更高等級的方案解鎖多語言問卷",
"upload": "上傳",
@@ -1628,6 +1626,7 @@
"upper_label": "上標籤",
"url_filters": "網址篩選器",
"url_not_supported": "不支援網址",
"use_with_caution": "謹慎使用",
"variable_is_used_in_logic_of_question_please_remove_it_from_logic_first": "'{'variable'}' 用於問題 '{'questionIndex'}' 的邏輯中。請先從邏輯中移除。",
"variable_is_used_in_quota_please_remove_it_from_quota_first": "變數 \"{variableName}\" 正被使用於 \"{quotaName}\" 配額中",
"variable_name_is_already_taken_please_choose_another": "已使用此變數名稱,請選擇另一個名稱。",
@@ -1637,13 +1636,11 @@
"variable_used_in_recall_welcome": "變數 \"{variable}\" 於 歡迎 Card 中被召回。",
"verify_email_before_submission": "提交前驗證電子郵件",
"verify_email_before_submission_description": "僅允許擁有真實電子郵件的人員回應。",
"visibility_and_recontact": "可見性與重新聯絡",
"visibility_and_recontact_description": "控制此問卷何時可以顯示以及可以重新顯示的頻率。",
"wait": "等待",
"wait_a_few_seconds_after_the_trigger_before_showing_the_survey": "在觸發後等待幾秒鐘再顯示問卷",
"waiting_time_across_surveys": "專案範圍內的等待時間",
"waiting_time_across_surveys_description": "為避免問卷疲勞,選擇此問卷如何與專案範圍內的等待時間互動。",
"waiting_period": "等待時間",
"welcome_message": "歡迎訊息",
"when_conditions_match_waiting_time_will_be_ignored_and_survey_shown": "當條件符合時,等待時間將被忽略且顯示問卷。",
"without_a_filter_all_of_your_users_can_be_surveyed": "如果沒有篩選器,則可以調查您的所有使用者。",
"you_have_not_created_a_segment_yet": "您尚未建立區隔",
"you_need_to_have_two_or_more_languages_set_up_in_your_project_to_work_with_translations": "您需要在您的專案中設定兩個或更多語言,才能使用翻譯。",

View File

@@ -85,6 +85,6 @@ export const middleware = async (originalRequest: NextRequest) => {
export const config = {
matcher: [
"/((?!_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt|js|css|images|fonts|icons|public|animated-bgs).*)",
"/((?!_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt|js|css|images|fonts|icons|public).*)",
],
};

View File

@@ -52,6 +52,7 @@ export const getCloudPricingData = (t: TFunction): { plans: TPricingPlan[] } =>
t("environments.settings.billing.7500_contacts"),
t("environments.settings.billing.3_projects"),
t("environments.settings.billing.remove_branding"),
t("environments.settings.billing.email_follow_ups"),
t("environments.settings.billing.attribute_based_targeting"),
],
};
@@ -68,7 +69,6 @@ export const getCloudPricingData = (t: TFunction): { plans: TPricingPlan[] } =>
},
mainFeatures: [
t("environments.settings.billing.everything_in_startup"),
t("environments.settings.billing.email_follow_ups"),
t("environments.settings.billing.custom_response_limit"),
t("environments.settings.billing.custom_contacts_limit"),
t("environments.settings.billing.custom_project_limit"),

View File

@@ -62,10 +62,7 @@ const validateLanguages = (languages: Language[], t: TFunction) => {
return false;
}
// Prevent choosing an alias that clashes with the ISO code of some other
// language. Without this guard users could create ambiguous language entries
// (e.g. alias "nl" pointing to a non-Dutch language) which later breaks the
// dropdowns that rely on ISO identifiers.
// Check if the chosen alias matches an ISO identifier of a language that hasn't been added
for (const alias of languageAliases) {
if (iso639Languages.some((language) => language.alpha2 === alias && !languageCodes.includes(alias))) {
toast.error(t("environments.project.languages.conflict_between_selected_alias_and_another_language"), {

View File

@@ -43,13 +43,8 @@ export function LanguageSelect({ language, onLanguageChange, disabled, locale }:
setIsOpen(false);
};
// Most ISO entries don't ship with every locale translation, so fall back to
// English to keep the dropdown readable for locales such as Dutch that were
// added recently.
const getLabelForLocale = (item: TIso639Language) => item.label[locale] ?? item.label["en-US"];
const filteredItems = items.filter((item) =>
getLabelForLocale(item).toLowerCase().includes(searchTerm.toLowerCase())
item.label[locale].toLowerCase().includes(searchTerm.toLowerCase())
);
// Focus the input when the dropdown is opened
@@ -66,9 +61,7 @@ export function LanguageSelect({ language, onLanguageChange, disabled, locale }:
disabled={disabled}
onClick={toggleDropdown}
variant="ghost">
<span className="mr-2">
{selectedOption ? getLabelForLocale(selectedOption) : t("common.select")}
</span>
<span className="mr-2">{selectedOption?.label[locale] ?? t("common.select")}</span>
<ChevronDown className="h-4 w-4" />
</Button>
<div
@@ -91,7 +84,7 @@ export function LanguageSelect({ language, onLanguageChange, disabled, locale }:
onClick={() => {
handleOptionSelect(item);
}}>
{getLabelForLocale(item)}
{item.label[locale]}
</button>
))}
</div>

View File

@@ -51,7 +51,7 @@ export const AppConnectionPage = async ({ params }: { params: Promise<{ environm
<div className="space-y-4">
<WidgetStatusIndicator environment={environment} />
{!environment.appSetupCompleted ? (
<Alert variant="info">
<Alert variant="outbound">
<AlertTitle>{t("environments.project.app-connection.setup_alert_title")}</AlertTitle>
<AlertDescription>
{t("environments.project.app-connection.setup_alert_description")}

View File

@@ -3,6 +3,7 @@
import * as Collapsible from "@radix-ui/react-collapsible";
import { Hand } from "lucide-react";
import { usePathname } from "next/navigation";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { TSurvey, TSurveyQuestionId, TSurveyWelcomeCard } from "@formbricks/types/surveys/types";
import { TUserLocale } from "@formbricks/types/user";
@@ -37,6 +38,8 @@ export const EditWelcomeCard = ({
}: EditWelcomeCardProps) => {
const { t } = useTranslation();
const [firstRender, setFirstRender] = useState(true);
const path = usePathname();
const environmentId = path?.split("/environments/")[1]?.split("/")[0];
@@ -135,6 +138,8 @@ export const EditWelcomeCard = ({
setSelectedLanguageCode={setSelectedLanguageCode}
locale={locale}
isStorageConfigured={isStorageConfigured}
firstRender={firstRender}
setFirstRender={setFirstRender}
/>
</div>
<div className="mt-3">
@@ -150,6 +155,8 @@ export const EditWelcomeCard = ({
setSelectedLanguageCode={setSelectedLanguageCode}
locale={locale}
isStorageConfigured={isStorageConfigured}
firstRender={firstRender}
setFirstRender={setFirstRender}
/>
</div>
@@ -170,6 +177,8 @@ export const EditWelcomeCard = ({
label={t("environments.surveys.edit.next_button_label")}
locale={locale}
isStorageConfigured={isStorageConfigured}
firstRender={firstRender}
setFirstRender={setFirstRender}
/>
</div>
</div>

View File

@@ -3,9 +3,11 @@
import { useAutoAnimate } from "@formkit/auto-animate/react";
import * as Collapsible from "@radix-ui/react-collapsible";
import { CheckIcon } from "lucide-react";
import Link from "next/link";
import { useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { TSurvey } from "@formbricks/types/surveys/types";
import { AdvancedOptionToggle } from "@/modules/ui/components/advanced-option-toggle";
import { Input } from "@/modules/ui/components/input";
import { Label } from "@/modules/ui/components/label";
import { RadioGroup, RadioGroupItem } from "@/modules/ui/components/radio-group";
@@ -16,45 +18,19 @@ interface DisplayOption {
description: string;
}
interface WaitingTimeOption {
id: "respect" | "ignore" | "overwrite";
value: number | null;
name: string;
description: string;
}
interface RecontactOptionsCardProps {
localSurvey: TSurvey;
setLocalSurvey: (survey: TSurvey) => void;
environmentId: string;
}
export const RecontactOptionsCard = ({ localSurvey, setLocalSurvey }: RecontactOptionsCardProps) => {
export const RecontactOptionsCard = ({
localSurvey,
setLocalSurvey,
environmentId,
}: RecontactOptionsCardProps) => {
const { t } = useTranslation();
const waitingTimeOptions: WaitingTimeOption[] = useMemo(
() => [
{
id: "respect",
value: null,
name: t("environments.surveys.edit.respect_global_waiting_time"),
description: t("environments.surveys.edit.respect_global_waiting_time_description"),
},
{
id: "ignore",
value: 0,
name: t("environments.surveys.edit.ignore_global_waiting_time"),
description: t("environments.surveys.edit.ignore_global_waiting_time_description"),
},
{
id: "overwrite",
value: 1,
name: t("environments.surveys.edit.overwrite_global_waiting_time"),
description: t("environments.surveys.edit.overwrite_global_waiting_time_description"),
},
],
[t]
);
const displayOptions: DisplayOption[] = useMemo(
() => [
{
@@ -86,34 +62,26 @@ export const RecontactOptionsCard = ({ localSurvey, setLocalSurvey }: RecontactO
);
const [open, setOpen] = useState(false);
const ignoreWaiting = localSurvey.recontactDays !== null;
const [inputDays, setInputDays] = useState(
localSurvey.recontactDays !== null && localSurvey.recontactDays > 0 ? localSurvey.recontactDays : 1
localSurvey.recontactDays !== null ? localSurvey.recontactDays : 1
);
const [displayLimit, setDisplayLimit] = useState(localSurvey.displayLimit ?? 1);
// Determine current waiting time option
const getWaitingTimeOption = (): "respect" | "ignore" | "overwrite" => {
if (localSurvey.recontactDays === null) return "respect";
if (localSurvey.recontactDays === 0) return "ignore";
return "overwrite";
};
// Auto animate
const [parent] = useAutoAnimate();
const handleWaitingTimeChange = (optionId: string) => {
const option = waitingTimeOptions.find((opt) => opt.id === optionId);
if (option) {
let newRecontactDays = option.value;
if (optionId === "overwrite") {
newRecontactDays = inputDays;
}
const updatedSurvey = { ...localSurvey, recontactDays: newRecontactDays };
const handleCheckMark = () => {
if (ignoreWaiting) {
const updatedSurvey = { ...localSurvey, recontactDays: null };
setLocalSurvey(updatedSurvey);
} else {
const updatedSurvey = { ...localSurvey, recontactDays: 0 };
setLocalSurvey(updatedSurvey);
}
};
const handleOverwriteDaysChange = (event) => {
const handleRecontactDaysChange = (event) => {
const value = Number(event.target.value);
setInputDays(value);
@@ -121,7 +89,7 @@ export const RecontactOptionsCard = ({ localSurvey, setLocalSurvey }: RecontactO
setLocalSurvey(updatedSurvey);
};
const handleDisplayLimitChange = (event) => {
const handleRecontactSessionDaysChange = (event) => {
const value = Number(event.target.value);
setDisplayLimit(value);
@@ -160,11 +128,9 @@ export const RecontactOptionsCard = ({ localSurvey, setLocalSurvey }: RecontactO
/>
</div>
<div>
<p className="font-semibold text-slate-800">
{t("environments.surveys.edit.visibility_and_recontact")}
</p>
<p className="font-semibold text-slate-800">{t("environments.surveys.edit.recontact_options")}</p>
<p className="mt-1 text-sm text-slate-500">
{t("environments.surveys.edit.visibility_and_recontact_description")}
{t("environments.surveys.edit.decide_how_often_people_can_answer_this_survey")}
</p>
</div>
</div>
@@ -172,72 +138,6 @@ export const RecontactOptionsCard = ({ localSurvey, setLocalSurvey }: RecontactO
<Collapsible.CollapsibleContent className={`flex flex-col ${open && "pb-3"}`} ref={parent}>
<hr className="py-1 text-slate-600" />
<div className="p-3">
{/* Waiting Time Section */}
<div className="mb-4 space-y-1 px-1">
<h3 className="font-semibold text-slate-800">
{t("environments.surveys.edit.waiting_time_across_surveys")}
</h3>
<p className="text-sm text-slate-500">
{t("environments.surveys.edit.waiting_time_across_surveys_description")}
</p>
</div>
<RadioGroup
value={getWaitingTimeOption()}
className="flex flex-col space-y-3"
onValueChange={handleWaitingTimeChange}>
{waitingTimeOptions.map((option) => (
<div key={option.id}>
<Label
htmlFor={`waiting-time-${option.id}`}
className="flex w-full cursor-pointer items-center rounded-lg border bg-slate-50 p-4"
data-testid={`waiting-time-option-${option.id}`}>
<RadioGroupItem
value={option.id}
id={`waiting-time-${option.id}`}
className="aria-checked:border-brand-dark mx-5 disabled:border-slate-400 aria-checked:border-2"
/>
<div>
<p className="font-semibold text-slate-700">{option.name}</p>
<p className="mt-2 text-xs font-normal text-slate-600">{option.description}</p>
</div>
</Label>
{option.id === "overwrite" && getWaitingTimeOption() === "overwrite" && (
<div className="border-t-none -mt-1.5 w-full rounded-b-lg border bg-slate-50 p-4">
<label htmlFor="overwriteDays">
<p className="text-sm text-slate-700">
{t("environments.surveys.edit.wait")}
<Input
type="number"
min="1"
id="overwriteDays"
value={inputDays}
onChange={handleOverwriteDaysChange}
className="ml-2 mr-2 inline w-20 bg-white text-center text-sm"
/>
{t("environments.surveys.edit.days_before_showing_this_survey_again")}
</p>
</label>
</div>
)}
</div>
))}
</RadioGroup>
</div>
<hr className="my-3 text-slate-600" />
<div className="p-3">
{/* Recontact Options Section */}
<div className="mb-4 space-y-1 px-1">
<h3 className="font-semibold text-slate-800">
{t("environments.surveys.edit.recontact_options_section")}
</h3>
<p className="text-sm text-slate-500">
{t("environments.surveys.edit.recontact_options_section_description")}
</p>
</div>
<RadioGroup
value={localSurvey.displayOption}
className="flex flex-col space-y-3"
@@ -258,12 +158,11 @@ export const RecontactOptionsCard = ({ localSurvey, setLocalSurvey }: RecontactO
<div key={option.id}>
<Label
key={option.name}
htmlFor={`recontact-option-${option.id}`}
className="flex w-full cursor-pointer items-center rounded-lg border bg-slate-50 p-4"
data-testid={`recontact-option-${option.id}`}>
htmlFor={option.name}
className="flex w-full cursor-pointer items-center rounded-lg border bg-slate-50 p-4">
<RadioGroupItem
value={option.id}
id={`recontact-option-${option.id}`}
id={option.name}
className="aria-checked:border-brand-dark mx-5 disabled:border-slate-400 aria-checked:border-2"
/>
<div>
@@ -273,27 +172,105 @@ export const RecontactOptionsCard = ({ localSurvey, setLocalSurvey }: RecontactO
</div>
</Label>
{option.id === "displaySome" && localSurvey.displayOption === "displaySome" && (
<div className="border-t-none -mt-1.5 w-full rounded-b-lg border bg-slate-50 p-4">
<label htmlFor="displayLimit">
<p className="text-sm text-slate-700">
{t("environments.surveys.edit.show_survey_maximum_of")}
<Input
type="number"
min="1"
id="displayLimit"
value={displayLimit.toString()}
onChange={(e) => handleDisplayLimitChange(e)}
className="ml-2 mr-2 inline w-20 bg-white text-center text-sm"
/>
{t("environments.surveys.edit.times")}.
</p>
</label>
</div>
<label htmlFor="displayLimit" className="cursor-pointer p-4">
<p className="text-sm font-semibold text-slate-700">
{t("environments.surveys.edit.show_survey_maximum_of")}
<Input
type="number"
min="1"
id="displayLimit"
value={displayLimit.toString()}
onChange={(e) => handleRecontactSessionDaysChange(e)}
className="mx-2 inline w-16 bg-white text-center text-sm"
/>
{t("environments.surveys.edit.times")}.
</p>
</label>
)}
</div>
))}
</RadioGroup>
</div>
<AdvancedOptionToggle
htmlId="recontactDays"
isChecked={ignoreWaiting}
onToggle={handleCheckMark}
title={t("environments.surveys.edit.ignore_waiting_time_between_surveys")}
childBorder={false}
description={
<>
{t("environments.surveys.edit.this_setting_overwrites_your")}{" "}
<Link
className="decoration-brand-dark underline"
href={`/environments/${environmentId}/project/general`}
target="_blank">
{t("environments.surveys.edit.waiting_period")}
</Link>
. {t("environments.surveys.edit.use_with_caution")}
</>
}>
{localSurvey.recontactDays !== null && (
<RadioGroup
value={localSurvey.recontactDays.toString()}
className="flex w-full flex-col space-y-3 bg-white"
onValueChange={(v) => {
const updatedSurvey = { ...localSurvey, recontactDays: v === "null" ? null : Number(v) };
setLocalSurvey(updatedSurvey);
}}>
<Label
htmlFor="ignore"
className="flex w-full cursor-pointer items-center rounded-lg border bg-slate-50 p-4">
<RadioGroupItem
value="0"
id="ignore"
className="aria-checked:border-brand-dark mx-4 text-sm disabled:border-slate-400 aria-checked:border-2"
/>
<div>
<p className="font-semibold text-slate-700">
{t("environments.surveys.edit.always_show_survey")}
</p>
<p className="mt-2 text-xs font-normal text-slate-600">
{t(
"environments.surveys.edit.when_conditions_match_waiting_time_will_be_ignored_and_survey_shown"
)}
</p>
</div>
</Label>
<label
htmlFor="newDays"
className="flex w-full cursor-pointer items-center rounded-lg border bg-slate-50 p-4">
<RadioGroupItem
value={inputDays === 0 ? "1" : inputDays.toString()} //Fixes that both radio buttons are checked when inputDays is 0
id="newDays"
className="aria-checked:border-brand-dark mx-4 disabled:border-slate-400 aria-checked:border-2"
/>
<div>
<p className="text-sm font-semibold text-slate-700">
{t("environments.surveys.edit.wait")}
<Input
type="number"
min="1"
id="inputDays"
value={inputDays === 0 ? 1 : inputDays}
onChange={handleRecontactDaysChange}
className="ml-2 mr-2 inline w-16 bg-white text-center text-sm"
/>
{t("environments.surveys.edit.days_before_showing_this_survey_again")}.
</p>
<p className="mt-2 text-xs font-normal text-slate-600">
{t("environments.surveys.edit.overwrites_waiting_period_between_surveys_to_x_days", {
days: inputDays === 0 ? 1 : inputDays,
})}
</p>
</div>
</label>
</RadioGroup>
)}
</AdvancedOptionToggle>
</Collapsible.CollapsibleContent>
</Collapsible.Root>
);

View File

@@ -97,7 +97,11 @@ export const SettingsView = ({
isSpamProtectionAllowed={isSpamProtectionAllowed}
/>
<RecontactOptionsCard localSurvey={localSurvey} setLocalSurvey={setLocalSurvey} />
<RecontactOptionsCard
localSurvey={localSurvey}
setLocalSurvey={setLocalSurvey}
environmentId={environment.id}
/>
{isAppSurvey && (
<SurveyPlacementCard

View File

@@ -65,7 +65,7 @@ export const SurveyEditorTabs = ({
let tabsToDisplay = isCxMode ? tabsComputed.filter((tab) => tab.id !== "settings") : tabsComputed;
return (
<div className="fixed z-30 flex h-12 w-full items-center justify-center border-b bg-white md:w-2/3">
<div className="fixed z-30 flex h-12 w-full items-center justify-center border-b bg-white md:w-1/2">
<nav className="flex h-full items-center space-x-4" aria-label="Tabs">
{tabsToDisplay.map((tab) => (
<button

View File

@@ -176,7 +176,7 @@ export const SurveyEditor = ({
/>
<div className="relative z-0 flex flex-1 overflow-hidden">
<main
className="relative z-0 w-full overflow-y-auto bg-slate-50 focus:outline-none md:w-2/3"
className="relative z-0 w-1/2 flex-1 overflow-y-auto bg-slate-50 focus:outline-none"
ref={surveyEditorRef}>
<SurveyEditorTabs
activeId={activeView}
@@ -260,7 +260,7 @@ export const SurveyEditor = ({
)}
</main>
<aside className="group hidden w-1/3 flex-shrink-0 items-center justify-center overflow-hidden border-l border-slate-200 bg-slate-100 shadow-inner md:flex md:flex-col">
<aside className="group hidden flex-1 flex-shrink-0 items-center justify-center overflow-hidden border-l border-slate-200 bg-slate-100 shadow-inner md:flex md:flex-col">
<PreviewSurvey
survey={localSurvey}
questionId={activeQuestionId}

View File

@@ -10,8 +10,6 @@ vi.mock("@/lib/constants", async () => {
IS_FORMBRICKS_CLOUD: true,
PROJECT_FEATURE_KEYS: {
FREE: "free",
STARTUP: "startup",
CUSTOM: "custom",
},
};
});
@@ -26,13 +24,8 @@ describe("getSurveyFollowUpsPermission", () => {
expect(result).toBe(false);
});
test("should return false for startup plan on Formbricks Cloud", async () => {
test("should return true for non-free plan on Formbricks Cloud", async () => {
const result = await getSurveyFollowUpsPermission("startup" as TOrganizationBillingPlan);
expect(result).toBe(false);
});
test("should return true for custom plan on Formbricks Cloud", async () => {
const result = await getSurveyFollowUpsPermission("custom" as TOrganizationBillingPlan);
expect(result).toBe(true);
});

View File

@@ -4,6 +4,6 @@ import { IS_FORMBRICKS_CLOUD, PROJECT_FEATURE_KEYS } from "@/lib/constants";
export const getSurveyFollowUpsPermission = async (
billingPlan: Organization["billing"]["plan"]
): Promise<boolean> => {
if (IS_FORMBRICKS_CLOUD) return billingPlan === PROJECT_FEATURE_KEYS.CUSTOM;
if (IS_FORMBRICKS_CLOUD) return billingPlan !== PROJECT_FEATURE_KEYS.FREE;
return true;
};

View File

@@ -32,16 +32,6 @@ vi.mock("@/lib/styling/constants", () => ({
},
}));
// Mock recall utility
vi.mock("@/lib/utils/recall", () => ({
recallToHeadline: vi.fn((headline) => headline),
}));
// Mock text content extraction
vi.mock("@formbricks/types/surveys/validation", () => ({
getTextContent: vi.fn((text) => text),
}));
describe("Metadata Utils", () => {
// Reset all mocks before each test
beforeEach(() => {
@@ -183,75 +173,6 @@ describe("Metadata Utils", () => {
WEBAPP_URL: "https://test.formbricks.com",
}));
});
test("handles welcome card headline with HTML content", async () => {
const { getTextContent } = await import("@formbricks/types/surveys/validation");
const mockSurvey = {
id: mockSurveyId,
environmentId: mockEnvironmentId,
name: "Test Survey",
metadata: {},
languages: [],
welcomeCard: {
enabled: true,
timeToFinish: false,
showResponseCount: false,
headline: {
default: "<p>Welcome <strong>Headline</strong></p>",
},
html: {
default: "Welcome Description",
},
} as TSurveyWelcomeCard,
} as TSurvey;
vi.mocked(getSurvey).mockResolvedValue(mockSurvey);
vi.mocked(getTextContent).mockReturnValue("Welcome Headline");
const result = await getBasicSurveyMetadata(mockSurveyId);
expect(getTextContent).toHaveBeenCalled();
expect(result.title).toBe("Welcome Headline");
});
test("handles welcome card headline with recall variables", async () => {
const { recallToHeadline } = await import("@/lib/utils/recall");
const mockSurvey = {
id: mockSurveyId,
environmentId: mockEnvironmentId,
name: "Test Survey",
metadata: {},
languages: [],
welcomeCard: {
enabled: true,
timeToFinish: false,
showResponseCount: false,
headline: {
default: "Welcome #recall:name/fallback:User#",
},
html: {
default: "Welcome Description",
},
} as TSurveyWelcomeCard,
} as TSurvey;
vi.mocked(getSurvey).mockResolvedValue(mockSurvey);
vi.mocked(recallToHeadline).mockReturnValue({
default: "Welcome @User",
});
const result = await getBasicSurveyMetadata(mockSurveyId);
expect(recallToHeadline).toHaveBeenCalledWith(
mockSurvey.welcomeCard.headline,
mockSurvey,
false,
"default"
);
expect(result.title).toBe("Welcome @User");
});
});
describe("getSurveyOpenGraphMetadata", () => {

View File

@@ -1,10 +1,8 @@
import { Metadata } from "next";
import { getTextContent } from "@formbricks/types/surveys/validation";
import { IS_FORMBRICKS_CLOUD } from "@/lib/constants";
import { getPublicDomain } from "@/lib/getPublicUrl";
import { getLocalizedValue } from "@/lib/i18n/utils";
import { COLOR_DEFAULTS } from "@/lib/styling/constants";
import { recallToHeadline } from "@/lib/utils/recall";
import { getSurvey } from "@/modules/survey/lib/survey";
type TBasicSurveyMetadata = {
@@ -50,9 +48,7 @@ export const getBasicSurveyMetadata = async (
const titleFromMetadata = metadata?.title ? getLocalizedValue(metadata.title, langCode) || "" : undefined;
const titleFromWelcome =
welcomeCard?.enabled && welcomeCard.headline
? getTextContent(
getLocalizedValue(recallToHeadline(welcomeCard.headline, survey, false, langCode), langCode)
) || ""
? getLocalizedValue(welcomeCard.headline, langCode) || ""
: undefined;
let title = titleFromMetadata || titleFromWelcome || survey.name;

View File

@@ -0,0 +1,11 @@
"use client";
export const LinkSurveyLoading = () => {
return (
<div className="flex h-full w-full items-center justify-center">
<div className="flex h-1/2 w-3/4 flex-col sm:w-1/2 lg:w-1/4">
<div className="ph-no-capture h-16 w-1/3 animate-pulse rounded-lg bg-slate-200 font-medium text-slate-900"></div>
<div className="ph-no-capture mt-4 h-full animate-pulse rounded-lg bg-slate-200 text-slate-900"></div>
</div>
</div>
);
};

View File

@@ -1,13 +1,12 @@
"use server";
import { z } from "zod";
import { OperationNotAllowedError, ResourceNotFoundError } from "@formbricks/types/errors";
import { ResourceNotFoundError } from "@formbricks/types/errors";
import { ZSurveyFilterCriteria } from "@formbricks/types/surveys/types";
import { authenticatedActionClient } from "@/lib/utils/action-client";
import { checkAuthorizationUpdated } from "@/lib/utils/action-client/action-client-middleware";
import { AuthenticatedActionClientCtx } from "@/lib/utils/action-client/types/context";
import {
getEnvironmentIdFromSurveyId,
getOrganizationIdFromEnvironmentId,
getOrganizationIdFromSurveyId,
getProjectIdFromEnvironmentId,
@@ -51,6 +50,7 @@ export const getSurveyAction = authenticatedActionClient
});
const ZCopySurveyToOtherEnvironmentAction = z.object({
environmentId: z.string().cuid2(),
surveyId: z.string().cuid2(),
targetEnvironmentId: z.string().cuid2(),
});
@@ -66,10 +66,9 @@ export const copySurveyToOtherEnvironmentAction = authenticatedActionClient
parsedInput,
}: {
ctx: AuthenticatedActionClientCtx;
parsedInput: z.infer<typeof ZCopySurveyToOtherEnvironmentAction>;
parsedInput: Record<string, any>;
}) => {
const sourceEnvironmentId = await getEnvironmentIdFromSurveyId(parsedInput.surveyId);
const sourceEnvironmentProjectId = await getProjectIdIfEnvironmentExists(sourceEnvironmentId);
const sourceEnvironmentProjectId = await getProjectIdIfEnvironmentExists(parsedInput.environmentId);
const targetEnvironmentProjectId = await getProjectIdIfEnvironmentExists(
parsedInput.targetEnvironmentId
);
@@ -77,25 +76,13 @@ export const copySurveyToOtherEnvironmentAction = authenticatedActionClient
if (!sourceEnvironmentProjectId || !targetEnvironmentProjectId) {
throw new ResourceNotFoundError(
"Environment",
sourceEnvironmentProjectId ? parsedInput.targetEnvironmentId : sourceEnvironmentId
sourceEnvironmentProjectId ? parsedInput.targetEnvironmentId : parsedInput.environmentId
);
}
const sourceEnvironmentOrganizationId = await getOrganizationIdFromEnvironmentId(sourceEnvironmentId);
const targetEnvironmentOrganizationId = await getOrganizationIdFromEnvironmentId(
parsedInput.targetEnvironmentId
);
if (sourceEnvironmentOrganizationId !== targetEnvironmentOrganizationId) {
throw new OperationNotAllowedError(
"Source and target environments must be in the same organization"
);
}
// authorization check for source environment
await checkAuthorizationUpdated({
userId: ctx.user.id,
organizationId: sourceEnvironmentOrganizationId,
organizationId: await getOrganizationIdFromEnvironmentId(parsedInput.environmentId),
access: [
{
type: "organization",
@@ -109,10 +96,9 @@ export const copySurveyToOtherEnvironmentAction = authenticatedActionClient
],
});
// authorization check for target environment
await checkAuthorizationUpdated({
userId: ctx.user.id,
organizationId: targetEnvironmentOrganizationId,
organizationId: await getOrganizationIdFromEnvironmentId(parsedInput.environmentId),
access: [
{
type: "organization",
@@ -126,10 +112,12 @@ export const copySurveyToOtherEnvironmentAction = authenticatedActionClient
],
});
ctx.auditLoggingCtx.organizationId = sourceEnvironmentOrganizationId;
ctx.auditLoggingCtx.organizationId = await getOrganizationIdFromEnvironmentId(
parsedInput.environmentId
);
ctx.auditLoggingCtx.surveyId = parsedInput.surveyId;
const result = await copySurveyToOtherEnvironment(
sourceEnvironmentId,
parsedInput.environmentId,
parsedInput.surveyId,
parsedInput.targetEnvironmentId,
ctx.user.id

View File

@@ -129,6 +129,7 @@ export const CopySurveyForm = ({ defaultProjects, survey, onCancel, setOpen }: C
return {
operation: copySurveyToOtherEnvironmentAction({
environmentId: survey.environmentId,
surveyId: survey.id,
targetEnvironmentId: environmentId,
}),

View File

@@ -113,6 +113,7 @@ export const SurveyDropDownMenu = ({
setLoading(true);
try {
const duplicatedSurveyResponse = await copySurveyToOtherEnvironmentAction({
environmentId,
surveyId,
targetEnvironmentId: environmentId,
});

View File

@@ -262,27 +262,22 @@ export const ToolbarPlugin = (
const root = $getRoot();
root.clear();
root.append(...nodes);
editor.registerUpdateListener(({ editorState }) => {
editorState.read(() => {
const textInHtml = $generateHtmlFromNodes(editor)
.replace(/&lt;/g, "<")
.replace(/&gt;/g, ">")
.replace(/white-space:\s*pre-wrap;?/g, "");
setText.current(textInHtml);
});
});
});
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
// Register text-saving update listener - always active for each editor instance
useEffect(() => {
const unregister = editor.registerUpdateListener(({ editorState }) => {
editorState.read(() => {
const textInHtml = $generateHtmlFromNodes(editor)
.replace(/&lt;/g, "<")
.replace(/&gt;/g, ">")
.replace(/white-space:\s*pre-wrap;?/g, "");
setText.current(textInHtml);
});
});
return unregister;
}, [editor]);
useEffect(() => {
return mergeRegister(
editor.registerUpdateListener(({ editorState }) => {

View File

@@ -167,7 +167,7 @@ export const MediaBackground: React.FC<MediaBackgroundProps> = ({
<div
ref={ContentRef}
data-testid="mobile-preview-container"
className={`relative h-[90%] w-full overflow-hidden rounded-[3rem] border-[6px] border-slate-400 lg:w-[75%] ${getFilterStyle()}`}>
className={`relative h-[90%] w-[45%] overflow-hidden rounded-[3rem] border-[6px] border-slate-400 ${getFilterStyle()}`}>
{/* below element is use to create notch for the mobile device mockup */}
<div className="absolute left-1/2 right-1/2 top-2 z-20 h-4 w-1/3 -translate-x-1/2 transform rounded-full bg-slate-400"></div>
{surveyType === "link" && renderBackground()}

View File

@@ -1,13 +1,12 @@
"use client";
import { Environment, Project } from "@prisma/client";
import { motion } from "framer-motion";
import { Variants, motion } from "framer-motion";
import { ExpandIcon, MonitorIcon, ShrinkIcon, SmartphoneIcon } from "lucide-react";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { TProjectStyling } from "@formbricks/types/project";
import { TSurvey, TSurveyQuestionId, TSurveyStyling } from "@formbricks/types/surveys/types";
import { cn } from "@/lib/cn";
import { ClientLogo } from "@/modules/ui/components/client-logo";
import { MediaBackground } from "@/modules/ui/components/media-background";
import { ResetProgressButton } from "@/modules/ui/components/reset-progress-button";
@@ -29,6 +28,33 @@ interface PreviewSurveyProps {
let surveyNameTemp: string;
const previewParentContainerVariant: Variants = {
expanded: {
position: "fixed",
height: "100%",
width: "100%",
backgroundColor: "rgba(0, 0, 0, 0.4)",
backdropFilter: "blur(15px)",
left: 0,
top: 0,
zIndex: 1040,
transition: {
ease: "easeIn",
duration: 0.001,
},
},
shrink: {
display: "none",
position: "fixed",
backgroundColor: "rgba(0, 0, 0, 0.0)",
backdropFilter: "blur(0px)",
transition: {
duration: 0,
},
zIndex: -1,
},
};
let setQuestionId = (_: string) => {};
export const PreviewSurvey = ({
@@ -46,8 +72,44 @@ export const PreviewSurvey = ({
const [appSetupCompleted, setAppSetupCompleted] = useState(false);
const [previewMode, setPreviewMode] = useState("desktop");
const [previewPosition, setPreviewPosition] = useState("relative");
const ContentRef = useRef<HTMLDivElement | null>(null);
const [shrink, setShrink] = useState(false);
const { projectOverwrites } = survey || {};
const previewScreenVariants: Variants = {
expanded: {
right: "5%",
bottom: "10%",
top: "12%",
width: "40%",
position: "fixed",
height: "80%",
zIndex: 1050,
boxShadow: "0px 4px 5px 4px rgba(169, 169, 169, 0.25)",
transition: {
ease: "easeInOut",
duration: shrink ? 0.3 : 0,
},
},
expanded_with_fixed_positioning: {
zIndex: 1050,
position: "fixed",
top: "5%",
right: "5%",
bottom: "10%",
width: "90%",
height: "90%",
transition: {
ease: "easeOut",
duration: 0.4,
},
},
shrink: {
display: "relative",
width: ["95%"],
height: ["95%"],
},
};
const { placement: surveyPlacement } = projectOverwrites || {};
const { darkOverlay: surveyDarkOverlay } = projectOverwrites || {};
@@ -164,40 +226,22 @@ export const PreviewSurvey = ({
};
return (
<div
className="flex h-full w-full flex-col items-center justify-items-center p-2 py-4"
id="survey-preview">
<div className="flex h-full w-full flex-col items-center justify-items-center py-4" id="survey-preview">
<motion.div
className={cn(
"z-50 flex h-full w-fit items-center justify-center",
isFullScreenPreview && "h-full w-full bg-zinc-500/50 backdrop-blur-md"
)}
style={{
position: isFullScreenPreview ? "fixed" : "absolute",
zIndex: 50,
left: isFullScreenPreview ? 0 : undefined,
top: isFullScreenPreview ? 0 : undefined,
}}
transition={{
ease: "easeInOut",
delay: 1.5,
}}
variants={previewParentContainerVariant}
animate={isFullScreenPreview ? "expanded" : "shrink"}
/>
<motion.div
layout
style={{
left: isFullScreenPreview ? "2.5%" : undefined,
top: isFullScreenPreview ? 0 : undefined,
}}
transition={{
duration: 0.8,
ease: "easeInOut",
type: "spring",
}}
className={cn(
"z-50 flex h-[95%] w-full items-center justify-center overflow-hidden rounded-lg border border-slate-300",
isFullScreenPreview && "absolute z-50 h-[95%] w-[95%]"
)}>
variants={previewScreenVariants}
animate={
isFullScreenPreview
? previewPosition === "relative"
? "expanded"
: "expanded_with_fixed_positioning"
: "shrink"
}
className="relative flex h-full w-[95%] items-center justify-center rounded-lg border border-slate-300">
{previewMode === "mobile" && (
<>
<p className="absolute left-0 top-0 m-2 rounded bg-slate-100 px-2 py-1 text-xs text-slate-400">
@@ -272,9 +316,13 @@ export const PreviewSurvey = ({
className="h-3 w-3 cursor-pointer rounded-full bg-emerald-500"
onClick={() => {
if (isFullScreenPreview) {
setIsFullScreenPreview(false);
setShrink(true);
setPreviewPosition("relative");
setTimeout(() => setIsFullScreenPreview(false), 300);
} else {
setShrink(false);
setIsFullScreenPreview(true);
setTimeout(() => setPreviewPosition("fixed"), 300);
}
}}
aria-label={isFullScreenPreview ? "Shrink Preview" : "Expand Preview"}></button>
@@ -291,14 +339,18 @@ export const PreviewSurvey = ({
<ShrinkIcon
className="mr-1 h-[22px] w-[22px] cursor-pointer rounded-md bg-white p-1 text-slate-500 hover:text-slate-700"
onClick={() => {
setIsFullScreenPreview(false);
setShrink(true);
setPreviewPosition("relative");
setTimeout(() => setIsFullScreenPreview(false), 300);
}}
/>
) : (
<ExpandIcon
className="mr-1 h-[22px] w-[22px] cursor-pointer rounded-md bg-white p-1 text-slate-500 hover:text-slate-700"
onClick={() => {
setShrink(false);
setIsFullScreenPreview(true);
setTimeout(() => setPreviewPosition("fixed"), 300);
}}
/>
)}

View File

@@ -102,7 +102,7 @@
"markdown-it": "14.1.0",
"mime-types": "3.0.1",
"next": "15.5.6",
"next-auth": "4.24.12",
"next-auth": "4.24.11",
"next-safe-action": "7.10.8",
"node-fetch": "3.3.2",
"nodemailer": "7.0.9",

View File

@@ -87,8 +87,8 @@ test.describe("JS Package Test", async () => {
await page.getByRole("button", { name: "Create action" }).click();
await page.locator("#recontactOptionsCardTrigger").click();
await page.locator('[data-testid="recontact-option-respondMultiple"]').click();
await page.locator('[data-testid="waiting-time-option-ignore"]').click();
await page.locator("label").filter({ hasText: "Keep showing while conditions" }).click();
await page.locator("#recontactDays").check();
await page.getByRole("button", { name: "Publish" }).click();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

View File

@@ -211,18 +211,7 @@ vi.mock("@/lib/constants", () => ({
SESSION_MAX_AGE: 1000,
MAX_ATTRIBUTE_CLASSES_PER_ENVIRONMENT: 100,
MAX_OTHER_OPTION_LENGTH: 250,
AVAILABLE_LOCALES: [
"en-US",
"de-DE",
"pt-BR",
"fr-FR",
"nl-NL",
"zh-Hant-TW",
"pt-PT",
"ro-RO",
"ja-JP",
"zh-Hans-CN",
],
AVAILABLE_LOCALES: ["en-US", "de-DE", "pt-BR", "fr-FR", "zh-Hant-TW", "pt-PT"],
DEFAULT_LOCALE: "en-US",
BREVO_API_KEY: "mock-brevo-api-key",
ITEMS_PER_PAGE: 30,

View File

@@ -1238,45 +1238,21 @@
"requestBody": {
"content": {
"application/json": {
"examples": {
"default": {
"value": {
"data": {
"hs8yd14l9h8u353tjmv6rzaw": "clicked",
"tcgls0063n8ri7dtrbnepcmz": "Who? Who? Who?"
},
"finished": false,
"meta": {
"action": "test action",
"source": "Postman API",
"url": "https://postman.com"
},
"surveyId": "{{surveyId}}",
"userId": "{{userId}}"
}
}
},
"schema": {
"properties": {
"data": { "additionalProperties": true, "type": "object" },
"finished": { "type": "boolean" },
"language": {
"description": "Language of the response (survey should have this language enabled)",
"enum": ["en", "de", "pt", "etc.."],
"type": "string"
"example": {
"data": {
"hs8yd14l9h8u353tjmv6rzaw": "clicked",
"tcgls0063n8ri7dtrbnepcmz": "Who? Who? Who?"
},
"finished": false,
"meta": {
"properties": {
"action": { "type": "string" },
"source": { "type": "string" },
"url": { "type": "string" }
},
"type": "object"
"action": "test action",
"source": "Postman API",
"url": "https://postman.com"
},
"surveyId": { "type": "string" },
"userId": { "type": "string" }
"surveyId": "{{surveyId}}",
"userId": "{{userId}} (optional)"
},
"required": ["surveyId"],
"type": "object"
}
}
@@ -2385,55 +2361,20 @@
},
"noCodeConfig": {
"description": "Configuration object required when type is 'noCode'. Defines the conditions for triggering the action. Not needed for 'code' type.",
"nullable": true,
"properties": {
"example": {
"elementSelector": {
"description": "Element selector (required for click type)",
"properties": {
"cssSelector": {
"description": "CSS selector for the element",
"type": "string"
},
"innerHtml": {
"description": "Inner HTML text to match",
"type": "string"
}
},
"type": "object"
"cssSelector": ".button-class",
"innerHtml": "Click me"
},
"type": {
"description": "Type of no-code trigger",
"enum": ["click", "pageView", "exitIntent", "fiftyPercentScroll"],
"type": "string"
},
"urlFilters": {
"items": {
"properties": {
"rule": {
"description": "URL matching rule",
"enum": [
"exactMatch",
"contains",
"startsWith",
"endsWith",
"notMatch",
"notContains",
"matchesRegex"
],
"type": "string"
},
"value": {
"description": "URL pattern to match",
"type": "string"
}
},
"required": ["rule", "value"],
"type": "object"
},
"type": "array"
}
"type": "click",
"urlFilters": [
{
"rule": "contains",
"value": "https://www.google.com"
}
]
},
"required": ["type", "urlFilters"],
"nullable": true,
"type": "object"
},
"type": {
@@ -5080,52 +5021,17 @@
"requestBody": {
"content": {
"application/json": {
"examples": {
"default": {
"value": {
"createdAt": "2024-09-05T08:44:16.051Z",
"data": {
"hg508afs7lgx8nlni5dtit5u": ["Hello World"]
},
"finished": false,
"language": "en",
"surveyId": "clwj7hi7r0000vfhpfze6vjdg",
"updatedAt": "2024-09-05T08:44:16.051Z"
}
}
},
"schema": {
"properties": {
"createdAt": {
"description": "Creation timestamp (optional; usually set by server)",
"format": "date-time",
"type": "string"
},
"example": {
"createdAt": "2024-09-05T08:44:16.051Z",
"data": {
"additionalProperties": true,
"description": "Answers keyed by questionId; value shape depends on question type",
"type": "object"
"hg508afs7lgx8nlni5dtit5u": ["Hello World"]
},
"finished": {
"description": "Whether the response is marked as finished",
"type": "boolean"
},
"language": {
"description": "Language of the response (survey should have this language enabled)",
"enum": ["en", "de", "pt", "etc.."],
"type": "string"
},
"surveyId": {
"description": "The ID of the survey this response belongs to",
"type": "string"
},
"updatedAt": {
"description": "Update timestamp (optional; usually set by server)",
"format": "date-time",
"type": "string"
}
"finished": false,
"language": "default",
"surveyId": "clwj7hi7r0000vfhpfze6vjdg",
"updatedAt": "2024-09-05T08:44:16.051Z"
},
"required": ["surveyId"],
"type": "object"
}
}
@@ -5862,32 +5768,6 @@
"allowedFileExtensions": {
"description": "Optional. List of allowed file extensions.",
"items": {
"enum": [
"heic",
"png",
"jpeg",
"jpg",
"webp",
"pdf",
"eml",
"doc",
"docx",
"xls",
"xlsx",
"ppt",
"pptx",
"txt",
"csv",
"mp4",
"mov",
"avi",
"mkv",
"webm",
"zip",
"rar",
"7z",
"tar"
],
"type": "string"
},
"type": "array"
@@ -6228,153 +6108,113 @@
"requestBody": {
"content": {
"application/json": {
"examples": {
"default": {
"value": {
"autoClose": null,
"autoComplete": null,
"createdBy": null,
"delay": 0,
"displayLimit": null,
"displayOption": "displayOnce",
"displayPercentage": null,
"endings": [
{
"buttonLabel": { "default": "Create your own Survey" },
"buttonLink": "https://formbricks.com/signup",
"headline": { "default": "Thank you!" },
"id": "p73t62dgwq0cvmtt6ug0hmfc",
"subheader": { "default": "We appreciate your feedback." },
"type": "endScreen"
}
],
"environmentId": "{{environmentId}}",
"hiddenFields": { "enabled": false, "fieldIds": [] },
"isVerifyEmailEnabled": false,
"languages": [],
"name": "Example Survey",
"pin": null,
"productOverwrites": null,
"questions": [
{
"headline": { "default": "What would you like to know?" },
"id": "ovpy6va1hab7fl12n913zua0",
"inputType": "text",
"placeholder": { "default": "Type your answer here..." },
"required": true,
"subheader": { "default": "This is an example survey." },
"type": "openText"
},
{
"choices": [
{ "id": "xpoxuu3sifk1ee8he67ctf5i", "label": { "default": "Sun \u2600\ufe0f" } },
{ "id": "hnsovcdmxtcbly6tig1az3qc", "label": { "default": "Ocean \ud83c\udf0a" } },
{ "id": "kcnelzdxknvwo8fq20d3nrr5", "label": { "default": "Palms \ud83c\udf34" } }
],
"headline": { "default": "What's important on vacay?" },
"id": "awkn2llljy7a4oulp5t15yec",
"required": true,
"shuffleOption": "none",
"type": "multipleChoiceMulti"
}
],
"recontactDays": null,
"redirectUrl": null,
"segmentId": null,
"showLanguageSwitch": null,
"singleUse": { "enabled": false, "isEncrypted": true },
"status": "inProgress",
"styling": null,
"surveyClosedMessage": null,
"triggers": [],
"type": "link",
"welcomeCard": {
"enabled": true,
"fileUrl": "",
"headline": { "default": "Welcome!" },
"html": {
"default": "<p class=\"fb-editor-paragraph\" dir=\"ltr\"><span style=\"white-space: pre-wrap;\">Thanks for providing your feedback - let's go!</span></p>"
},
"showResponseCount": false,
"timeToFinish": false
}
}
}
},
"schema": {
"properties": {
"displayOption": {
"enum": ["displayOnce", "displayMultiple", "respondMultiple", "displaySome"],
"type": "string"
},
"environmentId": { "type": "string" },
"languages": {
"items": {
"properties": {
"default": { "type": "boolean" },
"enabled": { "type": "boolean" },
"language": {
"description": "Language of the survey (This language should exist in your environment)",
"enum": ["en", "de", "pt", "etc.."],
"type": "string"
}
"example": {
"autoClose": null,
"autoComplete": null,
"createdBy": null,
"delay": 0,
"displayLimit": null,
"displayOption": "displayOnce",
"displayPercentage": null,
"endings": [
{
"buttonLabel": {
"default": "Create your own Survey"
},
"type": "object"
},
"type": "array"
},
"name": { "type": "string" },
"questions": {
"items": {
"properties": {
"date": {
"properties": {
"format": { "enum": ["M-d-y", "d-M-y", "y-M-d"], "type": "string" }
},
"type": "object"
},
"id": { "type": "string" },
"inputType": {
"enum": ["text", "email", "url", "number", "phone"],
"type": "string"
},
"rating": {
"properties": {
"range": { "enum": [3, 4, 5, 6, 7, 10], "type": "integer" },
"scale": { "enum": ["number", "smiley", "star"], "type": "string" }
},
"type": "object"
},
"shuffleOption": { "enum": ["none", "all", "exceptLast"], "type": "string" },
"type": {
"enum": [
"address",
"cta",
"consent",
"date",
"fileUpload",
"matrix",
"multipleChoiceMulti",
"multipleChoiceSingle",
"nps",
"openText",
"pictureSelection",
"rating",
"cal",
"ranking",
"contactInfo"
],
"type": "string"
}
"buttonLink": "https://formbricks.com/signup",
"headline": {
"default": "Thank you!"
},
"type": "object"
},
"type": "array"
"id": "p73t62dgwq0cvmtt6ug0hmfc",
"subheader": {
"default": "We appreciate your feedback."
},
"type": "endScreen"
}
],
"environmentId": "{{environmentId}}",
"hiddenFields": {
"enabled": false,
"fieldIds": []
},
"status": { "enum": ["draft", "inProgress", "paused", "completed"], "type": "string" },
"type": { "enum": ["link", "app"], "type": "string" }
"isVerifyEmailEnabled": false,
"languages": [],
"name": "Example Survey",
"pin": null,
"productOverwrites": null,
"questions": [
{
"headline": {
"default": "What would you like to know?"
},
"id": "ovpy6va1hab7fl12n913zua0",
"inputType": "text",
"placeholder": {
"default": "Type your answer here..."
},
"required": true,
"subheader": {
"default": "This is an example survey."
},
"type": "openText"
},
{
"choices": [
{
"id": "xpoxuu3sifk1ee8he67ctf5i",
"label": {
"default": "Sun \u2600\ufe0f"
}
},
{
"id": "hnsovcdmxtcbly6tig1az3qc",
"label": {
"default": "Ocean \ud83c\udf0a"
}
},
{
"id": "kcnelzdxknvwo8fq20d3nrr5",
"label": {
"default": "Palms \ud83c\udf34"
}
}
],
"headline": {
"default": "What's important on vacay?"
},
"id": "awkn2llljy7a4oulp5t15yec",
"required": true,
"shuffleOption": "none",
"type": "multipleChoiceMulti"
}
],
"recontactDays": null,
"redirectUrl": null,
"segmentId": null,
"showLanguageSwitch": null,
"singleUse": {
"enabled": false,
"isEncrypted": true
},
"status": "inProgress",
"styling": null,
"surveyClosedMessage": null,
"triggers": [],
"type": "link",
"welcomeCard": {
"enabled": true,
"fileUrl": "",
"headline": {
"default": "Welcome!"
},
"html": {
"default": "<p class=\"fb-editor-paragraph\" dir=\"ltr\"><span style=\"white-space: pre-wrap;\">Thanks for providing your feedback - let's go!</span></p>"
},
"showResponseCount": false,
"timeToFinish": false
}
},
"required": ["environmentId", "name", "type", "status"],
"type": "object"
}
}
@@ -7628,41 +7468,11 @@
"requestBody": {
"content": {
"application/json": {
"examples": {
"default": {
"value": {
"triggers": ["responseCreated", "responseUpdated", "responseFinished"],
"url": "https://eoy8o887lmsqmhz.m.pipedream.net"
}
}
},
"schema": {
"properties": {
"name": {
"description": "Optional name for the webhook",
"type": "string"
},
"surveyIds": {
"description": "Optional list of survey IDs to filter webhook calls",
"items": {
"type": "string"
},
"type": "array"
},
"triggers": {
"description": "List of events that trigger this webhook",
"items": {
"enum": ["responseCreated", "responseUpdated", "responseFinished"],
"type": "string"
},
"type": "array"
},
"url": {
"description": "The webhook URL to call when triggers are fired",
"type": "string"
}
"example": {
"triggers": ["responseCreated", "responseUpdated", "responseFinished"],
"url": "https://eoy8o887lmsqmhz.m.pipedream.net"
},
"required": ["url", "triggers"],
"type": "object"
}
}
@@ -8137,7 +7947,7 @@
},
"servers": [
{
"url": "https://{baseurl}",
"url": "http://{{baseurl}}",
"variables": {
"baseurl": {
"default": "localhost:3000"

View File

@@ -97,44 +97,10 @@ paths:
content:
application/json:
schema:
type: object
properties:
surveyId:
type: string
description: The ID of the survey this response belongs to
responses:
type: object
additionalProperties: true
description: Answers keyed by questionId; value shape depends on question type
finished:
type: boolean
description: Whether the response is marked as finished
language:
type: string
enum:
[
"en-US",
"de-DE",
"pt-BR",
"fr-FR",
"zh-Hant-TW",
"pt-PT",
"ro-RO",
"ja-JP",
"zh-Hans-CN",
]
description: Locale of the response
meta:
type: object
properties:
action: { type: string }
source: { type: string }
url: { type: string }
description: Optional metadata about the response
required: ["surveyId"]
example:
surveyId: survey123
responses: {}
type: object
responses:
"201":
content:
@@ -170,15 +136,9 @@ paths:
content:
application/json:
schema:
type: object
properties:
attributes:
type: object
additionalProperties: true
description: Key-value pairs of contact attributes
required: ["attributes"]
example:
attributes: {}
type: object
responses:
"200":
content:

View File

@@ -102,7 +102,6 @@ When PUBLIC_URL is configured, the following routes are automatically served fro
- `/fonts/*` - Font files
- `/icons/*` - Icon assets
- `/public/*` - Public static files
- `/animated-bgs/*` - Animated Background assets
#### Storage Routes

View File

@@ -117,191 +117,6 @@ Please take a look at our [migration guide](/self-hosting/advanced/migration) fo
docker compose up -d
```
## Optional: Adding MinIO for File Storage
MinIO provides S3-compatible object storage for file uploads in Formbricks. If you want to enable features like image uploads, file uploads in surveys, or custom logos, you can add MinIO to your Docker setup.
<Note>
For detailed information about file storage options and configuration, see our [File Uploads
Configuration](/self-hosting/configuration/file-uploads) guide.
</Note>
<Warning>
**For production deployments with HTTPS**, use the [one-click setup script](/self-hosting/setup/one-click)
which automatically configures MinIO with Traefik, SSL certificates, and a subdomain (required for MinIO in
production). The setups below are suitable for local development or testing only.
</Warning>
### Quick Start: Using docker-compose.dev.yml
The fastest way to test MinIO with Formbricks is to use the included `docker-compose.dev.yml` which already has MinIO pre-configured.
1. **Start MinIO and Services**
From the repository root:
```bash
docker compose -f docker-compose.dev.yml up -d
```
This starts PostgreSQL, Valkey (Redis), MinIO, and Mailhog.
2. **Access MinIO Console**
Open http://localhost:9001 in your browser.
Login credentials:
- Username: `devminio`
- Password: `devminio123`
3. **Create Bucket**
- Click "Buckets" in the left sidebar
- Click "Create Bucket"
- Name it: `formbricks`
4. **Configure Formbricks**
Update your `.env` file or environment variables with MinIO configuration:
```bash
# MinIO S3 Storage
S3_ACCESS_KEY="devminio"
S3_SECRET_KEY="devminio123"
S3_REGION="us-east-1"
S3_BUCKET_NAME="formbricks"
S3_ENDPOINT_URL="http://localhost:9000"
S3_FORCE_PATH_STYLE="1"
```
5. **Verify in MinIO Console**
After uploading files in Formbricks, view them at http://localhost:9001:
- Navigate to Buckets → formbricks → Browse
- Your uploaded files will appear here
<Note>
The `docker-compose.dev.yml` file includes MinIO with console access on port 9001, making it easy to
visually verify file uploads. This is the recommended approach for development and testing.
</Note>
### Manual MinIO Setup (Custom Configuration)
<Note>
<strong>Recommended:</strong> If you can, use <code>docker-compose.dev.yml</code> for the fastest path. Use
this manual approach only when you need to integrate MinIO into an existing <code>docker-compose.yml</code>{" "}
or customize settings.
</Note>
If you prefer to add MinIO to your own `docker-compose.yml`, follow these steps:
1. **Add the MinIO service**
Add this service alongside your existing `formbricks` and `postgres` services:
```yaml
services:
# ... your existing services (formbricks, postgres, redis/valkey, etc.)
minio:
image: minio/minio:latest
restart: always
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: "formbricks-root"
MINIO_ROOT_PASSWORD: "change-this-secure-password"
ports:
- "9000:9000" # S3 API
- "9001:9001" # Web console
volumes:
- minio-data:/data
```
<Note>
For production pinning, consider using a digest (e.g., <code>minio/minio@sha256:...</code>) and review
periodically with <code>docker inspect minio/minio:latest</code>.
</Note>
2. **Declare the MinIO volume**
Add (or extend) your `volumes` block:
```yaml
volumes:
postgres:
driver: local
redis:
driver: local
minio-data:
driver: local
```
3. **Start services**
```bash
docker compose up -d
```
4. **Open the MinIO Console & Create a Bucket**
- Visit **http://localhost:9001**
- Log in with:
- **Username:** `formbricks-root`
- **Password:** `change-this-secure-password`
- Go to **Buckets → Create Bucket**
- Name it: **`formbricks`**
5. **Configure Formbricks to use MinIO**
In your `.env` or `formbricks` service environment, set:
```bash
# MinIO S3 Storage
S3_ACCESS_KEY="formbricks-root"
S3_SECRET_KEY="change-this-secure-password"
S3_REGION="us-east-1"
S3_BUCKET_NAME="formbricks"
S3_ENDPOINT_URL="http://minio:9000"
S3_FORCE_PATH_STYLE="1"
```
<Note>
These credentials should match <code>MINIO_ROOT_USER</code> and <code>MINIO_ROOT_PASSWORD</code> above.
For local/dev this is fine. For production, create a dedicated MinIO user with restricted policies.
</Note>
6. **Verify uploads**
After uploading a file in Formbricks, check **http://localhost:9001**:
- **Buckets → formbricks → Browse**
You should see your uploaded files.
#### Tips & Common Gotchas
- **Connection refused**: Ensure the `minio` container is running and port **9000** is reachable from the Formbricks container (use the internal URL `http://minio:9000`).
- **Bucket not found**: Create the `formbricks` bucket in the console before uploading.
- **Auth failed**: Confirm `S3_ACCESS_KEY`/`S3_SECRET_KEY` match MinIO credentials.
- **Health check**: From the Formbricks container:
```bash
docker compose exec formbricks sh -c 'wget -O- http://minio:9000/minio/health/ready'
```
### Production Setup with Traefik
For production deployments, use the [one-click setup script](/self-hosting/setup/one-click) which automatically configures:
- MinIO service with Traefik reverse proxy
- Dedicated subdomain (e.g., `files.yourdomain.com`) - **required for production**
- Automatic SSL certificate generation via Let's Encrypt
- CORS configuration for your domain
- Rate limiting middleware
- Secure credential generation
The production setup from [formbricks.sh](https://github.com/formbricks/formbricks/blob/main/docker/formbricks.sh) includes advanced features not covered in this manual setup. For production use, we strongly recommend using the one-click installer.
## Debug
If you encounter any issues, you can check the logs of the container with this command:

View File

@@ -74,7 +74,7 @@ spec:
{{- end }}
{{- if .Values.deployment.securityContext }}
securityContext:
{{ toYaml .Values.deployment.securityContext | nindent 8 }}
{{ toYaml .Values.deployment.securityContext | indent 8 }}
{{- end }}
terminationGracePeriodSeconds: {{ .Values.deployment.terminationGracePeriodSeconds | default 30 }}
containers:

View File

@@ -79,7 +79,7 @@
},
"pnpm": {
"patchedDependencies": {
"next-auth@4.24.12": "patches/next-auth@4.24.12.patch"
"next-auth@4.24.11": "patches/next-auth@4.24.11.patch"
},
"overrides": {
"axios": ">=1.12.2",

File diff suppressed because it is too large Load Diff

View File

@@ -7,7 +7,7 @@
},
"locale": {
"source": "en",
"targets": ["de", "it", "fr", "es", "ar", "pt", "ru", "uz", "ro", "ja", "zh-Hans", "hi", "nl"]
"targets": ["de", "it", "fr", "es", "ar", "pt", "ru", "uz", "ro", "ja", "zh-Hans", "hi"]
},
"version": 1.8
}

View File

@@ -1,73 +0,0 @@
{
"common": {
"and": "en",
"apply": "Toepassen",
"auto_close_wrapper": "Automatisch sluitende wrapper",
"back": "Terug",
"click_or_drag_to_upload_files": "Klik of sleep om bestanden te uploaden.",
"close_survey": "Enquête sluiten",
"company_logo": "Bedrijfslogo",
"delete_file": "Bestand verwijderen",
"file_upload": "Bestand uploaden",
"finish": "Voltooien",
"language_switch": "Taalschakelaar",
"less_than_x_minutes": "{count, plural, one {minder dan 1 minuut} other {minder dan {count} minuten}}",
"move_down": "Verplaats {item} naar beneden",
"move_up": "Verplaats {item} omhoog",
"next": "Volgende",
"open_in_new_tab": "Openen in nieuw tabblad",
"optional": "Optioneel",
"options": "Opties",
"people_responded": "{count, plural, one {1 persoon heeft gereageerd} other {{count} mensen hebben gereageerd}}",
"please_retry_now_or_try_again_later": "Probeer het nu opnieuw of probeer het later opnieuw.",
"powered_by": "Aangedreven door",
"privacy_policy": "Privacybeleid",
"protected_by_reCAPTCHA_and_the_Google": "Beschermd door reCAPTCHA en Google",
"question": "Vraag",
"question_video": "Vraagvideo",
"ranking_items": "Items rangschikken",
"respondents_will_not_see_this_card": "Respondenten zien deze kaart niet",
"retry": "Opnieuw proberen",
"select_a_date": "Selecteer een datum",
"select_for_ranking": "Selecteer {item} voor rangschikking",
"sending_responses": "Reacties verzenden...",
"takes": "Neemt",
"terms_of_service": "Servicevoorwaarden",
"the_servers_cannot_be_reached_at_the_moment": "De servers zijn momenteel niet bereikbaar.",
"they_will_be_redirected_immediately": "Ze worden onmiddellijk doorgestuurd",
"upload_files_by_clicking_or_dragging_them_here": "Upload bestanden door ze hierheen te klikken of te slepen",
"uploading": "Uploaden",
"x_minutes": "{count, plural, one {1 minuut} other {{count} minuten}}",
"x_plus_minutes": "{count}+ minuten",
"you_have_selected_x_date": "Je hebt {date} geselecteerd",
"you_have_successfully_uploaded_the_file": "Je hebt het bestand {fileName} succesvol geüpload",
"your_feedback_is_stuck": "Je feedback blijft hangen :("
},
"errors": {
"file_input": {
"duplicate_files": "De volgende bestanden zijn al geüpload: {duplicateNames}. Dubbele bestanden zijn niet toegestaan.",
"file_size_exceeded": "De volgende bestanden overschrijden de maximale grootte van {maxSizeInMB} MB en zijn verwijderd: {fileNames}",
"file_size_exceeded_alert": "Het bestand moet kleiner zijn dan {maxSizeInMB} MB",
"no_valid_file_types_selected": "Geen geldige bestandstypen geselecteerd. Selecteer een geldig bestandstype.",
"only_one_file_can_be_uploaded_at_a_time": "Er kan slechts één bestand tegelijk worden geüpload.",
"upload_failed": "Uploaden mislukt! Probeer het opnieuw.",
"you_can_only_upload_a_maximum_of_files": "Je kunt maximaal {FILE_LIMIT} bestanden uploaden."
},
"invalid_device_error": {
"message": "Schakel de spambeveiliging uit in de enquête-instellingen om dit apparaat te blijven gebruiken.",
"title": "Dit apparaat ondersteunt geen spambeveiliging."
},
"please_book_an_appointment": "Maak een afspraak",
"please_enter_a_valid_email_address": "Voer een geldig e-mailadres in",
"please_enter_a_valid_phone_number": "Voer een geldig telefoonnummer in",
"please_enter_a_valid_url": "Voer een geldige URL in",
"please_fill_out_this_field": "Vul dit veld in",
"please_rank_all_items_before_submitting": "Rangschik alle items voordat u ze verzendt",
"please_select_a_date": "Selecteer een datum",
"please_upload_a_file": "Upload een bestand",
"recaptcha_error": {
"message": "Uw reactie kan niet worden verzonden omdat deze is gemarkeerd als geautomatiseerde activiteit. Als u ademhaalt, probeer het dan opnieuw.",
"title": "We konden niet verifiëren dat je een mens bent."
}
}
}

View File

@@ -9,7 +9,6 @@ import frTranslations from "../../locales/fr.json";
import hiTranslations from "../../locales/hi.json";
import itTranslations from "../../locales/it.json";
import jaTranslations from "../../locales/ja.json";
import nlTranslations from "../../locales/nl.json";
import ptTranslations from "../../locales/pt.json";
import roTranslations from "../../locales/ro.json";
import ruTranslations from "../../locales/ru.json";
@@ -21,7 +20,7 @@ i18n
.use(initReactI18next)
.init({
fallbackLng: "en",
supportedLngs: ["en", "de", "it", "fr", "es", "ar", "pt", "ro", "ja", "ru", "uz", "zh-Hans", "hi", "nl"],
supportedLngs: ["en", "de", "it", "fr", "es", "ar", "pt", "ro", "ja", "ru", "uz", "zh-Hans", "hi"],
resources: {
en: { translation: enTranslations },
@@ -33,7 +32,6 @@ i18n
pt: { translation: ptTranslations },
ro: { translation: roTranslations },
ja: { translation: jaTranslations },
nl: { translation: nlTranslations },
ru: { translation: ruTranslations },
uz: { translation: uzTranslations },
"zh-Hans": { translation: zhHansTranslations },

View File

@@ -5,7 +5,6 @@ export const ZUserLocale = z.enum([
"de-DE",
"pt-BR",
"fr-FR",
"nl-NL",
"zh-Hant-TW",
"pt-PT",
"ro-RO",

5361
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff