mirror of
https://github.com/formbricks/formbricks.git
synced 2026-01-05 16:19:55 -06:00
fix: email embed styles (#2554)
Co-authored-by: Matti Nannt <mail@matthiasnannt.com>
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
import { getPreviewEmailTemplateHtml } from "@formbricks/email/components/survey/PreviewEmailTemplste";
|
||||
import { getPreviewEmailTemplateHtml } from "@formbricks/email/components/survey/PreviewEmailTemplate";
|
||||
import { WEBAPP_URL } from "@formbricks/lib/constants";
|
||||
import { getProductByEnvironmentId } from "@formbricks/lib/product/service";
|
||||
import { COLOR_DEFAULTS } from "@formbricks/lib/styling/constants";
|
||||
import { getSurvey } from "@formbricks/lib/survey/service";
|
||||
import { getStyling } from "@formbricks/lib/utils/styling";
|
||||
|
||||
export const getEmailTemplateHtml = async (surveyId) => {
|
||||
export const getEmailTemplateHtml = async (surveyId: string) => {
|
||||
const survey = await getSurvey(surveyId);
|
||||
if (!survey) {
|
||||
throw new Error("Survey not found");
|
||||
@@ -13,9 +13,10 @@ export const getEmailTemplateHtml = async (surveyId) => {
|
||||
if (!product) {
|
||||
throw new Error("Product not found");
|
||||
}
|
||||
const brandColor = product.styling.brandColor?.light || COLOR_DEFAULTS.brandColor;
|
||||
|
||||
const styling = getStyling(product, survey);
|
||||
const surveyUrl = WEBAPP_URL + "/s/" + survey.id;
|
||||
const html = getPreviewEmailTemplateHtml(survey, surveyUrl, brandColor);
|
||||
const html = getPreviewEmailTemplateHtml(survey, surveyUrl, styling);
|
||||
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, "");
|
||||
|
||||
@@ -15,48 +15,52 @@ import React from "react";
|
||||
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
import { getLocalizedValue } from "@formbricks/lib/i18n/utils";
|
||||
import { isLight } from "@formbricks/lib/utils";
|
||||
import { TSurvey, TSurveyQuestionType } from "@formbricks/types/surveys";
|
||||
import { COLOR_DEFAULTS } from "@formbricks/lib/styling/constants";
|
||||
import { isLight, mixColor } from "@formbricks/lib/utils";
|
||||
import { TSurvey, TSurveyQuestionType, TSurveyStyling } from "@formbricks/types/surveys";
|
||||
import { RatingSmiley } from "@formbricks/ui/RatingSmiley";
|
||||
|
||||
interface PreviewEmailTemplateProps {
|
||||
survey: TSurvey;
|
||||
surveyUrl: string;
|
||||
brandColor: string;
|
||||
styling: TSurveyStyling;
|
||||
}
|
||||
|
||||
export const getPreviewEmailTemplateHtml = (survey: TSurvey, surveyUrl: string, brandColor: string) => {
|
||||
return render(<PreviewEmailTemplate survey={survey} surveyUrl={surveyUrl} brandColor={brandColor} />, {
|
||||
export const getPreviewEmailTemplateHtml = (survey: TSurvey, surveyUrl: string, styling: TSurveyStyling) => {
|
||||
return render(<PreviewEmailTemplate survey={survey} surveyUrl={surveyUrl} styling={styling} />, {
|
||||
pretty: true,
|
||||
});
|
||||
};
|
||||
|
||||
export const PreviewEmailTemplate = ({ survey, surveyUrl, brandColor }: PreviewEmailTemplateProps) => {
|
||||
export const PreviewEmailTemplate = ({ survey, surveyUrl, styling }: PreviewEmailTemplateProps) => {
|
||||
const url = `${surveyUrl}?preview=true`;
|
||||
const urlWithPrefilling = `${surveyUrl}?preview=true&`;
|
||||
const defaultLanguageCode = "default";
|
||||
const firstQuestion = survey.questions[0];
|
||||
|
||||
const brandColor = styling?.brandColor?.light || COLOR_DEFAULTS.brandColor;
|
||||
|
||||
switch (firstQuestion.type) {
|
||||
case TSurveyQuestionType.OpenText:
|
||||
return (
|
||||
<EmailTemplateWrapper surveyUrl={url} brandColor={brandColor}>
|
||||
<Text className="m-0 mr-8 block p-0 text-base font-semibold leading-6 text-slate-800">
|
||||
<EmailTemplateWrapper surveyUrl={url} styling={styling}>
|
||||
<Text className="text-question-color m-0 mr-8 block p-0 text-base font-semibold leading-6">
|
||||
{getLocalizedValue(firstQuestion.headline, defaultLanguageCode)}
|
||||
</Text>
|
||||
<Text className="m-0 block p-0 text-sm font-normal leading-6 text-slate-500">
|
||||
<Text className="text-question-color m-0 block p-0 text-sm font-normal leading-6">
|
||||
{getLocalizedValue(firstQuestion.subheader, defaultLanguageCode)}
|
||||
</Text>
|
||||
<Section className="mt-4 block h-20 w-full rounded-lg border border-solid border-slate-200 bg-slate-50" />
|
||||
<Section className="border-input-border-color rounded-custom mt-4 block h-20 w-full border border-solid bg-slate-50" />
|
||||
<EmailFooter />
|
||||
</EmailTemplateWrapper>
|
||||
);
|
||||
case TSurveyQuestionType.Consent:
|
||||
return (
|
||||
<EmailTemplateWrapper surveyUrl={url} brandColor={brandColor}>
|
||||
<Text className="m-0 block text-base font-semibold leading-6 text-slate-800">
|
||||
<EmailTemplateWrapper surveyUrl={url} styling={styling}>
|
||||
<Text className="text-question-color m-0 block text-base font-semibold leading-6">
|
||||
{getLocalizedValue(firstQuestion.headline, defaultLanguageCode)}
|
||||
</Text>
|
||||
<Container className="m-0 text-sm font-normal leading-6 text-slate-500">
|
||||
<Container className="text-question-color m-0 text-sm font-normal leading-6">
|
||||
<Text
|
||||
className="m-0 p-0"
|
||||
dangerouslySetInnerHTML={{
|
||||
@@ -64,8 +68,8 @@ export const PreviewEmailTemplate = ({ survey, surveyUrl, brandColor }: PreviewE
|
||||
}}></Text>
|
||||
</Container>
|
||||
|
||||
<Container className="m-0 mt-4 block w-full max-w-none rounded-lg border border-solid border-slate-200 bg-slate-50 p-4 font-medium text-slate-800">
|
||||
<Text className="m-0 inline-block">
|
||||
<Container className="border-input-border-color bg-input-color rounded-custom m-0 mt-4 block w-full max-w-none border border-solid p-4 font-medium text-slate-800">
|
||||
<Text className="text-question-color m-0 inline-block">
|
||||
{getLocalizedValue(firstQuestion.label, defaultLanguageCode)}
|
||||
</Text>
|
||||
</Container>
|
||||
@@ -73,14 +77,14 @@ export const PreviewEmailTemplate = ({ survey, surveyUrl, brandColor }: PreviewE
|
||||
{!firstQuestion.required && (
|
||||
<EmailButton
|
||||
href={`${urlWithPrefilling}${firstQuestion.id}=dismissed`}
|
||||
className="inline-flex cursor-pointer appearance-none rounded-md px-6 py-3 text-sm font-medium text-black">
|
||||
className="rounded-custom inline-flex cursor-pointer appearance-none px-6 py-3 text-sm font-medium text-black">
|
||||
Reject
|
||||
</EmailButton>
|
||||
)}
|
||||
<EmailButton
|
||||
href={`${urlWithPrefilling}${firstQuestion.id}=accepted`}
|
||||
className={cn(
|
||||
"bg-brand-color ml-2 inline-flex cursor-pointer appearance-none rounded-md px-6 py-3 text-sm font-medium",
|
||||
"bg-brand-color rounded-custom ml-2 inline-flex cursor-pointer appearance-none px-6 py-3 text-sm font-medium",
|
||||
isLight(brandColor) ? "text-black" : "text-white"
|
||||
)}>
|
||||
Accept
|
||||
@@ -91,26 +95,26 @@ export const PreviewEmailTemplate = ({ survey, surveyUrl, brandColor }: PreviewE
|
||||
);
|
||||
case TSurveyQuestionType.NPS:
|
||||
return (
|
||||
<EmailTemplateWrapper surveyUrl={url} brandColor={brandColor}>
|
||||
<EmailTemplateWrapper surveyUrl={url} styling={styling}>
|
||||
<Section>
|
||||
<Text className="m-0 block text-base font-semibold leading-6 text-slate-800">
|
||||
<Text className="text-question-color m-0 block text-base font-semibold leading-6">
|
||||
{getLocalizedValue(firstQuestion.headline, defaultLanguageCode)}
|
||||
</Text>
|
||||
<Text className="m-0 block p-0 text-sm font-normal leading-6 text-slate-500">
|
||||
<Text className="text-question-color m-0 block p-0 text-sm font-normal leading-6">
|
||||
{getLocalizedValue(firstQuestion.subheader, defaultLanguageCode)}
|
||||
</Text>
|
||||
<Container className="mx-0 mt-4 flex w-max flex-col">
|
||||
<Section className="block overflow-hidden rounded-md border border-slate-200">
|
||||
<Section className="border-input-border-color rounded-custom block overflow-hidden border">
|
||||
{Array.from({ length: 11 }, (_, i) => (
|
||||
<EmailButton
|
||||
key={i}
|
||||
href={`${urlWithPrefilling}${firstQuestion.id}=${i}`}
|
||||
className="m-0 inline-flex h-10 w-10 items-center justify-center border-slate-200 p-0 text-slate-800">
|
||||
className="border-input-border-color m-0 inline-flex h-10 w-10 items-center justify-center border p-0 text-slate-800">
|
||||
{i}
|
||||
</EmailButton>
|
||||
))}
|
||||
</Section>
|
||||
<Section className="mt-2 px-1.5 text-xs leading-6 text-slate-500">
|
||||
<Section className="text-question-color mt-2 px-1.5 text-xs leading-6">
|
||||
<Row>
|
||||
<Column>
|
||||
<Text className="m-0 inline-block w-max p-0">
|
||||
@@ -131,11 +135,11 @@ export const PreviewEmailTemplate = ({ survey, surveyUrl, brandColor }: PreviewE
|
||||
);
|
||||
case TSurveyQuestionType.CTA:
|
||||
return (
|
||||
<EmailTemplateWrapper surveyUrl={url} brandColor={brandColor}>
|
||||
<Text className="m-0 block text-base font-semibold leading-6 text-slate-800">
|
||||
<EmailTemplateWrapper surveyUrl={url} styling={styling}>
|
||||
<Text className="text-question-color m-0 block text-base font-semibold leading-6">
|
||||
{getLocalizedValue(firstQuestion.headline, defaultLanguageCode)}
|
||||
</Text>
|
||||
<Container className="mt-2 text-sm font-normal leading-6 text-slate-500">
|
||||
<Container className="text-question-color ml-0 mt-2 text-sm font-normal leading-6">
|
||||
<Text
|
||||
className="m-0 p-0"
|
||||
dangerouslySetInnerHTML={{
|
||||
@@ -147,14 +151,14 @@ export const PreviewEmailTemplate = ({ survey, surveyUrl, brandColor }: PreviewE
|
||||
{!firstQuestion.required && (
|
||||
<EmailButton
|
||||
href={`${urlWithPrefilling}${firstQuestion.id}=dismissed`}
|
||||
className="inline-flex cursor-pointer appearance-none rounded-md px-6 py-3 text-sm font-medium text-black">
|
||||
className="rounded-custom inline-flex cursor-pointer appearance-none px-6 py-3 text-sm font-medium text-black">
|
||||
{getLocalizedValue(firstQuestion.dismissButtonLabel, defaultLanguageCode) || "Skip"}
|
||||
</EmailButton>
|
||||
)}
|
||||
<EmailButton
|
||||
href={`${urlWithPrefilling}${firstQuestion.id}=clicked`}
|
||||
className={cn(
|
||||
"bg-brand-color inline-flex cursor-pointer appearance-none rounded-md px-6 py-3 text-sm font-medium",
|
||||
"bg-brand-color rounded-custom inline-flex cursor-pointer appearance-none px-6 py-3 text-sm font-medium",
|
||||
isLight(brandColor) ? "text-black" : "text-white"
|
||||
)}>
|
||||
{getLocalizedValue(firstQuestion.buttonLabel, defaultLanguageCode)}
|
||||
@@ -165,17 +169,17 @@ export const PreviewEmailTemplate = ({ survey, surveyUrl, brandColor }: PreviewE
|
||||
);
|
||||
case TSurveyQuestionType.Rating:
|
||||
return (
|
||||
<EmailTemplateWrapper surveyUrl={url} brandColor={brandColor}>
|
||||
<Section className=" w-full">
|
||||
<Text className="m-0 block text-base font-semibold leading-6 text-slate-800">
|
||||
<EmailTemplateWrapper surveyUrl={url} styling={styling}>
|
||||
<Section className="w-full">
|
||||
<Text className="text-question-color m-0 block text-base font-semibold leading-6">
|
||||
{getLocalizedValue(firstQuestion.headline, defaultLanguageCode)}
|
||||
</Text>
|
||||
<Text className="m-0 block p-0 text-sm font-normal leading-6 text-slate-500">
|
||||
<Text className="text-question-color m-0 block p-0 text-sm font-normal leading-6">
|
||||
{getLocalizedValue(firstQuestion.subheader, defaultLanguageCode)}
|
||||
</Text>
|
||||
<Container className="mx-0 mt-4 w-full items-center justify-center">
|
||||
<Section
|
||||
className={cn("w-full overflow-hidden rounded-md", {
|
||||
className={cn("rounded-custom w-full overflow-hidden", {
|
||||
["border border-solid border-gray-200"]: firstQuestion.scale === "number",
|
||||
})}>
|
||||
<Column className="mb-4 flex w-full justify-around">
|
||||
@@ -184,7 +188,7 @@ export const PreviewEmailTemplate = ({ survey, surveyUrl, brandColor }: PreviewE
|
||||
key={i}
|
||||
href={`${urlWithPrefilling}${firstQuestion.id}=${i + 1}`}
|
||||
className={cn(
|
||||
" m-0 h-10 w-full p-0 text-center align-middle leading-10 text-slate-800",
|
||||
"m-0 h-10 w-full p-0 text-center align-middle leading-10 text-slate-800",
|
||||
{
|
||||
["border border-solid border-gray-200"]: firstQuestion.scale === "number",
|
||||
}
|
||||
@@ -200,7 +204,7 @@ export const PreviewEmailTemplate = ({ survey, surveyUrl, brandColor }: PreviewE
|
||||
))}
|
||||
</Column>
|
||||
</Section>
|
||||
<Section className="m-0 px-1.5 text-xs leading-6 text-slate-500">
|
||||
<Section className="text-question-color m-0 px-1.5 text-xs leading-6">
|
||||
<Row>
|
||||
<Column>
|
||||
<Text className="m-0 inline-block p-0">
|
||||
@@ -221,17 +225,17 @@ export const PreviewEmailTemplate = ({ survey, surveyUrl, brandColor }: PreviewE
|
||||
);
|
||||
case TSurveyQuestionType.MultipleChoiceMulti:
|
||||
return (
|
||||
<EmailTemplateWrapper surveyUrl={url} brandColor={brandColor}>
|
||||
<Text className="m-0 mr-8 block p-0 text-base font-semibold leading-6 text-slate-800">
|
||||
<EmailTemplateWrapper surveyUrl={url} styling={styling}>
|
||||
<Text className="text-question-color m-0 mr-8 block p-0 text-base font-semibold leading-6">
|
||||
{getLocalizedValue(firstQuestion.headline, defaultLanguageCode)}
|
||||
</Text>
|
||||
<Text className="m-0 mb-2 block p-0 text-sm font-normal leading-6 text-slate-500">
|
||||
<Text className="text-question-color m-0 mb-2 block p-0 text-sm font-normal leading-6">
|
||||
{getLocalizedValue(firstQuestion.subheader, defaultLanguageCode)}
|
||||
</Text>
|
||||
<Container className="mx-0 max-w-none">
|
||||
{firstQuestion.choices.map((choice) => (
|
||||
<Section
|
||||
className="mt-2 block w-full rounded-lg border border-solid border-slate-200 bg-slate-50 p-4 text-slate-800"
|
||||
className="border-input-border-color bg-input-color text-question-color rounded-custom mt-2 block w-full border border-solid p-4"
|
||||
key={choice.id}>
|
||||
{getLocalizedValue(choice.label, defaultLanguageCode)}
|
||||
</Section>
|
||||
@@ -242,18 +246,18 @@ export const PreviewEmailTemplate = ({ survey, surveyUrl, brandColor }: PreviewE
|
||||
);
|
||||
case TSurveyQuestionType.MultipleChoiceSingle:
|
||||
return (
|
||||
<EmailTemplateWrapper surveyUrl={url} brandColor={brandColor}>
|
||||
<Text className="m-0 mr-8 block p-0 text-base font-semibold leading-6 text-slate-800">
|
||||
<EmailTemplateWrapper surveyUrl={url} styling={styling}>
|
||||
<Text className="text-question-color m-0 mr-8 block p-0 text-base font-semibold leading-6">
|
||||
{getLocalizedValue(firstQuestion.headline, defaultLanguageCode)}
|
||||
</Text>
|
||||
<Text className="m-0 mb-2 block p-0 text-sm font-normal leading-6 text-slate-500">
|
||||
<Text className="text-question-color m-0 mb-2 block p-0 text-sm font-normal leading-6">
|
||||
{getLocalizedValue(firstQuestion.subheader, defaultLanguageCode)}
|
||||
</Text>
|
||||
<Container className="mx-0 max-w-none">
|
||||
{firstQuestion.choices.map((choice) => (
|
||||
<Link
|
||||
key={choice.id}
|
||||
className="mt-2 block rounded-lg border border-solid border-slate-200 bg-slate-50 p-4 text-slate-800 hover:bg-slate-100"
|
||||
className="border-input-border-color bg-input-color text-question-color rounded-custom mt-2 block border border-solid p-4 hover:bg-slate-100"
|
||||
href={`${urlWithPrefilling}${firstQuestion.id}=${getLocalizedValue(choice.label, defaultLanguageCode)}`}>
|
||||
{getLocalizedValue(choice.label, defaultLanguageCode)}
|
||||
</Link>
|
||||
@@ -264,11 +268,11 @@ export const PreviewEmailTemplate = ({ survey, surveyUrl, brandColor }: PreviewE
|
||||
);
|
||||
case TSurveyQuestionType.PictureSelection:
|
||||
return (
|
||||
<EmailTemplateWrapper surveyUrl={url} brandColor={brandColor}>
|
||||
<Text className="m-0 mr-8 block p-0 text-base font-semibold leading-6 text-slate-800">
|
||||
<EmailTemplateWrapper surveyUrl={url} styling={styling}>
|
||||
<Text className="text-question-color m-0 mr-8 block p-0 text-base font-semibold leading-6">
|
||||
{getLocalizedValue(firstQuestion.headline, defaultLanguageCode)}
|
||||
</Text>
|
||||
<Text className="m-0 mb-2 block p-0 text-sm font-normal leading-6 text-slate-500">
|
||||
<Text className="text-question-color m-0 mb-2 block p-0 text-sm font-normal leading-6">
|
||||
{getLocalizedValue(firstQuestion.subheader, defaultLanguageCode)}
|
||||
</Text>
|
||||
<Section className="mx-0">
|
||||
@@ -276,14 +280,14 @@ export const PreviewEmailTemplate = ({ survey, surveyUrl, brandColor }: PreviewE
|
||||
firstQuestion.allowMulti ? (
|
||||
<Img
|
||||
src={choice.imageUrl}
|
||||
className="mb-1 mr-1 inline-block h-[110px] w-[220px] rounded-lg"
|
||||
className="rounded-custom mb-1 mr-1 inline-block h-[110px] w-[220px]"
|
||||
/>
|
||||
) : (
|
||||
<Link
|
||||
href={`${urlWithPrefilling}${firstQuestion.id}=${choice.id}`}
|
||||
target="_blank"
|
||||
className="mb-1 mr-1 inline-block h-[110px] w-[220px] rounded-lg">
|
||||
<Img src={choice.imageUrl} className="h-full w-full rounded-lg" />
|
||||
className="rounded-custom mb-1 mr-1 inline-block h-[110px] w-[220px]">
|
||||
<Img src={choice.imageUrl} className="rounded-custom h-full w-full" />
|
||||
</Link>
|
||||
)
|
||||
)}
|
||||
@@ -293,17 +297,17 @@ export const PreviewEmailTemplate = ({ survey, surveyUrl, brandColor }: PreviewE
|
||||
);
|
||||
case TSurveyQuestionType.Cal:
|
||||
return (
|
||||
<EmailTemplateWrapper surveyUrl={url} brandColor={brandColor}>
|
||||
<EmailTemplateWrapper surveyUrl={url} styling={styling}>
|
||||
<Container>
|
||||
<Text className="m-0 mb-2 block p-0 text-sm font-normal leading-6 text-slate-500">
|
||||
<Text className="text-question-color m-0 mb-2 block p-0 text-sm font-normal leading-6">
|
||||
{getLocalizedValue(firstQuestion.subheader, defaultLanguageCode)}
|
||||
</Text>
|
||||
<Text className="m-0 mb-2 block p-0 text-sm font-normal leading-6 text-slate-500">
|
||||
<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.
|
||||
</Text>
|
||||
<EmailButton
|
||||
className={cn(
|
||||
"bg-brand-color mx-auto block w-max cursor-pointer appearance-none rounded-md px-6 py-3 text-sm font-medium ",
|
||||
"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
|
||||
@@ -314,27 +318,27 @@ export const PreviewEmailTemplate = ({ survey, surveyUrl, brandColor }: PreviewE
|
||||
);
|
||||
case TSurveyQuestionType.Date:
|
||||
return (
|
||||
<EmailTemplateWrapper surveyUrl={url} brandColor={brandColor}>
|
||||
<Text className="m-0 mr-8 block p-0 text-base font-semibold leading-6 text-slate-800">
|
||||
<EmailTemplateWrapper surveyUrl={url} styling={styling}>
|
||||
<Text className="text-question-color m-0 mr-8 block p-0 text-base font-semibold leading-6">
|
||||
{getLocalizedValue(firstQuestion.headline, defaultLanguageCode)}
|
||||
</Text>
|
||||
<Text className="m-0 block p-0 text-sm font-normal leading-6 text-slate-500">
|
||||
<Text className="text-question-color m-0 block p-0 text-sm font-normal leading-6">
|
||||
{getLocalizedValue(firstQuestion.subheader, defaultLanguageCode)}
|
||||
</Text>
|
||||
<Section className="mt-4 flex h-12 w-full items-center justify-center rounded-lg border border-solid border-slate-200 bg-white">
|
||||
<CalendarDaysIcon className="mb-1 inline h-4 w-4" />
|
||||
<Text className="inline text-sm font-medium">Select a date</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>
|
||||
</Section>
|
||||
<EmailFooter />
|
||||
</EmailTemplateWrapper>
|
||||
);
|
||||
case TSurveyQuestionType.Matrix:
|
||||
return (
|
||||
<EmailTemplateWrapper surveyUrl={url} brandColor={brandColor}>
|
||||
<Text className="m-0 mr-8 block p-0 text-base font-semibold leading-6 text-slate-800">
|
||||
<EmailTemplateWrapper surveyUrl={url} styling={styling}>
|
||||
<Text className="text-question-color m-0 mr-8 block p-0 text-base font-semibold leading-6">
|
||||
{getLocalizedValue(firstQuestion.headline, "default")}
|
||||
</Text>
|
||||
<Text className="m-0 mb-2 block p-0 text-sm font-normal leading-6 text-slate-500">
|
||||
<Text className="text-question-color m-0 mb-2 block p-0 text-sm font-normal leading-6">
|
||||
{getLocalizedValue(firstQuestion.subheader, "default")}
|
||||
</Text>
|
||||
<Container className="mx-0">
|
||||
@@ -345,7 +349,7 @@ export const PreviewEmailTemplate = ({ survey, surveyUrl, brandColor }: PreviewE
|
||||
return (
|
||||
<Column
|
||||
key={columnIndex}
|
||||
className="max-w-40 break-words px-4 py-2 text-center text-gray-800">
|
||||
className="text-question-color max-w-40 break-words px-4 py-2 text-center">
|
||||
{getLocalizedValue(column, "default")}
|
||||
</Column>
|
||||
);
|
||||
@@ -353,14 +357,16 @@ export const PreviewEmailTemplate = ({ survey, surveyUrl, brandColor }: PreviewE
|
||||
</Row>
|
||||
{firstQuestion.rows.map((row, rowIndex) => {
|
||||
return (
|
||||
<Row key={rowIndex} className={`${rowIndex % 2 === 0 ? "bg-gray-100" : ""} rounded-custom`}>
|
||||
<Row
|
||||
key={rowIndex}
|
||||
className={`${rowIndex % 2 === 0 ? "bg-input-color" : ""} rounded-custom`}>
|
||||
<Column className="w-40 break-words px-4 py-2">
|
||||
{getLocalizedValue(row, "default")}
|
||||
</Column>
|
||||
{firstQuestion.columns.map(() => {
|
||||
return (
|
||||
<Column className="px-4 py-2 text-gray-800">
|
||||
<Section className="h-4 w-4 rounded-full bg-white p-2 outline"></Section>
|
||||
<Column className="text-question-color px-4 py-2">
|
||||
<Section className="bg-card-bg-color h-4 w-4 rounded-full p-2 outline"></Section>
|
||||
</Column>
|
||||
);
|
||||
})}
|
||||
@@ -374,17 +380,17 @@ export const PreviewEmailTemplate = ({ survey, surveyUrl, brandColor }: PreviewE
|
||||
);
|
||||
case TSurveyQuestionType.Address:
|
||||
return (
|
||||
<EmailTemplateWrapper surveyUrl={url} brandColor={brandColor}>
|
||||
<Text className="m-0 mr-8 block p-0 text-base font-semibold leading-6 text-slate-800">
|
||||
<EmailTemplateWrapper surveyUrl={url} styling={styling}>
|
||||
<Text className="text-question-color m-0 mr-8 block p-0 text-base font-semibold leading-6">
|
||||
{getLocalizedValue(firstQuestion.headline, defaultLanguageCode)}
|
||||
</Text>
|
||||
<Text className="m-0 block p-0 text-sm font-normal leading-6 text-slate-500">
|
||||
<Text className="text-question-color m-0 block p-0 text-sm font-normal leading-6">
|
||||
{getLocalizedValue(firstQuestion.subheader, defaultLanguageCode)}
|
||||
</Text>
|
||||
{Array.from({ length: 6 }).map((_, index) => (
|
||||
<Section
|
||||
key={index}
|
||||
className="mt-4 block h-10 w-full rounded-lg border border-solid border-slate-200 bg-slate-50"
|
||||
className="border-input-border-color bg-input-color rounded-custom mt-4 block h-10 w-full border border-solid"
|
||||
/>
|
||||
))}
|
||||
<EmailFooter />
|
||||
@@ -393,14 +399,42 @@ export const PreviewEmailTemplate = ({ survey, surveyUrl, brandColor }: PreviewE
|
||||
}
|
||||
};
|
||||
|
||||
const EmailTemplateWrapper = ({ children, surveyUrl, brandColor }) => {
|
||||
const EmailTemplateWrapper = ({
|
||||
children,
|
||||
surveyUrl,
|
||||
styling,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
surveyUrl: string;
|
||||
styling: TSurveyStyling;
|
||||
}) => {
|
||||
let signatureColor = "";
|
||||
const colors = {
|
||||
"brand-color": styling.brandColor?.light ?? COLOR_DEFAULTS.brandColor,
|
||||
"card-bg-color": styling.cardBackgroundColor?.light ?? COLOR_DEFAULTS.cardBackgroundColor,
|
||||
"input-color": styling.inputColor?.light ?? COLOR_DEFAULTS.inputColor,
|
||||
"input-border-color": styling.inputBorderColor?.light ?? COLOR_DEFAULTS.inputBorderColor,
|
||||
"card-border-color": styling.cardBorderColor?.light ?? COLOR_DEFAULTS.cardBorderColor,
|
||||
"question-color": styling.questionColor?.light ?? COLOR_DEFAULTS.questionColor,
|
||||
};
|
||||
|
||||
if (isLight(colors["question-color"])) {
|
||||
signatureColor = mixColor(colors["question-color"], "#000000", 0.2);
|
||||
} else {
|
||||
signatureColor = mixColor(colors["question-color"], "#ffffff", 0.2);
|
||||
}
|
||||
|
||||
return (
|
||||
<Tailwind
|
||||
config={{
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
"brand-color": brandColor,
|
||||
...colors,
|
||||
"signature-color": signatureColor,
|
||||
},
|
||||
borderRadius: {
|
||||
custom: styling.roundness ?? 8,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -408,7 +442,7 @@ const EmailTemplateWrapper = ({ children, surveyUrl, brandColor }) => {
|
||||
<Link
|
||||
href={surveyUrl}
|
||||
target="_blank"
|
||||
className="mx-0 my-2 block overflow-auto rounded-lg border border-solid border-slate-300 bg-white p-8 font-sans text-inherit">
|
||||
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">
|
||||
{children}
|
||||
</Link>
|
||||
</Tailwind>
|
||||
@@ -417,8 +451,8 @@ const EmailTemplateWrapper = ({ children, surveyUrl, brandColor }) => {
|
||||
|
||||
const EmailFooter = () => {
|
||||
return (
|
||||
<Container className="m-auto mt-8 text-center ">
|
||||
<Link href="https://formbricks.com/" target="_blank" className="text-xs text-slate-400">
|
||||
<Container className="m-auto mt-8 text-center">
|
||||
<Link href="https://formbricks.com/" target="_blank" className="text-signature-color text-xs">
|
||||
Powered by Formbricks
|
||||
</Link>
|
||||
</Container>
|
||||
@@ -1,6 +1,7 @@
|
||||
import { FormbricksAPI } from "@formbricks/api";
|
||||
import { ResponseQueue } from "@formbricks/lib/responseQueue";
|
||||
import SurveyState from "@formbricks/lib/surveyState";
|
||||
import { getStyling } from "@formbricks/lib/utils/styling";
|
||||
import { TResponseUpdate } from "@formbricks/types/responses";
|
||||
import { TSurvey } from "@formbricks/types/surveys";
|
||||
|
||||
@@ -92,26 +93,6 @@ const renderWidget = async (survey: TSurvey, action?: string) => {
|
||||
const isBrandingEnabled = product.inAppSurveyBranding;
|
||||
const formbricksSurveys = await loadFormbricksSurveysExternally();
|
||||
|
||||
const getStyling = () => {
|
||||
// allow style overwrite is disabled from the product
|
||||
if (!product.styling.allowStyleOverwrite) {
|
||||
return product.styling;
|
||||
}
|
||||
|
||||
// allow style overwrite is enabled from the product
|
||||
if (product.styling.allowStyleOverwrite) {
|
||||
// survey style overwrite is disabled
|
||||
if (!survey.styling?.overwriteThemeStyling) {
|
||||
return product.styling;
|
||||
}
|
||||
|
||||
// survey style overwrite is enabled
|
||||
return survey.styling;
|
||||
}
|
||||
|
||||
return product.styling;
|
||||
};
|
||||
|
||||
setTimeout(() => {
|
||||
formbricksSurveys.renderSurveyModal({
|
||||
survey: survey,
|
||||
@@ -120,7 +101,7 @@ const renderWidget = async (survey: TSurvey, action?: string) => {
|
||||
darkOverlay,
|
||||
languageCode,
|
||||
placement,
|
||||
styling: getStyling(),
|
||||
styling: getStyling(product, survey),
|
||||
getSetIsError: (f: (value: boolean) => void) => {
|
||||
setIsError = f;
|
||||
},
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { FormbricksAPI } from "@formbricks/api";
|
||||
import { ResponseQueue } from "@formbricks/lib/responseQueue";
|
||||
import SurveyState from "@formbricks/lib/surveyState";
|
||||
import { getStyling } from "@formbricks/lib/utils/styling";
|
||||
import { TJSWebsiteStateDisplay } from "@formbricks/types/js";
|
||||
import { TResponseUpdate } from "@formbricks/types/responses";
|
||||
import { TSurvey } from "@formbricks/types/surveys";
|
||||
@@ -91,26 +92,6 @@ const renderWidget = async (survey: TSurvey, action?: string) => {
|
||||
const isBrandingEnabled = product.inAppSurveyBranding;
|
||||
const formbricksSurveys = await loadFormbricksSurveysExternally();
|
||||
|
||||
const getStyling = () => {
|
||||
// allow style overwrite is disabled from the product
|
||||
if (!product.styling.allowStyleOverwrite) {
|
||||
return product.styling;
|
||||
}
|
||||
|
||||
// allow style overwrite is enabled from the product
|
||||
if (product.styling.allowStyleOverwrite) {
|
||||
// survey style overwrite is disabled
|
||||
if (!survey.styling?.overwriteThemeStyling) {
|
||||
return product.styling;
|
||||
}
|
||||
|
||||
// survey style overwrite is enabled
|
||||
return survey.styling;
|
||||
}
|
||||
|
||||
return product.styling;
|
||||
};
|
||||
|
||||
setTimeout(() => {
|
||||
formbricksSurveys.renderSurveyModal({
|
||||
survey: survey,
|
||||
@@ -119,7 +100,7 @@ const renderWidget = async (survey: TSurvey, action?: string) => {
|
||||
darkOverlay,
|
||||
languageCode,
|
||||
placement,
|
||||
styling: getStyling(),
|
||||
styling: getStyling(product, survey),
|
||||
getSetIsError: (f: (value: boolean) => void) => {
|
||||
setIsError = f;
|
||||
},
|
||||
|
||||
22
packages/lib/utils/styling.ts
Normal file
22
packages/lib/utils/styling.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { TProduct } from "@formbricks/types/product";
|
||||
import { TSurvey } from "@formbricks/types/surveys";
|
||||
|
||||
export const getStyling = (product: TProduct, survey: TSurvey) => {
|
||||
// allow style overwrite is disabled from the product
|
||||
if (!product.styling.allowStyleOverwrite) {
|
||||
return product.styling;
|
||||
}
|
||||
|
||||
// allow style overwrite is enabled from the product
|
||||
if (product.styling.allowStyleOverwrite) {
|
||||
// survey style overwrite is disabled
|
||||
if (!survey.styling?.overwriteThemeStyling) {
|
||||
return product.styling;
|
||||
}
|
||||
|
||||
// survey style overwrite is enabled
|
||||
return survey.styling;
|
||||
}
|
||||
|
||||
return product.styling;
|
||||
};
|
||||
Reference in New Issue
Block a user