Files
calendar/packages/emails/src/components/BaseEmailHtml.tsx
T
817e20f11e Stripe add the ability to place hold on cards (#8022)
* Add payment option to schema

* Add payment option to Stripe zod

* Set payment option on event type

* Create manual payment intent in Stripe

* Set payment option from Stripe app

* Add payment option to DB

* Pass React.ReactNode to checkbox

* Create uncaptured payment intent

* WIP

* Capture card in setup intent

* Show charge card option

* Charge card from booking page

* Bug fixes

* Clean up

* Clean up app card

* Add no-show fee messaging on booking page

* Send payment email on payment & add price

* Fix messaging

* Create no show fee charged email

* Send charge fee collected email

* Disable submit on card failure

* Clean up

* Serverside prevent charging card again if already charged

* Only confirm booking if paid for

* Type fixes

* More type fixes

* More type fixes

* Type fix

* Type fixes

* UI changes

* Payment component rework

* Update apps/web/public/static/locales/en/common.json

Co-authored-by: Alex van Andel <me@alexvanandel.com>

* Update apps/web/public/static/locales/en/common.json

Co-authored-by: Alex van Andel <me@alexvanandel.com>

* Update apps/web/components/dialog/ChargeCardDialog.tsx

Co-authored-by: Alex van Andel <me@alexvanandel.com>

* Update packages/trpc/server/routers/viewer/payments.tsx

Co-authored-by: Alex van Andel <me@alexvanandel.com>

* Revert GTM config

* Adjust payment option dropdown

* Show alert when seats are set

* Small bug fixes

* Create collect card method

* clean up

* Prevent seats & charge no-show fee to be enabled together

* Do not charge no-show fee on unconfirmed bookings

* Add check to collect card method

* Webhook send request emails

* Fix some dark mode colours

* Change awaiting payment language

* Type fixes

* Set height of Select and TextField both to 38px to fix alignment

* Fix message seats & payment error message

* Type fix

---------

Co-authored-by: Alex van Andel <me@alexvanandel.com>
2023-04-11 23:44:14 +02:00

206 lines
8.3 KiB
TypeScript

/* 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 type { BodyHeadType } from "./EmailSchedulingBodyHeader";
import EmailSchedulingBodyHeader 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 BaseEmailHtml = (props: {
children: React.ReactNode;
callToAction?: React.ReactNode;
subject: string;
title?: string;
subtitle?: React.ReactNode | string;
headerType?: BodyHeadType;
}) => {
return (
<Html>
<EmailHead title={props.subject} />
<body style={{ wordSpacing: "normal", backgroundColor: "#F3F4F6" }}>
<div style={{ backgroundColor: "#F3F4F6" }}>
<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>
<div
style={{
margin: "0px auto",
maxWidth: 600,
borderRadius: "8px",
border: "1px solid #E5E7EB",
padding: "2px",
backgroundColor: "#FFFFFF",
}}>
{props.headerType && (
<EmailSchedulingBodyHeader headerType={props.headerType} headStyles={{ border: 0 }} />
)}
{props.title && (
<EmailScheduledBodyHeaderContent
headStyles={{ border: 0 }}
title={props.title}
subtitle={props.subtitle}
/>
)}
{(props.headerType || props.title || props.subtitle) && (
<EmailSchedulingBodyDivider headStyles={{ border: 0 }} />
)}
<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={{
background: "#FFFFFF",
backgroundColor: "#FFFFFF",
margin: "0px auto",
maxWidth: 600,
}}>
<Row
align="center"
border="0"
style={{ background: "#FFFFFF", backgroundColor: "#FFFFFF", 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%",
}}>
<Row border="0" style={{ verticalAlign: "top" }} width="100%">
<td align="left" style={{ fontSize: 0, padding: "10px 25px", wordBreak: "break-word" }}>
<div
style={{
fontFamily: "Roboto, Helvetica, sans-serif",
fontSize: 16,
fontWeight: 500,
lineHeight: 1,
textAlign: "left",
color: "#101010",
}}>
{props.children}
</div>
</td>
</Row>
</div>
<RawHtml html="<!--[if mso | IE]></td></tr></table><![endif]-->" />
</td>
</Row>
</div>
{props.callToAction && <EmailSchedulingBodyDivider headStyles={{ border: 0 }} />}
<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={{
background: "#FFFFFF",
backgroundColor: "#FFFFFF",
margin: "0px auto",
maxWidth: 600,
}}>
<Row
align="center"
border="0"
style={{ background: "#FFFFFF", backgroundColor: "#FFFFFF", 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>
</div>
<EmailBodyLogo />
<RawHtml html="<!--[if mso | IE]></td></tr></table><![endif]-->" />
</div>
</body>
</Html>
);
};