Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Bailey Pumfleet <bailey@pumfleet.co.uk>
This commit is contained in:
authored and GitHub committed 2022-12-13 10:25:30 -03:00
1 parent da0bdfacae
commit 98a4684a2b
6 files changed
+234 -29

No files matched your search

+6 -16
View File
@@ -32,18 +32,6 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
timeZone: "America/Chihuahua",
language,
},
{
email: "pro@example.com",
name: "pro@example.com",
timeZone: "America/Chihuahua",
language,
},
{
email: "pro@example.com",
name: "pro@example.com",
timeZone: "America/Chihuahua",
language,
},
],
location: "Zoom video",
destinationCalendar: null,
@@ -60,10 +48,12 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
res.setHeader("Content-Type", "text/html");
res.setHeader("Cache-Control", "no-cache, no-store, private, must-revalidate");
res.write(
renderEmail("DisabledAppEmail", {
appName: "Stripe",
appType: ["payment"],
t,
renderEmail("TeamInviteEmail", {
language: t,
from: "From",
to: "To",
teamName: "Team name",
joinLink: "Join link",
})
);
res.end();
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

@@ -6,7 +6,7 @@
"second_other": "{{count}} seconds",
"upgrade_now": "Upgrade now",
"accept_invitation": "Accept Invitation",
"calcom_explained": "{{appName}} is the open source Calendly alternative putting you in control of your own data, workflow and appearance.",
"calcom_explained": "{{appName}} provides scheduling infrastructure for absolutely everyone.",
"have_any_questions": "Have questions? We're here to help.",
"reset_password_subject": "{{appName}}: Reset password instructions",
"event_declined_subject": "Declined: {{eventType}} with {{name}} at {{date}}",
@@ -385,7 +385,8 @@
"go_to_billing_portal": "Go to the billing portal",
"need_anything_else": "Need anything else?",
"further_billing_help": "If you need any further help with billing, our support team are here to help.",
"contact_our_support_team": "Contact our support team",
"contact": "Contact",
"our_support_team": "our support team",
"uh_oh": "Uh oh!",
"no_event_types_have_been_setup": "This user hasn't set up any event types yet.",
"edit_logo": "Edit logo",
@@ -0,0 +1,191 @@
/* eslint-disable @next/next/no-head-element */
import BaseTable from "./BaseTable";
import EmailBodyLogo from "./EmailBodyLogo";
import EmailHead from "./EmailHead";
import EmailScheduledBodyHeaderContent from "./EmailScheduledBodyHeaderContent";
import EmailSchedulingBodyDivider from "./EmailSchedulingBodyDivider";
import EmailSchedulingBodyHeader, { BodyHeadType } from "./EmailSchedulingBodyHeader";
import RawHtml from "./RawHtml";
import Row from "./Row";
const Html = (props: { children: React.ReactNode }) => (
<>
<RawHtml html="<!doctype html>" />
<html>{props.children}</html>
</>
);
export const V2BaseEmailHtml = (props: {
children: React.ReactNode;
callToAction?: React.ReactNode;
subject: string;
title?: string;
subtitle?: React.ReactNode;
headerType?: BodyHeadType;
}) => {
return (
<Html>
<EmailHead title={props.subject} />
<body style={{ wordSpacing: "normal", backgroundColor: "#F5F5F5" }}>
<div style={{ backgroundColor: "#F5F5F5" }}>
<RawHtml
html={`<!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->`}
/>
<div style={{ margin: "0px auto", maxWidth: 600 }}>
<Row align="center" border="0" style={{ width: "100%" }}>
<td
style={{
direction: "ltr",
fontSize: "0px",
padding: "0px",
paddingTop: "40px",
textAlign: "center",
}}>
<RawHtml
html={`<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr></tr></table><![endif]-->`}
/>
</td>
</Row>
</div>
{props.headerType && <EmailSchedulingBodyHeader headerType={props.headerType} />}
{props.title && <EmailScheduledBodyHeaderContent title={props.title} subtitle={props.subtitle} />}
{(props.headerType || props.title || props.subtitle) && <EmailSchedulingBodyDivider />}
<RawHtml
html={`<!--[if mso | IE]></td></tr></table><table align="center" border="0" cellpadding="0" cellspacing="0" className="" style="width:600px;" width="600" bgcolor="#FFFFFF" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->`}
/>
<div
style={{
margin: "0px auto",
maxWidth: 600,
}}>
<Row align="center" border="0" style={{ width: "100%" }}>
<td
style={{
direction: "ltr",
fontSize: 0,
padding: 0,
textAlign: "center",
}}>
<RawHtml
html={`<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td className="" style="vertical-align:top;width:598px;" ><![endif]-->`}
/>
<div
className="mj-column-per-100 mj-outlook-group-fix"
style={{
fontSize: 0,
textAlign: "left",
direction: "ltr",
display: "inline-block",
verticalAlign: "top",
width: "100%",
border: "1px solid #E1E1E1",
borderRadius: "6px",
}}>
<Row
border="0"
style={{
verticalAlign: "top",
borderRadius: "6px",
background: "#FFFFFF",
backgroundColor: "#FFFFFF",
}}
width="100%">
<td
align="left"
style={{
fontSize: 0,
padding: "40px",
wordBreak: "break-word",
}}>
<div
style={{
fontFamily: "Roboto, Helvetica, sans-serif",
fontSize: 16,
fontWeight: 500,
lineHeight: 1,
textAlign: "left",
color: "#3E3E3E",
}}>
{props.children}
</div>
</td>
</Row>
</div>
<RawHtml html="<!--[if mso | IE]></td></tr></table><![endif]-->" />
</td>
</Row>
</div>
{props.callToAction && <EmailSchedulingBodyDivider />}
<RawHtml
html={`<!--[if mso | IE]></td></tr></table><table align="center" border="0" cellpadding="0" cellspacing="0" className="" style="width:600px;" width="600" bgcolor="#FFFFFF" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->`}
/>
<div
style={{
margin: "0px auto",
maxWidth: 600,
}}>
<Row align="center" border="0" style={{ width: "100%" }}>
<td
style={{
direction: "ltr",
fontSize: 0,
padding: 0,
textAlign: "center",
}}>
<RawHtml
html={`<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td className="" style="vertical-align:top;width:598px;" ><![endif]-->`}
/>
{props.callToAction && (
<div
className="mj-column-per-100 mj-outlook-group-fix"
style={{
fontSize: 0,
textAlign: "left",
direction: "ltr",
display: "inline-block",
verticalAlign: "top",
width: "100%",
}}>
<BaseTable border="0" style={{ verticalAlign: "top" }} width="100%">
<tbody>
<tr>
<td
align="center"
vertical-align="middle"
style={{ fontSize: 0, padding: "10px 25px", wordBreak: "break-word" }}>
{props.callToAction}
</td>
</tr>
<tr>
<td
align="left"
style={{ fontSize: 0, padding: "10px 25px", wordBreak: "break-word" }}>
<div
style={{
fontFamily: "Roboto, Helvetica, sans-serif",
fontSize: 13,
lineHeight: 1,
textAlign: "left",
color: "#000000",
}}
/>
</td>
</tr>
</tbody>
</BaseTable>
</div>
)}
<RawHtml html="<!--[if mso | IE]></td></tr></table><![endif]-->" />
</td>
</Row>
</div>
<EmailBodyLogo />
<RawHtml html="<!--[if mso | IE]></td></tr></table><![endif]-->" />
</div>
</body>
</Html>
);
};
+1
View File
@@ -1,4 +1,5 @@
export { BaseEmailHtml } from "./BaseEmailHtml";
export { V2BaseEmailHtml } from "./V2BaseEmailHtml";
export { CallToAction } from "./CallToAction";
export { CallToActionTable } from "./CallToActionTable";
export { CustomInputs } from "./CustomInputs";
@@ -1,8 +1,8 @@
import type { TFunction } from "next-i18next";
import { APP_NAME } from "@calcom/lib/constants";
import { APP_NAME, BASE_URL, IS_PRODUCTION } from "@calcom/lib/constants";
import { BaseEmailHtml, CallToAction } from "../components";
import { V2BaseEmailHtml, CallToAction } from "../components";
type TeamInvite = {
language: TFunction;
@@ -12,15 +12,36 @@ type TeamInvite = {
joinLink: string;
};
export const TeamInviteEmail = (props: TeamInvite & Partial<React.ComponentProps<typeof BaseEmailHtml>>) => {
export const TeamInviteEmail = (
props: TeamInvite & Partial<React.ComponentProps<typeof V2BaseEmailHtml>>
) => {
return (
<BaseEmailHtml
<V2BaseEmailHtml
subject={props.language("user_invited_you", {
user: props.from,
team: props.teamName,
appName: APP_NAME,
})}>
<p>
<img
height="64"
src={
IS_PRODUCTION
? BASE_URL + "/emails/teamCircle@2x.png"
: "http://localhost:3000/emails/teamCircle@2x.png"
}
style={{
border: "0",
display: "block",
outline: "none",
textDecoration: "none",
height: "64px",
fontSize: "13px",
marginBottom: "24px",
}}
width="64"
alt=""
/>
<p style={{ fontSize: "24px", marginBottom: "16px" }}>
<>
{props.language("user_invited_you", {
user: props.from,
@@ -30,21 +51,22 @@ export const TeamInviteEmail = (props: TeamInvite & Partial<React.ComponentProps
!
</>
</p>
<p style={{ fontWeight: 400, lineHeight: "24px" }}>
<p style={{ fontWeight: 400, lineHeight: "24px", marginBottom: "32px" }}>
<>{props.language("calcom_explained", { appName: APP_NAME })}</>
</p>
<CallToAction label={props.language("accept_invitation")} href={props.joinLink} />
<div style={{ lineHeight: "6px" }}>
<p style={{ fontWeight: 400, lineHeight: "24px" }}>
<div style={{ borderTop: "1px solid #E1E1E1", marginTop: "32px", paddingTop: "32px" }}>
<p style={{ fontWeight: 400, margin: 0 }}>
<>
{props.language("have_any_questions")}{" "}
<a href="mailto:support@cal.com" style={{ color: "#3E3E3E" }} target="_blank" rel="noreferrer">
<>{props.language("contact_our_support_team")}</>
</a>
<>{props.language("contact")}</>
</a>{" "}
{props.language("our_support_team")}
</>
</p>
</div>
</BaseEmailHtml>
</V2BaseEmailHtml>
);
};