mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-21 07:10:33 +00:00
feat: wip invoice mail receipt preview
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import { InvoicePaymentPage, PaymentPageProps } from './PaymentPage';
|
import { InvoicePaymentPage, PaymentPageProps } from './PaymentPage';
|
||||||
|
|
||||||
interface InvoicePaymentPagePreviewProps extends Partial<PaymentPageProps> { }
|
export interface InvoicePaymentPagePreviewProps
|
||||||
|
extends Partial<PaymentPageProps> { }
|
||||||
|
|
||||||
export function InvoicePaymentPagePreview(
|
export function InvoicePaymentPagePreview(
|
||||||
props: InvoicePaymentPagePreviewProps,
|
props: InvoicePaymentPagePreviewProps,
|
||||||
|
|||||||
@@ -2,58 +2,117 @@ import { Text, Classes, Button, Intent, ButtonProps } from '@blueprintjs/core';
|
|||||||
import clsx from 'classnames';
|
import clsx from 'classnames';
|
||||||
import { Box, Group, Stack } from '@/components';
|
import { Box, Group, Stack } from '@/components';
|
||||||
import styles from './PaymentPortal.module.scss';
|
import styles from './PaymentPortal.module.scss';
|
||||||
|
import { css } from '@emotion/css';
|
||||||
|
|
||||||
export interface PaymentPageProps {
|
export interface PaymentPageProps {
|
||||||
|
// # Company name
|
||||||
companyLogoUri: string;
|
companyLogoUri: string;
|
||||||
organizationName: string;
|
organizationName: string;
|
||||||
|
organizationAddress: string;
|
||||||
|
|
||||||
|
// # Colors
|
||||||
|
primaryColor?: string;
|
||||||
|
|
||||||
|
// # Customer name
|
||||||
customerName: string;
|
customerName: string;
|
||||||
subtotal: string;
|
|
||||||
total: string;
|
|
||||||
dueDate: string;
|
|
||||||
viewInvoiceLabel?: string;
|
|
||||||
invoiceNumber: string;
|
|
||||||
totalLabel?: string;
|
|
||||||
subtotalLabel?: string;
|
|
||||||
customerAddress?: string;
|
customerAddress?: string;
|
||||||
downloadInvoiceBtnLabel?: string;
|
|
||||||
showPayButton?: boolean;
|
// # Subtotal
|
||||||
|
subtotal: string;
|
||||||
|
subtotalLabel?: string;
|
||||||
|
|
||||||
|
// # Total
|
||||||
|
total: string;
|
||||||
|
totalLabel?: string;
|
||||||
|
|
||||||
|
// # Due date
|
||||||
|
dueDate: string;
|
||||||
|
|
||||||
|
// # Paid amount
|
||||||
paidAmount: string;
|
paidAmount: string;
|
||||||
paidAmountLabel?: string;
|
paidAmountLabel?: string;
|
||||||
organizationAddress: string;
|
|
||||||
|
// # Due amount
|
||||||
dueAmount: string;
|
dueAmount: string;
|
||||||
dueAmountLabel?: string;
|
dueAmountLabel?: string;
|
||||||
|
|
||||||
|
// # Download invoice button
|
||||||
|
downloadInvoiceBtnLabel?: string;
|
||||||
downloadInvoiceButtonProps?: Partial<ButtonProps>;
|
downloadInvoiceButtonProps?: Partial<ButtonProps>;
|
||||||
payInvoiceButtonProps?: Partial<ButtonProps>;
|
|
||||||
|
// # View invoice button
|
||||||
|
viewInvoiceLabel?: string;
|
||||||
viewInvoiceButtonProps?: Partial<ButtonProps>;
|
viewInvoiceButtonProps?: Partial<ButtonProps>;
|
||||||
|
|
||||||
|
// # Invoice number
|
||||||
|
invoiceNumber: string;
|
||||||
invoiceNumberLabel?: string;
|
invoiceNumberLabel?: string;
|
||||||
|
|
||||||
|
// # Pay button
|
||||||
|
showPayButton?: boolean;
|
||||||
|
payButtonLabel?: string;
|
||||||
|
payInvoiceButtonProps?: Partial<ButtonProps>;
|
||||||
|
|
||||||
|
// # Buy note
|
||||||
buyNote?: string;
|
buyNote?: string;
|
||||||
|
|
||||||
|
// # Copyright
|
||||||
copyrightText?: string;
|
copyrightText?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function InvoicePaymentPage({
|
export function InvoicePaymentPage({
|
||||||
|
// # Company
|
||||||
companyLogoUri,
|
companyLogoUri,
|
||||||
organizationName,
|
organizationName,
|
||||||
|
organizationAddress,
|
||||||
|
|
||||||
|
// # Colors
|
||||||
|
primaryColor,
|
||||||
|
|
||||||
|
// # Customer
|
||||||
customerName,
|
customerName,
|
||||||
|
customerAddress,
|
||||||
|
|
||||||
|
// # Subtotal
|
||||||
subtotal,
|
subtotal,
|
||||||
|
subtotalLabel = 'Subtotal',
|
||||||
|
|
||||||
|
// # Total
|
||||||
total,
|
total,
|
||||||
|
totalLabel = 'Total',
|
||||||
|
|
||||||
|
// # Due date
|
||||||
dueDate,
|
dueDate,
|
||||||
|
|
||||||
|
// # Paid amount
|
||||||
paidAmount,
|
paidAmount,
|
||||||
paidAmountLabel = 'Paid Amount (-)',
|
paidAmountLabel = 'Paid Amount (-)',
|
||||||
|
|
||||||
|
// # Invoice number
|
||||||
invoiceNumber,
|
invoiceNumber,
|
||||||
customerAddress,
|
invoiceNumberLabel = 'Invoice #',
|
||||||
totalLabel = 'Total',
|
|
||||||
subtotalLabel = 'Subtotal',
|
// # Download invoice button
|
||||||
viewInvoiceLabel = 'View Invoice',
|
|
||||||
downloadInvoiceBtnLabel = 'Download Invoice',
|
downloadInvoiceBtnLabel = 'Download Invoice',
|
||||||
showPayButton = true,
|
downloadInvoiceButtonProps,
|
||||||
organizationAddress,
|
|
||||||
|
// # View invoice button
|
||||||
|
viewInvoiceLabel = 'View Invoice',
|
||||||
|
viewInvoiceButtonProps,
|
||||||
|
|
||||||
|
// # Due amount
|
||||||
dueAmount,
|
dueAmount,
|
||||||
dueAmountLabel = 'Due Amount',
|
dueAmountLabel = 'Due Amount',
|
||||||
downloadInvoiceButtonProps,
|
|
||||||
|
// # Pay button
|
||||||
|
showPayButton = true,
|
||||||
|
payButtonLabel = 'Pay {total}',
|
||||||
payInvoiceButtonProps,
|
payInvoiceButtonProps,
|
||||||
viewInvoiceButtonProps,
|
|
||||||
invoiceNumberLabel = 'Invoice #',
|
// # Buy note
|
||||||
buyNote = 'By confirming your payment, you allow Bigcapital Technology, Inc. to charge you for this payment and save your payment information in accordance with their terms.',
|
buyNote = 'By confirming your payment, you allow Bigcapital Technology, Inc. to charge you for this payment and save your payment information in accordance with their terms.',
|
||||||
|
|
||||||
|
// # Copyright
|
||||||
copyrightText = `© 2024 Bigcapital Technology, Inc. <br /> All rights reserved.`,
|
copyrightText = `© 2024 Bigcapital Technology, Inc. <br /> All rights reserved.`,
|
||||||
}: PaymentPageProps) {
|
}: PaymentPageProps) {
|
||||||
return (
|
return (
|
||||||
@@ -91,7 +150,9 @@ export function InvoicePaymentPage({
|
|||||||
)}
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
<h2 className={styles.invoiceNumber}>Invoice {invoiceNumber}</h2>
|
<h2 className={styles.invoiceNumber}>
|
||||||
|
{invoiceNumberLabel} {invoiceNumber}
|
||||||
|
</h2>
|
||||||
|
|
||||||
<Stack spacing={0} className={styles.totals}>
|
<Stack spacing={0} className={styles.totals}>
|
||||||
<Group
|
<Group
|
||||||
@@ -125,7 +186,7 @@ export function InvoicePaymentPage({
|
|||||||
position={'apart'}
|
position={'apart'}
|
||||||
className={clsx(styles.totalItem, styles.borderBottomDark)}
|
className={clsx(styles.totalItem, styles.borderBottomDark)}
|
||||||
>
|
>
|
||||||
<Text>Due Amount</Text>
|
<Text>{dueAmountLabel}</Text>
|
||||||
<Text style={{ fontWeight: 500 }}>{dueAmount}</Text>
|
<Text style={{ fontWeight: 500 }}>{dueAmount}</Text>
|
||||||
</Group>
|
</Group>
|
||||||
</Stack>
|
</Stack>
|
||||||
@@ -150,10 +211,18 @@ export function InvoicePaymentPage({
|
|||||||
{showPayButton && (
|
{showPayButton && (
|
||||||
<Button
|
<Button
|
||||||
intent={Intent.PRIMARY}
|
intent={Intent.PRIMARY}
|
||||||
className={clsx(styles.footerButton, styles.buyButton)}
|
className={clsx(
|
||||||
|
styles.footerButton,
|
||||||
|
styles.buyButton,
|
||||||
|
css`
|
||||||
|
&.bp4-intent-primary {
|
||||||
|
background-color: ${primaryColor};
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
)}
|
||||||
{...payInvoiceButtonProps}
|
{...payInvoiceButtonProps}
|
||||||
>
|
>
|
||||||
Pay {total}
|
{payButtonLabel.replace('{total}', total)}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: #222;
|
color: #222;
|
||||||
font-size: 26px;
|
font-size: 26px;
|
||||||
|
line-height: 1.35;
|
||||||
}
|
}
|
||||||
|
|
||||||
.invoiceDueDate{
|
.invoiceDueDate{
|
||||||
|
|||||||
@@ -1,11 +1,5 @@
|
|||||||
import React, { lazy, Suspense } from 'react';
|
import { lazy, Suspense } from 'react';
|
||||||
import * as R from 'ramda';
|
|
||||||
import { useFormikContext } from 'formik';
|
|
||||||
import { Spinner, Tab } from '@blueprintjs/core';
|
import { Spinner, Tab } from '@blueprintjs/core';
|
||||||
import {
|
|
||||||
InvoicePaperTemplate,
|
|
||||||
InvoicePaperTemplateProps,
|
|
||||||
} from './InvoicePaperTemplate';
|
|
||||||
import {
|
import {
|
||||||
ElementCustomize,
|
ElementCustomize,
|
||||||
ElementCustomizeContent,
|
ElementCustomizeContent,
|
||||||
@@ -17,21 +11,26 @@ import { InvoiceCustomizeSchema } from './InvoiceCustomizeForm.schema';
|
|||||||
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
|
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
|
||||||
import { useDrawerActions } from '@/hooks/state';
|
import { useDrawerActions } from '@/hooks/state';
|
||||||
import { BrandingTemplateForm } from '@/containers/BrandingTemplates/BrandingTemplateForm';
|
import { BrandingTemplateForm } from '@/containers/BrandingTemplates/BrandingTemplateForm';
|
||||||
import { useElementCustomizeContext } from '@/containers/ElementCustomize/ElementCustomizeProvider';
|
|
||||||
import { initialValues } from './constants';
|
import { initialValues } from './constants';
|
||||||
import { useIsTemplateNamedFilled } from '@/containers/BrandingTemplates/utils';
|
import { useIsTemplateNamedFilled } from '@/containers/BrandingTemplates/utils';
|
||||||
import { InvoiceCustomizeTabs } from './InvoiceCustomizeTabs';
|
import { InvoiceCustomizeTabs } from './InvoiceCustomizeTabs';
|
||||||
|
|
||||||
const InvoicePaymentPagePreview = lazy(() =>
|
const InvoiceCustomizePaymentPreview = lazy(() =>
|
||||||
import('@/containers/PaymentPortal/InvoicePaymentPagePreview').then(
|
import('./InvoiceCustomizePaymentPreview').then((module) => ({
|
||||||
(module) => ({ default: module.InvoicePaymentPagePreview }),
|
default: module.InvoiceCustomizePaymentPreview,
|
||||||
),
|
})),
|
||||||
);
|
);
|
||||||
|
|
||||||
const InvoiceMailReceiptPreview = lazy(() =>
|
const InvoiceCustomizeMailReceiptPreview = lazy(() =>
|
||||||
import(
|
import('./InvoiceCustomizeMailReceiptPreview').then((module) => ({
|
||||||
'@/containers/Sales/Invoices/InvoiceCustomize/InvoiceMailReceiptPreview'
|
default: module.InvoiceCustomizeMailReceiptPreview,
|
||||||
).then((module) => ({ default: module.InvoiceMailReceiptPreview })),
|
})),
|
||||||
|
);
|
||||||
|
|
||||||
|
const InvoiceCustomizePdfPreview = lazy(() =>
|
||||||
|
import('./InvoiceCustomizePdfPreview').then((module) => ({
|
||||||
|
default: module.InvoiceCustomizePdfPreview,
|
||||||
|
})),
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -80,7 +79,7 @@ function InvoiceCustomizeFormContent() {
|
|||||||
title={'PDF document'}
|
title={'PDF document'}
|
||||||
panel={
|
panel={
|
||||||
<Suspense fallback={<Spinner />}>
|
<Suspense fallback={<Spinner />}>
|
||||||
<InvoicePaperTemplateFormConnected />
|
<InvoiceCustomizePdfPreview />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
@@ -89,7 +88,7 @@ function InvoiceCustomizeFormContent() {
|
|||||||
title={'Payment page'}
|
title={'Payment page'}
|
||||||
panel={
|
panel={
|
||||||
<Suspense fallback={<Spinner />}>
|
<Suspense fallback={<Spinner />}>
|
||||||
<InvoicePaymentPagePreview />
|
<InvoiceCustomizePaymentPreview />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
@@ -98,7 +97,7 @@ function InvoiceCustomizeFormContent() {
|
|||||||
title={'Email receipt'}
|
title={'Email receipt'}
|
||||||
panel={
|
panel={
|
||||||
<Suspense fallback={<Spinner />}>
|
<Suspense fallback={<Spinner />}>
|
||||||
<InvoiceMailReceiptPreview mx={'auto'} />
|
<InvoiceCustomizeMailReceiptPreview mx={'auto'} />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
@@ -119,27 +118,3 @@ function InvoiceCustomizeFormContent() {
|
|||||||
</ElementCustomizeContent>
|
</ElementCustomizeContent>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Injects the `InvoicePaperTemplate` component props from the form and branding states.
|
|
||||||
* @param Component
|
|
||||||
* @returns {JSX.Element}
|
|
||||||
*/
|
|
||||||
const withInvoicePreviewTemplateProps = <P extends object>(
|
|
||||||
Component: React.ComponentType<P>,
|
|
||||||
) => {
|
|
||||||
return (props: Omit<P, keyof InvoicePaperTemplateProps>) => {
|
|
||||||
const { values } = useFormikContext<InvoiceCustomizeFormValues>();
|
|
||||||
const { brandingState } = useElementCustomizeContext();
|
|
||||||
|
|
||||||
const mergedProps: InvoicePaperTemplateProps = {
|
|
||||||
...brandingState,
|
|
||||||
...values,
|
|
||||||
};
|
|
||||||
return <Component {...(props as P)} {...mergedProps} />;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const InvoicePaperTemplateFormConnected = R.compose(
|
|
||||||
withInvoicePreviewTemplateProps,
|
|
||||||
)(InvoicePaperTemplate);
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import { Classes, Text } from '@blueprintjs/core';
|
import { Classes, Text } from '@blueprintjs/core';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
import {
|
import {
|
||||||
FFormGroup,
|
FFormGroup,
|
||||||
FieldRequiredHint,
|
FieldRequiredHint,
|
||||||
@@ -13,7 +14,6 @@ import { CreditCardIcon } from '@/icons/CreditCardIcon';
|
|||||||
import { Overlay } from './Overlay';
|
import { Overlay } from './Overlay';
|
||||||
import { useIsTemplateNamedFilled } from '@/containers/BrandingTemplates/utils';
|
import { useIsTemplateNamedFilled } from '@/containers/BrandingTemplates/utils';
|
||||||
import { BrandingCompanyLogoUploadField } from '@/containers/ElementCustomize/components/BrandingCompanyLogoUploadField';
|
import { BrandingCompanyLogoUploadField } from '@/containers/ElementCustomize/components/BrandingCompanyLogoUploadField';
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
import { MANAGE_LINK_URL } from './constants';
|
import { MANAGE_LINK_URL } from './constants';
|
||||||
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
|
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
|
||||||
import { useDrawerActions } from '@/hooks/state';
|
import { useDrawerActions } from '@/hooks/state';
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import * as R from 'ramda';
|
||||||
|
import { InvoicePaymentPagePreviewProps } from '@/containers/PaymentPortal/InvoicePaymentPagePreview';
|
||||||
|
import { InvoiceCustomizeFormValues } from './types';
|
||||||
|
import { useElementCustomizeContext } from '@/containers/ElementCustomize/ElementCustomizeProvider';
|
||||||
|
import { useFormikContext } from 'formik';
|
||||||
|
import { InvoiceMailReceiptPreview } from './InvoiceMailReceiptPreview';
|
||||||
|
|
||||||
|
const withInvoiceMailReceiptPreviewConnected = <P extends Object>(
|
||||||
|
Component: React.ComponentType<P>,
|
||||||
|
) => {
|
||||||
|
return (props: Omit<P, keyof InvoicePaymentPagePreviewProps>) => {
|
||||||
|
const { values } = useFormikContext<InvoiceCustomizeFormValues>();
|
||||||
|
const { brandingState } = useElementCustomizeContext();
|
||||||
|
|
||||||
|
const mergedBrandingState = {
|
||||||
|
...brandingState,
|
||||||
|
...values,
|
||||||
|
};
|
||||||
|
const mergedProps: InvoicePaymentPagePreviewProps = {
|
||||||
|
companyLogoUri: mergedBrandingState?.companyLogoUri,
|
||||||
|
primaryColor: mergedBrandingState?.primaryColor,
|
||||||
|
// organizationAddress: mergedBrandingState,
|
||||||
|
};
|
||||||
|
return <Component {...(props as P)} {...mergedProps} />;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const InvoiceCustomizeMailReceiptPreview = R.compose(
|
||||||
|
withInvoiceMailReceiptPreviewConnected,
|
||||||
|
)(InvoiceMailReceiptPreview);
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import * as R from 'ramda';
|
||||||
|
import { useFormikContext } from 'formik';
|
||||||
|
import {
|
||||||
|
InvoicePaymentPagePreview,
|
||||||
|
InvoicePaymentPagePreviewProps,
|
||||||
|
} from '@/containers/PaymentPortal/InvoicePaymentPagePreview';
|
||||||
|
import { useElementCustomizeContext } from '@/containers/ElementCustomize/ElementCustomizeProvider';
|
||||||
|
import { InvoiceCustomizeFormValues } from './types';
|
||||||
|
|
||||||
|
const withInvoicePaymentPreviewPageProps = <P extends Object>(
|
||||||
|
Component: React.ComponentType<P>,
|
||||||
|
) => {
|
||||||
|
return (props: Omit<P, keyof InvoicePaymentPagePreviewProps>) => {
|
||||||
|
const { values } = useFormikContext<InvoiceCustomizeFormValues>();
|
||||||
|
const { brandingState } = useElementCustomizeContext();
|
||||||
|
|
||||||
|
const mergedBrandingState = {
|
||||||
|
...brandingState,
|
||||||
|
...values,
|
||||||
|
};
|
||||||
|
const mergedProps: InvoicePaymentPagePreviewProps = {
|
||||||
|
companyLogoUri: mergedBrandingState?.companyLogoUri,
|
||||||
|
primaryColor: mergedBrandingState?.primaryColor,
|
||||||
|
};
|
||||||
|
return <Component {...(props as P)} {...mergedProps} />;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const InvoiceCustomizePaymentPreview = R.compose(
|
||||||
|
withInvoicePaymentPreviewPageProps,
|
||||||
|
)(InvoicePaymentPagePreview);
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import * as R from 'ramda';
|
||||||
|
import { useFormikContext } from 'formik';
|
||||||
|
import {
|
||||||
|
InvoicePaperTemplate,
|
||||||
|
InvoicePaperTemplateProps,
|
||||||
|
} from './InvoicePaperTemplate';
|
||||||
|
import { useElementCustomizeContext } from '@/containers/ElementCustomize/ElementCustomizeProvider';
|
||||||
|
import { InvoiceCustomizeFormValues } from './types';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injects the `InvoicePaperTemplate` component props from the form and branding states.
|
||||||
|
* @param Component
|
||||||
|
* @returns {JSX.Element}
|
||||||
|
*/
|
||||||
|
const withInvoicePreviewTemplateProps = <P extends object>(
|
||||||
|
Component: React.ComponentType<P>,
|
||||||
|
) => {
|
||||||
|
return (props: Omit<P, keyof InvoicePaperTemplateProps>) => {
|
||||||
|
const { values } = useFormikContext<InvoiceCustomizeFormValues>();
|
||||||
|
const { brandingState } = useElementCustomizeContext();
|
||||||
|
|
||||||
|
const mergedProps: InvoicePaperTemplateProps = {
|
||||||
|
...brandingState,
|
||||||
|
...values,
|
||||||
|
};
|
||||||
|
return <Component {...(props as P)} {...mergedProps} />;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const InvoiceCustomizePdfPreview = R.compose(
|
||||||
|
withInvoicePreviewTemplateProps,
|
||||||
|
)(InvoicePaperTemplate);
|
||||||
@@ -4,35 +4,75 @@ import { x } from '@xstyled/emotion';
|
|||||||
import { Group, Stack, StackProps } from '@/components';
|
import { Group, Stack, StackProps } from '@/components';
|
||||||
|
|
||||||
export interface InvoiceMailReceiptProps extends StackProps {
|
export interface InvoiceMailReceiptProps extends StackProps {
|
||||||
companyLogoUri?: string;
|
// # Company
|
||||||
message: string;
|
|
||||||
companyName: string;
|
companyName: string;
|
||||||
invoiceNumber: string;
|
companyLogoUri?: string;
|
||||||
|
|
||||||
|
// # Colors
|
||||||
|
primaryColor?: string,
|
||||||
|
|
||||||
|
// # Due date
|
||||||
dueDate: string;
|
dueDate: string;
|
||||||
items?: Array<{ label: string; total: string; quantity: string | number }>;
|
dueDateLabel?: string;
|
||||||
total: string;
|
|
||||||
dueAmount: string;
|
// # Due amount
|
||||||
totalLabel?: string;
|
|
||||||
dueAmountLabel?: string;
|
dueAmountLabel?: string;
|
||||||
|
dueAmount: string;
|
||||||
|
|
||||||
|
// # Total
|
||||||
|
total: string;
|
||||||
|
totalLabel?: string;
|
||||||
|
|
||||||
|
// # Invoice number
|
||||||
|
invoiceNumber: string;
|
||||||
|
invoiceNumberLabel?: string;
|
||||||
|
|
||||||
|
// # Mail message
|
||||||
|
message: string;
|
||||||
|
|
||||||
|
// # Invoice items
|
||||||
|
items?: Array<{ label: string; total: string; quantity: string | number }>;
|
||||||
|
|
||||||
|
// # View invoice button
|
||||||
|
showViewInvoiceButton?: boolean;
|
||||||
viewInvoiceButtonLabel?: string;
|
viewInvoiceButtonLabel?: string;
|
||||||
viewInvoiceButtonOnClick?: () => void;
|
viewInvoiceButtonOnClick?: () => void;
|
||||||
invoiceNumberLabel?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function InvoiceMailReceipt({
|
export function InvoiceMailReceipt({
|
||||||
companyLogoUri,
|
// Company
|
||||||
message,
|
|
||||||
companyName,
|
companyName,
|
||||||
total,
|
companyLogoUri,
|
||||||
invoiceNumber,
|
|
||||||
|
// # Colors
|
||||||
|
primaryColor,
|
||||||
|
|
||||||
|
// Due date
|
||||||
dueDate,
|
dueDate,
|
||||||
|
dueDateLabel = 'Due',
|
||||||
|
|
||||||
|
// Due amount
|
||||||
|
dueAmountLabel = 'Due Amount',
|
||||||
dueAmount,
|
dueAmount,
|
||||||
|
|
||||||
|
// Total
|
||||||
|
total,
|
||||||
|
totalLabel = 'Total',
|
||||||
|
|
||||||
|
// Invoice number
|
||||||
|
invoiceNumber,
|
||||||
|
invoiceNumberLabel = 'Invoice #',
|
||||||
|
|
||||||
|
// Invoice message
|
||||||
|
message,
|
||||||
|
|
||||||
|
// Invoice items
|
||||||
items,
|
items,
|
||||||
|
|
||||||
|
// View invoice button
|
||||||
|
showViewInvoiceButton = true,
|
||||||
viewInvoiceButtonLabel = 'View Invoice',
|
viewInvoiceButtonLabel = 'View Invoice',
|
||||||
viewInvoiceButtonOnClick,
|
viewInvoiceButtonOnClick,
|
||||||
totalLabel = 'Total',
|
|
||||||
dueAmountLabel = 'Due Amount',
|
|
||||||
invoiceNumberLabel = 'Invoice #',
|
|
||||||
...restProps
|
...restProps
|
||||||
}: InvoiceMailReceiptProps) {
|
}: InvoiceMailReceiptProps) {
|
||||||
return (
|
return (
|
||||||
@@ -48,7 +88,15 @@ export function InvoiceMailReceipt({
|
|||||||
>
|
>
|
||||||
<Stack spacing={16} textAlign={'center'}>
|
<Stack spacing={16} textAlign={'center'}>
|
||||||
{companyLogoUri && (
|
{companyLogoUri && (
|
||||||
<x.div h={'90px'} w={'90px'} bg="#F2F2F2" mx="auto"></x.div>
|
<x.div
|
||||||
|
h="90px"
|
||||||
|
w="90px"
|
||||||
|
mx="auto"
|
||||||
|
backgroundRepeat="no-repeat"
|
||||||
|
backgroundPosition="center center"
|
||||||
|
backgroundSize="contain"
|
||||||
|
backgroundImage={`url("${companyLogoUri}")`}
|
||||||
|
></x.div>
|
||||||
)}
|
)}
|
||||||
<Stack spacing={8}>
|
<Stack spacing={8}>
|
||||||
<x.h1 m={0} fontSize={'18px'} fontWeight={500} color="#404854">
|
<x.h1 m={0} fontSize={'18px'} fontWeight={500} color="#404854">
|
||||||
@@ -64,7 +112,7 @@ export function InvoiceMailReceipt({
|
|||||||
</x.span>
|
</x.span>
|
||||||
|
|
||||||
<x.span fontSize={'13px'} color="#404854">
|
<x.span fontSize={'13px'} color="#404854">
|
||||||
Due {dueDate}
|
{dueDateLabel} {dueDate}
|
||||||
</x.span>
|
</x.span>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
@@ -73,18 +121,23 @@ export function InvoiceMailReceipt({
|
|||||||
{message}
|
{message}
|
||||||
</x.p>
|
</x.p>
|
||||||
|
|
||||||
<Button
|
{showViewInvoiceButton && (
|
||||||
large
|
<Button
|
||||||
intent={Intent.PRIMARY}
|
large
|
||||||
className={css`
|
intent={Intent.PRIMARY}
|
||||||
&.bp4-large {
|
className={css`
|
||||||
min-height: 38px;
|
&.bp4-intent-primary{
|
||||||
}
|
background-color: ${primaryColor};
|
||||||
`}
|
}
|
||||||
onClick={viewInvoiceButtonOnClick}
|
&.bp4-large {
|
||||||
>
|
min-height: 38px;
|
||||||
{viewInvoiceButtonLabel}
|
}
|
||||||
</Button>
|
`}
|
||||||
|
onClick={viewInvoiceButtonOnClick}
|
||||||
|
>
|
||||||
|
{viewInvoiceButtonLabel}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
|
||||||
<Stack spacing={0}>
|
<Stack spacing={0}>
|
||||||
{items?.map((item, key) => (
|
{items?.map((item, key) => (
|
||||||
|
|||||||
Reference in New Issue
Block a user