Impl (#5993)
Co-authored-by: Peer Richelsen <peeroke@gmail.com> Co-authored-by: Bailey Pumfleet <bailey@pumfleet.co.uk>
This commit is contained in:
6 files changed
+234
-29
No files matched your search
@@ -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,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>
|
||||
);
|
||||
};
|
||||
Reference in new issue
Block a user