feat: pdf template customize

This commit is contained in:
Ahmed Bouhuolia
2024-09-12 16:50:44 +02:00
parent 632c4629de
commit 12226d469a
46 changed files with 436 additions and 191 deletions

View File

@@ -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>
);
}

View File

@@ -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>
);
}

View File

@@ -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>
}

View File

@@ -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>
);
}

View File

@@ -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>
);

View File

@@ -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>
);
}

View File

@@ -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 timeyou
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'}

View File

@@ -1,4 +1,6 @@
export const initialValues = {
templateName: '',
// Colors
primaryColor: '#2c3dd8',
secondaryColor: '#2c3dd8',

View File

@@ -1,4 +1,6 @@
export interface EstimateCustomizeValues {
import { BrandingTemplateValues } from "@/containers/BrandingTemplates/types";
export interface EstimateCustomizeValues extends BrandingTemplateValues {
// Colors
primaryColor?: string;
secondaryColor?: string;

View File

@@ -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>
}

View File

@@ -1,15 +0,0 @@
.table {
:global {
.table .tbody .tr .td{
padding-top: 14px;
padding-bottom: 14px;
}
.table .thead .th{
text-transform: uppercase;
font-size: 13px;
}
}
}

View File

@@ -1,50 +0,0 @@
import React, { createContext, useContext } from 'react';
import {
GetPdfTemplateResponse,
useGetPdfTemplate,
} from '@/hooks/query/pdf-templates';
import { Spinner } from '@blueprintjs/core';
interface PdfTemplateContextValue {
templateId: number | string;
pdfTemplate: GetPdfTemplateResponse | undefined;
isPdfTemplateLoading: boolean;
}
interface BrandingTemplateProps {
templateId: number;
children: React.ReactNode;
}
const PdfTemplateContext = createContext<PdfTemplateContextValue>(
{} as PdfTemplateContextValue,
);
export const BrandingTemplateBoot = ({
templateId,
children,
}: BrandingTemplateProps) => {
const { data: pdfTemplate, isLoading: isPdfTemplateLoading } =
useGetPdfTemplate(templateId, {
enabled: !!templateId,
});
const value = {
templateId,
pdfTemplate,
isPdfTemplateLoading,
};
if (isPdfTemplateLoading) {
return <Spinner size={20} />
}
return (
<PdfTemplateContext.Provider value={value}>
{children}
</PdfTemplateContext.Provider>
);
};
export const useBrandingTemplateBoot = () => {
return useContext<PdfTemplateContextValue>(PdfTemplateContext);
};

View File

@@ -1,35 +0,0 @@
// @ts-nocheck
import React from 'react';
import { Button, NavbarGroup, Intent } from '@blueprintjs/core';
import { DashboardActionsBar, Icon } from '@/components';
import { DRAWERS } from '@/constants/drawers';
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import { compose } from '@/utils';
/**
* Account drawer action bar.
*/
function BrandingTemplateActionsBarRoot({ openDrawer }) {
// Handle new child button click.
const handleCreateBtnClick = () => {
openDrawer(DRAWERS.INVOICE_CUSTOMIZE);
};
return (
<DashboardActionsBar>
<NavbarGroup>
<Button
intent={Intent.PRIMARY}
icon={<Icon icon="plus" />}
onClick={handleCreateBtnClick}
minimal
>
Create Invoice Branding
</Button>
</NavbarGroup>
</DashboardActionsBar>
);
}
export const BrandingTemplateActionsBar = compose(withDrawerActions)(
BrandingTemplateActionsBarRoot,
);

View File

@@ -1,32 +0,0 @@
import React, { createContext } from 'react';
import { useGetPdfTemplates } from '@/hooks/query/pdf-templates';
interface BrandingTemplatesBootValues {
pdfTemplates: any;
isPdfTemplatesLoading: boolean;
}
const BrandingTemplatesBootContext = createContext<BrandingTemplatesBootValues>(
{} as BrandingTemplatesBootValues,
);
interface BrandingTemplatesBootProps {
children: React.ReactNode;
}
function BrandingTemplatesBoot({ ...props }: BrandingTemplatesBootProps) {
const { data: pdfTemplates, isLoading: isPdfTemplatesLoading } =
useGetPdfTemplates();
const provider = {
pdfTemplates,
isPdfTemplatesLoading,
} as BrandingTemplatesBootValues;
return <BrandingTemplatesBootContext.Provider value={provider} {...props} />;
}
const useBrandingTemplatesBoot = () =>
React.useContext<BrandingTemplatesBootValues>(BrandingTemplatesBootContext);
export { BrandingTemplatesBoot, useBrandingTemplatesBoot };

View File

@@ -1,46 +0,0 @@
// @ts-nocheck
import * as R from 'ramda';
import { Button, Classes, Intent } from '@blueprintjs/core';
import { BrandingTemplatesBoot } from './BrandingTemplatesBoot';
import { Box, Card, DrawerHeaderContent, Group } from '@/components';
import { DRAWERS } from '@/constants/drawers';
import { BrandingTemplatesTable } from './BrandingTemplatesTable';
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import { BrandingTemplateActionsBar } from './BrandingTemplatesActionsBar';
export default function BrandingTemplateContent() {
return (
<Box>
<DrawerHeaderContent
name={DRAWERS.BRANDING_TEMPLATES}
title={'Branding Templates'}
/>
<Box className={Classes.DRAWER_BODY}>
<BrandingTemplatesBoot>
<BrandingTemplateActionsBar />
<Card style={{ padding: 0 }}>
<BrandingTemplatesTable />
</Card>
</BrandingTemplatesBoot>
</Box>
</Box>
);
}
const BrandingTemplateHeader = R.compose(withDrawerActions)(
({ openDrawer }) => {
const handleCreateBtnClick = () => {
openDrawer(DRAWERS.INVOICE_CUSTOMIZE);
};
return (
<Group>
<Button intent={Intent.PRIMARY} onClick={handleCreateBtnClick}>
Create Invoice Branding
</Button>
</Group>
);
},
);
BrandingTemplateHeader.displayName = 'BrandingTemplateHeader';

View File

@@ -1,37 +0,0 @@
// @ts-nocheck
import React from 'react';
import * as R from 'ramda';
import { Drawer, DrawerSuspense } from '@/components';
import withDrawers from '@/containers/Drawer/withDrawers';
const BrandingTemplatesContent = React.lazy(
() => import('./BrandingTemplatesContent'),
);
/**
* Invoice customize drawer.
* @returns {React.ReactNode}
*/
function BrandingTemplatesDrawerRoot({
name,
// #withDrawer
isOpen,
payload: {},
}) {
return (
<Drawer
isOpen={isOpen}
name={name}
size={'600px'}
style={{ borderLeftColor: '#cbcbcb' }}
>
<DrawerSuspense>
<BrandingTemplatesContent />
</DrawerSuspense>
</Drawer>
);
}
export const BrandingTemplatesDrawer = R.compose(withDrawers())(
BrandingTemplatesDrawerRoot,
);

View File

@@ -1,86 +0,0 @@
// @ts-nocheck
import * as R from 'ramda';
import { Classes, Tag } from '@blueprintjs/core';
import clsx from 'classnames';
import { DataTable, Group, TableSkeletonRows } from '@/components';
import { useBrandingTemplatesBoot } from './BrandingTemplatesBoot';
import { ActionsMenu } from './_components';
import withAlertActions from '@/containers/Alert/withAlertActions';
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import { DRAWERS } from '@/constants/drawers';
import styles from './BrandTemplates.module.scss';
interface BrandingTemplatesTableProps {}
function BrandingTemplateTableRoot({
openAlert,
openDrawer,
}: BrandingTemplatesTableProps) {
// Table columns.
const columns = useBrandingTemplatesColumns();
const { isPdfTemplatesLoading, pdfTemplates } = useBrandingTemplatesBoot();
const handleEditTemplate = (template) => {
openDrawer(DRAWERS.INVOICE_CUSTOMIZE, {
templateId: template.id,
resource: template.resource,
});
};
const handleDeleteTemplate = (template) => {
openAlert('branding-template-delete', { templateId: template.id });
};
const handleCellClick = (cell, event) => {
const templateId = cell.row.original.id;
const resource = cell.row.original.resource;
openDrawer(DRAWERS.INVOICE_CUSTOMIZE, { templateId, resource });
};
return (
<DataTable
columns={columns}
data={pdfTemplates || []}
loading={isPdfTemplatesLoading}
progressBarLoading={isPdfTemplatesLoading}
TableLoadingRenderer={TableSkeletonRows}
ContextMenu={ActionsMenu}
noInitialFetch={true}
payload={{
onDeleteTemplate: handleDeleteTemplate,
onEditTemplate: handleEditTemplate,
}}
rowContextMenu={ActionsMenu}
onCellClick={handleCellClick}
className={styles.table}
/>
);
}
export const BrandingTemplatesTable = R.compose(
withAlertActions,
withDrawerActions,
)(BrandingTemplateTableRoot);
const useBrandingTemplatesColumns = () => {
return [
{
Header: 'Template Name',
accessor: (row) => (
<Group spacing={10}>
{row.template_name} {row.default && <Tag round>Default</Tag>}
</Group>
),
width: 65,
clickable: true,
},
{
Header: 'Created At',
accessor: 'created_at_formatted',
width: 35,
className: clsx(Classes.TEXT_MUTED),
clickable: true,
},
];
};

View File

@@ -1,26 +0,0 @@
// @ts-nocheck
import { safeCallback } from '@/utils';
import { Intent, Menu, MenuDivider, MenuItem } from '@blueprintjs/core';
/**
* Templates table actions menu.
*/
export function ActionsMenu({
row: { original },
payload: { onDeleteTemplate, onEditTemplate },
}) {
return (
<Menu>
<MenuItem
text={'Edit Template'}
onClick={safeCallback(onEditTemplate, original)}
/>
<MenuDivider />
<MenuItem
text={'Delete Template'}
intent={Intent.DANGER}
onClick={safeCallback(onDeleteTemplate, original)}
/>
</Menu>
);
}

View File

@@ -1,10 +0,0 @@
// @ts-nocheck
import React from 'react';
const DeleteBrandingTemplateAlert = React.lazy(
() => import('./DeleteBrandingTemplateAlert'),
);
export const BrandingTemplatesAlerts = [
{ name: 'branding-template-delete', component: DeleteBrandingTemplateAlert },
];

View File

@@ -1,72 +0,0 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { AppToaster } from '@/components';
import { Alert, Intent } from '@blueprintjs/core';
import { useDeletePdfTemplate} from '@/hooks/query/pdf-templates';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils';
/**
* Delete branding template alert.
*/
function DeleteBrandingTemplateAlert({
// #ownProps
name,
// #withAlertStoreConnect
isOpen,
payload: { templateId },
// #withAlertActions
closeAlert,
}) {
const { mutateAsync: deleteBrandingTemplateMutate } = useDeletePdfTemplate();
const handleConfirmDelete = () => {
deleteBrandingTemplateMutate({ templateId })
.then(() => {
AppToaster.show({
message: 'The branding template has been deleted successfully.',
intent: Intent.SUCCESS,
});
closeAlert(name);
})
.catch((error) => {
AppToaster.show({
message: 'Something went wrong.',
intent: Intent.DANGER,
});
closeAlert(name);
});
};
const handleCancel = () => {
closeAlert(name);
};
return (
<Alert
cancelButtonText={intl.get('cancel')}
confirmButtonText={intl.get('delete')}
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancel}
onConfirm={handleConfirmDelete}
>
<p>
Are you sure want to delete branding template?
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(DeleteBrandingTemplateAlert);

View File

@@ -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() {

View File

@@ -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>
);
}

View File

@@ -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;

View File

@@ -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,

View File

@@ -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>
}

View File

@@ -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>
);
}

View File

@@ -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>
);
}

View File

@@ -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>
);

View File

@@ -1,4 +1,6 @@
export const initialValues = {
templateName: '',
// Colors
primaryColor: '#2c3dd8',
secondaryColor: '#2c3dd8',

View File

@@ -1,4 +1,6 @@
export interface PaymentReceivedCustomizeValues {
import { BrandingTemplateValues } from '@/containers/BrandingTemplates/types';
export interface PaymentReceivedCustomizeValues extends BrandingTemplateValues {
// Colors
primaryColor?: string;
secondaryColor?: string;

View File

@@ -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>
}

View File

@@ -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>
);
}

View File

@@ -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>
);

View File

@@ -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>
);
}

View File

@@ -1,4 +1,6 @@
export const initialValues = {
templateName: '',
// Colors
primaryColor: '#2c3dd8',
secondaryColor: '#2c3dd8',

View File

@@ -1,4 +1,6 @@
export interface ReceiptCustomizeValues {
import { BrandingTemplateValues } from "@/containers/BrandingTemplates/types";
export interface ReceiptCustomizeValues extends BrandingTemplateValues {
// Colors
primaryColor?: string;
secondaryColor?: string;

View File

@@ -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>
}