fix: email inconsistencies (#4678)

This commit is contained in:
Dhruwang Jariwala
2025-01-30 15:24:48 +05:30
committed by GitHub
parent 458f135ee1
commit f7f5737abf
24 changed files with 192 additions and 67 deletions

View File

@@ -43,7 +43,7 @@ export const sendEmbedSurveyPreviewEmailAction = authenticatedActionClient
throw new ResourceNotFoundError("Survey", parsedInput.surveyId);
}
const rawEmailHtml = await getEmailTemplateHtml(parsedInput.surveyId);
const rawEmailHtml = await getEmailTemplateHtml(parsedInput.surveyId, ctx.user.locale);
const emailHtml = rawEmailHtml
.replaceAll("?preview=true&", "?")
.replaceAll("?preview=true&;", "?")
@@ -51,7 +51,6 @@ export const sendEmbedSurveyPreviewEmailAction = authenticatedActionClient
return await sendEmbedSurveyPreviewEmail(
ctx.user.email,
"Formbricks Email Survey Preview",
emailHtml,
survey.environmentId,
ctx.user.locale,
@@ -182,5 +181,5 @@ export const getEmailHtmlAction = authenticatedActionClient
],
});
return await getEmailTemplateHtml(parsedInput.surveyId);
return await getEmailTemplateHtml(parsedInput.surveyId, ctx.user.locale);
});

View File

@@ -4,7 +4,7 @@ import { getProjectByEnvironmentId } from "@formbricks/lib/project/service";
import { getSurvey } from "@formbricks/lib/survey/service";
import { getStyling } from "@formbricks/lib/utils/styling";
export const getEmailTemplateHtml = async (surveyId: string) => {
export const getEmailTemplateHtml = async (surveyId: string, locale: string) => {
const survey = await getSurvey(surveyId);
if (!survey) {
throw new Error("Survey not found");
@@ -16,7 +16,7 @@ export const getEmailTemplateHtml = async (surveyId: string) => {
const styling = getStyling(project, survey);
const surveyUrl = WEBAPP_URL + "/s/" + survey.id;
const html = await getPreviewEmailTemplateHtml(survey, surveyUrl, styling);
const html = await getPreviewEmailTemplateHtml(survey, surveyUrl, styling, locale);
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, "");

View File

@@ -85,7 +85,12 @@ export const createUserAction = actionClient.schema(ZCreateUserAction).action(as
},
});
await sendInviteAcceptedEmail(invite.creator.name ?? "", user.name, invite.creator.email, user.locale);
await sendInviteAcceptedEmail(
invite.creator.name ?? "",
user.name,
invite.creator.email,
invite.creator.locale
);
await deleteInvite(invite.id);
}
// Handle organization assignment

View File

@@ -90,7 +90,6 @@ export const sendTestEmailAction = authenticatedActionClient
await sendEmailCustomizationPreviewEmail(
ctx.user.email,
"Formbricks Email Customization Preview",
ctx.user.name,
ctx.user.locale,
organization?.whitelabel?.logoUrl || ""

View File

@@ -1,10 +1,15 @@
import { translateEmailText } from "@/modules/email/lib/utils";
import { Text } from "@react-email/components";
export function EmailFooter(): React.JSX.Element {
interface EmailFooterProps {
locale: string;
}
export function EmailFooter({ locale }: EmailFooterProps): React.JSX.Element {
return (
<Text>
Have a great day!
<br /> The Formbricks Team
{translateEmailText("email_footer_text_1", locale)}
<br /> {translateEmailText("email_footer_text_2", locale)}
</Text>
);
}

View File

@@ -1,3 +1,4 @@
import { translateEmailText } from "@/modules/email/lib/utils";
import { Body, Container, Html, Img, Link, Section, Tailwind, Text } from "@react-email/components";
import { IMPRINT_ADDRESS, IMPRINT_URL, PRIVACY_URL } from "@formbricks/lib/constants";
@@ -8,9 +9,10 @@ const logoLink = "https://formbricks.com?utm_source=email_header&utm_medium=emai
interface EmailTemplateProps {
children: React.ReactNode;
logoUrl?: string;
locale: string;
}
export function EmailTemplate({ children, logoUrl }: EmailTemplateProps): React.JSX.Element {
export function EmailTemplate({ children, logoUrl, locale }: EmailTemplateProps): React.JSX.Element {
const isDefaultLogo = !logoUrl || logoUrl === fbLogoUrl;
return (
@@ -35,21 +37,22 @@ export function EmailTemplate({ children, logoUrl }: EmailTemplateProps): React.
</Container>
<Section className="mt-4 text-center text-sm">
<Text className="m-0 font-normal text-slate-500">This email was sent via Formbricks.</Text>
<Text className="m-0 font-normal text-slate-500">
{translateEmailText("email_template_text_1", locale)}
</Text>
{IMPRINT_ADDRESS && (
<Text className="m-0 font-normal text-slate-500 opacity-50">{IMPRINT_ADDRESS}</Text>
)}
<Text className="m-0 font-normal text-slate-500 opacity-50">
{IMPRINT_URL && (
<Link href={IMPRINT_URL} target="_blank" rel="noopener noreferrer" className="text-slate-500">
Imprint{" "}
{translateEmailText("imprint", locale)}
</Link>
)}
{IMPRINT_URL && PRIVACY_URL && "•"}
{PRIVACY_URL && (
<Link href={PRIVACY_URL} target="_blank" rel="noopener noreferrer" className="text-slate-500">
{" "}
Privacy Policy
{translateEmailText("privacy_policy", locale)}
</Link>
)}
</Text>

View File

@@ -18,28 +18,34 @@ import { getLocalizedValue } from "@formbricks/lib/i18n/utils";
import { COLOR_DEFAULTS } from "@formbricks/lib/styling/constants";
import { isLight, mixColor } from "@formbricks/lib/utils/colors";
import { type TSurvey, TSurveyQuestionTypeEnum, type TSurveyStyling } from "@formbricks/types/surveys/types";
import { getNPSOptionColor, getRatingNumberOptionColor } from "../lib/utils";
import { getNPSOptionColor, getRatingNumberOptionColor, translateEmailText } from "../lib/utils";
interface PreviewEmailTemplateProps {
survey: TSurvey;
surveyUrl: string;
styling: TSurveyStyling;
locale: string;
}
export const getPreviewEmailTemplateHtml = async (
survey: TSurvey,
surveyUrl: string,
styling: TSurveyStyling
styling: TSurveyStyling,
locale: string
): Promise<string> => {
return render(<PreviewEmailTemplate styling={styling} survey={survey} surveyUrl={surveyUrl} />, {
pretty: true,
});
return render(
<PreviewEmailTemplate styling={styling} survey={survey} surveyUrl={surveyUrl} locale={locale} />,
{
pretty: true,
}
);
};
export function PreviewEmailTemplate({
survey,
surveyUrl,
styling,
locale,
}: PreviewEmailTemplateProps): React.JSX.Element {
const url = `${surveyUrl}?preview=true`;
const urlWithPrefilling = `${surveyUrl}?preview=true&skipPrefilled=true&`;
@@ -87,7 +93,7 @@ export function PreviewEmailTemplate({
<EmailButton
className="rounded-custom inline-flex cursor-pointer appearance-none px-6 py-3 text-sm font-medium text-black"
href={`${urlWithPrefilling}${firstQuestion.id}=dismissed`}>
Reject
{translateEmailText("reject", locale)}
</EmailButton>
)}
<EmailButton
@@ -96,7 +102,7 @@ export function PreviewEmailTemplate({
isLight(brandColor) ? "text-black" : "text-white"
)}
href={`${urlWithPrefilling}${firstQuestion.id}=accepted`}>
Accept
{translateEmailText("accept", locale)}
</EmailButton>
</Container>
<EmailFooter />
@@ -365,17 +371,17 @@ export function PreviewEmailTemplate({
<EmailTemplateWrapper styling={styling} surveyUrl={url}>
<Container>
<Text className="text-question-color m-0 mb-2 block p-0 text-sm font-normal leading-6">
{getLocalizedValue(firstQuestion.subheader, defaultLanguageCode)}
{getLocalizedValue(firstQuestion.headline, defaultLanguageCode)}
</Text>
<Text className="text-question-color m-0 mb-2 block p-0 text-sm font-normal leading-6">
You have been invited to schedule a meet via cal.com.
{getLocalizedValue(firstQuestion.subheader, defaultLanguageCode)}
</Text>
<EmailButton
className={cn(
"bg-brand-color rounded-custom mx-auto block w-max cursor-pointer appearance-none px-6 py-3 text-sm font-medium",
isLight(brandColor) ? "text-black" : "text-white"
)}>
Schedule your meeting
{translateEmailText("schedule_your_meeting", defaultLanguageCode)}
</EmailButton>
</Container>
<EmailFooter />
@@ -392,7 +398,9 @@ export function PreviewEmailTemplate({
</Text>
<Section className="border-input-border-color bg-input-color rounded-custom mt-4 flex h-12 w-full items-center justify-center border border-solid">
<CalendarDaysIcon className="text-question-color inline h-4 w-4" />
<Text className="text-question-color inline text-sm font-medium">Select a date</Text>
<Text className="text-question-color inline text-sm font-medium">
{translateEmailText("select_a_date", defaultLanguageCode)}
</Text>
</Section>
<EmailFooter />
</EmailTemplateWrapper>
@@ -478,7 +486,9 @@ export function PreviewEmailTemplate({
<Section className="border-input-border-color rounded-custom mt-4 flex h-24 w-full items-center justify-center border border-dashed bg-slate-50">
<Container className="mx-auto flex items-center text-center">
<UploadIcon className="mt-6 inline h-5 w-5 text-slate-400" />
<Text className="text-slate-400">Click or drag to upload files.</Text>
<Text className="text-slate-400">
{translateEmailText("click_or_drag_to_upload_files", defaultLanguageCode)}
</Text>
</Container>
</Section>
<EmailFooter />

View File

@@ -12,7 +12,7 @@ interface ForgotPasswordEmailProps {
export function ForgotPasswordEmail({ verifyLink, locale }: ForgotPasswordEmailProps): React.JSX.Element {
return (
<EmailTemplate>
<EmailTemplate locale={locale}>
<Container>
<Heading>{translateEmailText("forgot_password_email_heading", locale)}</Heading>
<Text>{translateEmailText("forgot_password_email_text", locale)}</Text>
@@ -24,7 +24,7 @@ export function ForgotPasswordEmail({ verifyLink, locale }: ForgotPasswordEmailP
{translateEmailText("forgot_password_email_link_valid_for_24_hours", locale)}
</Text>
<Text className="mb-0">{translateEmailText("forgot_password_email_did_not_request", locale)}</Text>
<EmailFooter />
<EmailFooter locale={locale} />
</Container>
</EmailTemplate>
);

View File

@@ -10,11 +10,11 @@ interface PasswordResetNotifyEmailProps {
export function PasswordResetNotifyEmail({ locale }: PasswordResetNotifyEmailProps): React.JSX.Element {
return (
<EmailTemplate>
<EmailTemplate locale={locale}>
<Container>
<Heading>{translateEmailText("password_changed_email_heading", locale)}</Heading>
<Text>{translateEmailText("password_changed_email_text", locale)}</Text>
<EmailFooter />
<EmailFooter locale={locale} />
</Container>
</EmailTemplate>
);

View File

@@ -17,7 +17,7 @@ export function VerificationEmail({
locale,
}: VerificationEmailProps): React.JSX.Element {
return (
<EmailTemplate>
<EmailTemplate locale={locale}>
<Container>
<Heading>{translateEmailText("verification_email_heading", locale)}</Heading>
<Text>{translateEmailText("verification_email_text", locale)}</Text>
@@ -38,7 +38,7 @@ export function VerificationEmail({
{translateEmailText("verification_email_request_new_verification", locale)}
</Link>
</Text>
<EmailFooter />
<EmailFooter locale={locale} />
</Container>
</EmailTemplate>
);

View File

@@ -15,7 +15,7 @@ export function EmailCustomizationPreviewEmail({
logoUrl,
}: EmailCustomizationPreviewEmailProps): React.JSX.Element {
return (
<EmailTemplate logoUrl={logoUrl}>
<EmailTemplate logoUrl={logoUrl} locale={locale}>
<Container>
<Heading>
{translateEmailText("email_customization_preview_email_heading", locale, {

View File

@@ -16,7 +16,7 @@ export function InviteAcceptedEmail({
locale,
}: InviteAcceptedEmailProps): React.JSX.Element {
return (
<EmailTemplate>
<EmailTemplate locale={locale}>
<Container>
<Text>
{translateEmailText("invite_accepted_email_heading", locale)} {inviterName},
@@ -25,7 +25,7 @@ export function InviteAcceptedEmail({
{translateEmailText("invite_accepted_email_text_par1", locale)} {inviteeName}{" "}
{translateEmailText("invite_accepted_email_text_par2", locale)}
</Text>
<EmailFooter />
<EmailFooter locale={locale} />
</Container>
</EmailTemplate>
);

View File

@@ -19,7 +19,7 @@ export function InviteEmail({
locale,
}: InviteEmailProps): React.JSX.Element {
return (
<EmailTemplate>
<EmailTemplate locale={locale}>
<Container>
<Text>
{translateEmailText("invite_email_heading", locale)} {inviteeName},
@@ -28,8 +28,8 @@ export function InviteEmail({
{translateEmailText("invite_email_text_par1", locale)} {inviterName}{" "}
{translateEmailText("invite_email_text_par2", locale)}
</Text>
<EmailButton href={verifyLink} label="Join organization" />
<EmailFooter />
<EmailButton href={verifyLink} label={translateEmailText("invite_email_button_label", locale)} />
<EmailFooter locale={locale} />
</Container>
</EmailTemplate>
);

View File

@@ -20,7 +20,7 @@ export function OnboardingInviteEmail({
inviteeName,
}: OnboardingInviteEmailProps): React.JSX.Element {
return (
<EmailTemplate>
<EmailTemplate locale={locale}>
<Container>
<Heading>
{translateEmailText("onboarding_invite_email_heading", locale)} {inviteeName} 👋
@@ -34,8 +34,11 @@ export function OnboardingInviteEmail({
<li>{translateEmailText("onboarding_invite_email_connect_formbricks", locale)}</li>
<li>{translateEmailText("onboarding_invite_email_done", locale)} </li>
</ol>
<EmailButton href={verifyLink} label={`Join ${inviterName}'s organization`} />
<EmailFooter />
<EmailButton
href={verifyLink}
label={translateEmailText("onboarding_invite_email_button_label", locale, { inviterName })}
/>
<EmailFooter locale={locale} />
</Container>
</EmailTemplate>
);

View File

@@ -17,7 +17,7 @@ export function EmbedSurveyPreviewEmail({
logoUrl,
}: EmbedSurveyPreviewEmailProps): React.JSX.Element {
return (
<EmailTemplate logoUrl={logoUrl}>
<EmailTemplate logoUrl={logoUrl} locale={locale}>
<Container>
<Heading>{translateEmailText("embed_survey_preview_email_heading", locale)}</Heading>
<Text>{translateEmailText("embed_survey_preview_email_text", locale)}</Text>

View File

@@ -19,7 +19,7 @@ export function LinkSurveyEmail({
logoUrl,
}: LinkSurveyEmailProps): React.JSX.Element {
return (
<EmailTemplate logoUrl={logoUrl}>
<EmailTemplate logoUrl={logoUrl} locale={locale}>
<Container>
<Heading>{translateEmailText("verification_email_hey", locale)}</Heading>
<Text>{translateEmailText("verification_email_thanks", locale)}</Text>
@@ -28,7 +28,7 @@ export function LinkSurveyEmail({
<Text className="text-xs text-slate-400">
{translateEmailText("verification_email_survey_name", locale)}: {surveyName}
</Text>
<EmailFooter />
<EmailFooter locale={locale} />
</Container>
</EmailTemplate>
);

View File

@@ -93,7 +93,7 @@ export function ResponseFinishedEmail({
const questions = getQuestionResponseMapping(survey, response);
return (
<EmailTemplate>
<EmailTemplate locale={locale}>
<Container>
<Row>
<Column>

View File

@@ -24,7 +24,7 @@ export function WeeklySummaryNotificationEmail({
locale,
}: WeeklySummaryNotificationEmailProps): React.JSX.Element {
return (
<EmailTemplate>
<EmailTemplate locale={locale}>
<NotificationHeader
endDate={endDate}
endYear={endYear}

View File

@@ -46,8 +46,10 @@ interface SendEmailDataProps {
html: string;
}
const getEmailSubject = (projectName: string): string => {
return `${projectName} User Insights - Last Week by Formbricks`;
const getEmailSubject = (projectName: string, locale: string): string => {
return translateEmailText("weekly_summary_email_subject", locale, {
projectName,
});
};
export const sendEmail = async (emailData: SendEmailDataProps): Promise<boolean> => {
@@ -117,7 +119,7 @@ export const sendForgotPasswordEmail = async (user: {
const html = await render(ForgotPasswordEmail({ verifyLink, locale: user.locale }));
return await sendEmail({
to: user.email,
subject: "Reset your Formbricks password",
subject: translateEmailText("forgot_password_email_subject", user.locale),
html,
});
};
@@ -129,7 +131,7 @@ export const sendPasswordResetNotifyEmail = async (user: {
const html = await render(PasswordResetNotifyEmail({ locale: user.locale }));
return await sendEmail({
to: user.email,
subject: "Your Formbricks password has been changed",
subject: translateEmailText("password_reset_notify_email_subject", user.locale),
html,
});
};
@@ -155,14 +157,16 @@ export const sendInviteMemberEmail = async (
);
return await sendEmail({
to: email,
subject: `${inviterName} needs a hand setting up Formbricks. Can you help out?`,
subject: translateEmailText("onboarding_invite_email_subject", locale, {
inviterName,
}),
html,
});
} else {
const html = await render(InviteEmail({ inviteeName, inviterName, verifyLink, locale }));
return await sendEmail({
to: email,
subject: `You're invited to collaborate on Formbricks!`,
subject: translateEmailText("invite_member_email_subject", locale),
html,
});
}
@@ -177,7 +181,7 @@ export const sendInviteAcceptedEmail = async (
const html = await render(InviteAcceptedEmail({ inviteeName, inviterName, locale }));
await sendEmail({
to: email,
subject: `You've got a new organization member!`,
subject: translateEmailText("invite_accepted_email_subject", locale),
html,
});
};
@@ -212,8 +216,13 @@ export const sendResponseFinishedEmail = async (
await sendEmail({
to: email,
subject: personEmail
? `${personEmail} just completed your ${survey.name} survey ✅`
: `A response for ${survey.name} was completed ✅`,
? translateEmailText("response_finished_email_subject_with_email", locale, {
personEmail,
surveyName: survey.name,
})
: translateEmailText("response_finished_email_subject", locale, {
surveyName: survey.name,
}),
replyTo: personEmail?.toString() ?? MAIL_FROM,
html,
});
@@ -221,7 +230,6 @@ export const sendResponseFinishedEmail = async (
export const sendEmbedSurveyPreviewEmail = async (
to: string,
subject: string,
innerHtml: string,
environmentId: string,
locale: string,
@@ -230,14 +238,13 @@ export const sendEmbedSurveyPreviewEmail = async (
const html = await render(EmbedSurveyPreviewEmail({ html: innerHtml, environmentId, locale, logoUrl }));
return await sendEmail({
to,
subject,
subject: translateEmailText("embed_survey_preview_email_subject", locale),
html,
});
};
export const sendEmailCustomizationPreviewEmail = async (
to: string,
subject: string,
userName: string,
locale: string,
logoUrl?: string
@@ -246,7 +253,7 @@ export const sendEmailCustomizationPreviewEmail = async (
return await sendEmail({
to,
subject,
subject: translateEmailText("email_customization_preview_email_subject", locale),
html: emailHtmlBody,
});
};
@@ -270,7 +277,7 @@ export const sendLinkSurveyToVerifiedEmail = async (data: TLinkSurveyEmailData):
const html = await render(LinkSurveyEmail({ surveyName, surveyLink, locale, logoUrl }));
return await sendEmail({
to: data.email,
subject: "Your survey is ready to be filled out.",
subject: translateEmailText("verified_link_survey_email_subject", locale),
html,
});
};
@@ -302,7 +309,7 @@ export const sendWeeklySummaryNotificationEmail = async (
);
await sendEmail({
to: email,
subject: getEmailSubject(notificationData.projectName),
subject: getEmailSubject(notificationData.projectName, locale),
html,
});
};
@@ -334,7 +341,7 @@ export const sendNoLiveSurveyNotificationEmail = async (
);
await sendEmail({
to: email,
subject: getEmailSubject(notificationData.projectName),
subject: getEmailSubject(notificationData.projectName, locale),
html,
});
};

View File

@@ -38,6 +38,7 @@ interface InviteWithCreator extends TInvite {
creator: {
name: string | null;
email: string;
locale: string;
};
}
export const getInvitesByOrganizationId = reactCache(
@@ -144,6 +145,7 @@ export const getInvite = reactCache(
select: {
name: true,
email: true,
locale: true,
},
},
},

View File

@@ -443,24 +443,36 @@
"you_will_be_downgraded_to_the_community_edition_on_date": "Du wirst am {Datum} auf die Community Edition herabgestuft."
},
"emails": {
"accept": "Annehmen",
"click_or_drag_to_upload_files": "Klicke oder ziehe, um Dateien hochzuladen.",
"email_customization_preview_email_heading": "Hey {userName}",
"email_customization_preview_email_subject": "Formbricks E-Mail-Umfrage Vorschau",
"email_customization_preview_email_text": "Dies ist eine E-Mail-Vorschau, um dir zu zeigen, welches Logo in den E-Mails gerendert wird.",
"email_footer_text_1": "Einen schönen Tag noch!",
"email_footer_text_2": "Dein Formbricks Team",
"email_template_text_1": "Diese E-Mail wurde via Formbricks gesendet.",
"embed_survey_preview_email_didnt_request": "Kein Interesse?",
"embed_survey_preview_email_environment_id": "Umgebungs-ID",
"embed_survey_preview_email_fight_spam": "Hilf uns, Spam zu bekämpfen, und leite diese Mail an hola@formbricks.com weiter.",
"embed_survey_preview_email_heading": "Vorschau Einbettung in E-Mail",
"embed_survey_preview_email_subject": "Formbricks E-Mail-Umfrage Vorschau",
"embed_survey_preview_email_text": "So sieht die Umfrage eingebettet in eine E-Mail aus:",
"forgot_password_email_change_password": "Passwort ändern",
"forgot_password_email_did_not_request": "Wenn Du sie nicht angefordert hast, ignoriere bitte diese E-Mail.",
"forgot_password_email_heading": "Passwort ändern",
"forgot_password_email_link_valid_for_24_hours": "Der Link ist 24 Stunden gültig.",
"forgot_password_email_subject": "Setz dein Formbricks-Passwort zurück",
"forgot_password_email_text": "Du hast einen Link angefordert, um dein Passwort zu ändern. Du kannst dies tun, indem Du auf den untenstehenden Link klickst:",
"imprint": "Impressum",
"invite_accepted_email_heading": "Hey",
"invite_accepted_email_subject": "Du hast einen neuen Organisation-Mitglied!",
"invite_accepted_email_text_par1": "Wollte dir nur Bescheid geben, dass",
"invite_accepted_email_text_par2": "deine Einladung angenommen hat. Viel Spaß bei der Zusammenarbeit!",
"invite_email_button_label": "Organisation beitreten",
"invite_email_heading": "Hey",
"invite_email_text_par1": "Dein Kollege",
"invite_email_text_par2": "hat Dich eingeladen, Formbricks zu nutzen. Um die Einladung anzunehmen, klicke bitte auf den untenstehenden Link:",
"invite_member_email_subject": "Du wurdest eingeladen, Formbricks zu nutzen!",
"live_survey_notification_completed": "Abgeschlossen",
"live_survey_notification_draft": "Entwurf",
"live_survey_notification_in_progress": "In Bearbeitung",
@@ -483,13 +495,22 @@
"notification_insight_displays": "Displays",
"notification_insight_responses": "Antworten",
"notification_insight_surveys": "Umfragen",
"onboarding_invite_email_button_label": "Tritt {inviterName}s Organisation bei",
"onboarding_invite_email_connect_formbricks": "Verbinde Formbricks in nur wenigen Minuten über ein HTML-Snippet oder via NPM mit deiner App oder Website.",
"onboarding_invite_email_create_account": "Erstelle ein Konto, um {inviterName}s Organisation beizutreten.",
"onboarding_invite_email_done": "Erledigt ✅",
"onboarding_invite_email_get_started_in_minutes": "Dauert nur wenige Minuten",
"onboarding_invite_email_heading": "Hey ",
"onboarding_invite_email_subject": "{inviterName} braucht Hilfe bei Formbricks. Kannst Du ihm helfen?",
"password_changed_email_heading": "Passwort geändert",
"password_changed_email_text": "Dein Passwort wurde erfolgreich geändert.",
"password_reset_notify_email_subject": "Dein Formbricks-Passwort wurde geändert",
"privacy_policy": "Datenschutzerklärung",
"reject": "Ablehnen",
"response_finished_email_subject": "Eine Antwort für {surveyName} wurde abgeschlossen ✅",
"response_finished_email_subject_with_email": "{personEmail} hat deine Umfrage {surveyName} abgeschlossen ✅",
"schedule_your_meeting": "Termin planen",
"select_a_date": "Datum auswählen",
"survey_response_finished_email_congrats": "Glückwunsch, Du hast eine neue Antwort auf deine Umfrage {surveyName} erhalten!",
"survey_response_finished_email_dont_want_notifications": "Möchtest Du diese Benachrichtigungen nicht erhalten?",
"survey_response_finished_email_hey": "Hey 👋",
@@ -512,12 +533,14 @@
"verification_email_thanks": "Danke, dass Du deine E-Mail bestätigt hast!",
"verification_email_to_fill_survey": "Um die Umfrage auszufüllen, klicke bitte auf den untenstehenden Button:",
"verification_email_verify_email": "E-Mail bestätigen",
"verified_link_survey_email_subject": "Deine Umfrage ist bereit zum Ausfüllen.",
"weekly_summary_create_reminder_notification_body_cal_slot": "Wähle einen 15-minütigen Termin im Kalender unseres Gründers aus.",
"weekly_summary_create_reminder_notification_body_dont_let_a_week_pass": "Lass keine Woche vergehen, ohne etwas über deine Nutzer zu lernen:",
"weekly_summary_create_reminder_notification_body_need_help": "Brauchst Du Hilfe, die richtige Umfrage für dein Produkt zu finden?",
"weekly_summary_create_reminder_notification_body_reply_email": "oder antworte auf diese E-Mail :)",
"weekly_summary_create_reminder_notification_body_setup_a_new_survey": "Neue Umfrage einrichten",
"weekly_summary_create_reminder_notification_body_text": "Wir würden dir gerne eine wöchentliche Zusammenfassung schicken, aber momentan laufen keine Umfragen für {projectName}."
"weekly_summary_create_reminder_notification_body_text": "Wir würden dir gerne eine wöchentliche Zusammenfassung schicken, aber momentan laufen keine Umfragen für {projectName}.",
"weekly_summary_email_subject": "{projectName} Nutzer-Insights Letzte Woche von Formbricks"
},
"environments": {
"actions": {

View File

@@ -443,24 +443,36 @@
"you_will_be_downgraded_to_the_community_edition_on_date": "You will be downgraded to the Community Edition on {date}."
},
"emails": {
"accept": "Accept",
"click_or_drag_to_upload_files": "Click or drag to upload files.",
"email_customization_preview_email_heading": "Hey {userName}",
"email_customization_preview_email_subject": "Formbricks Email Customization Preview",
"email_customization_preview_email_text": "This is an email preview to show you which logo will be rendered in the emails.",
"email_footer_text_1": "Have a great day!",
"email_footer_text_2": "The Formbricks Team",
"email_template_text_1": "This email was sent via Formbricks.",
"embed_survey_preview_email_didnt_request": "Didn't request this?",
"embed_survey_preview_email_environment_id": "Environment ID",
"embed_survey_preview_email_fight_spam": "Help us fight spam and forward this mail to hola@formbricks.com",
"embed_survey_preview_email_heading": "Preview Email Embed",
"embed_survey_preview_email_subject": "Formbricks Email Survey Preview",
"embed_survey_preview_email_text": "This is how the code snippet looks embedded into an email:",
"forgot_password_email_change_password": "Change password",
"forgot_password_email_did_not_request": "If you didn't request this, please ignore this email.",
"forgot_password_email_heading": "Change password",
"forgot_password_email_link_valid_for_24_hours": "The link is valid for 24 hours.",
"forgot_password_email_subject": "Reset your Formbricks password",
"forgot_password_email_text": "You have requested a link to change your password. You can do this by clicking the link below:",
"imprint": "Imprint",
"invite_accepted_email_heading": "Hey",
"invite_accepted_email_subject": "You've got a new organization member!",
"invite_accepted_email_text_par1": "Just letting you know that",
"invite_accepted_email_text_par2": "accepted your invitation. Have fun collaborating!",
"invite_email_button_label": "Join organization",
"invite_email_heading": "Hey",
"invite_email_text_par1": "Your colleague",
"invite_email_text_par2": "invited you to join them at Formbricks. To accept the invitation, please click the link below:",
"invite_member_email_subject": "You're invited to collaborate on Formbricks!",
"live_survey_notification_completed": "Completed",
"live_survey_notification_draft": "Draft",
"live_survey_notification_in_progress": "In Progress",
@@ -483,13 +495,22 @@
"notification_insight_displays": "Displays",
"notification_insight_responses": "Responses",
"notification_insight_surveys": "Surveys",
"onboarding_invite_email_button_label": "Join {inviterName}'s organization",
"onboarding_invite_email_connect_formbricks": "Connect Formbricks to your app or website via HTML Snippet or NPM in just a few minutes.",
"onboarding_invite_email_create_account": "Create an account to join {inviterName}'s organization.",
"onboarding_invite_email_done": "Done ✅",
"onboarding_invite_email_get_started_in_minutes": "Get Started in Minutes",
"onboarding_invite_email_heading": "Hey ",
"onboarding_invite_email_subject": "{inviterName} needs a hand setting up Formbricks. Can you help out?",
"password_changed_email_heading": "Password changed",
"password_changed_email_text": "Your password has been changed successfully.",
"password_reset_notify_email_subject": "Your Formbricks password has been changed",
"privacy_policy": "Privacy Policy",
"reject": "Reject",
"response_finished_email_subject": "A response for {surveyName} was completed ✅",
"response_finished_email_subject_with_email": "{personEmail} just completed your {surveyName} survey ✅",
"schedule_your_meeting": "Schedule your meeting",
"select_a_date": "Select a date",
"survey_response_finished_email_congrats": "Congrats, you received a new response to your survey! Someone just completed your survey: {surveyName}",
"survey_response_finished_email_dont_want_notifications": "Don't want to get these notifications?",
"survey_response_finished_email_hey": "Hey 👋",
@@ -512,12 +533,14 @@
"verification_email_thanks": "Thanks for validating your email!",
"verification_email_to_fill_survey": "To fill out the survey please click on the button below:",
"verification_email_verify_email": "Verify email",
"verified_link_survey_email_subject": "Your survey is ready to be filled out.",
"weekly_summary_create_reminder_notification_body_cal_slot": "Pick a 15-minute slot in our CEOs calendar",
"weekly_summary_create_reminder_notification_body_dont_let_a_week_pass": "Don't let a week pass without learning about your users:",
"weekly_summary_create_reminder_notification_body_need_help": "Need help finding the right survey for your product?",
"weekly_summary_create_reminder_notification_body_reply_email": "or reply to this email :)",
"weekly_summary_create_reminder_notification_body_setup_a_new_survey": "Setup a new survey",
"weekly_summary_create_reminder_notification_body_text": "We'd love to send you a Weekly Summary, but currently there are no surveys running for {projectName}."
"weekly_summary_create_reminder_notification_body_text": "We'd love to send you a Weekly Summary, but currently there are no surveys running for {projectName}.",
"weekly_summary_email_subject": "{projectName} User Insights - Last Week by Formbricks"
},
"environments": {
"actions": {

View File

@@ -443,24 +443,36 @@
"you_will_be_downgraded_to_the_community_edition_on_date": "Vous serez rétrogradé à l'édition communautaire le {date}."
},
"emails": {
"accept": "Accepter",
"click_or_drag_to_upload_files": "Cliquez ou faites glisser pour télécharger des fichiers.",
"email_customization_preview_email_heading": "Salut {userName}",
"email_customization_preview_email_subject": "Aperçu de la personnalisation des e-mails Formbricks",
"email_customization_preview_email_text": "C'est une prévisualisation d'e-mail pour vous montrer quel logo sera rendu dans les e-mails.",
"email_footer_text_1": "Passe une belle journée !",
"email_footer_text_2": "L'équipe Formbricks",
"email_template_text_1": "Cet e-mail a été envoyé via Formbricks.",
"embed_survey_preview_email_didnt_request": "Vous n'avez pas demandé cela ?",
"embed_survey_preview_email_environment_id": "ID d'environnement",
"embed_survey_preview_email_fight_spam": "Aidez-nous à lutter contre le spam et transférez ce mail à hola@formbricks.com.",
"embed_survey_preview_email_heading": "Aperçu de l'email intégré",
"embed_survey_preview_email_subject": "Aperçu du sondage par e-mail Formbricks",
"embed_survey_preview_email_text": "C'est ainsi que le code s'affiche intégré dans un e-mail :",
"forgot_password_email_change_password": "Changer le mot de passe",
"forgot_password_email_did_not_request": "Si vous n'avez pas demandé cela, veuillez ignorer cet e-mail.",
"forgot_password_email_heading": "Changer le mot de passe",
"forgot_password_email_link_valid_for_24_hours": "Le lien est valable pendant 24 heures.",
"forgot_password_email_subject": "Réinitialise ton mot de passe Formbricks",
"forgot_password_email_text": "Vous avez demandé un lien pour changer votre mot de passe. Vous pouvez le faire en cliquant sur le lien ci-dessous :",
"imprint": "Impressum",
"invite_accepted_email_heading": "Salut",
"invite_accepted_email_subject": "Vous avez un nouveau membre dans votre organisation !",
"invite_accepted_email_text_par1": "Je te fais savoir que",
"invite_accepted_email_text_par2": "accepté votre invitation. Amusez-vous bien à collaborer !",
"invite_email_button_label": "Rejoindre l'organisation",
"invite_email_heading": "Salut",
"invite_email_text_par1": "Votre collègue",
"invite_email_text_par2": "vous a invité à les rejoindre sur Formbricks. Pour accepter l'invitation, veuillez cliquer sur le lien ci-dessous :",
"invite_member_email_subject": "Vous avez été invité à collaborer sur Formbricks !",
"live_survey_notification_completed": "Terminé",
"live_survey_notification_draft": "Brouillon",
"live_survey_notification_in_progress": "En cours",
@@ -483,13 +495,22 @@
"notification_insight_displays": "Affichages",
"notification_insight_responses": "Réponses",
"notification_insight_surveys": "Enquêtes",
"onboarding_invite_email_button_label": "Rejoins l'organisation de {inviterName}",
"onboarding_invite_email_connect_formbricks": "Connectez Formbricks à votre application ou site web via un extrait HTML ou NPM en quelques minutes seulement.",
"onboarding_invite_email_create_account": "Créez un compte pour rejoindre l'organisation de {inviterName}.",
"onboarding_invite_email_done": "Fait ✅",
"onboarding_invite_email_get_started_in_minutes": "Commencez en quelques minutes",
"onboarding_invite_email_heading": "Salut ",
"onboarding_invite_email_subject": "{inviterName} a besoin d'aide pour configurer Formbricks. Peux-tu l'aider ?",
"password_changed_email_heading": "Mot de passe changé",
"password_changed_email_text": "Votre mot de passe a été changé avec succès.",
"password_reset_notify_email_subject": "Ton mot de passe Formbricks a été changé",
"privacy_policy": "Politique de confidentialité",
"reject": "Rejeter",
"response_finished_email_subject": "Une réponse pour {surveyName} a été complétée ✅",
"response_finished_email_subject_with_email": "{personEmail} vient de compléter votre enquête {surveyName} ✅",
"schedule_your_meeting": "Planifier votre rendez-vous",
"select_a_date": "Sélectionner une date",
"survey_response_finished_email_congrats": "Félicitations, vous avez reçu une nouvelle réponse à votre enquête ! Quelqu'un vient de compléter votre enquête : {surveyName}",
"survey_response_finished_email_dont_want_notifications": "Vous ne voulez pas recevoir ces notifications ?",
"survey_response_finished_email_hey": "Salut 👋",
@@ -512,12 +533,14 @@
"verification_email_thanks": "Merci de valider votre email !",
"verification_email_to_fill_survey": "Pour remplir le questionnaire, veuillez cliquer sur le bouton ci-dessous :",
"verification_email_verify_email": "Vérifier l'email",
"verified_link_survey_email_subject": "Votre enquête est prête à être remplie.",
"weekly_summary_create_reminder_notification_body_cal_slot": "Choisissez un créneau de 15 minutes dans le calendrier de notre PDG.",
"weekly_summary_create_reminder_notification_body_dont_let_a_week_pass": "Ne laissez pas une semaine passer sans en apprendre davantage sur vos utilisateurs :",
"weekly_summary_create_reminder_notification_body_need_help": "Besoin d'aide pour trouver le bon sondage pour votre produit ?",
"weekly_summary_create_reminder_notification_body_reply_email": "ou répondez à cet e-mail :)",
"weekly_summary_create_reminder_notification_body_setup_a_new_survey": "Configurer une nouvelle enquête",
"weekly_summary_create_reminder_notification_body_text": "Nous aimerions vous envoyer un résumé hebdomadaire, mais actuellement, il n'y a pas d'enquêtes en cours pour {projectName}."
"weekly_summary_create_reminder_notification_body_text": "Nous aimerions vous envoyer un résumé hebdomadaire, mais actuellement, il n'y a pas d'enquêtes en cours pour {projectName}.",
"weekly_summary_email_subject": "Aperçu des utilisateurs de {projectName} La semaine dernière par Formbricks"
},
"environments": {
"actions": {

View File

@@ -443,24 +443,36 @@
"you_will_be_downgraded_to_the_community_edition_on_date": "Você será rebaixado para a Edição Comunitária em {data}."
},
"emails": {
"accept": "Aceitar",
"click_or_drag_to_upload_files": "Clique ou arraste para fazer o upload de arquivos.",
"email_customization_preview_email_heading": "Oi {userName}",
"email_customization_preview_email_subject": "Prévia da personalização de e-mails do Formbricks",
"email_customization_preview_email_text": "Esta é uma pré-visualização de e-mail para mostrar qual logo será renderizado nos e-mails.",
"email_footer_text_1": "Tenha um ótimo dia!",
"email_footer_text_2": "O time Formbricks",
"email_template_text_1": "Este e-mail foi enviado através do Formbricks.",
"embed_survey_preview_email_didnt_request": "Não pediu isso?",
"embed_survey_preview_email_environment_id": "ID do Ambiente",
"embed_survey_preview_email_fight_spam": "Ajude a gente a combater spam e encaminhe este e-mail para hola@formbricks.com",
"embed_survey_preview_email_heading": "Pré-visualizar Incorporação de Email",
"embed_survey_preview_email_subject": "Prévia da pesquisa por e-mail do Formbricks",
"embed_survey_preview_email_text": "É assim que o trecho de código fica embutido em um e-mail:",
"forgot_password_email_change_password": "Mudar senha",
"forgot_password_email_did_not_request": "Se você não solicitou isso, por favor ignore este e-mail.",
"forgot_password_email_heading": "Mudar senha",
"forgot_password_email_link_valid_for_24_hours": "O link é válido por 24 horas.",
"forgot_password_email_subject": "Redefinir sua senha Formbricks",
"forgot_password_email_text": "Você pediu um link pra trocar sua senha. Você pode fazer isso clicando no link abaixo:",
"imprint": "Impressum",
"invite_accepted_email_heading": "E aí",
"invite_accepted_email_subject": "Você tem um novo membro na sua organização!",
"invite_accepted_email_text_par1": "Só pra te avisar que",
"invite_accepted_email_text_par2": "aceitou seu convite. Divirta-se colaborando!",
"invite_email_button_label": "Entrar na organização",
"invite_email_heading": "E aí",
"invite_email_text_par1": "Seu colega",
"invite_email_text_par2": "te convidou para se juntar a eles na Formbricks. Para aceitar o convite, por favor clique no link abaixo:",
"invite_member_email_subject": "Você foi convidado a colaborar no Formbricks!",
"live_survey_notification_completed": "Concluído",
"live_survey_notification_draft": "Rascunho",
"live_survey_notification_in_progress": "Em andamento",
@@ -483,13 +495,22 @@
"notification_insight_displays": "telas",
"notification_insight_responses": "Respostas",
"notification_insight_surveys": "pesquisas",
"onboarding_invite_email_button_label": "Entre na organização de {inviterName}",
"onboarding_invite_email_connect_formbricks": "Conecte o Formbricks ao seu app ou site via HTML Snippet ou NPM em apenas alguns minutos.",
"onboarding_invite_email_create_account": "Crie uma conta para entrar na organização de {inviterName}.",
"onboarding_invite_email_done": "Feito ✅",
"onboarding_invite_email_get_started_in_minutes": "Comece em Minutos",
"onboarding_invite_email_heading": "Oi ",
"onboarding_invite_email_subject": "{inviterName} precisa de ajuda para configurar o Formbricks. Você pode ajudar?",
"password_changed_email_heading": "Senha alterada",
"password_changed_email_text": "Sua senha foi alterada com sucesso.",
"password_reset_notify_email_subject": "Sua senha Formbricks foi alterada",
"privacy_policy": "Política de Privacidade",
"reject": "Rejeitar",
"response_finished_email_subject": "Uma resposta para {surveyName} foi concluída ✅",
"response_finished_email_subject_with_email": "{personEmail} acabou de completar sua pesquisa {surveyName} ✅",
"schedule_your_meeting": "Agendar sua reunião",
"select_a_date": "Selecione uma data",
"survey_response_finished_email_congrats": "Parabéns, você recebeu uma nova resposta na sua pesquisa! Alguém acabou de completar sua pesquisa: {surveyName}",
"survey_response_finished_email_dont_want_notifications": "Não quer receber essas notificações?",
"survey_response_finished_email_hey": "E aí 👋",
@@ -512,12 +533,14 @@
"verification_email_thanks": "Valeu por validar seu e-mail!",
"verification_email_to_fill_survey": "Para preencher a pesquisa, por favor clique no botão abaixo:",
"verification_email_verify_email": "Verificar e-mail",
"verified_link_survey_email_subject": "Sua pesquisa está pronta para ser preenchida.",
"weekly_summary_create_reminder_notification_body_cal_slot": "Escolha um horário de 15 minutos na agenda do nosso CEO",
"weekly_summary_create_reminder_notification_body_dont_let_a_week_pass": "Não deixe uma semana passar sem aprender sobre seus usuários:",
"weekly_summary_create_reminder_notification_body_need_help": "Precisa de ajuda pra encontrar a pesquisa certa pro seu produto?",
"weekly_summary_create_reminder_notification_body_reply_email": "ou responde a esse e-mail :)",
"weekly_summary_create_reminder_notification_body_setup_a_new_survey": "Configurar uma nova pesquisa",
"weekly_summary_create_reminder_notification_body_text": "Adoraríamos te enviar um Resumo Semanal, mas no momento não há pesquisas em andamento para {projectName}."
"weekly_summary_create_reminder_notification_body_text": "Adoraríamos te enviar um Resumo Semanal, mas no momento não há pesquisas em andamento para {projectName}.",
"weekly_summary_email_subject": "Insights de usuários do {projectName} Semana passada por Formbricks"
},
"environments": {
"actions": {