mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-18 13:50:31 +00:00
feat: estimate, receipt, credit note mail preview
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
import * as Yup from 'yup';
|
||||
|
||||
export const EstimateSendMailSchema = Yup.object().shape({});
|
||||
@@ -0,0 +1,52 @@
|
||||
import React, { createContext, useContext } from 'react';
|
||||
import { Spinner } from '@blueprintjs/core';
|
||||
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
|
||||
|
||||
interface EstimateSendMailBootValues {
|
||||
estimateId: number;
|
||||
|
||||
estimateMailState: GetSaleEstimateDefaultOptionsResponse | undefined;
|
||||
isEstimateMailState: boolean;
|
||||
}
|
||||
interface EstimateSendMailBootProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
const EstimateSendMailContentBootContext =
|
||||
createContext<EstimateSendMailBootValues>({} as EstimateSendMailBootValues);
|
||||
|
||||
export const EstimateSendMailBoot = ({ children }: EstimateSendMailBootProps) => {
|
||||
const {
|
||||
payload: { estimateId },
|
||||
} = useDrawerContext();
|
||||
|
||||
// Estimate mail options.
|
||||
const { data: estimateMailState, isLoading: isEstimateMailState } =
|
||||
useSaleEstimateMailState(estimateId);
|
||||
|
||||
const isLoading = isEstimateMailState;
|
||||
|
||||
if (isLoading) {
|
||||
return <Spinner size={20} />;
|
||||
}
|
||||
const value = {
|
||||
estimateId,
|
||||
|
||||
// # Estimate mail options
|
||||
isEstimateMailState,
|
||||
estimateMailState,
|
||||
};
|
||||
|
||||
return (
|
||||
<EstimateSendMailContentBootContext.Provider value={value}>
|
||||
{children}
|
||||
</EstimateSendMailContentBootContext.Provider>
|
||||
);
|
||||
};
|
||||
EstimateSendMailBoot.displayName = 'EstimateSendMailBoot';
|
||||
|
||||
export const useEstimateSendMailBoot = () => {
|
||||
return useContext<EstimateSendMailBootValues>(
|
||||
EstimateSendMailContentBootContext,
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
|
||||
export function EstimateSendMailContent() {
|
||||
|
||||
return (
|
||||
|
||||
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import * as R from 'ramda';
|
||||
import { Drawer, DrawerSuspense } from '@/components';
|
||||
import withDrawers from '@/containers/Drawer/withDrawers';
|
||||
|
||||
const EstimateSendMailDrawerProps = React.lazy(() =>
|
||||
import('./EstimateSendMailContent').then((module) => ({
|
||||
default: module.InvoiceSendMailContent,
|
||||
})),
|
||||
);
|
||||
|
||||
interface EstimateSendMailDrawerProps {
|
||||
name: string;
|
||||
isOpen?: boolean;
|
||||
payload?: any;
|
||||
}
|
||||
|
||||
function EstimateSendMailDrawerRoot({
|
||||
name,
|
||||
|
||||
// #withDrawer
|
||||
isOpen,
|
||||
payload,
|
||||
}: EstimateSendMailDrawerProps) {
|
||||
return (
|
||||
<Drawer
|
||||
isOpen={isOpen}
|
||||
name={name}
|
||||
payload={payload}
|
||||
size={'calc(100% - 10px)'}
|
||||
>
|
||||
<DrawerSuspense>
|
||||
<EstimateSendMailDrawerProps />
|
||||
</DrawerSuspense>
|
||||
</Drawer>
|
||||
);
|
||||
}
|
||||
|
||||
export const EstimateSendMailDrawer = R.compose(withDrawers())(
|
||||
EstimateSendMailDrawerRoot,
|
||||
);
|
||||
@@ -0,0 +1,79 @@
|
||||
import { Form, Formik, FormikHelpers } from 'formik';
|
||||
import { css } from '@emotion/css';
|
||||
import { Intent } from '@blueprintjs/core';
|
||||
import { InvoiceSendMailFormValues } from './_types';
|
||||
import { InvoiceSendMailFormSchema } from './InvoiceSendMailForm.schema';
|
||||
import { useSendSaleInvoiceMail } from '@/hooks/query';
|
||||
import { AppToaster } from '@/components';
|
||||
import { useInvoiceSendMailBoot } from './InvoiceSendMailContentBoot';
|
||||
import { useDrawerActions } from '@/hooks/state';
|
||||
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
|
||||
import { transformToForm } from '@/utils';
|
||||
import { useEstimateSendMailBoot } from './EstimateSendMailBoot';
|
||||
|
||||
const initialValues: InvoiceSendMailFormValues = {
|
||||
subject: '',
|
||||
message: '',
|
||||
to: [],
|
||||
cc: [],
|
||||
bcc: [],
|
||||
attachPdf: true,
|
||||
};
|
||||
|
||||
interface InvoiceSendMailFormProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export function EstimateSendMailForm({ children }: InvoiceSendMailFormProps) {
|
||||
const { mutateAsync: sendInvoiceMail } = useSendSaleInvoiceMail();
|
||||
const { estimateId, estimateMailState } = useEstimateSendMailBoot();
|
||||
|
||||
const { name } = useDrawerContext();
|
||||
const { closeDrawer } = useDrawerActions();
|
||||
|
||||
const _initialValues: InvoiceSendMailFormValues = {
|
||||
...initialValues,
|
||||
...transformToForm(invoiceMailState, initialValues),
|
||||
};
|
||||
const handleSubmit = (
|
||||
values: InvoiceSendMailFormValues,
|
||||
{ setSubmitting }: FormikHelpers<InvoiceSendMailFormValues>,
|
||||
) => {
|
||||
setSubmitting(true);
|
||||
sendInvoiceMail({ id: invoiceId, values: { ...values } })
|
||||
.then(() => {
|
||||
AppToaster.show({
|
||||
message: 'The invoice mail has been sent to the customer.',
|
||||
intent: Intent.SUCCESS,
|
||||
});
|
||||
setSubmitting(false);
|
||||
closeDrawer(name);
|
||||
})
|
||||
.catch((error) => {
|
||||
setSubmitting(false);
|
||||
AppToaster.show({
|
||||
message: 'Something went wrong!',
|
||||
intent: Intent.SUCCESS,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Formik
|
||||
initialValues={_initialValues}
|
||||
validationSchema={InvoiceSendMailFormSchema}
|
||||
onSubmit={handleSubmit}
|
||||
>
|
||||
<Form
|
||||
className={css`
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
`}
|
||||
>
|
||||
{children}
|
||||
</Form>
|
||||
</Formik>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export interface EstimateSendMailFormValues {}
|
||||
Reference in New Issue
Block a user