mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-18 13:50:31 +00:00
feat: estimate mail receipt
This commit is contained in:
12
packages/server/newrelic_agent.log
Normal file
12
packages/server/newrelic_agent.log
Normal file
@@ -0,0 +1,12 @@
|
||||
{"v":0,"level":30,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":5186,"time":"2024-11-18T22:14:20.534Z","msg":"Unable to find configuration file. If a configuration file is desired (common for non-containerized environments), a base configuration file can be copied from /Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.17.0/node_modules/newrelic/newrelic.js and renamed to \"newrelic.js\" in the directory from which you will start your application. Attempting to start agent using environment variables."}
|
||||
{"v":0,"level":30,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":5186,"time":"2024-11-18T22:14:20.542Z","msg":"Using New Relic for Node.js. Agent version: 11.17.0; Node version: v18.18.2."}
|
||||
{"v":0,"level":30,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":5186,"time":"2024-11-18T22:14:20.878Z","msg":"Using AsyncLocalContextManager"}
|
||||
{"v":0,"level":50,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":5186,"time":"2024-11-18T22:14:20.881Z","msg":"New Relic for Node.js was unable to bootstrap itself due to an error:","stack":"Error: New Relic requires that you name this application!\nSet app_name in your newrelic.js or newrelic.cjs file or set environment variable\nNEW_RELIC_APP_NAME. Not starting!\n at createAgent (/Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.17.0/node_modules/newrelic/index.js:160:11)\n at initialize (/Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.17.0/node_modules/newrelic/index.js:105:15)\n at Object.<anonymous> (/Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.17.0/node_modules/newrelic/index.js:39:3)\n at Module._compile (node:internal/modules/cjs/loader:1256:14)\n at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)\n at Module.load (node:internal/modules/cjs/loader:1119:32)\n at Module._load (node:internal/modules/cjs/loader:960:12)\n at Module.require (node:internal/modules/cjs/loader:1143:19)\n at require (node:internal/modules/cjs/helpers:119:18)\n at Object.newrelic (/Users/ahmedbouhuolia/repos/bigcapital/packages/server/build/index.js:49240:18)","message":"New Relic requires that you name this application!\nSet app_name in your newrelic.js or newrelic.cjs file or set environment variable\nNEW_RELIC_APP_NAME. Not starting!"}
|
||||
{"v":0,"level":30,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":36447,"time":"2024-11-19T14:46:43.059Z","msg":"Unable to find configuration file. If a configuration file is desired (common for non-containerized environments), a base configuration file can be copied from /Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.17.0/node_modules/newrelic/newrelic.js and renamed to \"newrelic.js\" in the directory from which you will start your application. Attempting to start agent using environment variables."}
|
||||
{"v":0,"level":30,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":36447,"time":"2024-11-19T14:46:43.068Z","msg":"Using New Relic for Node.js. Agent version: 11.17.0; Node version: v18.18.2."}
|
||||
{"v":0,"level":30,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":36447,"time":"2024-11-19T14:46:43.304Z","msg":"Using AsyncLocalContextManager"}
|
||||
{"v":0,"level":50,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":36447,"time":"2024-11-19T14:46:43.306Z","msg":"New Relic for Node.js was unable to bootstrap itself due to an error:","stack":"Error: New Relic requires that you name this application!\nSet app_name in your newrelic.js or newrelic.cjs file or set environment variable\nNEW_RELIC_APP_NAME. Not starting!\n at createAgent (/Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.17.0/node_modules/newrelic/index.js:160:11)\n at initialize (/Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.17.0/node_modules/newrelic/index.js:105:15)\n at Object.<anonymous> (/Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.17.0/node_modules/newrelic/index.js:39:3)\n at Module._compile (node:internal/modules/cjs/loader:1256:14)\n at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)\n at Module.load (node:internal/modules/cjs/loader:1119:32)\n at Module._load (node:internal/modules/cjs/loader:960:12)\n at Module.require (node:internal/modules/cjs/loader:1143:19)\n at require (node:internal/modules/cjs/helpers:119:18)\n at Object.newrelic (/Users/ahmedbouhuolia/repos/bigcapital/packages/server/build/index.js:49240:18)","message":"New Relic requires that you name this application!\nSet app_name in your newrelic.js or newrelic.cjs file or set environment variable\nNEW_RELIC_APP_NAME. Not starting!"}
|
||||
{"v":0,"level":30,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":60390,"time":"2024-11-19T19:55:31.373Z","msg":"Unable to find configuration file. If a configuration file is desired (common for non-containerized environments), a base configuration file can be copied from /Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.17.0/node_modules/newrelic/newrelic.js and renamed to \"newrelic.js\" in the directory from which you will start your application. Attempting to start agent using environment variables."}
|
||||
{"v":0,"level":30,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":60390,"time":"2024-11-19T19:55:31.382Z","msg":"Using New Relic for Node.js. Agent version: 11.17.0; Node version: v18.18.2."}
|
||||
{"v":0,"level":30,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":60390,"time":"2024-11-19T19:55:31.682Z","msg":"Using AsyncLocalContextManager"}
|
||||
{"v":0,"level":50,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":60390,"time":"2024-11-19T19:55:31.683Z","msg":"New Relic for Node.js was unable to bootstrap itself due to an error:","stack":"Error: New Relic requires that you name this application!\nSet app_name in your newrelic.js or newrelic.cjs file or set environment variable\nNEW_RELIC_APP_NAME. Not starting!\n at createAgent (/Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.17.0/node_modules/newrelic/index.js:160:11)\n at initialize (/Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.17.0/node_modules/newrelic/index.js:105:15)\n at Object.<anonymous> (/Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.17.0/node_modules/newrelic/index.js:39:3)\n at Module._compile (node:internal/modules/cjs/loader:1256:14)\n at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)\n at Module.load (node:internal/modules/cjs/loader:1119:32)\n at Module._load (node:internal/modules/cjs/loader:960:12)\n at Module.require (node:internal/modules/cjs/loader:1143:19)\n at require (node:internal/modules/cjs/helpers:119:18)\n at Object.newrelic (/Users/ahmedbouhuolia/repos/bigcapital/packages/server/build/index.js:49240:18)","message":"New Relic requires that you name this application!\nSet app_name in your newrelic.js or newrelic.cjs file or set environment variable\nNEW_RELIC_APP_NAME. Not starting!"}
|
||||
@@ -2,6 +2,7 @@ import { Suspense } from 'react';
|
||||
import { SendMailViewPreviewTabs } from '../SendMailViewDrawer/SendMailViewPreviewTabs';
|
||||
import { Tab } from '@blueprintjs/core';
|
||||
import { EstimateSendPdfPreviewConnected } from './EstimateSendPdfPreviewConnected';
|
||||
import { EstimateSendMailReceiptPreview } from './EstimateSendMailReceiptPreview';
|
||||
|
||||
export function EstimateSendMailPreviewTabs() {
|
||||
return (
|
||||
@@ -10,7 +11,9 @@ export function EstimateSendMailPreviewTabs() {
|
||||
id={'payment-page'}
|
||||
title={'Payment page'}
|
||||
panel={
|
||||
<Suspense>{/* <InvoiceMailReceiptPreviewConnected /> */}</Suspense>
|
||||
<Suspense>
|
||||
<EstimateSendMailReceiptPreview />
|
||||
</Suspense>
|
||||
}
|
||||
/>
|
||||
<Tab
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
import { x } from '@xstyled/emotion';
|
||||
import { Group, Stack } from '@/components';
|
||||
import { SendMailReceipt, SendMailReceiptProps } from '../SendMailViewDrawer/SendMailViewReceiptPreview';
|
||||
|
||||
interface EstimateSendMailReceiptProps extends SendMailReceiptProps {
|
||||
// # Company name.
|
||||
companyLogoUri?: string;
|
||||
companyName: string;
|
||||
|
||||
// # Estimate number.
|
||||
estimateNumberLabel?: string;
|
||||
estimateNumber: string;
|
||||
|
||||
// # Total.
|
||||
total: string;
|
||||
totalLabel?: string;
|
||||
|
||||
// # Expiration date.
|
||||
expirationDateLabel?: string;
|
||||
expirationDate: string;
|
||||
|
||||
// # Message.
|
||||
message: string;
|
||||
|
||||
// # Estimate items.
|
||||
items?: Array<{ label: string; total: string; quantity: string | number }>;
|
||||
|
||||
// # Subtotal
|
||||
subtotalLabel?: string;
|
||||
subtotal: string;
|
||||
|
||||
// # View estimate button
|
||||
showViewEstimateButton?: boolean;
|
||||
viewEstimateButtonLabel?: string;
|
||||
viewEstimateButtonOnClick?: () => void;
|
||||
}
|
||||
|
||||
export function EstimateSendMailReceipt({
|
||||
// # Company name.
|
||||
companyLogoUri,
|
||||
companyName,
|
||||
|
||||
// # Estimate number.
|
||||
estimateNumberLabel = 'Estimate #',
|
||||
estimateNumber,
|
||||
|
||||
// # Total.
|
||||
total,
|
||||
totalLabel = 'Total',
|
||||
|
||||
// # Expiration date.
|
||||
expirationDateLabel = 'Expiration Date',
|
||||
expirationDate,
|
||||
|
||||
// # Message
|
||||
message,
|
||||
|
||||
// # Items
|
||||
items,
|
||||
|
||||
// # Subtotal
|
||||
subtotal,
|
||||
subtotalLabel = 'Subtotal',
|
||||
|
||||
// # View estimate button
|
||||
showViewEstimateButton = true,
|
||||
viewEstimateButtonLabel = 'View Estimate',
|
||||
viewEstimateButtonOnClick,
|
||||
|
||||
...props
|
||||
}: EstimateSendMailReceiptProps) {
|
||||
return (
|
||||
<SendMailReceipt {...props}>
|
||||
<Stack spacing={16} textAlign={'center'}>
|
||||
{companyLogoUri && <SendMailReceipt.CompanyLogo src={companyLogoUri} />}
|
||||
|
||||
<Stack spacing={8}>
|
||||
<x.h1 m={0} fontSize={'18px'} fontWeight={500} color="#404854">
|
||||
{companyName}
|
||||
</x.h1>
|
||||
|
||||
<x.h3 color="#383E47" fontWeight={500}>
|
||||
{total}
|
||||
</x.h3>
|
||||
|
||||
<x.span fontSize={'13px'} color="#404854">
|
||||
{estimateNumberLabel} {estimateNumber}
|
||||
</x.span>
|
||||
|
||||
<x.span fontSize={'13px'} color="#404854">
|
||||
{expirationDateLabel} {expirationDate}
|
||||
</x.span>
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
<x.p m={0} whiteSpace={'pre-line'} color="#252A31">
|
||||
{message}
|
||||
</x.p>
|
||||
|
||||
{showViewEstimateButton && (
|
||||
<SendMailReceipt.PrimaryButton
|
||||
primaryColor={'#000'}
|
||||
onClick={viewEstimateButtonOnClick}
|
||||
>
|
||||
{viewEstimateButtonLabel}
|
||||
</SendMailReceipt.PrimaryButton>
|
||||
)}
|
||||
|
||||
<Stack spacing={0}>
|
||||
{items?.map((item, key) => (
|
||||
<Group
|
||||
key={key}
|
||||
h={'40px'}
|
||||
position={'apart'}
|
||||
borderBottomStyle="solid"
|
||||
borderBottomWidth={'1px'}
|
||||
borderBottomColor={'#D9D9D9'}
|
||||
borderTopStyle="solid"
|
||||
borderTopColor={'#D9D9D9'}
|
||||
borderTopWidth={'1px'}
|
||||
>
|
||||
<x.span>{item.label}</x.span>
|
||||
<x.span>
|
||||
{item.quantity} x {item.total}
|
||||
</x.span>
|
||||
</Group>
|
||||
))}
|
||||
|
||||
<Group
|
||||
h={'40px'}
|
||||
position={'apart'}
|
||||
borderBottomStyle="solid"
|
||||
borderBottomWidth={'1px'}
|
||||
borderBottomColor={'#000'}
|
||||
>
|
||||
<x.span fontWeight={500}>{subtotalLabel}</x.span>
|
||||
<x.span fontWeight={600} fontSize={15}>
|
||||
{subtotal}
|
||||
</x.span>
|
||||
</Group>
|
||||
|
||||
<Group
|
||||
h={'40px'}
|
||||
position={'apart'}
|
||||
borderBottomStyle="solid"
|
||||
borderBottomWidth={'1px'}
|
||||
borderColor={'#000'}
|
||||
>
|
||||
<x.span fontWeight={500}>{totalLabel}</x.span>
|
||||
<x.span fontWeight={600} fontSize={15}>
|
||||
{total}
|
||||
</x.span>
|
||||
</Group>
|
||||
</Stack>
|
||||
</SendMailReceipt>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { EstimateSendMailReceipt } from './EstimateSendMailReceipt';
|
||||
import { EstimateSendMailPreviewHeader } from './EstimateSendMailPreviewHeader';
|
||||
import { Stack } from '@/components';
|
||||
|
||||
export const EstimateSendMailReceiptPreview = () => {
|
||||
const props = {
|
||||
companyName: 'Bigcapital Technology, Inc.',
|
||||
companyLogoUri: ' ',
|
||||
|
||||
message: '',
|
||||
total: '$1,000.00',
|
||||
subtotal: '$1,000.00',
|
||||
estimateNumber: 'INV-0001',
|
||||
expirationDate: '2 Oct 2024',
|
||||
dueAmount: '$1,000.00',
|
||||
items: [{ label: 'Web development', total: '$1000.00', quantity: 1 }],
|
||||
message: `Hi Ahmed Bouhuolia,
|
||||
|
||||
Here's invoice # INV-00002 for $738.30
|
||||
|
||||
The amount outstanding of $737.30 is due on 01 Feb 2023.
|
||||
|
||||
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,
|
||||
Bigcapital`,
|
||||
};
|
||||
|
||||
return (
|
||||
<Stack>
|
||||
<EstimateSendMailPreviewHeader />
|
||||
|
||||
<Stack px={4} py={6}>
|
||||
<EstimateSendMailReceipt
|
||||
{...props}
|
||||
className={css`
|
||||
margin: 0 auto;
|
||||
border-radius: 5px !important;
|
||||
transform: scale(0.9);
|
||||
transform-origin: top;
|
||||
boxshadow: 0 10px 15px rgba(0, 0, 0, 0.05) !important;
|
||||
`}
|
||||
/>
|
||||
</Stack>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
@@ -24,7 +24,6 @@ function EstimateSendPdfPreviewIframe() {
|
||||
if (isLoading && data) {
|
||||
return <Spinner size={20} />;
|
||||
}
|
||||
|
||||
const iframeSrcDoc = data?.htmlContent;
|
||||
|
||||
return <SendMailViewPreviewPdfIframe srcDoc={iframeSrcDoc} />;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { Button, ButtonProps, Intent } from '@blueprintjs/core';
|
||||
import { css } from '@emotion/css';
|
||||
import { lighten } from 'polished';
|
||||
import { x } from '@xstyled/emotion';
|
||||
import { Stack, StackProps } from '@/components';
|
||||
|
||||
interface SendMailReceiptProps extends StackProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
export type SendMailReceiptProps = StackProps;
|
||||
|
||||
export function SendMailReceipt({
|
||||
children,
|
||||
...restProps
|
||||
}: SendMailReceiptProps) {
|
||||
return (
|
||||
@@ -19,7 +19,7 @@ export function SendMailReceipt({
|
||||
boxShadow={'0 10px 15px rgba(0, 0, 0, 0.05)'}
|
||||
color={'black'}
|
||||
{...restProps}
|
||||
></Stack>
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -46,4 +46,36 @@ function SendMailReceiptCompanyLogo({
|
||||
);
|
||||
}
|
||||
|
||||
interface SendMailReceiptTitleProps extends ButtonProps {
|
||||
primaryColor?: string;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
function SendMailReceiptPrimaryButton({
|
||||
primaryColor,
|
||||
...props
|
||||
}: SendMailReceiptTitleProps) {
|
||||
return (
|
||||
<Button
|
||||
large
|
||||
intent={Intent.PRIMARY}
|
||||
className={css`
|
||||
&.bp4-intent-primary {
|
||||
background-color: ${primaryColor};
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: ${lighten(0.1, primaryColor || '#000')};
|
||||
}
|
||||
}
|
||||
&.bp4-large {
|
||||
min-height: 38px;
|
||||
}
|
||||
`}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
SendMailReceipt.PrimaryButton = SendMailReceiptPrimaryButton;
|
||||
SendMailReceipt.CompanyLogo = SendMailReceiptCompanyLogo;
|
||||
|
||||
@@ -41,36 +41,36 @@ export interface InvoiceMailReceiptProps extends StackProps {
|
||||
}
|
||||
|
||||
export function InvoiceMailReceipt({
|
||||
// Company
|
||||
// # Company
|
||||
companyName,
|
||||
companyLogoUri,
|
||||
|
||||
// # Colors
|
||||
primaryColor = 'rgb(0, 82, 204)',
|
||||
|
||||
// Due date
|
||||
// # Due date
|
||||
dueDate,
|
||||
dueDateLabel = 'Due',
|
||||
|
||||
// Due amount
|
||||
// # Due amount
|
||||
dueAmountLabel = 'Due Amount',
|
||||
dueAmount,
|
||||
|
||||
// Total
|
||||
// # Total
|
||||
total,
|
||||
totalLabel = 'Total',
|
||||
|
||||
// Invoice number
|
||||
// # Invoice number
|
||||
invoiceNumber,
|
||||
invoiceNumberLabel = 'Invoice #',
|
||||
|
||||
// Invoice message
|
||||
// # Invoice message
|
||||
message,
|
||||
|
||||
// Invoice items
|
||||
// # Invoice items
|
||||
items,
|
||||
|
||||
// View invoice button
|
||||
// # View invoice button
|
||||
showViewInvoiceButton = true,
|
||||
viewInvoiceButtonLabel = 'View Invoice',
|
||||
viewInvoiceButtonOnClick,
|
||||
|
||||
Reference in New Issue
Block a user