diff --git a/packages/server/src/models/PdfTemplate.ts b/packages/server/src/models/PdfTemplate.ts index 5cf27f358..ccf5f48d2 100644 --- a/packages/server/src/models/PdfTemplate.ts +++ b/packages/server/src/models/PdfTemplate.ts @@ -1,6 +1,9 @@ +import { getUploadedObjectUri } from '@/services/Attachments/utils'; import TenantModel from 'models/TenantModel'; export class PdfTemplate extends TenantModel { + public readonly attributes: Record; + /** * Table name. */ @@ -47,7 +50,17 @@ export class PdfTemplate extends TenantModel { * Virtual attributes. */ static get virtualAttributes() { - return []; + return ['companyLogoUri']; + } + + /** + * Retrieves the company logo uri. + * @returns {string} + */ + get companyLogoUri() { + return this.attributes.companyLogoKey + ? getUploadedObjectUri(this.attributes.companyLogoKey) + : ''; } /** diff --git a/packages/server/src/services/CreditNotes/CreditNoteBrandingTemplate.ts b/packages/server/src/services/CreditNotes/CreditNoteBrandingTemplate.ts index 872f16ef4..ef0150747 100644 --- a/packages/server/src/services/CreditNotes/CreditNoteBrandingTemplate.ts +++ b/packages/server/src/services/CreditNotes/CreditNoteBrandingTemplate.ts @@ -35,9 +35,12 @@ export class CreditNoteBrandingTemplate { ...defaultCreditNoteBrandingAttributes, ...commonOrgBrandingAttrs, }; - + const brandingTemplateAttrs = { + ...template.attributes, + companyLogoUri: template.companyLogoUri, + }; const attributes = mergePdfTemplateWithDefaultAttributes( - template.attributes, + brandingTemplateAttrs, organizationBrandingAttrs ); return { diff --git a/packages/server/src/services/PdfTemplate/GetPdfTemplateTransformer.ts b/packages/server/src/services/PdfTemplate/GetPdfTemplateTransformer.ts index fddc28c59..5d7470018 100644 --- a/packages/server/src/services/PdfTemplate/GetPdfTemplateTransformer.ts +++ b/packages/server/src/services/PdfTemplate/GetPdfTemplateTransformer.ts @@ -1,10 +1,9 @@ import { Transformer } from '@/lib/Transformer/Transformer'; import { getTransactionTypeLabel } from '@/utils/transactions-types'; -import { getUploadedObjectUri } from '../Attachments/utils'; export class GetPdfTemplateTransformer extends Transformer { /** - * Includeded attributes. + * Included attributes. * @returns {string[]} */ public includeAttributes = (): string[] => { @@ -44,20 +43,10 @@ export class GetPdfTemplateTransformer extends Transformer { class GetPdfTemplateAttributesTransformer extends Transformer { /** - * Includeded attributes. + * Included attributes. * @returns {string[]} */ public includeAttributes = (): string[] => { - return ['companyLogoUri']; + return []; }; - - /** - * Retrieves the company logo uri. - * @returns {string} - */ - protected companyLogoUri(template) { - return template.companyLogoKey - ? getUploadedObjectUri(template.companyLogoKey) - : ''; - } } diff --git a/packages/server/src/services/PdfTemplate/types.ts b/packages/server/src/services/PdfTemplate/types.ts index 6fad632ab..de1029afa 100644 --- a/packages/server/src/services/PdfTemplate/types.ts +++ b/packages/server/src/services/PdfTemplate/types.ts @@ -66,7 +66,6 @@ export interface ICreateInvoicePdfTemplateDTO { showStatement?: boolean; } - export interface CommonOrganizationBrandingAttributes { companyName?: string; primaryColor?: string; diff --git a/packages/server/src/services/Sales/Invoices/GetInvoicePaymentMailAttributesTransformer.ts b/packages/server/src/services/Sales/Invoices/GetInvoicePaymentMailAttributesTransformer.ts index 976b5053f..1ac116064 100644 --- a/packages/server/src/services/Sales/Invoices/GetInvoicePaymentMailAttributesTransformer.ts +++ b/packages/server/src/services/Sales/Invoices/GetInvoicePaymentMailAttributesTransformer.ts @@ -41,7 +41,7 @@ export class GetInvoiceMailTemplateAttributesTransformer extends Transformer { }; public companyLogoUri(): string { - return this.options.brandingTemplate?.attributes?.companyLogoUri; + return this.options.brandingTemplate?.companyLogoUri; } public companyName(): string { diff --git a/packages/server/src/services/Sales/Invoices/GetSaleInvoiceMailState.ts b/packages/server/src/services/Sales/Invoices/GetSaleInvoiceMailState.ts index c32fa2430..6f00dd08d 100644 --- a/packages/server/src/services/Sales/Invoices/GetSaleInvoiceMailState.ts +++ b/packages/server/src/services/Sales/Invoices/GetSaleInvoiceMailState.ts @@ -18,7 +18,6 @@ export class GetSaleInvoiceMailState { /** * Retrieves the invoice mail state of the given sale invoice. * Invoice mail state includes the mail options, branding attributes and the invoice details. - * * @param {number} tenantId * @param {number} saleInvoiceId * @returns {Promise} diff --git a/packages/server/src/services/Sales/Invoices/GetSaleInvoiceMailStateTransformer.ts b/packages/server/src/services/Sales/Invoices/GetSaleInvoiceMailStateTransformer.ts index 75d3d1f62..e1676d845 100644 --- a/packages/server/src/services/Sales/Invoices/GetSaleInvoiceMailStateTransformer.ts +++ b/packages/server/src/services/Sales/Invoices/GetSaleInvoiceMailStateTransformer.ts @@ -1,4 +1,3 @@ -import { Transformer } from '@/lib/Transformer/Transformer'; import { SaleInvoiceTransformer } from './SaleInvoiceTransformer'; import { ItemEntryTransformer } from './ItemEntryTransformer'; @@ -11,6 +10,10 @@ export class GetSaleInvoiceMailStateTransformer extends SaleInvoiceTransformer { return ['*']; }; + /** + * Included attributes. + * @returns {Array} + */ public includeAttributes = (): string[] => { return [ 'invoiceDate', @@ -39,14 +42,26 @@ export class GetSaleInvoiceMailStateTransformer extends SaleInvoiceTransformer { ]; }; + /** + * Retrieves the company name. + * @returns {string} + */ protected companyName = () => { return this.context.organization.name; }; + /** + * Retrieves the company logo uri. + * @returns {string | null} + */ protected companyLogoUri = (invoice) => { - return invoice.pdfTemplate?.attributes?.companyLogoUri; + return invoice.pdfTemplate?.companyLogoUri; }; + /** + * Retrieves the primary color. + * @returns {string} + */ protected primaryColor = (invoice) => { return invoice.pdfTemplate?.attributes?.primaryColor; }; diff --git a/packages/server/src/services/Sales/Invoices/SaleEstimatePdfTemplate.ts b/packages/server/src/services/Sales/Invoices/SaleEstimatePdfTemplate.ts index 54048619a..544468b49 100644 --- a/packages/server/src/services/Sales/Invoices/SaleEstimatePdfTemplate.ts +++ b/packages/server/src/services/Sales/Invoices/SaleEstimatePdfTemplate.ts @@ -33,8 +33,12 @@ export class SaleEstimatePdfTemplate { ...defaultEstimatePdfBrandingAttributes, ...commonOrgBrandingAttrs, }; + const brandingTemplateAttrs = { + ...template.attributes, + companyLogoUri: template.companyLogoUri, + }; const attributes = mergePdfTemplateWithDefaultAttributes( - template.attributes, + brandingTemplateAttrs, orgainizationBrandingAttrs ); return { diff --git a/packages/server/src/services/Sales/Invoices/SaleInvoicePdfTemplate.ts b/packages/server/src/services/Sales/Invoices/SaleInvoicePdfTemplate.ts index ca1f8c142..e7cffd69f 100644 --- a/packages/server/src/services/Sales/Invoices/SaleInvoicePdfTemplate.ts +++ b/packages/server/src/services/Sales/Invoices/SaleInvoicePdfTemplate.ts @@ -32,8 +32,12 @@ export class SaleInvoicePdfTemplate { ...defaultInvoicePdfTemplateAttributes, ...commonOrgBrandingAttrs, }; + const brandingTemplateAttrs = { + ...template.attributes, + companyLogoUri: template.companyLogoUri, + }; const attributes = mergePdfTemplateWithDefaultAttributes( - template.attributes, + brandingTemplateAttrs, organizationBrandingAttrs ); return { diff --git a/packages/server/src/services/Sales/Invoices/SaleInvoicesApplication.ts b/packages/server/src/services/Sales/Invoices/SaleInvoicesApplication.ts index e04ce4439..5490bec44 100644 --- a/packages/server/src/services/Sales/Invoices/SaleInvoicesApplication.ts +++ b/packages/server/src/services/Sales/Invoices/SaleInvoicesApplication.ts @@ -28,9 +28,7 @@ import { GetInvoicePaymentsService } from './GetInvoicePaymentsService'; import { SaleInvoiceNotifyBySms } from './SaleInvoiceNotifyBySms'; import { SendInvoiceMailReminder } from './SendSaleInvoiceMailReminder'; import { SendSaleInvoiceMail } from './SendSaleInvoiceMail'; -import { GetSaleInvoiceMailReminder } from './GetSaleInvoiceMailReminder'; import { GetSaleInvoiceState } from './GetSaleInvoiceState'; -import { GetSaleInvoiceBrandTemplate } from './GetSaleInvoiceBrandTemplate'; import { GetSaleInvoiceMailState } from './GetSaleInvoiceMailState'; @Service() @@ -366,7 +364,10 @@ export class SaleInvoiceApplication { * @param {number} saleInvoiceid * @returns {Promise} */ - public getSaleInvoiceMailState(tenantId: number, saleInvoiceid: number) { + public getSaleInvoiceMailState( + tenantId: number, + saleInvoiceid: number + ): Promise { return this.getSaleInvoiceMailStateService.getInvoiceMailState( tenantId, saleInvoiceid diff --git a/packages/server/src/services/Sales/Invoices/constants.ts b/packages/server/src/services/Sales/Invoices/constants.ts index cff791b3c..0e2b9989c 100644 --- a/packages/server/src/services/Sales/Invoices/constants.ts +++ b/packages/server/src/services/Sales/Invoices/constants.ts @@ -1,20 +1,19 @@ import config from '@/config'; export const DEFAULT_INVOICE_MAIL_SUBJECT = - 'Invoice {Invoice Number} from {Company Name}'; -export const DEFAULT_INVOICE_MAIL_CONTENT = ` -

Dear {Customer Name}

-

Thank you for your business, You can view or print your invoice from attachements.

-

-Invoice #{Invoice Number}
-Due Date : {Invoice Due Date}
-Amount : {Invoice Amount}
-

+ 'Invoice {Invoice Number} from {Company Name} for {Customer Name}'; +export const DEFAULT_INVOICE_MAIL_CONTENT = `Hi {Customer Name}, -

-Regards
-{Company Name} -

+Here's invoice # {Invoice Number} for {Invoice Amount} + +The amount outstanding of {Invoice Due Amount} is due on {Invoice Due Date}. + +From your online payment page you can print a PDF or view your outstanding bills. + +If you have any questions, please let us know. + +Thanks, +{Company Name} `; export const DEFAULT_INVOICE_REMINDER_MAIL_SUBJECT = diff --git a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedBrandingTemplate.ts b/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedBrandingTemplate.ts index 5e7c89fb7..d7a88bf6b 100644 --- a/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedBrandingTemplate.ts +++ b/packages/server/src/services/Sales/PaymentReceived/PaymentReceivedBrandingTemplate.ts @@ -37,8 +37,12 @@ export class PaymentReceivedBrandingTemplate { ...defaultPaymentReceivedPdfTemplateAttributes, ...commonOrgBrandingAttrs, }; + const brandingTemplateAttrs = { + ...template.attributes, + companyLogoUri: template.companyLogoUri, + }; const attributes = mergePdfTemplateWithDefaultAttributes( - template.attributes, + brandingTemplateAttrs, organizationBrandingAttrs ); return { diff --git a/packages/server/src/services/Sales/Receipts/SaleReceiptBrandingTemplate.ts b/packages/server/src/services/Sales/Receipts/SaleReceiptBrandingTemplate.ts index 1cef714b9..12689d7cd 100644 --- a/packages/server/src/services/Sales/Receipts/SaleReceiptBrandingTemplate.ts +++ b/packages/server/src/services/Sales/Receipts/SaleReceiptBrandingTemplate.ts @@ -37,8 +37,12 @@ export class SaleReceiptBrandingTemplate { ...defaultSaleReceiptBrandingAttributes, ...commonOrgBrandingAttrs, }; + const brandingTemplateAttrs = { + ...template.attributes, + companyLogoUri: template.companyLogoUri, + }; const attributes = mergePdfTemplateWithDefaultAttributes( - template.attributes, + brandingTemplateAttrs, organizationBrandingAttrs ); return { diff --git a/packages/webapp/package.json b/packages/webapp/package.json index 95abc13dd..c997612b2 100644 --- a/packages/webapp/package.json +++ b/packages/webapp/package.json @@ -5,7 +5,7 @@ "dependencies": { "@bigcapital/utils": "*", "@bigcapital/pdf-templates": "*", - "@blueprintjs-formik/core": "^0.3.6", + "@blueprintjs-formik/core": "^0.3.7", "@blueprintjs-formik/datetime": "^0.3.7", "@blueprintjs-formik/select": "^0.3.5", "@blueprintjs/colors": "4.1.19", diff --git a/packages/webapp/src/containers/Sales/Invoices/InvoiceCustomize/InvoiceMailReceipt.tsx b/packages/webapp/src/containers/Sales/Invoices/InvoiceCustomize/InvoiceMailReceipt.tsx index 02801698a..7669a1fc9 100644 --- a/packages/webapp/src/containers/Sales/Invoices/InvoiceCustomize/InvoiceMailReceipt.tsx +++ b/packages/webapp/src/containers/Sales/Invoices/InvoiceCustomize/InvoiceMailReceipt.tsx @@ -93,6 +93,7 @@ export function InvoiceMailReceipt({ h="90px" w="90px" mx="auto" + borderRadius="3px" backgroundRepeat="no-repeat" backgroundPosition="center center" backgroundSize="contain" diff --git a/packages/webapp/src/containers/Sales/Invoices/InvoiceSendMailDrawer/InvoiceMailReceiptPreviewConnected..tsx b/packages/webapp/src/containers/Sales/Invoices/InvoiceSendMailDrawer/InvoiceMailReceiptPreviewConnected..tsx deleted file mode 100644 index b93d26696..000000000 --- a/packages/webapp/src/containers/Sales/Invoices/InvoiceSendMailDrawer/InvoiceMailReceiptPreviewConnected..tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { useMemo } from 'react'; -import { css } from '@emotion/css'; -import { Box, } from '@/components'; -import { InvoiceMailReceiptPreview } from '../InvoiceCustomize/InvoiceMailReceiptPreview'; -import { useInvoiceSendMailBoot } from './InvoiceSendMailContentBoot'; -import { InvoiceSendMailPreviewWithHeader } from './InvoiceSendMailHeaderPreview'; -import { useSendInvoiceMailMessage } from './_hooks'; - -export function InvoiceMailReceiptPreviewConneceted() { - const mailMessage = useSendInvoiceMailMessage(); - const { invoiceMailState } = useInvoiceSendMailBoot(); - - const items = useMemo( - () => - invoiceMailState?.entries?.map((entry: any) => ({ - quantity: entry.quantity, - total: entry.totalFormatted, - label: entry.name, - })), - [invoiceMailState?.entries], - ); - - return ( - - - - - - ); -} \ No newline at end of file diff --git a/packages/webapp/src/containers/Sales/Invoices/InvoiceSendMailDrawer/InvoiceMailReceiptPreviewConnected.tsx b/packages/webapp/src/containers/Sales/Invoices/InvoiceSendMailDrawer/InvoiceMailReceiptPreviewConnected.tsx new file mode 100644 index 000000000..ff6704ceb --- /dev/null +++ b/packages/webapp/src/containers/Sales/Invoices/InvoiceSendMailDrawer/InvoiceMailReceiptPreviewConnected.tsx @@ -0,0 +1,64 @@ +import { useMemo, ComponentType } from 'react'; +import { css } from '@emotion/css'; +import { Box } from '@/components'; +import { + InvoiceMailReceiptPreview, + InvoiceMailReceiptPreviewProps, +} from '../InvoiceCustomize/InvoiceMailReceiptPreview'; +import { useInvoiceSendMailBoot } from './InvoiceSendMailContentBoot'; +import { InvoiceSendMailPreviewWithHeader } from './InvoiceSendMailHeaderPreview'; +import { useSendInvoiceMailMessage } from './_hooks'; + +export function InvoiceMailReceiptPreviewConnected() { + return ( + + + + + + ); +} + +/** + * Injects props from invoice mail state into the InvoiceMailReceiptPreview component. + */ +const withInvoiceMailReceiptPreviewProps = < + P extends InvoiceMailReceiptPreviewProps, +>( + WrappedComponent: ComponentType

, +) => { + return function WithInvoiceMailReceiptPreviewProps(props: P) { + const message = useSendInvoiceMailMessage(); + const { invoiceMailState } = useInvoiceSendMailBoot(); + + const items = useMemo( + () => + invoiceMailState?.entries?.map((entry: any) => ({ + quantity: entry.quantity, + total: entry.totalFormatted, + label: entry.name, + })), + [invoiceMailState?.entries], + ); + + const mailReceiptPreviewProps = { + companyName: invoiceMailState?.companyName, + companyLogoUri: invoiceMailState?.companyLogoUri, + primaryColor: invoiceMailState?.primaryColor, + total: invoiceMailState?.totalFormatted, + dueDate: invoiceMailState?.dueDateFormatted, + dueAmount: invoiceMailState?.dueAmountFormatted, + invoiceNumber: invoiceMailState?.invoiceNo, + items, + message, + }; + return ; + }; +}; + +export const InvoiceMailReceiptPreviewWithProps = + withInvoiceMailReceiptPreviewProps(InvoiceMailReceiptPreview); diff --git a/packages/webapp/src/containers/Sales/Invoices/InvoiceSendMailDrawer/InvoiceSendMailContentBoot.tsx b/packages/webapp/src/containers/Sales/Invoices/InvoiceSendMailDrawer/InvoiceSendMailContentBoot.tsx index dab0e5269..3af865ccb 100644 --- a/packages/webapp/src/containers/Sales/Invoices/InvoiceSendMailDrawer/InvoiceSendMailContentBoot.tsx +++ b/packages/webapp/src/containers/Sales/Invoices/InvoiceSendMailDrawer/InvoiceSendMailContentBoot.tsx @@ -1,4 +1,3 @@ -// @ts-nocheck import React, { createContext, useContext } from 'react'; import { Spinner } from '@blueprintjs/core'; import { diff --git a/packages/webapp/src/containers/Sales/Invoices/InvoiceSendMailDrawer/InvoiceSendMailDrawer.tsx b/packages/webapp/src/containers/Sales/Invoices/InvoiceSendMailDrawer/InvoiceSendMailDrawer.tsx index 237f37149..2df27d89f 100644 --- a/packages/webapp/src/containers/Sales/Invoices/InvoiceSendMailDrawer/InvoiceSendMailDrawer.tsx +++ b/packages/webapp/src/containers/Sales/Invoices/InvoiceSendMailDrawer/InvoiceSendMailDrawer.tsx @@ -1,7 +1,8 @@ +// @ts-nocheck +import React from 'react'; import * as R from 'ramda'; import { Drawer, DrawerSuspense } from '@/components'; import withDrawers from '@/containers/Drawer/withDrawers'; -import React from 'react'; const InvoiceSendMailContent = React.lazy(() => import('./InvoiceSendMailContent').then((module) => ({ diff --git a/packages/webapp/src/containers/Sales/Invoices/InvoiceSendMailDrawer/InvoiceSendMailFields.tsx b/packages/webapp/src/containers/Sales/Invoices/InvoiceSendMailDrawer/InvoiceSendMailFields.tsx index 17956ff24..1ae32d1d7 100644 --- a/packages/webapp/src/containers/Sales/Invoices/InvoiceSendMailDrawer/InvoiceSendMailFields.tsx +++ b/packages/webapp/src/containers/Sales/Invoices/InvoiceSendMailDrawer/InvoiceSendMailFields.tsx @@ -18,9 +18,14 @@ import { import { useDrawerContext } from '@/components/Drawer/DrawerProvider'; import { useDrawerActions } from '@/hooks/state'; import { useInvoiceMailItems, useSendInvoiceFormatArgsOptions } from './_hooks'; +import { InvoiceSendMailFormValues } from './_types'; // Create new account renderer. -const createNewItemRenderer = (query, active, handleClick) => { +const createNewItemRenderer = ( + query: string, + active: boolean, + handleClick: React.MouseEventHandler, +) => { return ( { }; // Create new item from the given query string. -const createNewItemFromQuery = (name) => ({ name }); +const createNewItemFromQuery = (text: string): SelectOptionProps => ({ text }); const styleEmailButton = css` &.bp4-button.bp4-small { @@ -62,19 +67,19 @@ export function InvoiceSendMailFields() { const [showCCField, setShowCCField] = useState(false); const [showBccField, setShowBccField] = useState(false); const textareaRef = useRef(null); - - const { values, setFieldValue } = useFormikContext(); + const { values, setFieldValue } = + useFormikContext(); const items = useInvoiceMailItems(); const argsOptions = useSendInvoiceFormatArgsOptions(); - const handleClickCcBtn = (event) => { + const handleClickCcBtn = (event: React.MouseEvent) => { event.preventDefault(); event.stopPropagation(); setShowCCField(true); }; - const handleClickBccBtn = (event) => { + const handleClickBccBtn = (event: React.MouseEvent) => { event.preventDefault(); event.stopPropagation(); @@ -82,64 +87,71 @@ export function InvoiceSendMailFields() { }; const handleCreateToItemSelect = (value: SelectOptionProps) => { - setFieldValue('to', [...values?.to, value?.name]); + setFieldValue('to', [...values?.to, value?.text]); }; const handleCreateCcItemSelect = (value: SelectOptionProps) => { - setFieldValue('cc', [...values?.cc, value?.name]); + setFieldValue('cc', [...values?.cc, value?.text]); }; + const handleCreateBccItemSelect = (value: SelectOptionProps) => { - setFieldValue('bcc', [...values?.bcc, value?.name]); + setFieldValue('bcc', [...values?.bcc, value?.text]); }; - const rightElementsToField = useMemo(() => ( - - + - - - ), []); + + + ), + [], + ); - const handleTextareaChange = useCallback((item: SelectOptionProps) => { - const textarea = textareaRef.current; - if (!textarea) return; + const handleTextareaChange = useCallback( + (item: SelectOptionProps) => { + const textarea = textareaRef.current; + if (!textarea) return; - const { selectionStart, selectionEnd, value: text } = textarea; - const insertText = `{${item.value}}`; - const message = - text.substring(0, selectionStart) + - insertText + - text.substring(selectionEnd); + const { selectionStart, selectionEnd, value: text } = textarea; + const insertText = `{${item.value}}`; + const message = + text.substring(0, selectionStart) + + insertText + + text.substring(selectionEnd); - setFieldValue('message', message); + setFieldValue('message', message); - // Move the cursor to the end of the inserted text - setTimeout(() => { - textarea.selectionStart = textarea.selectionEnd = - selectionStart + insertText.length; - textarea.focus(); - }, 0); - }, [setFieldValue]); + // Move the cursor to the end of the inserted text + setTimeout(() => { + textarea.selectionStart = textarea.selectionEnd = + selectionStart + insertText.length; + textarea.focus(); + }, 0); + }, + [setFieldValue], + ); return ( ( + input={() => ( - {invoiceMessage} - +

+ {items.map((item, index) => ( + + + {item.label} + -
- {items.map((item, index) => ( - + + + {item.quantity} x {item.rate} + + + + ))} + + - {item.label} + + {dueAmountLabel} + - - {item.quantity} x {item.rate} + + {dueAmount} - ))} - - - - {dueAmountLabel} - - + + + {totalLabel} + - - - {dueAmount} - - - - - - - {totalLabel} - - - - {total} - - + + {total} + + +
- - - - - - ); -}; + + + + + ); + }; export const renderInvoicePaymentEmail = (props: InvoicePaymentEmailProps) => { return render(); @@ -274,6 +274,7 @@ const invoiceMessageStyle: CSSProperties = { whiteSpace: 'pre-line', color: '#252A31', margin: '0 0 20px 0', + lineHeight: '20px', }; const dueAmounLineRowStyle: CSSProperties = {