mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-17 21:30:31 +00:00
feat: pdf template customize
This commit is contained in:
@@ -28,7 +28,7 @@ import { EstimateCustomizeDrawer } from '@/containers/Sales/Estimates/EstimateCu
|
||||
import { ReceiptCustomizeDrawer } from '@/containers/Sales/Receipts/ReceiptCustomize/ReceiptCustomizeDrawer';
|
||||
import { CreditNoteCustomizeDrawer } from '@/containers/Sales/CreditNotes/CreditNoteCustomize/CreditNoteCustomizeDrawer';
|
||||
import { PaymentReceivedCustomizeDrawer } from '@/containers/Sales/PaymentsReceived/PaymentReceivedCustomize/PaymentReceivedCustomizeDrawer';
|
||||
import { BrandingTemplatesDrawer } from '@/containers/Sales/Invoices/BrandingTemplates/BrandingTemplatesDrawer';
|
||||
import { BrandingTemplatesDrawer } from '@/containers/BrandingTemplates/BrandingTemplatesDrawer';
|
||||
|
||||
import { DRAWERS } from '@/constants/drawers';
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ import { CashflowAlerts } from '../CashFlow/CashflowAlerts';
|
||||
import { BankRulesAlerts } from '../Banking/Rules/RulesList/BankRulesAlerts';
|
||||
import { SubscriptionAlerts } from '../Subscriptions/alerts/alerts';
|
||||
import { BankAccountAlerts } from '@/containers/CashFlow/AccountTransactions/alerts';
|
||||
import { BrandingTemplatesAlerts } from '../Sales/Invoices/BrandingTemplates/alerts/BrandingTemplatesAlerts';
|
||||
import { BrandingTemplatesAlerts } from '../BrandingTemplates/alerts/BrandingTemplatesAlerts';
|
||||
|
||||
export default [
|
||||
...AccountsAlerts,
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
import * as Yup from 'yup';
|
||||
import {
|
||||
ElementCustomize,
|
||||
ElementCustomizeProps,
|
||||
} from '../ElementCustomize/ElementCustomize';
|
||||
import {
|
||||
transformToEditRequest,
|
||||
transformToNewRequest,
|
||||
useBrandingTemplateFormInitialValues,
|
||||
} from './_utils';
|
||||
import { AppToaster } from '@/components';
|
||||
import { Intent } from '@blueprintjs/core';
|
||||
import {
|
||||
useCreatePdfTemplate,
|
||||
useEditPdfTemplate,
|
||||
} from '@/hooks/query/pdf-templates';
|
||||
import { FormikHelpers } from 'formik';
|
||||
import { BrandingTemplateValues } from './types';
|
||||
|
||||
interface BrandingTemplateFormProps<T> extends ElementCustomizeProps<T> {
|
||||
resource: string;
|
||||
templateId?: number;
|
||||
onSuccess?: () => void;
|
||||
onError?: () => void;
|
||||
defaultValues?: T;
|
||||
}
|
||||
|
||||
export function BrandingTemplateForm<T extends BrandingTemplateValues>({
|
||||
templateId,
|
||||
onSuccess,
|
||||
onError,
|
||||
defaultValues,
|
||||
resource,
|
||||
...props
|
||||
}: BrandingTemplateFormProps<T>) {
|
||||
const { mutateAsync: createPdfTemplate } = useCreatePdfTemplate();
|
||||
const { mutateAsync: editPdfTemplate } = useEditPdfTemplate();
|
||||
|
||||
const initialValues = useBrandingTemplateFormInitialValues<T>(defaultValues);
|
||||
|
||||
const handleFormSubmit = (values: T, { setSubmitting }: FormikHelpers<T>) => {
|
||||
const handleSuccess = (message: string) => {
|
||||
AppToaster.show({ intent: Intent.SUCCESS, message });
|
||||
setSubmitting(false);
|
||||
onSuccess && onSuccess();
|
||||
};
|
||||
const handleError = (message: string) => {
|
||||
AppToaster.show({ intent: Intent.DANGER, message });
|
||||
setSubmitting(false);
|
||||
onError && onError();
|
||||
};
|
||||
if (templateId) {
|
||||
const reqValues = transformToEditRequest(values);
|
||||
setSubmitting(true);
|
||||
|
||||
// Edit existing template
|
||||
editPdfTemplate({ templateId, values: reqValues })
|
||||
.then(() => handleSuccess('PDF template updated successfully!'))
|
||||
.catch(() =>
|
||||
handleError('An error occurred while updating the PDF template.'),
|
||||
);
|
||||
} else {
|
||||
const reqValues = transformToNewRequest(values, resource);
|
||||
setSubmitting(true);
|
||||
|
||||
// Create new template
|
||||
createPdfTemplate(reqValues)
|
||||
.then(() => handleSuccess('PDF template created successfully!'))
|
||||
.catch(() =>
|
||||
handleError('An error occurred while creating the PDF template.'),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<ElementCustomize<T>
|
||||
initialValues={initialValues}
|
||||
validationSchema={validationSchema}
|
||||
onSubmit={handleFormSubmit}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export const validationSchema = Yup.object().shape({
|
||||
templateName: Yup.string().required('Template Name is required'),
|
||||
});
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { createContext } from 'react';
|
||||
import { useGetPdfTemplates } from '@/hooks/query/pdf-templates';
|
||||
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
|
||||
|
||||
interface BrandingTemplatesBootValues {
|
||||
pdfTemplates: any;
|
||||
@@ -15,8 +16,11 @@ interface BrandingTemplatesBootProps {
|
||||
}
|
||||
|
||||
function BrandingTemplatesBoot({ ...props }: BrandingTemplatesBootProps) {
|
||||
const { payload } = useDrawerContext();
|
||||
const resource = payload?.resource || null;
|
||||
|
||||
const { data: pdfTemplates, isLoading: isPdfTemplatesLoading } =
|
||||
useGetPdfTemplates();
|
||||
useGetPdfTemplates({ resource });
|
||||
|
||||
const provider = {
|
||||
pdfTemplates,
|
||||
@@ -16,12 +16,13 @@ function BrandingTemplatesDrawerRoot({
|
||||
name,
|
||||
// #withDrawer
|
||||
isOpen,
|
||||
payload: {},
|
||||
payload,
|
||||
}) {
|
||||
return (
|
||||
<Drawer
|
||||
isOpen={isOpen}
|
||||
name={name}
|
||||
payload={payload}
|
||||
size={'600px'}
|
||||
style={{ borderLeftColor: '#cbcbcb' }}
|
||||
>
|
||||
52
packages/webapp/src/containers/BrandingTemplates/_utils.ts
Normal file
52
packages/webapp/src/containers/BrandingTemplates/_utils.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { omit } from 'lodash';
|
||||
import {
|
||||
CreatePdfTemplateValues,
|
||||
EditPdfTemplateValues,
|
||||
} from '@/hooks/query/pdf-templates';
|
||||
import { useBrandingTemplateBoot } from './BrandingTemplateBoot';
|
||||
import { transformToForm } from '@/utils';
|
||||
import { BrandingTemplateValues } from './types';
|
||||
import { useFormikContext } from 'formik';
|
||||
|
||||
export const transformToEditRequest = <T extends BrandingTemplateValues>(
|
||||
values: T,
|
||||
): EditPdfTemplateValues => {
|
||||
return {
|
||||
templateName: values.templateName,
|
||||
attributes: omit(values, ['templateName']),
|
||||
};
|
||||
};
|
||||
|
||||
export const transformToNewRequest = <T extends BrandingTemplateValues>(
|
||||
values: T,
|
||||
resource: string
|
||||
): CreatePdfTemplateValues => {
|
||||
return {
|
||||
resource,
|
||||
templateName: values.templateName,
|
||||
attributes: omit(values, ['templateName']),
|
||||
};
|
||||
};
|
||||
|
||||
export const useIsTemplateNamedFilled = () => {
|
||||
const { values } = useFormikContext<BrandingTemplateValues>();
|
||||
|
||||
return values.templateName && values.templateName?.length >= 4;
|
||||
};
|
||||
|
||||
export const useBrandingTemplateFormInitialValues = <
|
||||
T extends BrandingTemplateValues,
|
||||
>(
|
||||
initialValues = {},
|
||||
) => {
|
||||
const { pdfTemplate } = useBrandingTemplateBoot();
|
||||
|
||||
const defaultPdfTemplate = {
|
||||
templateName: pdfTemplate?.templateName,
|
||||
...pdfTemplate?.attributes,
|
||||
};
|
||||
return {
|
||||
...initialValues,
|
||||
...(transformToForm(defaultPdfTemplate, initialValues) as T),
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
|
||||
export interface BrandingTemplateValues {
|
||||
templateName: string;
|
||||
}
|
||||
@@ -1,39 +1,35 @@
|
||||
import { Box } from '@/components';
|
||||
import { Classes } from '@blueprintjs/core';
|
||||
import { useFormikContext } from 'formik';
|
||||
import { ElementCustomize } from '../../../ElementCustomize/ElementCustomize';
|
||||
import { CreditNoteCustomizeGeneralField } from './CreditNoteCustomizeGeneralFields';
|
||||
import { CreditNoteCustomizeContentFields } from './CreditNoteCutomizeContentFields';
|
||||
import { CreditNotePaperTemplate } from './CreditNotePaperTemplate';
|
||||
import { CreditNoteCustomizeValues } from './types';
|
||||
import { initialValues } from './constants';
|
||||
import { useFormikContext } from 'formik';
|
||||
|
||||
export default function CreditNoteCustomizeContent() {
|
||||
export function CreditNoteCustomizeContent() {
|
||||
const handleFormSubmit = (values: CreditNoteCustomizeValues) => {};
|
||||
|
||||
return (
|
||||
<Box className={Classes.DRAWER_BODY}>
|
||||
<ElementCustomize<CreditNoteCustomizeValues>
|
||||
initialValues={initialValues}
|
||||
onSubmit={handleFormSubmit}
|
||||
>
|
||||
<ElementCustomize.PaperTemplate>
|
||||
<CreditNotePaperTemplateFormConnected />
|
||||
</ElementCustomize.PaperTemplate>
|
||||
<ElementCustomize<CreditNoteCustomizeValues>
|
||||
initialValues={initialValues}
|
||||
onSubmit={handleFormSubmit}
|
||||
>
|
||||
<ElementCustomize.PaperTemplate>
|
||||
<CreditNotePaperTemplateFormConnected />
|
||||
</ElementCustomize.PaperTemplate>
|
||||
|
||||
<ElementCustomize.FieldsTab id={'general'} label={'General'}>
|
||||
<CreditNoteCustomizeGeneralField />
|
||||
</ElementCustomize.FieldsTab>
|
||||
<ElementCustomize.FieldsTab id={'general'} label={'General'}>
|
||||
<CreditNoteCustomizeGeneralField />
|
||||
</ElementCustomize.FieldsTab>
|
||||
|
||||
<ElementCustomize.FieldsTab id={'content'} label={'Content'}>
|
||||
<CreditNoteCustomizeContentFields />
|
||||
</ElementCustomize.FieldsTab>
|
||||
<ElementCustomize.FieldsTab id={'content'} label={'Content'}>
|
||||
<CreditNoteCustomizeContentFields />
|
||||
</ElementCustomize.FieldsTab>
|
||||
|
||||
<ElementCustomize.FieldsTab id={'totals'} label={'Totals'}>
|
||||
asdfasdfdsaf #3
|
||||
</ElementCustomize.FieldsTab>
|
||||
</ElementCustomize>
|
||||
</Box>
|
||||
<ElementCustomize.FieldsTab id={'totals'} label={'Totals'}>
|
||||
asdfasdfdsaf #3
|
||||
</ElementCustomize.FieldsTab>
|
||||
</ElementCustomize>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Box } from '@/components';
|
||||
import { CreditNoteCustomizeContent } from './CreditNoteCustomizeContent';
|
||||
import { Classes } from '@blueprintjs/core';
|
||||
import { BrandingTemplateBoot } from '@/containers/BrandingTemplates/BrandingTemplateBoot';
|
||||
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
|
||||
|
||||
export default function CreditNoteCustomizeDrawerBody() {
|
||||
const { payload } = useDrawerContext();
|
||||
const templateId = payload.templateId;
|
||||
|
||||
return (
|
||||
<Box className={Classes.DRAWER_BODY}>
|
||||
<BrandingTemplateBoot templateId={templateId}>
|
||||
<CreditNoteCustomizeContent />
|
||||
</BrandingTemplateBoot>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@@ -101,7 +101,7 @@ function CreditNotesActionsBar({
|
||||
};
|
||||
// Handle the customize button click.
|
||||
const handleCustomizeBtnClick = () => {
|
||||
openDrawer(DRAWERS.CREDIT_NOTE_CUSTOMIZE);
|
||||
openDrawer(DRAWERS.BRANDING_TEMPLATES, { resource: 'CreditNote' });
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -174,7 +174,7 @@ function CreditNotesActionsBar({
|
||||
<Menu>
|
||||
<MenuItem
|
||||
onClick={handleCustomizeBtnClick}
|
||||
text={'Customize Invoice'}
|
||||
text={'Customize Templates'}
|
||||
/>
|
||||
</Menu>
|
||||
}
|
||||
|
||||
@@ -1,40 +1,49 @@
|
||||
import React from 'react';
|
||||
import { Box } from '@/components';
|
||||
import { Classes } from '@blueprintjs/core';
|
||||
import { useFormikContext } from 'formik';
|
||||
import { Box } from '@/components';
|
||||
import { ElementCustomize } from '../../../ElementCustomize/ElementCustomize';
|
||||
import { EstimateCustomizeGeneralField } from './EstimateCustomizeFieldsGeneral';
|
||||
import { EstimateCustomizeContentFields } from './EstimateCustomizeFieldsContent';
|
||||
import { EstimatePaperTemplate } from './EstimatePaperTemplate';
|
||||
import { EstimateCustomizeValues } from './types';
|
||||
import { initialValues } from './constants';
|
||||
import { useFormikContext } from 'formik';
|
||||
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
|
||||
import { useDrawerActions } from '@/hooks/state';
|
||||
import { BrandingTemplateForm } from '@/containers/BrandingTemplates/BrandingTemplateForm';
|
||||
|
||||
export default function EstimateCustomizeContent() {
|
||||
const handleFormSubmit = (values: EstimateCustomizeValues) => {};
|
||||
export function EstimateCustomizeContent() {
|
||||
const { payload, name } = useDrawerContext();
|
||||
const { closeDrawer } = useDrawerActions();
|
||||
|
||||
const templateId = payload?.templateId || null;
|
||||
|
||||
const handleSuccess = () => {
|
||||
closeDrawer(name);
|
||||
};
|
||||
|
||||
return (
|
||||
<Box className={Classes.DRAWER_BODY}>
|
||||
<ElementCustomize<EstimateCustomizeValues>
|
||||
initialValues={initialValues}
|
||||
onSubmit={handleFormSubmit}
|
||||
>
|
||||
<ElementCustomize.PaperTemplate>
|
||||
<EstimatePaperTemplateFormConnected />
|
||||
</ElementCustomize.PaperTemplate>
|
||||
<BrandingTemplateForm<EstimateCustomizeValues>
|
||||
templateId={templateId}
|
||||
defaultValues={initialValues}
|
||||
onSuccess={handleSuccess}
|
||||
resource={'SaleEstimate'}
|
||||
>
|
||||
<ElementCustomize.PaperTemplate>
|
||||
<EstimatePaperTemplateFormConnected />
|
||||
</ElementCustomize.PaperTemplate>
|
||||
|
||||
<ElementCustomize.FieldsTab id={'general'} label={'General'}>
|
||||
<EstimateCustomizeGeneralField />
|
||||
</ElementCustomize.FieldsTab>
|
||||
<ElementCustomize.FieldsTab id={'general'} label={'General'}>
|
||||
<EstimateCustomizeGeneralField />
|
||||
</ElementCustomize.FieldsTab>
|
||||
|
||||
<ElementCustomize.FieldsTab id={'content'} label={'Content'}>
|
||||
<EstimateCustomizeContentFields />
|
||||
</ElementCustomize.FieldsTab>
|
||||
<ElementCustomize.FieldsTab id={'content'} label={'Content'}>
|
||||
<EstimateCustomizeContentFields />
|
||||
</ElementCustomize.FieldsTab>
|
||||
|
||||
<ElementCustomize.FieldsTab id={'totals'} label={'Totals'}>
|
||||
asdfasdfdsaf #3
|
||||
</ElementCustomize.FieldsTab>
|
||||
</ElementCustomize>
|
||||
</Box>
|
||||
<ElementCustomize.FieldsTab id={'totals'} label={'Totals'}>
|
||||
asdfasdfdsaf #3
|
||||
</ElementCustomize.FieldsTab>
|
||||
</BrandingTemplateForm>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ import * as R from 'ramda';
|
||||
import { Drawer, DrawerSuspense } from '@/components';
|
||||
import withDrawers from '@/containers/Drawer/withDrawers';
|
||||
|
||||
const EstimateCustomizeContent = React.lazy(
|
||||
() => import('./EstimateCustomizeContent'),
|
||||
const EstimateCustomizeDrawerBody = React.lazy(
|
||||
() => import('./EstimateCustomizeDrawerBody'),
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -22,7 +22,7 @@ function EstimateCustomizeDrawerRoot({
|
||||
return (
|
||||
<Drawer isOpen={isOpen} name={name} size={'100%'}>
|
||||
<DrawerSuspense>
|
||||
<EstimateCustomizeContent />
|
||||
<EstimateCustomizeDrawerBody />
|
||||
</DrawerSuspense>
|
||||
</Drawer>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Box } from '@/components';
|
||||
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
|
||||
import { BrandingTemplateBoot } from '@/containers/BrandingTemplates/BrandingTemplateBoot';
|
||||
import { Classes } from '@blueprintjs/core';
|
||||
import { EstimateCustomizeContent } from './EstimateCustomizeContent';
|
||||
|
||||
export default function EstimateCustomizeDrawerBody() {
|
||||
const { payload } = useDrawerContext();
|
||||
const templateId = payload?.templateId || null;
|
||||
|
||||
return (
|
||||
<Box className={Classes.DRAWER_BODY}>
|
||||
<BrandingTemplateBoot templateId={templateId}>
|
||||
<EstimateCustomizeContent />
|
||||
</BrandingTemplateBoot>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@@ -1,6 +1,13 @@
|
||||
// @ts-nocheck
|
||||
import { Classes, Text } from '@blueprintjs/core';
|
||||
import { FFormGroup, FSwitch, Group, Stack } from '@/components';
|
||||
import {
|
||||
FFormGroup,
|
||||
FInputGroup,
|
||||
FSwitch,
|
||||
FieldRequiredHint,
|
||||
Group,
|
||||
Stack,
|
||||
} from '@/components';
|
||||
import { FColorInput } from '@/components/Forms/FColorInput';
|
||||
// import styles from './InvoiceCustomizeFields.module.scss';
|
||||
|
||||
@@ -10,11 +17,21 @@ export function EstimateCustomizeGeneralField() {
|
||||
<Stack spacing={0}>
|
||||
<h2 style={{ fontSize: 16, marginBottom: 10 }}>General Branding</h2>
|
||||
<p className={Classes.TEXT_MUTED}>
|
||||
Set your invoice details to be automatically applied every time
you
|
||||
Set your invoice details to be automatically applied every timeyou
|
||||
create a new invoice.
|
||||
</p>
|
||||
</Stack>
|
||||
|
||||
<FFormGroup
|
||||
name={'templateName'}
|
||||
label={'Template Name'}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
fastField
|
||||
style={{ marginBottom: 10 }}
|
||||
>
|
||||
<FInputGroup name={'templateName'} fastField />
|
||||
</FFormGroup>
|
||||
|
||||
<Stack spacing={0}>
|
||||
<FFormGroup
|
||||
name={'primaryColor'}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export const initialValues = {
|
||||
templateName: '',
|
||||
|
||||
// Colors
|
||||
primaryColor: '#2c3dd8',
|
||||
secondaryColor: '#2c3dd8',
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export interface EstimateCustomizeValues {
|
||||
import { BrandingTemplateValues } from "@/containers/BrandingTemplates/types";
|
||||
|
||||
export interface EstimateCustomizeValues extends BrandingTemplateValues {
|
||||
// Colors
|
||||
primaryColor?: string;
|
||||
secondaryColor?: string;
|
||||
|
||||
@@ -108,7 +108,7 @@ function EstimateActionsBar({
|
||||
};
|
||||
// Handle customize button clicl.
|
||||
const handleCustomizeBtnClick = () => {
|
||||
openDrawer(DRAWERS.ESTIMATE_CUSTOMIZE);
|
||||
openDrawer(DRAWERS.BRANDING_TEMPLATES, { resource: 'SaleEstimate' });
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -192,7 +192,7 @@ function EstimateActionsBar({
|
||||
<Menu>
|
||||
<MenuItem
|
||||
onClick={handleCustomizeBtnClick}
|
||||
text={'Customize Estimate'}
|
||||
text={'Customize Templates'}
|
||||
/>
|
||||
</Menu>
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// @ts-nocheck
|
||||
import { Classes } from '@blueprintjs/core';
|
||||
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
|
||||
import { BrandingTemplateBoot } from '../BrandingTemplates/BrandingTemplateBoot';
|
||||
import { InvoiceCustomizeContent } from './InvoiceCustomizeContent';
|
||||
import { BrandingTemplateBoot } from '@/containers/BrandingTemplates/BrandingTemplateBoot';
|
||||
import { Box } from '@/components';
|
||||
|
||||
export default function InvoiceCustomize() {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import React from 'react';
|
||||
import * as R from 'ramda';
|
||||
import { AppToaster } from '@/components';
|
||||
import { Intent } from '@blueprintjs/core';
|
||||
import { FormikHelpers, useFormikContext } from 'formik';
|
||||
import { useFormikContext } from 'formik';
|
||||
import {
|
||||
InvoicePaperTemplate,
|
||||
InvoicePaperTemplateProps,
|
||||
@@ -11,70 +9,29 @@ import { ElementCustomize } from '../../../ElementCustomize/ElementCustomize';
|
||||
import { InvoiceCustomizeGeneralField } from './InvoiceCustomizeGeneralFields';
|
||||
import { InvoiceCustomizeContentFields } from './InvoiceCutomizeContentFields';
|
||||
import { InvoiceCustomizeValues } from './types';
|
||||
import {
|
||||
useCreatePdfTemplate,
|
||||
useEditPdfTemplate,
|
||||
} from '@/hooks/query/pdf-templates';
|
||||
import {
|
||||
transformToEditRequest,
|
||||
transformToNewRequest,
|
||||
useInvoiceCustomizeInitialValues,
|
||||
} from './utils';
|
||||
import { InvoiceCustomizeSchema } from './InvoiceCustomizeForm.schema';
|
||||
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
|
||||
import { useDrawerActions } from '@/hooks/state';
|
||||
import { BrandingTemplateForm } from '@/containers/BrandingTemplates/BrandingTemplateForm';
|
||||
import { initialValues } from './constants';
|
||||
|
||||
export function InvoiceCustomizeContent() {
|
||||
const { mutateAsync: createPdfTemplate } = useCreatePdfTemplate();
|
||||
const { mutateAsync: editPdfTemplate } = useEditPdfTemplate();
|
||||
|
||||
const { payload, name } = useDrawerContext();
|
||||
const { closeDrawer } = useDrawerActions();
|
||||
|
||||
const templateId = payload?.templateId || null;
|
||||
|
||||
const handleFormSubmit = (
|
||||
values: InvoiceCustomizeValues,
|
||||
{ setSubmitting }: FormikHelpers<InvoiceCustomizeValues>,
|
||||
) => {
|
||||
const handleSuccess = (message: string) => {
|
||||
AppToaster.show({ intent: Intent.SUCCESS, message });
|
||||
setSubmitting(false);
|
||||
closeDrawer(name);
|
||||
};
|
||||
const handleError = (message: string) => {
|
||||
AppToaster.show({ intent: Intent.DANGER, message });
|
||||
setSubmitting(false);
|
||||
};
|
||||
if (templateId) {
|
||||
const reqValues = transformToEditRequest(values);
|
||||
setSubmitting(true);
|
||||
|
||||
// Edit existing template
|
||||
editPdfTemplate({ templateId, values: reqValues })
|
||||
.then(() => handleSuccess('PDF template updated successfully!'))
|
||||
.catch(() =>
|
||||
handleError('An error occurred while updating the PDF template.'),
|
||||
);
|
||||
} else {
|
||||
const reqValues = transformToNewRequest(values);
|
||||
setSubmitting(true);
|
||||
|
||||
// Create new template
|
||||
createPdfTemplate(reqValues)
|
||||
.then(() => handleSuccess('PDF template created successfully!'))
|
||||
.catch(() =>
|
||||
handleError('An error occurred while creating the PDF template.'),
|
||||
);
|
||||
}
|
||||
const handleSuccess = () => {
|
||||
closeDrawer(name);
|
||||
};
|
||||
const initialValues = useInvoiceCustomizeInitialValues();
|
||||
|
||||
return (
|
||||
<ElementCustomize<InvoiceCustomizeValues>
|
||||
initialValues={initialValues}
|
||||
<BrandingTemplateForm<InvoiceCustomizeValues>
|
||||
templateId={templateId}
|
||||
defaultValues={initialValues}
|
||||
validationSchema={InvoiceCustomizeSchema}
|
||||
onSubmit={handleFormSubmit}
|
||||
onSuccess={handleSuccess}
|
||||
resource={'SaleInvoice'}
|
||||
>
|
||||
<ElementCustomize.PaperTemplate>
|
||||
<InvoicePaperTemplateFormConnected />
|
||||
@@ -91,7 +48,7 @@ export function InvoiceCustomizeContent() {
|
||||
<ElementCustomize.FieldsTab id={'totals'} label={'Totals'}>
|
||||
asdfasdfdsaf #3
|
||||
</ElementCustomize.FieldsTab>
|
||||
</ElementCustomize>
|
||||
</BrandingTemplateForm>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export interface InvoiceCustomizeValues {
|
||||
templateName: string;
|
||||
import { BrandingTemplateValues } from "@/containers/BrandingTemplates/types";
|
||||
|
||||
export interface InvoiceCustomizeValues extends BrandingTemplateValues {
|
||||
// Colors
|
||||
primaryColor?: string;
|
||||
secondaryColor?: string;
|
||||
|
||||
@@ -5,9 +5,9 @@ import {
|
||||
CreatePdfTemplateValues,
|
||||
EditPdfTemplateValues,
|
||||
} from '@/hooks/query/pdf-templates';
|
||||
import { useBrandingTemplateBoot } from '../BrandingTemplates/BrandingTemplateBoot';
|
||||
import { transformToForm } from '@/utils';
|
||||
import { initialValues } from './constants';
|
||||
import { useBrandingTemplateBoot } from '@/containers/BrandingTemplates/BrandingTemplateBoot';
|
||||
|
||||
export const transformToEditRequest = (
|
||||
values: InvoiceCustomizeValues,
|
||||
|
||||
@@ -109,7 +109,7 @@ function InvoiceActionsBar({
|
||||
|
||||
// Handles the invoice customize button click.
|
||||
const handleCustomizeBtnClick = () => {
|
||||
openDrawer(DRAWERS.BRANDING_TEMPLATES);
|
||||
openDrawer(DRAWERS.BRANDING_TEMPLATES, { resource: 'SaleInvoice' });
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -190,7 +190,7 @@ function InvoiceActionsBar({
|
||||
<Menu>
|
||||
<MenuItem
|
||||
onClick={handleCustomizeBtnClick}
|
||||
text={'Invoice Templates'}
|
||||
text={'Customize Templates'}
|
||||
/>
|
||||
</Menu>
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Box } from '@/components';
|
||||
import { Classes } from '@blueprintjs/core';
|
||||
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
|
||||
import { PaymentReceivedCustomizeContent } from './PaymentReceivedCustomizeContent';
|
||||
import { BrandingTemplateBoot } from '@/containers/BrandingTemplates/BrandingTemplateBoot';
|
||||
|
||||
export default function PaymentReceivedCustomize() {
|
||||
const { payload } = useDrawerContext();
|
||||
const templateId = payload.templateId;
|
||||
|
||||
return (
|
||||
<Box className={Classes.DRAWER_BODY}>
|
||||
<BrandingTemplateBoot templateId={templateId}>
|
||||
<PaymentReceivedCustomizeContent />
|
||||
</BrandingTemplateBoot>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@@ -1,40 +1,47 @@
|
||||
import React from 'react';
|
||||
import { useFormikContext } from 'formik';
|
||||
import { Classes } from '@blueprintjs/core';
|
||||
import { Box } from '@/components';
|
||||
import { ElementCustomize } from '../../../ElementCustomize/ElementCustomize';
|
||||
import { PaymentReceivedCustomizeGeneralField } from './PaymentReceivedCustomizeFieldsGeneral';
|
||||
import { PaymentReceivedCustomizeContentFields } from './PaymentReceivedCustomizeFieldsContent';
|
||||
import { PaymentReceivedCustomizeValues } from './types';
|
||||
import { PaymentReceivedPaperTemplate } from './PaymentReceivedPaperTemplate';
|
||||
import { initialValues } from './constants';
|
||||
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
|
||||
import { useDrawerActions } from '@/hooks/state';
|
||||
import { BrandingTemplateForm } from '@/containers/BrandingTemplates/BrandingTemplateForm';
|
||||
|
||||
export default function PaymentReceivedCustomizeContent() {
|
||||
const handleFormSubmit = (values: PaymentReceivedCustomizeValues) => {};
|
||||
export function PaymentReceivedCustomizeContent() {
|
||||
const { payload, name } = useDrawerContext();
|
||||
const { closeDrawer } = useDrawerActions();
|
||||
|
||||
const templateId = payload?.templateId || null;
|
||||
|
||||
const handleSuccess = () => {
|
||||
closeDrawer(name);
|
||||
};
|
||||
|
||||
return (
|
||||
<Box className={Classes.DRAWER_BODY}>
|
||||
<ElementCustomize<PaymentReceivedCustomizeValues>
|
||||
initialValues={initialValues}
|
||||
onSubmit={handleFormSubmit}
|
||||
>
|
||||
<ElementCustomize.PaperTemplate>
|
||||
<PaymentReceivedPaperTemplateFormConnected />
|
||||
</ElementCustomize.PaperTemplate>
|
||||
<BrandingTemplateForm<PaymentReceivedCustomizeValues>
|
||||
templateId={templateId}
|
||||
defaultValues={initialValues}
|
||||
onSuccess={handleSuccess}
|
||||
resource={'PaymentReceive'}
|
||||
>
|
||||
<ElementCustomize.PaperTemplate>
|
||||
<PaymentReceivedPaperTemplateFormConnected />
|
||||
</ElementCustomize.PaperTemplate>
|
||||
|
||||
<ElementCustomize.FieldsTab id={'general'} label={'General'}>
|
||||
<PaymentReceivedCustomizeGeneralField />
|
||||
</ElementCustomize.FieldsTab>
|
||||
<ElementCustomize.FieldsTab id={'general'} label={'General'}>
|
||||
<PaymentReceivedCustomizeGeneralField />
|
||||
</ElementCustomize.FieldsTab>
|
||||
|
||||
<ElementCustomize.FieldsTab id={'content'} label={'Content'}>
|
||||
<PaymentReceivedCustomizeContentFields />
|
||||
</ElementCustomize.FieldsTab>
|
||||
<ElementCustomize.FieldsTab id={'content'} label={'Content'}>
|
||||
<PaymentReceivedCustomizeContentFields />
|
||||
</ElementCustomize.FieldsTab>
|
||||
|
||||
<ElementCustomize.FieldsTab id={'totals'} label={'Totals'}>
|
||||
asdfasdfdsaf #3
|
||||
</ElementCustomize.FieldsTab>
|
||||
</ElementCustomize>
|
||||
</Box>
|
||||
<ElementCustomize.FieldsTab id={'totals'} label={'Totals'}>
|
||||
asdfasdfdsaf #3
|
||||
</ElementCustomize.FieldsTab>
|
||||
</BrandingTemplateForm>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ import * as R from 'ramda';
|
||||
import { Drawer, DrawerSuspense } from '@/components';
|
||||
import withDrawers from '@/containers/Drawer/withDrawers';
|
||||
|
||||
const PaymentReceivedCustomizeContent = React.lazy(
|
||||
() => import('./PaymentReceivedCustomizeContent'),
|
||||
const PaymentReceivedCustomize = React.lazy(
|
||||
() => import('./PaymentReceivedCustomize'),
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -16,12 +16,12 @@ function PaymentReceivedCustomizeDrawerRoot({
|
||||
name,
|
||||
// #withDrawer
|
||||
isOpen,
|
||||
payload: {},
|
||||
payload
|
||||
}) {
|
||||
return (
|
||||
<Drawer isOpen={isOpen} name={name} size={'100%'}>
|
||||
<Drawer isOpen={isOpen} name={name} size={'100%'} payload={payload}>
|
||||
<DrawerSuspense>
|
||||
<PaymentReceivedCustomizeContent />
|
||||
<PaymentReceivedCustomize />
|
||||
</DrawerSuspense>
|
||||
</Drawer>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export const initialValues = {
|
||||
templateName: '',
|
||||
|
||||
// Colors
|
||||
primaryColor: '#2c3dd8',
|
||||
secondaryColor: '#2c3dd8',
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export interface PaymentReceivedCustomizeValues {
|
||||
import { BrandingTemplateValues } from '@/containers/BrandingTemplates/types';
|
||||
|
||||
export interface PaymentReceivedCustomizeValues extends BrandingTemplateValues {
|
||||
// Colors
|
||||
primaryColor?: string;
|
||||
secondaryColor?: string;
|
||||
|
||||
@@ -113,7 +113,7 @@ function PaymentsReceivedActionsBar({
|
||||
};
|
||||
// Handle the customize button click.
|
||||
const handleCustomizeBtnClick = () => {
|
||||
openDrawer(DRAWERS.PAYMENT_RECEIVED_CUSTOMIZE);
|
||||
openDrawer(DRAWERS.BRANDING_TEMPLATES, { resource: 'PaymentReceive' });
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -195,7 +195,7 @@ function PaymentsReceivedActionsBar({
|
||||
<Menu>
|
||||
<MenuItem
|
||||
onClick={handleCustomizeBtnClick}
|
||||
text={'Customize Invoice'}
|
||||
text={'Customize Templates'}
|
||||
/>
|
||||
</Menu>
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { Box } from '@/components';
|
||||
import { Classes } from '@blueprintjs/core';
|
||||
import { ElementCustomize } from '../../../ElementCustomize/ElementCustomize';
|
||||
import { ReceiptCustomizeGeneralField } from './ReceiptCustomizeFieldsGeneral';
|
||||
import { ReceiptCustomizeFieldsContent } from './ReceiptCustomizeFieldsContent';
|
||||
@@ -7,33 +5,43 @@ import { ReceiptPaperTemplate } from './ReceiptPaperTemplate';
|
||||
import { ReceiptCustomizeValues } from './types';
|
||||
import { initialValues } from './constants';
|
||||
import { useFormikContext } from 'formik';
|
||||
import { BrandingTemplateForm } from '@/containers/BrandingTemplates/BrandingTemplateForm';
|
||||
import { useDrawerActions } from '@/hooks/state';
|
||||
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
|
||||
|
||||
export default function ReceiptCustomizeContent() {
|
||||
const handleFormSubmit = (values: ReceiptCustomizeValues) => {};
|
||||
export function ReceiptCustomizeContent() {
|
||||
const { payload, name } = useDrawerContext();
|
||||
const { closeDrawer } = useDrawerActions();
|
||||
|
||||
const templateId = payload?.templateId || null;
|
||||
|
||||
const handleFormSuccess = () => {
|
||||
closeDrawer(name);
|
||||
};
|
||||
|
||||
return (
|
||||
<Box className={Classes.DRAWER_BODY}>
|
||||
<ElementCustomize<ReceiptCustomizeValues>
|
||||
initialValues={initialValues}
|
||||
onSubmit={handleFormSubmit}
|
||||
>
|
||||
<ElementCustomize.PaperTemplate>
|
||||
<ReceiptPaperTemplateFormConnected />
|
||||
</ElementCustomize.PaperTemplate>
|
||||
<BrandingTemplateForm<ReceiptCustomizeValues>
|
||||
templateId={templateId}
|
||||
initialValues={initialValues}
|
||||
onSuccess={handleFormSuccess}
|
||||
resource={'SaleReceipt'}
|
||||
>
|
||||
<ElementCustomize.PaperTemplate>
|
||||
<ReceiptPaperTemplateFormConnected />
|
||||
</ElementCustomize.PaperTemplate>
|
||||
|
||||
<ElementCustomize.FieldsTab id={'general'} label={'General'}>
|
||||
<ReceiptCustomizeGeneralField />
|
||||
</ElementCustomize.FieldsTab>
|
||||
<ElementCustomize.FieldsTab id={'general'} label={'General'}>
|
||||
<ReceiptCustomizeGeneralField />
|
||||
</ElementCustomize.FieldsTab>
|
||||
|
||||
<ElementCustomize.FieldsTab id={'content'} label={'Content'}>
|
||||
<ReceiptCustomizeFieldsContent />
|
||||
</ElementCustomize.FieldsTab>
|
||||
<ElementCustomize.FieldsTab id={'content'} label={'Content'}>
|
||||
<ReceiptCustomizeFieldsContent />
|
||||
</ElementCustomize.FieldsTab>
|
||||
|
||||
<ElementCustomize.FieldsTab id={'totals'} label={'Totals'}>
|
||||
asdfasdfdsaf #3
|
||||
</ElementCustomize.FieldsTab>
|
||||
</ElementCustomize>
|
||||
</Box>
|
||||
<ElementCustomize.FieldsTab id={'totals'} label={'Totals'}>
|
||||
asdfasdfdsaf #3
|
||||
</ElementCustomize.FieldsTab>
|
||||
</BrandingTemplateForm>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ import * as R from 'ramda';
|
||||
import { Drawer, DrawerSuspense } from '@/components';
|
||||
import withDrawers from '@/containers/Drawer/withDrawers';
|
||||
|
||||
const ReceiptCustomizeContent = React.lazy(
|
||||
() => import('./ReceiptCustomizeContent'),
|
||||
const ReceiptCustomizeDrawerBody = React.lazy(
|
||||
() => import('./ReceiptCustomizeDrawerBody'),
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -16,12 +16,12 @@ function ReceiptCustomizeDrawerRoot({
|
||||
name,
|
||||
// #withDrawer
|
||||
isOpen,
|
||||
payload: {},
|
||||
payload,
|
||||
}) {
|
||||
return (
|
||||
<Drawer isOpen={isOpen} name={name} size={'100%'}>
|
||||
<Drawer isOpen={isOpen} name={name} size={'100%'} payload={payload}>
|
||||
<DrawerSuspense>
|
||||
<ReceiptCustomizeContent />
|
||||
<ReceiptCustomizeDrawerBody />
|
||||
</DrawerSuspense>
|
||||
</Drawer>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Box } from '@/components';
|
||||
import { Classes } from '@blueprintjs/core';
|
||||
import { ReceiptCustomizeContent } from './ReceiptCustomizeContent';
|
||||
import { BrandingTemplateBoot } from '@/containers/BrandingTemplates/BrandingTemplateBoot';
|
||||
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
|
||||
|
||||
export default function ReceiptCustomizeDrawerBody() {
|
||||
const { payload } = useDrawerContext();
|
||||
const templateId = payload.templateId;
|
||||
|
||||
return (
|
||||
<Box className={Classes.DRAWER_BODY}>
|
||||
<BrandingTemplateBoot templateId={templateId}>
|
||||
<ReceiptCustomizeContent />
|
||||
</BrandingTemplateBoot>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
export const initialValues = {
|
||||
templateName: '',
|
||||
|
||||
// Colors
|
||||
primaryColor: '#2c3dd8',
|
||||
secondaryColor: '#2c3dd8',
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export interface ReceiptCustomizeValues {
|
||||
import { BrandingTemplateValues } from "@/containers/BrandingTemplates/types";
|
||||
|
||||
export interface ReceiptCustomizeValues extends BrandingTemplateValues {
|
||||
// Colors
|
||||
primaryColor?: string;
|
||||
secondaryColor?: string;
|
||||
|
||||
@@ -115,7 +115,7 @@ function ReceiptActionsBar({
|
||||
};
|
||||
// Handle customize button click.
|
||||
const handleCustomizeBtnClick = () => {
|
||||
openDrawer(DRAWERS.RECEIPT_CUSTOMIZE);
|
||||
openDrawer(DRAWERS.BRANDING_TEMPLATES, { resource: 'SaleReceipt' });
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -198,7 +198,7 @@ function ReceiptActionsBar({
|
||||
<Menu>
|
||||
<MenuItem
|
||||
onClick={handleCustomizeBtnClick}
|
||||
text={'Customize Receipt'}
|
||||
text={'Customize Template'}
|
||||
/>
|
||||
</Menu>
|
||||
}
|
||||
|
||||
@@ -153,12 +153,16 @@ export const useGetPdfTemplate = (
|
||||
|
||||
// Hook for getting multiple PDF templates
|
||||
export const useGetPdfTemplates = (
|
||||
query?: { resource: string },
|
||||
options?: UseQueryOptions<GetPdfTemplatesResponse, Error>,
|
||||
): UseQueryResult<GetPdfTemplatesResponse, Error> => {
|
||||
const apiRequest = useApiRequest();
|
||||
return useQuery<GetPdfTemplatesResponse, Error>(
|
||||
PdfTemplatesQueryKey,
|
||||
() => apiRequest.get('/pdf-templates').then((res) => res.data),
|
||||
[PdfTemplatesQueryKey, query],
|
||||
() =>
|
||||
apiRequest
|
||||
.get('/pdf-templates', { params: query })
|
||||
.then((res) => res.data),
|
||||
options,
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user