fix: linting warnings in email package (#2998)

This commit is contained in:
Dhruwang Jariwala
2024-08-12 20:15:50 +05:30
committed by GitHub
parent fb149796fa
commit bbab7fa672
22 changed files with 150 additions and 119 deletions

View File

@@ -7,7 +7,7 @@ interface ForgotPasswordEmailProps {
verifyLink: string;
}
export function ForgotPasswordEmail({ verifyLink }: ForgotPasswordEmailProps) {
export function ForgotPasswordEmail({ verifyLink }: ForgotPasswordEmailProps): React.JSX.Element {
return (
<Container>
<Heading>Change password</Heading>

View File

@@ -2,7 +2,7 @@ import { Container, Heading, Text } from "@react-email/components";
import React from "react";
import { EmailFooter } from "../general/email-footer";
export function PasswordResetNotifyEmail() {
export function PasswordResetNotifyEmail(): React.JSX.Element {
return (
<Container>
<Heading>Password changed</Heading>

View File

@@ -8,7 +8,10 @@ interface VerificationEmailProps {
verificationRequestLink: string;
}
export function VerificationEmail({ verifyLink, verificationRequestLink }: VerificationEmailProps) {
export function VerificationEmail({
verifyLink,
verificationRequestLink,
}: VerificationEmailProps): React.JSX.Element {
return (
<Container>
<Heading>Almost there!</Heading>

View File

@@ -6,7 +6,7 @@ interface EmailButtonProps {
href: string;
}
export function EmailButton({ label, href }: EmailButtonProps) {
export function EmailButton({ label, href }: EmailButtonProps): React.JSX.Element {
return (
<Button className="rounded-md bg-black p-4 text-white" href={href}>
{label}

View File

@@ -1,6 +1,6 @@
import { Text } from "@react-email/components";
export function EmailFooter() {
export function EmailFooter(): React.JSX.Element {
return (
<Text>
Have a great day!

View File

@@ -4,78 +4,76 @@ interface EmailTemplateProps {
content: JSX.Element;
}
export function EmailTemplate({ content }: EmailTemplateProps) {
export function EmailTemplate({ content }: EmailTemplateProps): React.JSX.Element {
return (
<Html>
<Tailwind>
<>
<Body
className="m-0 h-full w-full justify-center bg-slate-100 bg-slate-50 p-6 text-center text-base font-medium text-slate-800"
style={{
fontFamily: "'Jost', 'Helvetica Neue', 'Segoe UI', 'Helvetica', 'sans-serif'",
}}>
<Section>
<Link href="https://formbricks.com?utm_source=email_header&utm_medium=email" target="_blank">
<Img
alt="Formbricks Logo"
className="mx-auto w-80"
src="https://s3.eu-central-1.amazonaws.com/listmonk-formbricks/Formbricks-Light-transparent.png"
/>
</Link>
</Section>
<Container className="mx-auto my-8 max-w-xl bg-white p-4 text-left">{content}</Container>
<Body
className="m-0 h-full w-full justify-center bg-slate-100 bg-slate-50 p-6 text-center text-base font-medium text-slate-800"
style={{
fontFamily: "'Jost', 'Helvetica Neue', 'Segoe UI', 'Helvetica', 'sans-serif'",
}}>
<Section>
<Link href="https://formbricks.com?utm_source=email_header&utm_medium=email" target="_blank">
<Img
alt="Formbricks Logo"
className="mx-auto w-80"
src="https://s3.eu-central-1.amazonaws.com/listmonk-formbricks/Formbricks-Light-transparent.png"
/>
</Link>
</Section>
<Container className="mx-auto my-8 max-w-xl bg-white p-4 text-left">{content}</Container>
<Section>
<Row>
<Column align="right" key="twitter">
<Link href="https://twitter.com/formbricks" target="_blank">
<Img
alt="Tw"
src="https://s3.eu-central-1.amazonaws.com/listmonk-formbricks/Twitter-transp.png"
title="Twitter"
width="32"
/>
</Link>
</Column>
<Column align="center" className="w-20" key="github">
<Link href="https://formbricks.com/github" target="_blank">
<Img
alt="GitHub"
src="https://s3.eu-central-1.amazonaws.com/listmonk-formbricks/Github-transp.png"
title="GitHub"
width="32"
/>
</Link>
</Column>
<Column align="left" key="discord">
<Link href="https://formbricks.com/discord" target="_blank">
<Img
alt="Discord"
src="https://s3.eu-central-1.amazonaws.com/listmonk-formbricks/Discord-transp.png"
title="Discord"
width="32"
/>
</Link>
</Column>
</Row>
</Section>
<Section className="mt-4 text-center">
Formbricks {new Date().getFullYear()}. All rights reserved.
<br />
<Link
href="https://formbricks.com/imprint?utm_source=email_footer&utm_medium=email"
target="_blank">
Imprint
</Link>{" "}
|{" "}
<Link
href="https://formbricks.com/privacy-policy?utm_source=email_footer&utm_medium=email"
target="_blank">
Privacy Policy
</Link>
</Section>
</Body>
</>
<Section>
<Row>
<Column align="right" key="twitter">
<Link href="https://twitter.com/formbricks" target="_blank">
<Img
alt="Tw"
src="https://s3.eu-central-1.amazonaws.com/listmonk-formbricks/Twitter-transp.png"
title="Twitter"
width="32"
/>
</Link>
</Column>
<Column align="center" className="w-20" key="github">
<Link href="https://formbricks.com/github" target="_blank">
<Img
alt="GitHub"
src="https://s3.eu-central-1.amazonaws.com/listmonk-formbricks/Github-transp.png"
title="GitHub"
width="32"
/>
</Link>
</Column>
<Column align="left" key="discord">
<Link href="https://formbricks.com/discord" target="_blank">
<Img
alt="Discord"
src="https://s3.eu-central-1.amazonaws.com/listmonk-formbricks/Discord-transp.png"
title="Discord"
width="32"
/>
</Link>
</Column>
</Row>
</Section>
<Section className="mt-4 text-center">
Formbricks {new Date().getFullYear()}. All rights reserved.
<br />
<Link
href="https://formbricks.com/imprint?utm_source=email_footer&utm_medium=email"
target="_blank">
Imprint
</Link>{" "}
|{" "}
<Link
href="https://formbricks.com/privacy-policy?utm_source=email_footer&utm_medium=email"
target="_blank">
Privacy Policy
</Link>
</Section>
</Body>
</Tailwind>
</Html>
);

View File

@@ -7,7 +7,10 @@ interface InviteAcceptedEmailProps {
inviteeName: string;
}
export function InviteAcceptedEmail({ inviterName, inviteeName }: InviteAcceptedEmailProps) {
export function InviteAcceptedEmail({
inviterName,
inviteeName,
}: InviteAcceptedEmailProps): React.JSX.Element {
return (
<Container>
<Text>Hey {inviterName},</Text>

View File

@@ -9,7 +9,7 @@ interface InviteEmailProps {
verifyLink: string;
}
export function InviteEmail({ inviteeName, inviterName, verifyLink }: InviteEmailProps) {
export function InviteEmail({ inviteeName, inviterName, verifyLink }: InviteEmailProps): React.JSX.Element {
return (
<Container>
<Text>Hey {inviteeName},</Text>

View File

@@ -12,7 +12,7 @@ export function OnboardingInviteEmail({
inviteMessage,
inviterName,
verifyLink,
}: OnboardingInviteEmailProps) {
}: OnboardingInviteEmailProps): React.JSX.Element {
return (
<Container>
<Heading>Hey 👋</Heading>

View File

@@ -6,7 +6,10 @@ interface EmbedSurveyPreviewEmailProps {
environmentId: string;
}
export function EmbedSurveyPreviewEmail({ html, environmentId }: EmbedSurveyPreviewEmailProps) {
export function EmbedSurveyPreviewEmail({
html,
environmentId,
}: EmbedSurveyPreviewEmailProps): React.JSX.Element {
return (
<Container>
<Heading>Preview Email Embed</Heading>

View File

@@ -8,7 +8,7 @@ interface LinkSurveyEmailProps {
getSurveyLink: () => string;
}
export function LinkSurveyEmail({ surveyName, getSurveyLink }: LinkSurveyEmailProps) {
export function LinkSurveyEmail({ surveyName, getSurveyLink }: LinkSurveyEmailProps): React.JSX.Element {
return (
<Container>
<Heading>Hey 👋</Heading>

View File

@@ -18,7 +18,7 @@ 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 { RatingSmiley } from "@formbricks/ui/RatingSmiley";
import { getNPSOptionColor, getRatingNumberOptionColor } from "../../utils";
import { getNPSOptionColor, getRatingNumberOptionColor } from "../../lib/utils";
interface PreviewEmailTemplateProps {
survey: TSurvey;
@@ -26,13 +26,21 @@ interface PreviewEmailTemplateProps {
styling: TSurveyStyling;
}
export const getPreviewEmailTemplateHtml = (survey: TSurvey, surveyUrl: string, styling: TSurveyStyling) => {
export const getPreviewEmailTemplateHtml = (
survey: TSurvey,
surveyUrl: string,
styling: TSurveyStyling
): string => {
return render(<PreviewEmailTemplate styling={styling} survey={survey} surveyUrl={surveyUrl} />, {
pretty: true,
});
};
export function PreviewEmailTemplate({ survey, surveyUrl, styling }: PreviewEmailTemplateProps) {
export function PreviewEmailTemplate({
survey,
surveyUrl,
styling,
}: PreviewEmailTemplateProps): React.JSX.Element {
const url = `${surveyUrl}?preview=true`;
const urlWithPrefilling = `${surveyUrl}?preview=true&skipPrefilled=true&`;
const defaultLanguageCode = "default";
@@ -371,11 +379,11 @@ export function PreviewEmailTemplate({ survey, surveyUrl, styling }: PreviewEmai
<Section className="w-full table-auto">
<Row>
<Column className="w-40 break-words px-4 py-2" />
{firstQuestion.columns.map((column, columnIndex) => {
{firstQuestion.columns.map((column) => {
return (
<Column
className="text-question-color max-w-40 break-words px-4 py-2 text-center"
key={columnIndex}>
key={getLocalizedValue(column, "default")}>
{getLocalizedValue(column, "default")}
</Column>
);
@@ -385,13 +393,15 @@ export function PreviewEmailTemplate({ survey, surveyUrl, styling }: PreviewEmai
return (
<Row
className={`${rowIndex % 2 === 0 ? "bg-input-color" : ""} rounded-custom`}
key={rowIndex}>
key={getLocalizedValue(row, "default")}>
<Column className="w-40 break-words px-4 py-2">
{getLocalizedValue(row, "default")}
</Column>
{firstQuestion.columns.map((_, index) => {
{firstQuestion.columns.map((_) => {
return (
<Column className="text-question-color px-4 py-2" key={index}>
<Column
className="text-question-color px-4 py-2"
key={getLocalizedValue(_, "default")}>
<Section className="bg-card-bg-color h-4 w-4 rounded-full p-2 outline" />
</Column>
);
@@ -459,7 +469,7 @@ function EmailTemplateWrapper({
children: React.ReactNode;
surveyUrl: string;
styling: TSurveyStyling;
}) {
}): React.JSX.Element {
let signatureColor = "";
const colors = {
"brand-color": styling.brandColor?.light ?? COLOR_DEFAULTS.brandColor,
@@ -501,7 +511,7 @@ function EmailTemplateWrapper({
);
}
function EmailFooter() {
function EmailFooter(): React.JSX.Element {
return (
<Container className="m-auto mt-8 text-center">
<Link className="text-signature-color text-xs" href="https://formbricks.com/" target="_blank">

View File

@@ -10,7 +10,10 @@ import {
} from "@formbricks/types/surveys/types";
import { EmailButton } from "../general/email-button";
export const renderEmailResponseValue = (response: string | string[], questionType: TSurveyQuestionType) => {
export const renderEmailResponseValue = (
response: string | string[],
questionType: TSurveyQuestionType
): React.JSX.Element => {
switch (questionType) {
case TSurveyQuestionTypeEnum.FileUpload:
return (
@@ -67,7 +70,7 @@ export function ResponseFinishedEmail({
WEBAPP_URL,
environmentId,
organization,
}: ResponseFinishedEmailProps) {
}: ResponseFinishedEmailProps): React.JSX.Element {
const questions = getQuestionResponseMapping(survey, response);
return (
@@ -143,7 +146,7 @@ export function ResponseFinishedEmail({
);
}
function FileIcon() {
function FileIcon(): React.JSX.Element {
return (
<svg
className="lucide lucide-file"
@@ -162,7 +165,7 @@ function FileIcon() {
);
}
function EyeOffIcon() {
function EyeOffIcon(): React.JSX.Element {
return (
<svg
xmlns="http://www.w3.org/2000/svg"

View File

@@ -9,7 +9,9 @@ interface CreateReminderNotificationBodyProps {
notificationData: TWeeklySummaryNotificationResponse;
}
export function CreateReminderNotificationBody({ notificationData }: CreateReminderNotificationBodyProps) {
export function CreateReminderNotificationBody({
notificationData,
}: CreateReminderNotificationBodyProps): React.JSX.Element {
return (
<Container>
<Text>

View File

@@ -33,8 +33,13 @@ interface LiveSurveyNotificationProps {
surveys: TWeeklySummaryNotificationDataSurvey[];
}
export const LiveSurveyNotification = ({ environmentId, surveys }: LiveSurveyNotificationProps) => {
const createSurveyFields = (surveyResponses: TWeeklySummarySurveyResponseData[]) => {
export const LiveSurveyNotification = ({
environmentId,
surveys,
}: LiveSurveyNotificationProps): React.JSX.Element[] => {
const createSurveyFields = (
surveyResponses: TWeeklySummarySurveyResponseData[]
): React.JSX.Element | React.JSX.Element[] => {
if (surveyResponses.length === 0) {
return (
<Container className="mt-4">
@@ -66,14 +71,14 @@ export const LiveSurveyNotification = ({ environmentId, surveys }: LiveSurveyNot
return surveyFields;
};
if (!surveys.length) return "";
if (!surveys.length) return [];
return surveys.map((survey, index) => {
return surveys.map((survey) => {
const displayStatus = convertSurveyStatus(survey.status);
const isInProgress = displayStatus === "In Progress";
const noResponseLastWeek = isInProgress && survey.responses.length === 0;
return (
<Tailwind key={index}>
<Tailwind key={survey.id}>
<Container className="mt-12">
<Text className="mb-0 inline">
<Link

View File

@@ -17,7 +17,7 @@ export function NoLiveSurveyNotificationEmail({
endDate,
startYear,
endYear,
}: NoLiveSurveyNotificationEmailProps) {
}: NoLiveSurveyNotificationEmailProps): React.JSX.Element {
return (
<div>
<NotificationHeader

View File

@@ -5,7 +5,7 @@ import { WEBAPP_URL } from "@formbricks/lib/constants";
interface NotificatonFooterProps {
environmentId: string;
}
export function NotificationFooter({ environmentId }: NotificatonFooterProps) {
export function NotificationFooter({ environmentId }: NotificatonFooterProps): React.JSX.Element {
return (
<Tailwind>
<Container className="w-full">

View File

@@ -15,8 +15,8 @@ export function NotificationHeader({
endDate,
startYear,
endYear,
}: NotificationHeaderProps) {
const getNotificationHeaderimePeriod = () => {
}: NotificationHeaderProps): React.JSX.Element {
const getNotificationHeaderimePeriod = (): React.JSX.Element => {
if (startYear === endYear) {
return (
<Text className="m-0 text-right">

View File

@@ -6,7 +6,7 @@ interface NotificationInsightProps {
insights: TWeeklySummaryInsights;
}
export function NotificationInsight({ insights }: NotificationInsightProps) {
export function NotificationInsight({ insights }: NotificationInsightProps): React.JSX.Element {
return (
<Container>
<Section className="my-4 rounded-md bg-slate-100">

View File

@@ -19,7 +19,7 @@ export function WeeklySummaryNotificationEmail({
endDate,
startYear,
endYear,
}: WeeklySummaryNotificationEmailProps) {
}: WeeklySummaryNotificationEmailProps): React.JSX.Element {
return (
<div>
<NotificationHeader

View File

@@ -1,5 +1,5 @@
import { render } from "@react-email/render";
import nodemailer from "nodemailer";
import { createTransport } from "nodemailer";
import type SMTPTransport from "nodemailer/lib/smtp-transport";
import {
DEBUG,
@@ -56,10 +56,10 @@ const getEmailSubject = (productName: string): string => {
return `${productName} User Insights - Last Week by Formbricks`;
};
export const sendEmail = async (emailData: SendEmailDataProps) => {
export const sendEmail = async (emailData: SendEmailDataProps): Promise<void> => {
if (!IS_SMTP_CONFIGURED) return;
const transporter = nodemailer.createTransport({
const transporter = createTransport({
host: SMTP_HOST,
port: SMTP_PORT,
secure: SMTP_SECURE_ENABLED, // true for 465, false for other ports
@@ -79,7 +79,7 @@ export const sendEmail = async (emailData: SendEmailDataProps) => {
await transporter.sendMail({ ...emailDefaults, ...emailData });
};
export const sendVerificationEmail = async (user: TEmailUser) => {
export const sendVerificationEmail = async (user: TEmailUser): Promise<void> => {
const token = createToken(user.id, user.email, {
expiresIn: "1d",
});
@@ -94,7 +94,7 @@ export const sendVerificationEmail = async (user: TEmailUser) => {
});
};
export const sendForgotPasswordEmail = async (user: TEmailUser) => {
export const sendForgotPasswordEmail = async (user: TEmailUser): Promise<void> => {
const token = createToken(user.id, user.email, {
expiresIn: "1d",
});
@@ -106,7 +106,7 @@ export const sendForgotPasswordEmail = async (user: TEmailUser) => {
});
};
export const sendPasswordResetNotifyEmail = async (user: TEmailUser) => {
export const sendPasswordResetNotifyEmail = async (user: TEmailUser): Promise<void> => {
await sendEmail({
to: user.email,
subject: "Your Formbricks password has been changed",
@@ -121,7 +121,7 @@ export const sendInviteMemberEmail = async (
inviteeName: string,
isOnboardingInvite?: boolean,
inviteMessage?: string
) => {
): Promise<void> => {
const token = createInviteToken(inviteId, email, {
expiresIn: "7d",
});
@@ -145,7 +145,11 @@ export const sendInviteMemberEmail = async (
}
};
export const sendInviteAcceptedEmail = async (inviterName: string, inviteeName: string, email: string) => {
export const sendInviteAcceptedEmail = async (
inviterName: string,
inviteeName: string,
email: string
): Promise<void> => {
await sendEmail({
to: email,
subject: `You've got a new organization member!`,
@@ -159,7 +163,7 @@ export const sendResponseFinishedEmail = async (
survey: TSurvey,
response: TResponse,
responseCount: number
) => {
): Promise<void> => {
const personEmail = response.personAttributes?.email;
const organization = await getOrganizationByEnvironmentId(environmentId);
@@ -193,7 +197,7 @@ export const sendEmbedSurveyPreviewEmail = async (
subject: string,
html: string,
environmentId: string
) => {
): Promise<void> => {
await sendEmail({
to,
subject,
@@ -201,13 +205,13 @@ export const sendEmbedSurveyPreviewEmail = async (
});
};
export const sendLinkSurveyToVerifiedEmail = async (data: LinkSurveyEmailData) => {
export const sendLinkSurveyToVerifiedEmail = async (data: LinkSurveyEmailData): Promise<void> => {
const surveyId = data.surveyId;
const email = data.email;
const surveyName = data.surveyName;
const singleUseId = data.suId;
const token = createTokenForLinkSurvey(surveyId, email);
const getSurveyLink = () => {
const getSurveyLink = (): string => {
if (singleUseId) {
return `${WEBAPP_URL}/s/${surveyId}?verify=${encodeURIComponent(token)}&suId=${singleUseId}`;
}
@@ -223,7 +227,7 @@ export const sendLinkSurveyToVerifiedEmail = async (data: LinkSurveyEmailData) =
export const sendWeeklySummaryNotificationEmail = async (
email: string,
notificationData: TWeeklySummaryNotificationResponse
) => {
): Promise<void> => {
const startDate = `${notificationData.lastWeekDate.getDate().toString()} ${notificationData.lastWeekDate.toLocaleString(
"default",
{ month: "short" }
@@ -254,7 +258,7 @@ export const sendWeeklySummaryNotificationEmail = async (
export const sendNoLiveSurveyNotificationEmail = async (
email: string,
notificationData: TWeeklySummaryNotificationResponse
) => {
): Promise<void> => {
const startDate = `${notificationData.lastWeekDate.getDate().toString()} ${notificationData.lastWeekDate.toLocaleString(
"default",
{ month: "short" }

View File

@@ -4,7 +4,7 @@ export const getNPSOptionColor = (idx: number): string => {
return "bg-rose-100";
};
export const getRatingNumberOptionColor = (range: number, idx: number) => {
export const getRatingNumberOptionColor = (range: number, idx: number): string => {
if (range > 5) {
if (range - idx < 2) return "bg-emerald-100";
if (range - idx < 4) return "bg-orange-100";