Compare commits

..

4 Commits

Author SHA1 Message Date
Tiago Farto e79cbf549c fix(email): improve Outlook preview markup 2026-04-21 14:44:20 +00:00
Bhagya Amarasinghe fc33c52133 fix: patch protobufjs transitive vulnerabilities (#7790) 2026-04-21 09:59:12 +00:00
Balázs Úr 75cf9293b1 fix: Hungarian translation (#7752) 2026-04-21 08:41:53 +00:00
Serhat e489c6a346 feat: Add Turkish (tr) translations (#7645)
Co-authored-by: Dhruwang <dhruwangjariwala18@gmail.com>
2026-04-20 12:51:25 +00:00
38 changed files with 3832 additions and 198 deletions
@@ -0,0 +1,28 @@
import { describe, expect, test } from "vitest";
import { extractEmailBodyFragment } from "./emailTemplate";
describe("extractEmailBodyFragment", () => {
test("returns the body contents for rendered email documents", () => {
const html = `
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<style>.foo { color: red; }</style>
</head>
<body class="email-body">
<table>
<tr>
<td>Preview content</td>
</tr>
</table>
</body>
</html>
`;
expect(extractEmailBodyFragment(html)).toBe("<table>\n <tr>\n <td>Preview content</td>\n </tr>\n </table>");
});
test("falls back to the original markup when no body tag exists", () => {
expect(extractEmailBodyFragment("<div>Preview content</div>")).toBe("<div>Preview content</div>");
});
});
@@ -6,6 +6,16 @@ import { getStyling } from "@/lib/utils/styling";
import { getTranslate } from "@/lingodotdev/server";
import { getPreviewEmailTemplateHtml } from "@/modules/email/components/preview-email-template";
const EMAIL_DOCTYPE_PATTERN = /<!DOCTYPE[^>]*>/i;
const EMAIL_BODY_PATTERN = /<body\b[^>]*>([\s\S]*?)<\/body>/i;
export const extractEmailBodyFragment = (html: string): string => {
const htmlWithoutDoctype = html.replace(EMAIL_DOCTYPE_PATTERN, "").trim();
const bodyMatch = htmlWithoutDoctype.match(EMAIL_BODY_PATTERN);
return bodyMatch?.[1].trim() ?? htmlWithoutDoctype;
};
export const getEmailTemplateHtml = async (surveyId: string, locale: string) => {
const t = await getTranslate();
const survey = await getSurvey(surveyId);
@@ -20,9 +30,6 @@ export const getEmailTemplateHtml = async (surveyId: string, locale: string) =>
const styling = getStyling(project, survey);
const surveyUrl = getPublicDomain() + "/s/" + survey.id;
const html = await getPreviewEmailTemplateHtml(survey, surveyUrl, styling, locale, t);
const doctype =
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
const htmlCleaned = html.toString().replace(doctype, "");
return htmlCleaned;
return extractEmailBodyFragment(html.toString());
};
+1
View File
@@ -19,6 +19,7 @@
"ro-RO",
"ru-RU",
"sv-SE",
"tr-TR",
"zh-Hans-CN",
"zh-Hant-TW"
]
+1
View File
@@ -182,6 +182,7 @@ export const AVAILABLE_LOCALES: TUserLocale[] = [
"ro-RO",
"ru-RU",
"sv-SE",
"tr-TR",
"zh-Hans-CN",
"zh-Hant-TW",
];
+7
View File
@@ -213,6 +213,13 @@ export const appLanguages = [
native: "Svenska",
},
},
{
code: "tr-TR",
label: {
"en-US": "Turkish",
native: "Türkçe",
},
},
{
code: "zh-Hans-CN",
label: {
+2 -1
View File
@@ -1,5 +1,5 @@
import { type Locale, formatDistance } from "date-fns";
import { de, enUS, es, fr, hu, ja, nl, pt, ptBR, ro, ru, sv, zhCN, zhTW } from "date-fns/locale";
import { de, enUS, es, fr, hu, ja, nl, pt, ptBR, ro, ru, sv, tr, zhCN, zhTW } from "date-fns/locale";
import { TUserLocale } from "@formbricks/types/user";
import { formatDateForDisplay } from "./utils/datetime";
@@ -17,6 +17,7 @@ const TIME_SINCE_LOCALES: Record<TUserLocale, Locale> = {
"ro-RO": ro,
"ru-RU": ru,
"sv-SE": sv,
"tr-TR": tr,
"zh-Hans-CN": zhCN,
"zh-Hant-TW": zhTW,
};
+63 -63
View File
@@ -63,8 +63,8 @@
"login_with_email": "Bejelentkezés e-mail-címmel",
"lost_access": "Elvesztette a hozzáférést?",
"new_to_formbricks": "Új a Formbicksen?",
"oauth_account_not_linked_description": "This SSO provider is not linked to an existing Formbricks account. Please sign in with the method you used originally. If that was email and password, complete email verification first if you are prompted.",
"oauth_account_not_linked_title": "This SSO sign-in could not be linked",
"oauth_account_not_linked_description": "Ez az SSO-szolgáltató nincs összekapcsolva egy meglévő Formbricks-fiókkal. Jelentkezzen be az eredetileg használt módszerrel. Ha ez e-mail és jelszó páros volt, akkor először végezze el az e-mail-ellenőrzést, ha a rendszer erre kéri.",
"oauth_account_not_linked_title": "Ezt az SSO-bejelentkezést nem sikerült összekapcsolni",
"use_a_backup_code": "Visszaszerzési kód használata"
},
"saml_connection_error": "Valami probléma történt. A további részletekért nézze meg az alkalmazás konzolját.",
@@ -150,8 +150,8 @@
"bottom_right": "Jobbra lent",
"cancel": "Mégse",
"centered_modal": "Középre helyezett kizárólagos",
"change_organization": "Szervezet módosítása",
"change_workspace": "Munkaterület módosítása",
"change_organization": "Szervezet megváltoztatása",
"change_workspace": "Munkaterület megváltoztatása",
"choice_n": "{{n}}. választás",
"choices": "Választási lehetőségek",
"choose_environment": "Környezet kiválasztása",
@@ -173,7 +173,7 @@
"connect": "Kapcsolódás",
"connect_formbricks": "Kapcsolódás a Formbrickshez",
"connected": "Kapcsolódva",
"contact": "Kapcsolat",
"contact": "Partner",
"contacts": "Partnerek",
"continue": "Folytatás",
"copied": "Másolva",
@@ -238,7 +238,7 @@
"failed_to_copy_to_clipboard": "Nem sikerült másolni a vágólapra",
"failed_to_load_organizations": "Nem sikerült betölteni a szervezeteket",
"failed_to_load_workspaces": "Nem sikerült a munkaterületek betöltése",
"field_placeholder": "{{field}} helyőrző",
"field_placeholder": "{{field}} helykitöltője",
"filter": "Szűrő",
"finish": "Befejezés",
"first_name": "Keresztnév",
@@ -250,7 +250,7 @@
"generate": "Előállítás",
"go_back": "Vissza",
"go_to_dashboard": "Ugrás a vezérlőpultra",
"headline": "Címsor",
"headline": "Főcím",
"hidden": "Rejtett",
"hidden_field": "Rejtett mező",
"hidden_fields": "Rejtett mezők",
@@ -272,7 +272,7 @@
"invite": "Meghívás",
"invite_them": "Meghívó nekik",
"javascript_required": "JavaScript szükséges",
"javascript_required_description": "A Formbricks használatához JavaScript szükséges. Kérjük, engedélyezze a JavaScriptet a böngésző beállításaiban a folytatáshoz.",
"javascript_required_description": "A Formbricks megfelelő működéséhez JavaScript szükséges. Engedélyezze a JavaScriptet a böngésző beállításaiban a folytatáshoz.",
"key": "Kulcs",
"label": "Címke",
"language": "Nyelv",
@@ -326,9 +326,9 @@
"notifications": "Értesítések",
"number": "Szám",
"off": "Ki",
"offline_all_responses_synced": "Az Ön válasza sikeresen mentésre került.",
"offline_syncing_responses": "Az Ön válaszainak szinkronizálása folyamatban…",
"offline_you_are_offline": "Ön offline állapotban van. Az Ön válasza a böngészőjében tárolásra került, és mentésre kerül, amint ismét online lesz.",
"offline_all_responses_synced": "A válasz sikeresen el lett mentve.",
"offline_syncing_responses": "Válaszok szinkronizálása…",
"offline_you_are_offline": "Ön nem érhető el. A válasza a böngészőjében van tárolva, és akkor lesz elmentve, ha újra elérhető lesz.",
"on": "Be",
"only_one_file_allowed": "Csak egy fájl engedélyezett",
"only_owners_managers_and_manage_access_members_can_perform_this_action": "Csak tulajdonosok és kezelők hajthatják végre ezt a műveletet.",
@@ -341,7 +341,7 @@
"organization_settings": "Szervezet beállításai",
"other": "Egyéb",
"other_filters": "Egyéb szűrők",
"other_placeholder": "Egyéb helyőrző",
"other_placeholder": "Egyéb helykitöltő",
"overlay_color": "Rávetítés színe",
"overview": "Áttekintés",
"password": "Jelszó",
@@ -446,7 +446,7 @@
"team_name": "Csapat neve",
"team_role": "Csapatszerep",
"teams": "Csapatok",
"terms_of_service": "Felhasználási feltételek",
"terms_of_service": "Használati feltételek",
"text": "Szöveg",
"time": "Idő",
"time_to_finish": "Idő a befejezésig",
@@ -555,7 +555,7 @@
"verification_email_heading": "Már majdnem kész vagyunk!",
"verification_email_hey": "Helló 👋",
"verification_email_if_expired_request_new_token": "Ha lejárt, kérjen új tokent itt:",
"verification_email_link_valid_for_24_hours": "A hivatkozás 24 órán keresztül érvényes.",
"verification_email_link_valid_for_24_hours": "A hivatkozás 24 óráig érvényes.",
"verification_email_request_new_verification": "Új ellenőrzés kérése",
"verification_email_subject": "Ellenőrizze az e-mail-címét a Formbricks használatához",
"verification_email_survey_name": "Kérdőív neve",
@@ -864,16 +864,16 @@
"created_by_third_party": "Harmadik fél által létrehozva",
"discord_webhook_not_supported": "A Discord webhorgok jelenleg nem támogatottak.",
"empty_webhook_message": "A webhorgai itt fognak megjelenni, amint hozzáadja azokat. ⏲️",
"endpoint_bad_gateway_error": "Hibás átjáró (502): Proxy-/átjáróhiba, a szolgáltatás nem érhető el",
"endpoint_gateway_timeout_error": "Átjáró időtúllépés (504): Átjáró időtúllépés, a szolgáltatás nem érhető el",
"endpoint_internal_server_error": "Belső szerverhiba (500): A szolgáltatás váratlan hibába ütközött",
"endpoint_method_not_allowed_error": "A metódus nem engedélyezett (405): A végpont létezik, de nem fogad POST kéréseket",
"endpoint_not_found_error": "Nem található (404): A végpont nem létezik",
"endpoint_bad_gateway_error": "Hibás átjáró (502): proxy- vagy átjáróhiba, a szolgáltatás nem érhető el",
"endpoint_gateway_timeout_error": "Átjáró időtúllépés (504): átjáró időtúllépés, a szolgáltatás nem érhető el",
"endpoint_internal_server_error": "Belső kiszolgálóhiba (500): a szolgáltatás váratlan hibába ütközött",
"endpoint_method_not_allowed_error": "A módszer nem engedélyezett (405): a végpont létezik, de nem fogad POST-kéréseket",
"endpoint_not_found_error": "Nem található (404): a végpont nem létezik",
"endpoint_pinged": "Hurrá! Képesek vagyunk pingelni a webhorgot!",
"endpoint_pinged_error": "Nem lehet pingelni a webhorgot!",
"endpoint_service_unavailable_error": "A szolgáltatás nem érhető el (503): A szolgáltatás átmenetileg nem elérhető",
"endpoint_service_unavailable_error": "A szolgáltatás nem érhető el (503): a szolgáltatás átmenetileg nem érhető el",
"learn_to_verify": "Tudja meg, hogy kell ellenőrizni a webhorog aláírásait",
"no_triggers": "Nincsenek Triggerek",
"no_triggers": "Nincsenek aktiválók",
"please_check_console": "További részletekért nézze meg a konzolt",
"please_enter_a_url": "Adjon meg egy URL-t",
"response_created": "Válasz létrehozva",
@@ -889,7 +889,7 @@
"webhook_created": "Webhorog létrehozva",
"webhook_delete_confirmation": "Biztosan törölni szeretné ezt a webhorgot? Ez le fogja állítani a jövőbeli értesítések küldését.",
"webhook_deleted_successfully": "A webhorog sikeresen törölve",
"webhook_name_placeholder": "Választható: címkézze meg a webhorgot az egyszerű azonosításért",
"webhook_name_placeholder": "Elhagyható: címkézze meg a webhorgot az egyszerű azonosításért",
"webhook_test_failed_due_to": "A webhorog tesztelése sikertelen a következő miatt:",
"webhook_updated_successfully": "A webhorog sikeresen frissítve",
"webhook_url_placeholder": "Illessze be azt az URL-t, amelyen az eseményt aktiválni szeretné"
@@ -1015,9 +1015,9 @@
"plan_change_applied": "A csomag sikeresen frissítve.",
"plan_change_scheduled": "A csomagváltoztatás sikeresen ütemezve.",
"plan_custom": "Egyéni",
"plan_feature_everything_in_hobby": "Minden a Hobbi csomagban",
"plan_feature_everything_in_hobby": "Minden a Hobby csomagban",
"plan_feature_everything_in_pro": "Minden a Pro csomagban",
"plan_hobby": "Hobbi",
"plan_hobby": "Hobby",
"plan_hobby_description": "Magánszemélyeknek és kis csapatoknak, akik most teszik meg a kezdeti lépéseket a Formbricks Cloud szolgáltatással.",
"plan_hobby_feature_responses": "250 válasz/hónap",
"plan_hobby_feature_workspaces": "1 munkaterület",
@@ -1025,11 +1025,11 @@
"plan_pro_description": "Növekvő csapatoknak, akiknek magasabb korlátokra, automatizálásra és dinamikus túllépési lehetőségekre van szükségük.",
"plan_pro_feature_responses": "2000 válasz/hónap (dinamikus túllépés)",
"plan_pro_feature_workspaces": "3 munkaterület",
"plan_scale": "Méretezés",
"plan_scale": "Scale",
"plan_scale_description": "Nagyobb csapatoknak, amelyeknek több kapacitásra, erősebb irányításra és nagyobb válaszmennyiségre van szükségük.",
"plan_scale_feature_responses": "5000 válasz/hónap (dinamikus túllépés)",
"plan_scale_feature_workspaces": "5 munkaterület",
"plan_selection_description": "Hobbi, Pro és Méretezés csomagok összehasonlítása, majd csomagok közötti váltás közvetlenül a Formbricksben.",
"plan_selection_description": "Hobby, Pro és Scale csomagok összehasonlítása, majd csomagok közötti váltás közvetlenül a Formbricksben.",
"plan_selection_title": "Csomag kiválasztása",
"plan_unknown": "Ismeretlen",
"remove_branding": "Márkajel eltávolítása",
@@ -1037,7 +1037,7 @@
"select_plan_header_subtitle": "Nincs szükség hitelkártyára, nincs kötöttség.",
"select_plan_header_title": "Zökkenőmentesen integrált kérdőívek, 100%-ban az Ön márkájához igazítva.",
"status_trialing": "Próbaidőszak",
"stay_on_hobby_plan": "A Hobbi csomagnál szeretnék maradni",
"stay_on_hobby_plan": "A Hobby csomagnál szeretnék maradni",
"stripe_setup_incomplete": "A számlázási beállítás befejezetlen",
"stripe_setup_incomplete_description": "A számlázási beállítás nem fejeződött be sikeresen. Próbálja meg újra aktiválni az előfizetését.",
"subscription": "Előfizetés",
@@ -1142,17 +1142,17 @@
"unlock_the_full_power_of_formbricks_free_for_30_days": "A Formbricks teljes erejének feloldása. 30 napig ingyen."
},
"general": {
"ai_data_analysis_disabled_for_organization": "Az MI-alapú adatelemzés és adatgazdagítás ki van kapcsolva ennél a szervezetnél.",
"ai_data_analysis_enabled": "Adatgazdagítás és elemzés (AI)",
"ai_data_analysis_enabled_description": "AI segítségével többet hozhat ki az adataiból, irányítópultokat, diagramokat, jelentéseket és egyebeket állíthat be. Hozzáfér az élményekhez kapcsolódó adatokhoz.",
"ai_enabled": "Formbricks AI",
"ai_enabled_description": "AI-alapú funkciók kezelése ehhez a szervezethez.",
"ai_data_analysis_disabled_for_organization": "Az MI-adatelemzés le van tiltva ennél a szervezetnél.",
"ai_data_analysis_enabled": "Adatgazdagítás és -elemzés (MI)",
"ai_data_analysis_enabled_description": "Mesterséges intelligencia ahhoz, hogy többet hozzon ki az adataiból. Vezérlőpultok, diagramok, jelentések és még sok más beállítása. Az élményadatokra is kiterjed.",
"ai_enabled": "Formbricks MI",
"ai_enabled_description": "MI-alapú funkciók kezelése ennél a szervezetnél.",
"ai_features_not_enabled_for_organization": "Az MI-funkciók nincsenek engedélyezve ennél a szervezetnél.",
"ai_instance_not_configured": "Az MI példányszinten, környezeti változókkal van konfigurálva. Kérd meg a rendszergazdát, hogy állítsa be az AI_PROVIDER értékét, a szolgáltató hitelesítő adatait és a megfelelő modelllistát, mielőtt engedélyezné az MI-funkciókat.",
"ai_settings_updated_successfully": "AI beállítások sikeresen frissítve",
"ai_smart_tools_disabled_for_organization": "Az MI intelligens funkciói ki vannak kapcsolva ennél a szervezetnél.",
"ai_smart_tools_enabled": "Intelligens funkciók (AI)",
"ai_smart_tools_enabled_description": "AI segítségével kevesebb idő alatt többet érhet el. Soha nem fér hozzá a Formbricks által gyűjtött adatokhoz. Csak például felmérések más nyelvekre történő fordításához használatos.",
"ai_instance_not_configured": "Az MI példányszinten van beállítva környezeti változókon keresztül. Kérje meg az adminisztrátort, hogy állítsa be az AI_PROVIDER, AI_MODEL és a hozzájuk tartozó szolgáltató hitelesítési adatait, mielőtt engedélyezné az MI-funkciókat.",
"ai_settings_updated_successfully": "Az MI-beállítások sikeresen frissítve",
"ai_smart_tools_disabled_for_organization": "Az MI intelligens eszközei le vannak tiltva ennél a szervezetnél.",
"ai_smart_tools_enabled": "Intelligens funkcionalitás (MI)",
"ai_smart_tools_enabled_description": "Mesterséges intelligencia ahhoz, hogy segítsen Önnek többet elérni kevesebb idő alatt. Soha sem érinti a Formbricks segítségével gyűjtött adatokat. Csak például a kérdőívek más nyelvekre történő fordításához kerül felhasználásra.",
"bulk_invite_warning_description": "Az ingyenes csomagban az összes szervezeti tag mindig a „Tulajdonos” szerephez van hozzárendelve.",
"cannot_delete_only_organization": "Ez az egyetlen szervezete, nem lehet törölni. Először hozzon létre egy új szervezetet.",
"cannot_leave_only_organization": "Nem hagyhatja el ezt a szervezetet, mivel ez az egyetlen szervezete. Először hozzon létre egy új szervezetet.",
@@ -1358,8 +1358,8 @@
"assign": "= hozzárendelése",
"audience": "Közönség",
"auto_close_on_inactivity": "Automatikus lezárás tétlenségnél",
"auto_progress_rating_and_nps": "Automatikus továbblépés értékelési és NPS kérdéseknél",
"auto_progress_rating_and_nps_description": "Automatikus továbblépés egy kérdést tartalmazó blokkokban. A kötelező kérdések elrejtik a Tovább gombot, kivéve amikor az „Egyéb“ opció van kiválasztva.",
"auto_progress_rating_and_nps": "Értékelés és valós ügyfél-támogatottsági érték kérdések automatikus feldolgozása",
"auto_progress_rating_and_nps_description": "Automatikus továbblépés az egykérdéses blokkokban. A kötelező kérdések elrejtik a Tovább gombot, kivéve ha az „Egyéb van kiválasztva.",
"auto_save_disabled": "Az automatikus mentés letiltva",
"auto_save_disabled_tooltip": "A kérdőív csak akkor kerül automatikusan mentésre, ha piszkozatban van. Ez biztosítja, hogy a nyilvános kérdőívek ne legyenek véletlenül frissítve.",
"auto_save_on": "Automatikus mentés bekapcsolva",
@@ -1405,7 +1405,7 @@
"caution_text": "A változtatások következetlenségekhez vezetnek",
"change_anyway": "Változtatás mindenképp",
"change_background": "Háttér megváltoztatása",
"change_default": "Alapértelmezett módosítása",
"change_default": "Alapértelmezett megváltoztatása",
"change_question_type": "Kérdés típusának megváltoztatása",
"change_survey_type": "A kérdőív típusának megváltoztatása befolyásolja a meglévő hozzáférést",
"change_the_background_to_a_color_image_or_animation": "A háttér megváltoztatása színre, képre vagy animációra.",
@@ -1604,7 +1604,7 @@
"matrix_rows": "Sorok",
"max_file_size": "Legnagyobb fájlméret",
"max_file_size_limit_is": "A legnagyobb fájlméretkorlát",
"missing_first": "Hiányzók először",
"missing_first": "Hiányzik az első",
"move_question_to_block": "Kérdés áthelyezése egy blokkba",
"multiply": "Szorzás *",
"needed_for_self_hosted_cal_com_instance": "Saját üzemeltetésű Cal.com-példányhoz szükséges",
@@ -1612,7 +1612,7 @@
"next_button_label": "A „Következő” gomb címkéje",
"no_hidden_fields_yet_add_first_one_below": "Még nincsenek rejtett mezők. Adja hozzá az elsőt lent.",
"no_images_found_for": "Nem találhatók képek a(z) „{query}” lekérdezéshez",
"no_languages_found_add_first_one_to_get_started": "Nem található felmérési nyelv ebben a munkaterületen. Kérem, adjon hozzá egyet a kezdéshez.",
"no_languages_found_add_first_one_to_get_started": "Nem találhatók kérdőívnyelvek ezen a munkaterületen. Adja hozzá egyet a kezdéshez.",
"no_option_found": "Nem található lehetőség",
"no_recall_items_found": "Nem találhatók visszahívási elemek",
"no_variables_yet_add_first_one_below": "Még nincsenek változók. Adja hozzá az elsőt lent.",
@@ -1623,7 +1623,7 @@
"only_people_who_match_your_targeting_can_be_surveyed": "Csak azok a személyek kérdezhetők meg, akik megfelelnek a célcsoportnak.",
"option_idx": "{choiceIndex}. lehetőség",
"option_used_in_logic_error": "Ez a lehetőség használatban van a(z) {questionIndex}. kérdés logikájában. Először távolítsa el a logikából.",
"optional": "Választható",
"optional": "Elhagyható",
"options": "Beállítások*",
"options_used_in_logic_bulk_error": "A következő lehetőségek használatban vannak a logikában: {questionIndexes}. Először távolítsa el azokat a logikából.",
"override_theme_with_individual_styles_for_this_survey": "A téma felülírása egyéni stílusokkal ennél a kérdőívnél.",
@@ -1639,7 +1639,7 @@
"please_enter_a_valid_url": "Adjon meg egy érvényes URL-t (például https://example.com)",
"please_set_a_survey_trigger": "Állítson be kérdőív-aktiválót",
"please_specify": "Adja meg",
"present_your_survey_in_multiple_languages": "Mutassa be felmérését több nyelven",
"present_your_survey_in_multiple_languages": "A kérdőív bemutatása több nyelven",
"prevent_double_submission": "Kettős beküldés megakadályozása",
"prevent_double_submission_description": "E-mail-címenként csak 1 válasz engedélyezése",
"progress_saved": "Folyamat elmentve",
@@ -1708,8 +1708,8 @@
"response_limit_needs_to_exceed_number_of_received_responses": "A válaszkorlátnak meg kell haladnia a kapott válaszok számát ({responseCount}).",
"response_limits_redirections_and_more": "Válaszkorlátok, átirányítások és egyebek.",
"response_options": "Válasz beállításai",
"reverse_order_occasionally": "Sorrend alkalmi megfordítása",
"reverse_order_occasionally_except_last": "Sorrend alkalmi megfordítása az utolsó kivételével",
"reverse_order_occasionally": "Időnként fordított sorrendben",
"reverse_order_occasionally_except_last": "Időnként fordított sorrendben, kivéve az utolsó",
"roundness": "Kerekesség",
"roundness_description": "Annak vezérlése, hogy a sarkok mennyire legyenek lekerekítve.",
"row_used_in_logic_error": "Ez a sor használatban van a(z) {questionIndex}. kérdés logikájában. Először távolítsa el a logikából.",
@@ -1731,7 +1731,7 @@
"seven_points": "7 pont",
"show_block_settings": "Blokkbeállítások megjelenítése",
"show_button": "Gomb megjelenítése",
"show_in_order": "Sorrendben megjelenítés",
"show_in_order": "Megjelenítés sorrendben",
"show_language_switch": "Nyelvválasztó megjelenítése",
"show_multiple_times": "Megjelenítés korlátozott számú alkalommal",
"show_only_once": "Megjelenítés csak egyszer",
@@ -1770,7 +1770,7 @@
"the_survey_will_be_shown_once_even_if_person_doesnt_respond": "Megjelenítés egyetlen alkalommal, még akkor is, ha nem válaszolnak.",
"then": "Azután",
"this_action_will_remove_all_the_translations_from_this_survey": "Ez a művelet eltávolítja az összes fordítást ebből a kérdőívből.",
"this_will_remove_the_language_and_all_its_translations": "Ez eltávolítja ezt a nyelvet és az összes fordítását ebből a felmérésből. Ez a művelet nem vonható vissza.",
"this_will_remove_the_language_and_all_its_translations": "Ez el fogja távolítani ezt a nyelvet és annak összes fordítását ebből a kérdőívből. Ezt a műveletet nem lehet visszavonni.",
"three_points": "3 pont",
"times": "alkalom",
"to_keep_the_placement_over_all_surveys_consistent_you_can": "Ahhoz, hogy következetesen megtartsa az elhelyezést az összes kérdőívnél, az alábbiakat teheti:",
@@ -1790,11 +1790,11 @@
"upper_label": "Felső címke",
"url_filters": "URL szűrők",
"url_not_supported": "Az URL nem támogatott",
"validate_id_duplicate": "A(z) {type} azonosító már létezik a kérdések, rejtett mezők vagy változók között.",
"validate_id_empty": "Kérjük, adjon meg egy {type} azonosítót.",
"validate_id_invalid_chars": "A(z) {type} azonosító nem engedélyezett. Kérjük, csak alfanumerikus karaktereket, kötőjeleket vagy aláhúzásjeleket használjon.",
"validate_id_no_spaces": "A(z) {type} azonosító nem tartalmazhat szóközöket. Kérjük, távolítsa el a szóközöket.",
"validate_id_reserved": "A(z) {type} azonosító \"{field}\" nem engedélyezett. Ez egy fenntartott kulcsszó.",
"validate_id_duplicate": "A {type} azonosítója már létezik a kérdésekben, rejtett mezőkben vagy változókban.",
"validate_id_empty": "Adja meg egy {type} azonosítót.",
"validate_id_invalid_chars": "A {type} azonosítója nem engedélyezett. Használjon csak alfanumerikus karaktereket, kötőjeleket vagy aláhúzásjeleket.",
"validate_id_no_spaces": "A {type} azonosítója nem tartalmazhat szóközöket. Távolítsa el a szóközöket.",
"validate_id_reserved": "A {type} „{field}” azonosítója nem engedélyezett. Ez egy foglalt kulcsszó.",
"validation": {
"add_validation_rule": "Ellenőrzési szabály hozzáadása",
"answer_all_rows": "Válaszoljon az összes sorra",
@@ -2135,7 +2135,7 @@
"this_quarter": "Ez a negyedév",
"this_year": "Ez az év",
"time_to_complete": "Kitöltéshez szükséges idő",
"ttc_survey_tooltip": "A felmérés kitöltésének átlagos ideje.",
"ttc_survey_tooltip": "A kérdőív megválaszolásának átlagos ideje.",
"ttc_tooltip": "A kérdés megválaszolásának átlagos ideje.",
"unknown_question_type": "Ismeretlen kérdéstípus",
"use_personal_links": "Személyes hivatkozások használata",
@@ -2224,7 +2224,7 @@
"languages": {
"add_language": "Nyelv hozzáadása",
"alias": "Álnév",
"alias_tooltip": "Az álnév egy alternatív név a hivatkozás-kérdőívekben és az SDK-ban lévő nyelv azonosításához (választható)",
"alias_tooltip": "Az álnév egy alternatív név a hivatkozás-kérdőívekben és az SDK-ban lévő nyelv azonosításához (elhagyható)",
"cannot_remove_language_warning": "Nem tudja eltávolítani ezt a nyelvet, mert még mindig használatban van ezekben a kérdőívekben:",
"conflict_between_identifier_and_alias": "Ütközés van egy hozzáadott nyelv azonosítója és az álnevei egyike között. Az álnevek és az azonosítók nem lehetnek azonosak.",
"conflict_between_selected_alias_and_another_language": "Ütközés van a kiválasztott álnév és egy másik, ezzel az azonosítóval rendelkező nyelv között. A következetlenségek elkerülése érdekében ezzel az azonosítóval adja hozzá a nyelvet a munkaterületéhez.",
@@ -2302,11 +2302,11 @@
"advanced_styling_field_track_height": "Követés magassága",
"advanced_styling_field_track_height_description": "A folyamatjelző vastagságát vezérli.",
"advanced_styling_field_upper_label_color": "Címke színe",
"advanced_styling_field_upper_label_color_description": "A beviteli mezők feletti kis címkék és a skálacímkék színét állítja be.",
"advanced_styling_field_upper_label_color_description": "Kiszínezi a beviteli mezők fölötti kis címkéket és a méretezés címkéit.",
"advanced_styling_field_upper_label_size": "Címke betűmérete",
"advanced_styling_field_upper_label_size_description": "A beviteli mezők feletti kis címkék és a skálacímkék betűméretét állítja be.",
"advanced_styling_field_upper_label_size_description": "Átméretezi a beviteli mezők fölötti kis címkéket és a méretezés címkéit.",
"advanced_styling_field_upper_label_weight": "Címke betűvastagsága",
"advanced_styling_field_upper_label_weight_description": "A címkék vékonyabbá vagy vastagabbá tételét teszi lehetővé.",
"advanced_styling_field_upper_label_weight_description": "Vékonyabbá vagy vastagabbá teszi a címkéket.",
"advanced_styling_section_buttons": "Gombok",
"advanced_styling_section_headlines": "Címsorok és leírások",
"advanced_styling_section_inputs": "Beviteli mezők",
@@ -2643,7 +2643,7 @@
"csat_question_1_headline": "Mennyire valószínű, hogy ezt a(z) $[projectName] projektet ajánlaná egy ismerősnek vagy kollégának?",
"csat_question_1_lower_label": "Nem valószínű",
"csat_question_1_upper_label": "Nagyon valószínű",
"csat_question_2_choice_1": "Részben elégedett",
"csat_question_2_choice_1": "Valamelyest elégedett",
"csat_question_2_choice_2": "Nagyon elégedett",
"csat_question_2_choice_3": "Sem elégedett, sem elégedetlen",
"csat_question_2_choice_4": "Valamelyest elégedetlen",
@@ -2877,10 +2877,10 @@
"gauge_feature_satisfaction_question_2_headline": "Mi az egyetlen dolog, amelyet jobban csinálhatnánk?",
"identify_customer_goals_description": "Jobban megérteni, hogy az üzenetei a termék által nyújtott érték megfelelő elvárásait keltik-e.",
"identify_customer_goals_name": "Ügyfélcélok azonosítása",
"identify_customer_goals_question_1_choice_1": "Alaposan megismerni a felhasználói bázisomat",
"identify_customer_goals_question_1_choice_1": "A felhasználói bázisom alapos megértése",
"identify_customer_goals_question_1_choice_2": "Felülértékesítési lehetőségek azonosítása",
"identify_customer_goals_question_1_choice_3": "A lehető legjobb termék elkészítése",
"identify_customer_goals_question_1_choice_4": "Világuralmat szerezni, hogy mindenki kelbimbót egyen reggelire",
"identify_customer_goals_question_1_choice_4": "Világuralom szerezése, hogy mindenki kelbimbót egyen reggelire",
"identify_customer_goals_question_1_headline": "Mi az elsődleges célja a(z) $[projectName] használatával?",
"identify_sign_up_barriers_description": "Kedvezmény felajánlása a regisztrációs akadályokkal kapcsolatos tapasztalatok gyűjtéséhez.",
"identify_sign_up_barriers_name": "Regisztrációs akadályok azonosítása",
@@ -2957,13 +2957,13 @@
"improve_trial_conversion_question_2_button_label": "Következő",
"improve_trial_conversion_question_2_headline": "Sajnálattal halljuk. Mi volt a legnagyobb probléma a(z) $[projectName] projekt használatával?",
"improve_trial_conversion_question_3_button_label": "Következő",
"improve_trial_conversion_question_3_headline": "Mit várt a(z) $[projectName] projekttől?",
"improve_trial_conversion_question_3_headline": "Mit vár el a(z) $[projectName] projekttől?",
"improve_trial_conversion_question_4_button_label": "20% kedvezmény",
"improve_trial_conversion_question_4_headline": "Sajnálattal halljuk! 20% kedvezményt kap az első évre.",
"improve_trial_conversion_question_4_html": "<p class=\"fb-editor-paragraph\" dir=\"ltr\"><span>Boldogan felajánlunk 20% kedvezményt az éves csomagra.</span></p>",
"improve_trial_conversion_question_5_button_label": "Következő",
"improve_trial_conversion_question_5_headline": "Mit szeretne elérni?",
"improve_trial_conversion_question_5_subheader": "Kérjük, ismertesse az alábbiakban:",
"improve_trial_conversion_question_5_subheader": "Írja le az alábbiakban:",
"improve_trial_conversion_question_6_headline": "Hogyan oldja meg a problémáját most?",
"improve_trial_conversion_question_6_subheader": "Nevezzen meg alternatív megoldásokat:",
"integration_setup_survey_description": "Annak kiértékelése, hogy a felhasználók mennyire könnyen tudnak integrációkat hozzáadni a termékéhez. A vakfoltok megtalálása.",
File diff suppressed because it is too large Load Diff
@@ -442,7 +442,7 @@ export async function PreviewEmailTemplate({
function EmailTemplateWrapper({
children,
surveyUrl,
surveyUrl: _surveyUrl,
styling,
}: {
children: React.ReactNode;
@@ -480,12 +480,9 @@ function EmailTemplateWrapper({
},
},
}}>
<Link
className="bg-card-bg-color border-card-border-color rounded-custom mx-0 my-2 block overflow-auto border border-solid p-8 font-sans text-inherit"
href={surveyUrl}
target="_blank">
<Section className="bg-card-bg-color border-card-border-color rounded-custom mx-0 my-2 border border-solid p-8 font-sans text-inherit">
{children}
</Link>
</Section>
</Tailwind>
);
}
@@ -79,6 +79,7 @@ export const getWebAppLocale = (languageCode: string, survey: TSurvey): string =
ja: "ja-JP",
es: "es-ES",
sv: "sv-SE",
tr: "tr-TR",
ru: "ru-RU",
};
+1
View File
@@ -222,6 +222,7 @@ vi.mock("@/lib/constants", () => ({
"ro-RO",
"ru-RU",
"sv-SE",
"tr-TR",
"zh-Hans-CN",
"zh-Hant-TW",
],
+7 -1
View File
@@ -87,6 +87,12 @@
"@tootallnate/once": "3.0.1",
"schema-utils@3.3.0>ajv": "6.14.0",
"axios": "1.13.5",
"@grpc/proto-loader@0.7.15>protobufjs": "7.5.5",
"@grpc/proto-loader@0.8.0>protobufjs": "7.5.5",
"@opentelemetry/otlp-transformer@0.57.1>protobufjs": "7.5.5",
"@opentelemetry/otlp-transformer@0.208.0>protobufjs": "7.5.5",
"@opentelemetry/otlp-transformer@0.212.0>protobufjs": "8.0.1",
"@opentelemetry/otlp-transformer@0.213.0>protobufjs": "7.5.5",
"effect": "3.20.0",
"flatted": "3.4.2",
"hono": "4.12.7",
@@ -102,7 +108,7 @@
"diff": ">=8.0.3"
},
"comments": {
"overrides": "Security fixes for transitive dependencies. Remove when upstream packages update: @hono/node-server/hono (Dependabot #313/#316/#317) - awaiting Prisma update | @tootallnate/once (Dependabot #305) - awaiting sqlite3/node-gyp chain update | schema-utils@3>ajv (Dependabot #287) - awaiting eslint/file-loader schema-utils update | axios (CVE-2025-58754, CVE-2026-25639) - awaiting @boxyhq/saml-jackson update | effect (Dependabot #339) - awaiting Prisma update | flatted (Dependabot #324/#338) - awaiting eslint/flat-cache update | minimatch (Dependabot #288/#294/#297) - awaiting react-email/glob update | node-forge (Dependabot #230) - awaiting @boxyhq/saml-jackson update | qs (Dependabot #277) - awaiting googleapis/googleapis-common update | rollup (Dependabot #291) - awaiting Vite patch adoption | socket.io-parser (Dependabot #334) - awaiting react-email/socket.io update | tar (CVE-2026-23745/23950/24842/26960) - awaiting @boxyhq/saml-jackson/sqlite3 dependency updates | typeorm (Dependabot #223) - awaiting @boxyhq/saml-jackson update | undici (Dependabot #319/#322/#323) - awaiting jsdom/vitest/isomorphic-dompurify updates | fast-xml-parser (CVE-2026-25896/26278/33036/33349) - awaiting exact upstream pin updates | diff (Dependabot #269) - awaiting upstream patch range adoption"
"overrides": "Security fixes for transitive dependencies. Remove when upstream packages update: @hono/node-server/hono (Dependabot #313/#316/#317) - awaiting Prisma update | @tootallnate/once (Dependabot #305) - awaiting sqlite3/node-gyp chain update | schema-utils@3>ajv (Dependabot #287) - awaiting eslint/file-loader schema-utils update | axios (CVE-2025-58754, CVE-2026-25639) - awaiting @boxyhq/saml-jackson update | protobufjs (ENG-716 / CVE-2026-41242) - awaiting @boxyhq/saml-jackson and OpenTelemetry transitive updates | effect (Dependabot #339) - awaiting Prisma update | flatted (Dependabot #324/#338) - awaiting eslint/flat-cache update | minimatch (Dependabot #288/#294/#297) - awaiting react-email/glob update | node-forge (Dependabot #230) - awaiting @boxyhq/saml-jackson update | qs (Dependabot #277) - awaiting googleapis/googleapis-common update | rollup (Dependabot #291) - awaiting Vite patch adoption | socket.io-parser (Dependabot #334) - awaiting react-email/socket.io update | tar (CVE-2026-23745/23950/24842/26960) - awaiting @boxyhq/saml-jackson/sqlite3 dependency updates | typeorm (Dependabot #223) - awaiting @boxyhq/saml-jackson update | undici (Dependabot #319/#322/#323) - awaiting jsdom/vitest/isomorphic-dompurify updates | fast-xml-parser (CVE-2026-25896/26278/33036/33349) - awaiting exact upstream pin updates | diff (Dependabot #269) - awaiting upstream patch range adoption"
},
"patchedDependencies": {
"next-auth@4.24.13": "patches/next-auth@4.24.13.patch"
File diff suppressed because it is too large Load Diff
+1
View File
@@ -23,6 +23,7 @@
"ro",
"ru",
"sv",
"tr",
"uz",
"zh-Hans"
]
-2
View File
@@ -7,12 +7,10 @@ checksums:
common/back: f541015a827e37cb3b1234e56bc2aa3c
common/close_survey: 36e6aaa19051cb253aa155ad69a9edbc
common/company_logo: 82d5c0d5994508210ee02d684819f4b8
common/failed_to_load_booking_widget: 6fcdeae283dc6c08cc8186c3751ecf24
common/finish: ffa7a10f71182b48fefed7135bee24fa
common/language_switch: fd72a9ada13f672f4fd5da863b22cc46
common/next: 89ddbcf710eba274963494f312bdc8a9
common/no_results_found: 5518f2865757dc73900aa03ef8be6934
common/open_booking_page_directly_at: 5f51eb388be802279f52b0eda32985e7
common/open_in_new_tab: 6844e4922a7a40a7ee25c10ea109cdeb
common/people_responded: b685fb877090d8658db724ad07a0dbd8
common/please_retry_now_or_try_again_later: 949a3841e2eb01fa249790a42bf23aa5
-2
View File
@@ -6,12 +6,10 @@
"back": "رجوع",
"close_survey": "إغلاق الاستبيان",
"company_logo": "شعار الشركة",
"failed_to_load_booking_widget": "فشل تحميل نافذة الحجز. قد تكون بيئتك تحظر الموارد عبر النطاقات.",
"finish": "إنهاء",
"language_switch": "تبديل اللغة",
"next": "التالي",
"no_results_found": "لم يتم العثور على نتائج",
"open_booking_page_directly_at": "جرب فتح صفحة الحجز مباشرة على",
"open_in_new_tab": "فتح في علامة تبويب جديدة",
"people_responded": "{count, plural, one {شخص واحد استجاب} two {شخصان استجابا} few {{count} أشخاص استجابوا} many {{count} شخصًا استجابوا} other {{count} شخص استجابوا}}",
"please_retry_now_or_try_again_later": "يرجى إعادة المحاولة الآن أو المحاولة مرة أخرى لاحقًا.",
-2
View File
@@ -6,12 +6,10 @@
"back": "Tilbage",
"close_survey": "Luk undersøgelse",
"company_logo": "Firmalogo",
"failed_to_load_booking_widget": "Kunne ikke indlæse bookingwidget. Dit miljø blokerer muligvis ressourcer på tværs af domæner.",
"finish": "Afslut",
"language_switch": "Sprogskift",
"next": "Næste",
"no_results_found": "Ingen resultater fundet",
"open_booking_page_directly_at": "Prøv at åbne bookingsiden direkte på",
"open_in_new_tab": "Åbn i ny fane",
"people_responded": "{count, plural, one {1 person har svaret} other {{count} personer har svaret}}",
"please_retry_now_or_try_again_later": "Prøv igen nu eller prøv senere.",
-2
View File
@@ -6,12 +6,10 @@
"back": "Zurück",
"close_survey": "Umfrage schließen",
"company_logo": "Firmenlogo",
"failed_to_load_booking_widget": "Das Buchungs-Widget konnte nicht geladen werden. Deine Umgebung blockiert möglicherweise Cross-Origin-Ressourcen.",
"finish": "Fertig",
"language_switch": "Sprachwechsel",
"next": "Weiter",
"no_results_found": "Keine Ergebnisse gefunden",
"open_booking_page_directly_at": "Versuch, die Buchungsseite direkt zu öffnen unter",
"open_in_new_tab": "In neuem Tab öffnen",
"people_responded": "{count, plural, one {1 Person hat geantwortet} other {{count} Personen haben geantwortet}}",
"please_retry_now_or_try_again_later": "Bitte versuchen Sie es jetzt erneut oder später noch einmal.",
-2
View File
@@ -6,12 +6,10 @@
"back": "Back",
"close_survey": "Close survey",
"company_logo": "Company Logo",
"failed_to_load_booking_widget": "Failed to load booking widget. Your environment may be blocking cross-origin resources.",
"finish": "Finish",
"language_switch": "Language switch",
"next": "Next",
"no_results_found": "No results found",
"open_booking_page_directly_at": "Try opening the booking page directly at",
"open_in_new_tab": "Open in new tab",
"people_responded": "{count, plural, one {1 person responded} other {{count} people responded}}",
"please_retry_now_or_try_again_later": "Please retry now or try again later.",
-2
View File
@@ -6,12 +6,10 @@
"back": "Atrás",
"close_survey": "Cerrar encuesta",
"company_logo": "Logo de la empresa",
"failed_to_load_booking_widget": "No se pudo cargar el widget de reservas. Tu entorno puede estar bloqueando recursos de origen cruzado.",
"finish": "Finalizar",
"language_switch": "Cambio de idioma",
"next": "Siguiente",
"no_results_found": "No se encontraron resultados",
"open_booking_page_directly_at": "Intenta abrir la página de reservas directamente en",
"open_in_new_tab": "Abrir en nueva pestaña",
"people_responded": "{count, plural, one {1 persona respondió} other {{count} personas respondieron}}",
"please_retry_now_or_try_again_later": "Por favor, inténtalo ahora o prueba más tarde.",
-2
View File
@@ -6,12 +6,10 @@
"back": "Tagasi",
"close_survey": "Sulge küsitlus",
"company_logo": "Ettevõtte logo",
"failed_to_load_booking_widget": "Broneerimisvidina laadimine ebaõnnestus. Sinu keskkond võib blokeerida ristdomeenide ressursse.",
"finish": "Lõpeta",
"language_switch": "Keele vahetamine",
"next": "Edasi",
"no_results_found": "Tulemusi ei leitud",
"open_booking_page_directly_at": "Proovi avada broneerimislehte otse aadressil",
"open_in_new_tab": "Ava uuel vahelehel",
"people_responded": "{count, plural, one {1 inimene vastas} other {{count} inimest vastas}}",
"please_retry_now_or_try_again_later": "Palun proovi uuesti kohe või hiljem.",
-2
View File
@@ -6,12 +6,10 @@
"back": "Retour",
"close_survey": "Fermer le sondage",
"company_logo": "Logo de l'entreprise",
"failed_to_load_booking_widget": "Échec du chargement du widget de réservation. Votre environnement bloque peut-être les ressources d'origine croisée.",
"finish": "Terminer",
"language_switch": "Changement de langue",
"next": "Suivant",
"no_results_found": "Aucun résultat trouvé",
"open_booking_page_directly_at": "Essayez d'ouvrir la page de réservation directement à l'adresse",
"open_in_new_tab": "Ouvrir dans un nouvel onglet",
"people_responded": "{count, plural, one {1 personne a répondu} other {{count} personnes ont répondu}}",
"please_retry_now_or_try_again_later": "Veuillez réessayer maintenant ou réessayer plus tard.",
-2
View File
@@ -6,12 +6,10 @@
"back": "वापस",
"close_survey": "सर्वेक्षण बंद करें",
"company_logo": "कंपनी लोगो",
"failed_to_load_booking_widget": "बुकिंग विजेट लोड करने में विफल। आपका एनवायरनमेंट क्रॉस-ओरिजिन संसाधनों को ब्लॉक कर रहा है।",
"finish": "समाप्त करें",
"language_switch": "भाषा बदलें",
"next": "अगला",
"no_results_found": "कोई परिणाम नहीं मिला",
"open_booking_page_directly_at": "बुकिंग पेज को सीधे यहां खोलने का प्रयास करें",
"open_in_new_tab": "नए टैब में खोलें",
"people_responded": "{count, plural, one {1 व्यक्ति ने जवाब दिया} other {{count} लोगों ने जवाब दिया}}",
"please_retry_now_or_try_again_later": "कृपया अभी पुनः प्रयास करें या बाद में फिर से प्रयास करें।",
+5 -7
View File
@@ -6,12 +6,10 @@
"back": "Vissza",
"close_survey": "Kérdőív lezárása",
"company_logo": "Vállalat logója",
"failed_to_load_booking_widget": "A foglalási modul betöltése sikertelen. Lehet, hogy a környezeted blokkolja a különböző forrásokból származó erőforrásokat.",
"finish": "Befejezés",
"language_switch": "Nyelvválasztó",
"next": "Következő",
"no_results_found": "Nincs találat",
"open_booking_page_directly_at": "Próbáld meg közvetlenül megnyitni a foglalási oldalt itt:",
"no_results_found": "Nincsenek találatok",
"open_in_new_tab": "Megnyitás új lapon",
"people_responded": "{count, plural, one {1 személy válaszolt} other {{count} személy válaszolt}}",
"please_retry_now_or_try_again_later": "Próbálkozzon újra most, vagy próbálja meg később újra.",
@@ -22,10 +20,10 @@
"question_video": "Kérdés videója",
"required": "Kötelező",
"respondents_will_not_see_this_card": "A válaszadók nem fogják látni ezt a kártyát",
"response_saved_offline": "A válaszod még nem lett elküldve. Automatikusan el fogjuk küldeni, amint újra online leszel.",
"response_saved_offline": "A válasza még nem lett elküldve. Automatikusan elküldésre kerül, amint újra elérhető lesz.",
"retry": "Újrapróbálkozás",
"retrying": "Újrapróbálkozás…",
"search": "Keresés...",
"search": "Keresés",
"select_option": "Lehetőség kiválasztása",
"select_options": "Lehetőségek kiválasztása",
"sending_responses": "Válaszok küldése…",
@@ -49,9 +47,9 @@
"file_size_exceeded_alert": "A fájlnak kisebbnek kell lennie mint {maxSizeInMB} MB",
"no_valid_file_types_selected": "Nincs érvényes fájltípus kiválasztva. Válasszon egy érvényes fájltípust.",
"only_one_file_can_be_uploaded_at_a_time": "Egyszerre csak egy fájl tölthető fel.",
"placeholder_text": "Kattints vagy húzd ide a fájlokat a feltöltéshez",
"placeholder_text": "Kattintson vagy húzza ide a fájlok feltöltéséhez",
"upload_failed": "A feltöltés nem sikerült! Próbálja meg újra.",
"uploading": "Feltöltés...",
"uploading": "Feltöltés",
"you_can_only_upload_a_maximum_of_files": "Legfeljebb csak {FILE_LIMIT} fájlt tölthet fel."
},
"invalid_device_error": {
-2
View File
@@ -6,12 +6,10 @@
"back": "Indietro",
"close_survey": "Chiudi sondaggio",
"company_logo": "Logo aziendale",
"failed_to_load_booking_widget": "Impossibile caricare il widget di prenotazione. Il tuo ambiente potrebbe bloccare le risorse cross-origin.",
"finish": "Fine",
"language_switch": "Cambio lingua",
"next": "Avanti",
"no_results_found": "Nessun risultato trovato",
"open_booking_page_directly_at": "Prova ad aprire la pagina di prenotazione direttamente su",
"open_in_new_tab": "Apri in una nuova scheda",
"people_responded": "{count, plural, one {1 persona ha risposto} other {{count} persone hanno risposto}}",
"please_retry_now_or_try_again_later": "Riprova ora o più tardi.",
-2
View File
@@ -6,12 +6,10 @@
"back": "戻る",
"close_survey": "アンケートを閉じる",
"company_logo": "会社ロゴ",
"failed_to_load_booking_widget": "予約ウィジェットの読み込みに失敗しました。お使いの環境でクロスオリジンリソースがブロックされている可能性があります。",
"finish": "完了",
"language_switch": "言語切替",
"next": "次へ",
"no_results_found": "結果が見つかりません",
"open_booking_page_directly_at": "予約ページを直接開いてみてください:",
"open_in_new_tab": "新しいタブで開く",
"people_responded": "{count, plural, other {{count}人が回答しました}}",
"please_retry_now_or_try_again_later": "今すぐ再試行するか、後でもう一度お試しください。",
-2
View File
@@ -6,12 +6,10 @@
"back": "Terug",
"close_survey": "Enquête sluiten",
"company_logo": "Bedrijfslogo",
"failed_to_load_booking_widget": "Boekingswidget kan niet worden geladen. Je omgeving blokkeert mogelijk cross-origin resources.",
"finish": "Voltooien",
"language_switch": "Taalschakelaar",
"next": "Volgende",
"no_results_found": "Geen resultaten gevonden",
"open_booking_page_directly_at": "Probeer de boekingspagina direct te openen op",
"open_in_new_tab": "Openen in nieuw tabblad",
"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.",
-2
View File
@@ -6,12 +6,10 @@
"back": "Voltar",
"close_survey": "Fechar pesquisa",
"company_logo": "Logo da empresa",
"failed_to_load_booking_widget": "Falha ao carregar o widget de reserva. O teu ambiente pode estar a bloquear recursos de origem cruzada.",
"finish": "Finalizar",
"language_switch": "Alternar idioma",
"next": "Próximo",
"no_results_found": "Nenhum resultado encontrado",
"open_booking_page_directly_at": "Tenta abrir a página de reserva diretamente em",
"open_in_new_tab": "Abrir em nova aba",
"people_responded": "{count, plural, one {1 pessoa respondeu} other {{count} pessoas responderam}}",
"please_retry_now_or_try_again_later": "Por favor, tente novamente agora ou mais tarde.",
-2
View File
@@ -6,12 +6,10 @@
"back": "Înapoi",
"close_survey": "Închide sondajul",
"company_logo": "Sigla companiei",
"failed_to_load_booking_widget": "Nu s-a putut încărca widgetul de rezervare. Este posibil ca mediul tău să blocheze resursele cross-origin.",
"finish": "Finalizează",
"language_switch": "Schimbare limbă",
"next": "Următorul",
"no_results_found": "Nu s-au găsit rezultate",
"open_booking_page_directly_at": "Încearcă să deschizi pagina de rezervare direct la",
"open_in_new_tab": "Deschide într-o filă nouă",
"people_responded": "{count, plural, one {1 persoană a răspuns} other {{count} persoane au răspuns}}",
"please_retry_now_or_try_again_later": "Te rugăm să încerci din nou acum sau mai târziu.",
-2
View File
@@ -6,12 +6,10 @@
"back": "Назад",
"close_survey": "Закрыть опрос",
"company_logo": "Логотип компании",
"failed_to_load_booking_widget": "Не удалось загрузить виджет бронирования. Возможно, ваше окружение блокирует межсайтовые ресурсы.",
"finish": "Завершить",
"language_switch": "Переключение языка",
"next": "Далее",
"no_results_found": "Результатов не найдено",
"open_booking_page_directly_at": "Попробуйте открыть страницу бронирования напрямую по адресу",
"open_in_new_tab": "Открыть в новой вкладке",
"people_responded": "{count, plural, one {1 человек ответил} other {{count} человека ответили}}",
"please_retry_now_or_try_again_later": "Пожалуйста, повторите попытку сейчас или попробуйте позже.",
-2
View File
@@ -6,12 +6,10 @@
"back": "Tillbaka",
"close_survey": "Stäng enkät",
"company_logo": "Företagslogotyp",
"failed_to_load_booking_widget": "Det gick inte att ladda bokningswidgeten. Din miljö kan blockera resurser från andra domäner.",
"finish": "Slutför",
"language_switch": "Språkväxlare",
"next": "Nästa",
"no_results_found": "Inga resultat hittades",
"open_booking_page_directly_at": "Prova att öppna bokningssidan direkt på",
"open_in_new_tab": "Öppna i ny flik",
"people_responded": "{count, plural, one {1 person har svarat} other {{count} personer har svarat}}",
"please_retry_now_or_try_again_later": "Försök igen nu eller försök igen senare.",
+87
View File
@@ -0,0 +1,87 @@
{
"common": {
"and": "ve",
"apply": "uygula",
"auto_close_wrapper": "Otomatik kapatma sarmalayıcısı",
"back": "Geri",
"close_survey": "Anketi kapat",
"company_logo": "Şirket Logosu",
"finish": "Bitir",
"language_switch": "Dil değiştirme",
"next": "Sonraki",
"no_results_found": "Sonuç bulunamadı",
"open_in_new_tab": "Yeni sekmede aç",
"people_responded": "{count, plural, one {1 kişi yanıtladı} other {{count} kişi yanıtladı}}",
"please_retry_now_or_try_again_later": "Lütfen şimdi tekrar deneyin veya daha sonra tekrar deneyin.",
"powered_by": "Destekleyen",
"privacy_policy": "Gizlilik Politikası",
"protected_by_reCAPTCHA_and_the_Google": "reCAPTCHA ve Google tarafından korunmaktadır",
"question": "Soru",
"question_video": "Soru Videosu",
"required": "Zorunlu",
"respondents_will_not_see_this_card": "Yanıtlayıcılar bu kartı görmeyecek",
"response_saved_offline": "Yanıtın henüz gönderilmedi. İnternete geri döndüğünde otomatik olarak iletilecek.",
"retry": "Yeniden dene",
"retrying": "Yeniden deneniyor…",
"search": "Ara...",
"select_option": "Bir seçenek seçin",
"select_options": "Seçenekleri seçin",
"sending_responses": "Yanıtlar gönderiliyor…",
"takes_less_than_x_minutes": "{count, plural, one {1 dakikadan az sürer} other {{count} dakikadan az sürer}}",
"takes_x_minutes": "{count, plural, one {1 dakika sürer} other {{count} dakika sürer}}",
"takes_x_plus_minutes": "{count}+ dakika sürer",
"terms_of_service": "Hizmet Şartları",
"the_servers_cannot_be_reached_at_the_moment": "Sunuculara şu anda ulaşılamıyor.",
"they_will_be_redirected_immediately": "Hemen yönlendirilecekler",
"welcome_video": "Karşılama Kartı videosu",
"your_feedback_is_stuck": "Geri bildiriminiz takıldı :("
},
"errors": {
"all_options_must_be_ranked": "Lütfen tüm seçenekleri sıralayın",
"all_rows_must_be_answered": "Lütfen tüm satırları yanıtlayın",
"file_extension_must_be": "Dosya uzantısı {extension} olmalıdır",
"file_extension_must_not_be": "Dosya uzantısı {extension} olmamalıdır",
"file_input": {
"duplicate_files": "Şu dosyalar zaten yüklendi: {duplicateNames}. Yinelenen dosyalara izin verilmez.",
"file_size_exceeded": "Şu dosya(lar) maksimum {maxSizeInMB} MB boyutunu aşıyor ve kaldırıldı: {fileNames}",
"file_size_exceeded_alert": "Dosya {maxSizeInMB} MB'den küçük olmalıdır",
"no_valid_file_types_selected": "Geçerli dosya türü seçilmedi. Lütfen geçerli bir dosya türü seçin.",
"only_one_file_can_be_uploaded_at_a_time": "Aynı anda yalnızca bir dosya yüklenebilir.",
"placeholder_text": "Dosyaları yüklemek için tıklayın veya sürükleyin",
"upload_failed": "Yükleme başarısız oldu! Lütfen tekrar deneyin.",
"uploading": "Yükleniyor...",
"you_can_only_upload_a_maximum_of_files": "En fazla {FILE_LIMIT} dosya yükleyebilirsiniz."
},
"invalid_device_error": {
"message": "Bu cihazı kullanmaya devam etmek için lütfen anket ayarlarından spam korumasını devre dışı bırakın.",
"title": "Bu cihaz spam korumasını desteklemiyor."
},
"invalid_format": "Lütfen geçerli bir biçim girin",
"is_between": "Lütfen {startDate} ile {endDate} arasında bir tarih seçin",
"is_earlier_than": "Lütfen {date} tarihinden önceki bir tarih seçin",
"is_greater_than": "Lütfen {min} değerinden büyük bir değer girin",
"is_later_than": "Lütfen {date} tarihinden sonraki bir tarih seçin",
"is_less_than": "Lütfen {max} değerinden küçük bir değer girin",
"is_not_between": "Lütfen {startDate} ile {endDate} arasında olmayan bir tarih seçin",
"max_length": "Lütfen en fazla {max} karakter girin",
"max_selections": "Lütfen en fazla {max} seçenek seçin",
"max_value": "Lütfen en fazla {max} değerinde bir değer girin",
"min_length": "Lütfen en az {min} karakter girin",
"min_selections": "Lütfen en az {min} seçenek seçin",
"min_value": "Lütfen en az {min} değerinde bir değer girin",
"minimum_options_ranked": "Lütfen en az {min} seçeneği sıralayın",
"minimum_rows_answered": "Lütfen en az {min} satırı yanıtlayın",
"please_enter_a_valid_email_address": "Lütfen geçerli bir e-posta adresi girin",
"please_enter_a_valid_phone_number": "Lütfen geçerli bir telefon numarası girin",
"please_enter_a_valid_url": "Lütfen geçerli bir URL girin",
"please_fill_out_this_field": "Lütfen bu alanı doldurun",
"recaptcha_error": {
"message": "Yanıtınız otomatik etkinlik olarak işaretlendiği için gönderilemedi. Bir insansanız, lütfen tekrar deneyin.",
"title": "İnsan olduğunuzu doğrulayamadık."
},
"value_must_contain": "Değer {value} içermelidir",
"value_must_equal": "Değer {value} olmalıdır",
"value_must_not_contain": "Değer {value} içermemelidir",
"value_must_not_equal": "Değer {value} olmamalıdır"
}
}
-2
View File
@@ -6,12 +6,10 @@
"back": "Orqaga",
"close_survey": "Sorovnomani yopish",
"company_logo": "Kompaniya logotipi",
"failed_to_load_booking_widget": "Bron qilish vidjetini yuklash amalga oshmadi. Muhitingiz turli manbalardan resurslarni bloklayotgan bo'lishi mumkin.",
"finish": "Tugatish",
"language_switch": "Tilni almashtirish",
"next": "Keyingisi",
"no_results_found": "Natijalar topilmadi",
"open_booking_page_directly_at": "Bron qilish sahifasini to'g'ridan-to'g'ri ochishga harakat qiling",
"open_in_new_tab": "Yangi oynada ochish",
"people_responded": "{count, plural, one {1 kishi javob berdi} other {{count} kishi javob berdi}}",
"please_retry_now_or_try_again_later": "Iltimos, hozir qayta urinib koring yoki keyinroq urinib koring.",
-2
View File
@@ -6,12 +6,10 @@
"back": "返回",
"close_survey": "关闭调查",
"company_logo": "公司标志",
"failed_to_load_booking_widget": "预订小部件加载失败。您的环境可能正在阻止跨域资源。",
"finish": "完成",
"language_switch": "语言切换",
"next": "下一步",
"no_results_found": "未找到结果",
"open_booking_page_directly_at": "请尝试直接打开预订页面:",
"open_in_new_tab": "在新标签页中打开",
"people_responded": "{count, plural, one {1 人已回应} other {{count} 人已回应}}",
"please_retry_now_or_try_again_later": "请立即重试或稍后再试。",
@@ -1,6 +1,5 @@
import snippet from "@calcom/embed-snippet";
import { useEffect, useMemo, useState } from "preact/hooks";
import { useTranslation } from "react-i18next";
import { useEffect, useMemo } from "preact/hooks";
import { type TSurveyCalElement } from "@formbricks/types/surveys/elements";
import { cn } from "@/lib/utils";
@@ -10,9 +9,6 @@ interface CalEmbedProps {
}
export function CalEmbed({ element, onSuccessfulBooking }: CalEmbedProps) {
const [error, setError] = useState(false);
const { t } = useTranslation();
const cal = useMemo(() => {
const calInline = snippet("https://cal.com/embed.js");
@@ -50,76 +46,13 @@ export function CalEmbed({ element, onSuccessfulBooking }: CalEmbedProps) {
document.querySelectorAll("cal-inline").forEach((el) => {
el.remove();
});
setError(false);
cal("init", { calOrigin: element.calHost ? `https://${element.calHost}` : "https://cal.com" });
cal("inline", {
elementOrSelector: "#cal-embed",
calLink: element.calUserName,
});
// Event-driven error detection via MutationObserver
let observer: MutationObserver | null = null;
let timer: ReturnType<typeof setTimeout> | null = null;
const cleanup = () => {
if (timer) clearTimeout(timer);
if (observer) observer.disconnect();
};
const embedContainer = document.getElementById("cal-embed");
if (embedContainer) {
observer = new MutationObserver((mutations) => {
for (const mutation of mutations) {
for (const node of mutation.addedNodes) {
if (node instanceof HTMLIFrameElement) {
node.addEventListener("load", () => {
cleanup();
setError(false);
});
node.addEventListener("error", () => {
cleanup();
setError(true);
});
}
}
}
});
observer.observe(embedContainer, { childList: true, subtree: true });
// Fallback timeout in case no iframe appears at all
timer = setTimeout(() => {
const iframe = embedContainer.querySelector("iframe");
if (!iframe) {
cleanup();
setError(true);
}
}, 5000);
}
return cleanup;
}, [cal, element.calHost, element.calUserName]);
if (error) {
return (
<div className="relative mt-4 overflow-auto">
<div className="border-border rounded-input border p-4 text-center">
<p className="text-sm text-red-600">{t("common.failed_to_load_booking_widget")}</p>
<p className="text-muted-foreground mt-2 text-xs">
{t("common.open_booking_page_directly_at")}{" "}
<a
href={`https://${element.calHost || "cal.com"}/${element.calUserName}`}
target="_blank"
rel="noopener noreferrer"
className="underline">
{element.calHost || "cal.com"}/{element.calUserName}
</a>
</p>
</div>
</div>
);
}
return (
<div className="relative mt-4 overflow-auto">
<div id="cal-embed" className={cn("border-border rounded-input border")} />
+3
View File
@@ -17,6 +17,7 @@ import ptTranslations from "../../locales/pt.json";
import roTranslations from "../../locales/ro.json";
import ruTranslations from "../../locales/ru.json";
import svTranslations from "../../locales/sv.json";
import trTranslations from "../../locales/tr.json";
import uzTranslations from "../../locales/uz.json";
import zhHansTranslations from "../../locales/zh-Hans.json";
@@ -42,6 +43,7 @@ i18n
"ro",
"ru",
"sv",
"tr",
"uz",
"zh-Hans",
],
@@ -63,6 +65,7 @@ i18n
ro: { translation: roTranslations },
ru: { translation: ruTranslations },
sv: { translation: svTranslations },
tr: { translation: trTranslations },
uz: { translation: uzTranslations },
"zh-Hans": { translation: zhHansTranslations },
},
+1
View File
@@ -13,6 +13,7 @@ export const ZUserLocale = z.enum([
"ro-RO",
"ru-RU",
"sv-SE",
"tr-TR",
"zh-Hans-CN",
"zh-Hant-TW",
]);
+18 -12
View File
@@ -9,6 +9,12 @@ overrides:
'@tootallnate/once': 3.0.1
schema-utils@3.3.0>ajv: 6.14.0
axios: 1.13.5
'@grpc/proto-loader@0.7.15>protobufjs': 7.5.5
'@grpc/proto-loader@0.8.0>protobufjs': 7.5.5
'@opentelemetry/otlp-transformer@0.57.1>protobufjs': 7.5.5
'@opentelemetry/otlp-transformer@0.208.0>protobufjs': 7.5.5
'@opentelemetry/otlp-transformer@0.212.0>protobufjs': 8.0.1
'@opentelemetry/otlp-transformer@0.213.0>protobufjs': 7.5.5
effect: 3.20.0
flatted: 3.4.2
hono: 4.12.7
@@ -9962,12 +9968,12 @@ packages:
proper-lockfile@4.1.2:
resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==}
protobufjs@7.5.4:
resolution: {integrity: sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==}
protobufjs@7.5.5:
resolution: {integrity: sha512-3wY1AxV+VBNW8Yypfd1yQY9pXnqTAN+KwQxL8iYm3/BjKYMNg4i0owhEe26PWDOMaIrzeeF98Lqd5NGz4omiIg==}
engines: {node: '>=12.0.0'}
protobufjs@8.0.0:
resolution: {integrity: sha512-jx6+sE9h/UryaCZhsJWbJtTEy47yXoGNYI4z8ZaRncM0zBKeRqjO2JEcOUYwrYGb1WLhXM1FfMzW3annvFv0rw==}
protobufjs@8.0.1:
resolution: {integrity: sha512-NWWCCscLjs+cOKF/s/XVNFRW7Yih0fdH+9brffR5NZCy8k42yRdl5KlWKMVXuI1vfCoy4o1z80XR/W/QUb3V3w==}
engines: {node: '>=12.0.0'}
proxy-from-env@1.1.0:
@@ -13946,14 +13952,14 @@ snapshots:
dependencies:
lodash.camelcase: 4.3.0
long: 5.3.2
protobufjs: 7.5.4
protobufjs: 7.5.5
yargs: 17.7.2
'@grpc/proto-loader@0.8.0':
dependencies:
lodash.camelcase: 4.3.0
long: 5.3.2
protobufjs: 7.5.4
protobufjs: 7.5.5
yargs: 17.7.2
'@hono/node-server@1.19.10(hono@4.12.7)':
@@ -15395,7 +15401,7 @@ snapshots:
'@opentelemetry/sdk-logs': 0.208.0(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-metrics': 2.2.0(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-trace-base': 2.2.0(@opentelemetry/api@1.9.0)
protobufjs: 7.5.4
protobufjs: 7.5.5
'@opentelemetry/otlp-transformer@0.212.0(@opentelemetry/api@1.9.0)':
dependencies:
@@ -15406,7 +15412,7 @@ snapshots:
'@opentelemetry/sdk-logs': 0.212.0(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-metrics': 2.5.1(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-trace-base': 2.5.1(@opentelemetry/api@1.9.0)
protobufjs: 8.0.0
protobufjs: 8.0.1
'@opentelemetry/otlp-transformer@0.213.0(@opentelemetry/api@1.9.0)':
dependencies:
@@ -15417,7 +15423,7 @@ snapshots:
'@opentelemetry/sdk-logs': 0.213.0(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-metrics': 2.6.0(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-trace-base': 2.6.0(@opentelemetry/api@1.9.0)
protobufjs: 7.5.4
protobufjs: 7.5.5
'@opentelemetry/otlp-transformer@0.57.1(@opentelemetry/api@1.9.0)':
dependencies:
@@ -15428,7 +15434,7 @@ snapshots:
'@opentelemetry/sdk-logs': 0.57.1(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-metrics': 1.30.1(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-trace-base': 1.30.1(@opentelemetry/api@1.9.0)
protobufjs: 7.5.4
protobufjs: 7.5.5
'@opentelemetry/propagator-b3@2.6.0(@opentelemetry/api@1.9.0)':
dependencies:
@@ -22619,7 +22625,7 @@ snapshots:
signal-exit: 3.0.7
optional: true
protobufjs@7.5.4:
protobufjs@7.5.5:
dependencies:
'@protobufjs/aspromise': 1.1.2
'@protobufjs/base64': 1.1.2
@@ -22634,7 +22640,7 @@ snapshots:
'@types/node': 25.4.0
long: 5.3.2
protobufjs@8.0.0:
protobufjs@8.0.1:
dependencies:
'@protobufjs/aspromise': 1.1.2
'@protobufjs/base64': 1.1.2