feat: add ssr email templates rendering

This commit is contained in:
Ahmed Bouhuolia
2024-11-19 17:14:13 +02:00
parent f7bf24acb3
commit c6db54175f
7 changed files with 138 additions and 41 deletions

View File

@@ -5,6 +5,7 @@
"dependencies": { "dependencies": {
"@bigcapital/utils": "*", "@bigcapital/utils": "*",
"@bigcapital/pdf-templates": "*", "@bigcapital/pdf-templates": "*",
"@bigcapital/email-components": "*",
"@blueprintjs-formik/core": "^0.3.7", "@blueprintjs-formik/core": "^0.3.7",
"@blueprintjs-formik/datetime": "^0.3.7", "@blueprintjs-formik/datetime": "^0.3.7",
"@blueprintjs-formik/select": "^0.3.5", "@blueprintjs-formik/select": "^0.3.5",

View File

@@ -0,0 +1,49 @@
import { x } from '@xstyled/emotion';
import { Stack, StackProps } from '@/components';
interface SendMailReceiptProps extends StackProps {
children: React.ReactNode;
}
export function SendMailReceipt({
children,
...restProps
}: SendMailReceiptProps) {
return (
<Stack
bg="white"
w={'100%'}
maxWidth={'500px'}
p={'35px 25px'}
borderRadius={'5px'}
boxShadow={'0 10px 15px rgba(0, 0, 0, 0.05)'}
color={'black'}
{...restProps}
></Stack>
);
}
interface SendMailReceiptCompanyLogoProps extends StackProps {
src: string;
}
function SendMailReceiptCompanyLogo({
src,
...props
}: SendMailReceiptCompanyLogoProps) {
return (
<x.div
h="90px"
w="90px"
mx="auto"
borderRadius="3px"
backgroundRepeat="no-repeat"
backgroundPosition="center center"
backgroundSize="contain"
backgroundImage={`url("${src}")`}
{...props}
></x.div>
);
}
SendMailReceipt.CompanyLogo = SendMailReceiptCompanyLogo;

3
pnpm-lock.yaml generated
View File

@@ -484,6 +484,9 @@ importers:
packages/webapp: packages/webapp:
dependencies: dependencies:
'@bigcapital/email-components':
specifier: '*'
version: link:../../shared/email-components
'@bigcapital/pdf-templates': '@bigcapital/pdf-templates':
specifier: '*' specifier: '*'
version: link:../../shared/pdf-templates version: link:../../shared/pdf-templates

View File

@@ -1,8 +1,8 @@
import { import {
Button, Button,
Column, Column,
Container,
Heading, Heading,
render,
Row, Row,
Section, Section,
Text, Text,
@@ -135,6 +135,15 @@ export const CreditNoteEmailTemplate: React.FC<
); );
}; };
/**
* Renders the estimate mail template to string
* @param {EstimatePaymentEmailProps} props
* @returns {Promise<string>}
*/
export const renderCreditNoteEmailTemplate = (props: CreditNoteEmailProps) => {
return render(<CreditNoteEmailTemplate {...props} />);
};
const containerStyle: CSSProperties = { const containerStyle: CSSProperties = {
backgroundColor: '#fff', backgroundColor: '#fff',
width: '100%', width: '100%',

View File

@@ -4,6 +4,7 @@ import {
Column, Column,
Container, Container,
Heading, Heading,
render,
Row, Row,
Section, Section,
Text, Text,
@@ -143,6 +144,17 @@ export const EstimatePaymentEmail: React.FC<
); );
}; };
/**
* Renders the estimate mail template to string
* @param {EstimatePaymentEmailProps} props
* @returns {Promise<string>}
*/
export const renderEstimateEmailTemplate = (
props: EstimatePaymentEmailProps
) => {
return render(<EstimatePaymentEmail {...props} />);
};
const headerInfoStyle: CSSProperties = { const headerInfoStyle: CSSProperties = {
textAlign: 'center', textAlign: 'center',
marginBottom: 20, marginBottom: 20,

View File

@@ -2,6 +2,7 @@ import {
Button, Button,
Container, Container,
Heading, Heading,
render,
Row, Row,
Section, Section,
Text, Text,
@@ -65,47 +66,58 @@ export const PaymentReceivedEmailTemplate: React.FC<
viewPaymentButtonLabel = 'View Payment', viewPaymentButtonLabel = 'View Payment',
viewPaymentButtonUrl, viewPaymentButtonUrl,
}) => { }) => {
return ( return (
<EmailTemplateLayout preview={preview}> <EmailTemplateLayout preview={preview}>
<Container style={containerStyle}> <Container style={containerStyle}>
{companyLogoUri && ( {companyLogoUri && (
<Section style={logoSectionStyle}> <Section style={logoSectionStyle}>
<div <div
style={{ style={{
...companyLogoStyle, ...companyLogoStyle,
backgroundImage: `url("${companyLogoUri}")`, backgroundImage: `url("${companyLogoUri}")`,
}} }}
></div> ></div>
</Section>
)}
<Section style={headerInfoStyle}>
<Row>
<Heading style={invoiceCompanyNameStyle}>{companyName}</Heading>
</Row>
<Row>
<Text style={paymentAmountStyle}>{total}</Text>
</Row>
<Row>
<Text style={paymentNumberStyle}>
{paymentNumberLabel?.replace('{paymentNumber}', paymentNumber)}
</Text>
</Row>
</Section> </Section>
)}
<Section style={headerInfoStyle}>
<Row>
<Heading style={invoiceCompanyNameStyle}>{companyName}</Heading>
</Row>
<Row>
<Text style={paymentAmountStyle}>{total}</Text>
</Row>
<Row>
<Text style={paymentNumberStyle}>
{paymentNumberLabel?.replace('{paymentNumber}', paymentNumber)}
</Text>
</Row>
</Section>
<Text style={invoiceMessageStyle}>{message}</Text> <Text style={invoiceMessageStyle}>{message}</Text>
<Button <Button
href={viewPaymentButtonUrl} href={viewPaymentButtonUrl}
style={{ style={{
...viewInvoiceButtonStyle, ...viewInvoiceButtonStyle,
backgroundColor: primaryColor, backgroundColor: primaryColor,
}} }}
> >
{viewPaymentButtonLabel} {viewPaymentButtonLabel}
</Button> </Button>
</Container> </Container>
</EmailTemplateLayout> </EmailTemplateLayout>
); );
}; };
/**
* Renders the payment received mail template to string
* @param {EstimatePaymentEmailProps} props
* @returns {Promise<string>}
*/
export const renderPaymentReceivedEmailTemplate = (
props: PaymentReceivedEmailTemplateProps
) => {
return render(<PaymentReceivedEmailTemplate {...props} />);
};
const containerStyle: CSSProperties = { const containerStyle: CSSProperties = {
backgroundColor: '#fff', backgroundColor: '#fff',

View File

@@ -1,8 +1,8 @@
import { import {
Button, Button,
Column, Column,
Container,
Heading, Heading,
render,
Row, Row,
Section, Section,
Text, Text,
@@ -148,6 +148,17 @@ export const ReceiptEmailTemplate: React.FC<
); );
}; };
/**
* Renders the sale receipt mail template to string
* @param {ReceiptEmailTemplateProps} props
* @returns {Promise<string>}
*/
export const renderReceiptEmailTemplate = (
props: ReceiptEmailTemplateProps
) => {
return render(<ReceiptEmailTemplate {...props} />);
};
const headerInfoStyle: CSSProperties = { const headerInfoStyle: CSSProperties = {
textAlign: 'center', textAlign: 'center',
marginBottom: 20, marginBottom: 20,