feat: element customize component

This commit is contained in:
Ahmed Bouhuolia
2024-09-09 21:07:22 +02:00
parent dc18bde6be
commit f644ed6708
25 changed files with 319 additions and 292 deletions

View File

@@ -11,9 +11,9 @@ import {
import { HexColorPicker } from 'react-colorful'; import { HexColorPicker } from 'react-colorful';
import { useUncontrolled } from '@/hooks/useUncontrolled'; import { useUncontrolled } from '@/hooks/useUncontrolled';
import { Box, BoxProps } from '@/components'; import { Box, BoxProps } from '@/components';
import styles from './ColorField.module.scss'; import styles from './ColorInput.module.scss';
export interface ColorFieldProps { export interface ColorInputProps {
value?: string; value?: string;
initialValue?: string; initialValue?: string;
onChange?: (value: string) => void; onChange?: (value: string) => void;
@@ -23,7 +23,7 @@ export interface ColorFieldProps {
pickerWrapProps?: Partial<BoxProps>; pickerWrapProps?: Partial<BoxProps>;
} }
export function ColorField({ export function ColorInput({
value, value,
initialValue, initialValue,
onChange, onChange,
@@ -31,7 +31,7 @@ export function ColorField({
inputProps, inputProps,
pickerWrapProps, pickerWrapProps,
pickerProps, pickerProps,
}: ColorFieldProps) { }: ColorInputProps) {
const [_value, handleChange] = useUncontrolled({ const [_value, handleChange] = useUncontrolled({
value, value,
initialValue, initialValue,

View File

@@ -2,27 +2,27 @@ import React from 'react';
import { getIn, FieldConfig, FieldProps } from 'formik'; import { getIn, FieldConfig, FieldProps } from 'formik';
import { Intent } from '@blueprintjs/core'; import { Intent } from '@blueprintjs/core';
import { Field } from '@blueprintjs-formik/core'; import { Field } from '@blueprintjs-formik/core';
import { ColorField, ColorFieldProps } from './ColorField'; import { ColorInput, ColorInputProps } from './ColorInput';
interface ColorFieldInputGroupProps interface ColorInputInputGroupProps
extends Omit<FieldConfig, 'children' | 'component' | 'as' | 'value'>, extends Omit<FieldConfig, 'children' | 'component' | 'as' | 'value'>,
ColorFieldProps {} ColorInputProps {}
export interface ColorFieldToInputProps export interface ColorInputToInputProps
extends Omit<FieldProps, 'onChange'>, extends Omit<FieldProps, 'onChange'>,
ColorFieldProps {} ColorInputProps {}
/** /**
* Transforms field props to input group props for ColorField. * Transforms field props to input group props for ColorInput.
* @param {ColorFieldToInputProps} * @param {ColorInputToInputProps}
* @returns {ColorFieldProps} * @returns {ColorInputProps}
*/ */
function fieldToColorFieldInputGroup({ function fieldToColorInputInputGroup({
field: { onBlur: onFieldBlur, onChange: onFieldChange, value, ...field }, field: { onBlur: onFieldBlur, onChange: onFieldChange, value, ...field },
form: { touched, errors, setFieldValue }, form: { touched, errors, setFieldValue },
onChange, onChange,
...props ...props
}: ColorFieldToInputProps): ColorFieldProps { }: ColorInputToInputProps): ColorInputProps {
const fieldError = getIn(errors, field.name); const fieldError = getIn(errors, field.name);
const showError = getIn(touched, field.name) && !!fieldError; const showError = getIn(touched, field.name) && !!fieldError;
@@ -42,23 +42,23 @@ function fieldToColorFieldInputGroup({
} }
/** /**
* Transforms field props to input group props for ColorField. * Transforms field props to input group props for ColorInput.
* @param {ColorFieldToInputProps} props - * @param {ColorInputToInputProps} props -
* @returns {JSX.Element} * @returns {JSX.Element}
*/ */
function ColorFieldToInputGroup({ function ColorInputToInputGroup({
...props ...props
}: ColorFieldToInputProps): JSX.Element { }: ColorInputToInputProps): JSX.Element {
return <ColorField {...fieldToColorFieldInputGroup(props)} />; return <ColorInput {...fieldToColorInputInputGroup(props)} />;
} }
/** /**
* Input group Blueprint component binded with Formik for ColorField. * Input group Blueprint component binded with Formik for ColorInput.
* @param {ColorFieldInputGroupProps} * @param {ColorInputInputGroupProps}
* @returns {JSX.Element} * @returns {JSX.Element}
*/ */
export function FColorInput({ export function FColorInput({
...props ...props
}: ColorFieldInputGroupProps): JSX.Element { }: ColorInputInputGroupProps): JSX.Element {
return <Field {...props} component={ColorFieldToInputGroup} />; return <Field {...props} component={ColorInputToInputGroup} />;
} }

View File

@@ -0,0 +1,24 @@
.root {
background: #fff;
}
.mainFields{
width: 400px;
height: 100vh;
}
.fieldGroup {
:global .bp4-form-content{
margin-left: auto;
}
}
.footerActions{
padding: 10px 16px;
border-top: 1px solid #d9d9d9;
flex-flow: row-reverse;
}
.showCompanyLogoField:global(.bp4-large){
font-size: 14px;
}

View File

@@ -0,0 +1,74 @@
import React from 'react';
import { Box, Group } from '@/components';
import { ElementCustomizeProvider } from './ElementCustomizeProvider';
import {
ElementCustomizeForm,
ElementCustomizeFormProps,
} from './ElementCustomizerForm';
import { ElementCustomizeTabsControllerProvider } from './ElementCustomizeTabsController';
import { ElementCustomizeFields } from './ElementCustomizeFields';
import { ElementCustomizePreview } from './ElementCustomizePreview';
import { extractChildren } from '@/utils/extract-children';
export interface ElementCustomizeProps<T> extends ElementCustomizeFormProps<T> {
children?: React.ReactNode;
}
export function ElementCustomize<T>({
initialValues,
validationSchema,
onSubmit,
children,
}: ElementCustomizeProps<T>) {
const PaperTemplate = React.useMemo(
() => extractChildren(children, ElementCustomize.PaperTemplate),
[children],
);
const CustomizeTabs = React.useMemo(
() => extractChildren(children, ElementCustomize.FieldsTab),
[children],
);
const value = { PaperTemplate, CustomizeTabs };
return (
<ElementCustomizeForm
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={onSubmit}
>
<ElementCustomizeTabsControllerProvider>
<ElementCustomizeProvider value={value}>
<Group spacing={0} align="stretch">
<ElementCustomizeFields />
<ElementCustomizePreview />
</Group>
</ElementCustomizeProvider>
</ElementCustomizeTabsControllerProvider>
</ElementCustomizeForm>
);
}
export interface ElementCustomizePaperTemplateProps {
children?: React.ReactNode;
}
ElementCustomize.PaperTemplate = ({
children,
}: ElementCustomizePaperTemplateProps) => {
return <Box>{children}</Box>;
};
export interface ElementCustomizeContentProps {
id: string;
label: string;
children?: React.ReactNode;
}
ElementCustomize.FieldsTab = ({
id,
label,
children,
}: ElementCustomizeContentProps) => {
return <Box>{children}</Box>;
};

View File

@@ -2,28 +2,28 @@
import React from 'react'; import React from 'react';
import * as R from 'ramda'; import * as R from 'ramda';
import { Button, Intent } from '@blueprintjs/core'; import { Button, Intent } from '@blueprintjs/core';
import { Group, Stack } from '@/components';
import { InvoiceCustomizeHeader } from './InvoiceCustomizeHeader';
import { InvoiceCustomizeTabs } from './InvoiceCustomizeTabs';
import { useInvoiceCustomizeTabsController } from './InvoiceCustomizeTabsController';
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
import { useFormikContext } from 'formik'; import { useFormikContext } from 'formik';
import { useInvoiceCustomizeContext } from './InvoiceCustomizeProvider'; import { Group, Stack } from '@/components';
import styles from './InvoiceCustomizeFields.module.scss'; import { ElementCustomizeHeader } from './ElementCustomizeHeader';
import { ElementCustomizeTabs } from './ElementCustomizeTabs';
import { useElementCustomizeTabsController } from './ElementCustomizeTabsController';
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
import { useElementCustomizeContext } from './ElementCustomizeProvider';
import withDrawerActions from '@/containers/Drawer/withDrawerActions'; import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import styles from './ElementCustomize.module.scss';
export function InvoiceCustomizeFields() { export function ElementCustomizeFields() {
return ( return (
<Group spacing={0} align={'stretch'} className={styles.root}> <Group spacing={0} align={'stretch'} className={styles.root}>
<InvoiceCustomizeTabs /> <ElementCustomizeTabs />
<InvoiceCustomizeFieldsMain /> <ElementCustomizeFieldsMain />
</Group> </Group>
); );
} }
export function InvoiceCustomizeFieldsMain() { export function ElementCustomizeFieldsMain() {
const { currentTabId } = useInvoiceCustomizeTabsController(); const { currentTabId } = useElementCustomizeTabsController();
const { CustomizeTabs } = useInvoiceCustomizeContext(); const { CustomizeTabs } = useElementCustomizeContext();
const CustomizeTabPanel = React.useMemo( const CustomizeTabPanel = React.useMemo(
() => () =>
@@ -35,17 +35,17 @@ export function InvoiceCustomizeFieldsMain() {
return ( return (
<Stack spacing={0} className={styles.mainFields}> <Stack spacing={0} className={styles.mainFields}>
<InvoiceCustomizeHeader label={'Customize'} /> <ElementCustomizeHeader label={'Customize'} />
<Stack spacing={0} style={{ flex: '1 1 auto', overflow: 'auto' }}> <Stack spacing={0} style={{ flex: '1 1 auto', overflow: 'auto' }}>
{CustomizeTabPanel} {CustomizeTabPanel}
<InvoiceCustomizeFooterActions /> <ElementCustomizeFooterActions />
</Stack> </Stack>
</Stack> </Stack>
); );
} }
function InvoiceCustomizeFooterActionsRoot({ closeDrawer }) { function ElementCustomizeFooterActionsRoot({ closeDrawer }) {
const { name } = useDrawerContext(); const { name } = useDrawerContext();
const { submitForm } = useFormikContext(); const { submitForm } = useFormikContext();
@@ -70,6 +70,6 @@ function InvoiceCustomizeFooterActionsRoot({ closeDrawer }) {
); );
} }
const InvoiceCustomizeFooterActions = R.compose(withDrawerActions)( const ElementCustomizeFooterActions = R.compose(withDrawerActions)(
InvoiceCustomizeFooterActionsRoot, ElementCustomizeFooterActionsRoot,
); );

View File

@@ -1,20 +1,20 @@
import { Group, Icon } from '@/components';
import { Button, Classes } from '@blueprintjs/core'; import { Button, Classes } from '@blueprintjs/core';
import styles from './InvoiceCustomizeHeader.module.scss'; import { Group, Icon } from '@/components';
import styles from './ElementCustomizeHeader.module.scss';
interface InvoiceCustomizeHeaderProps { interface ElementCustomizeHeaderProps {
label?: string; label?: string;
children?: React.ReactNode; children?: React.ReactNode;
closeButton?: boolean; closeButton?: boolean;
onClose?: () => void; onClose?: () => void;
} }
export function InvoiceCustomizeHeader({ export function ElementCustomizeHeader({
label, label,
closeButton, closeButton,
onClose, onClose,
children, children,
}: InvoiceCustomizeHeaderProps) { }: ElementCustomizeHeaderProps) {
const handleClose = () => { const handleClose = () => {
onClose && onClose(); onClose && onClose();
}; };

View File

@@ -1,29 +1,32 @@
// @ts-nocheck // @ts-nocheck
import * as R from 'ramda'; import * as R from 'ramda';
import { Stack } from '@/components'; import { Stack } from '@/components';
import { InvoiceCustomizeHeader } from './InvoiceCustomizeHeader'; import { ElementCustomizeHeader } from './ElementCustomizeHeader';
import { InvoiceCustomizePreviewContent } from './InvoiceCustomizePreviewContent'; import { ElementCustomizePreviewContent } from './ElementCustomizePreviewContent';
import { useDrawerContext } from '@/components/Drawer/DrawerProvider'; import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
import withDrawerActions from '@/containers/Drawer/withDrawerActions'; import withDrawerActions from '@/containers/Drawer/withDrawerActions';
function InvoiceCustomizePreviewRoot({ closeDrawer }) { function ElementCustomizePreviewRoot({ closeDrawer }) {
const { name } = useDrawerContext(); const { name } = useDrawerContext();
const handleCloseBtnClick = () => { const handleCloseBtnClick = () => {
closeDrawer(name); closeDrawer(name);
}; };
return ( return (
<Stack spacing={0} style={{ borderLeft: '1px solid #D9D9D9', height: '100vh', flex: '1 1' }}> <Stack
<InvoiceCustomizeHeader spacing={0}
style={{ borderLeft: '1px solid #D9D9D9', height: '100vh', flex: '1 1' }}
>
<ElementCustomizeHeader
label={'Preview'} label={'Preview'}
closeButton closeButton
onClose={handleCloseBtnClick} onClose={handleCloseBtnClick}
/> />
<InvoiceCustomizePreviewContent /> <ElementCustomizePreviewContent />
</Stack> </Stack>
); );
} }
export const InvoiceCustomizePreview = R.compose(withDrawerActions)( export const ElementCustomizePreview = R.compose(withDrawerActions)(
InvoiceCustomizePreviewRoot, ElementCustomizePreviewRoot,
); );

View File

@@ -1,8 +1,8 @@
import { Box } from '@/components'; import { Box } from '@/components';
import { useInvoiceCustomizeContext } from './InvoiceCustomizeProvider'; import { useElementCustomizeContext } from './ElementCustomizeProvider';
export function InvoiceCustomizePreviewContent() { export function ElementCustomizePreviewContent() {
const { PaperTemplate } = useInvoiceCustomizeContext(); const { PaperTemplate } = useElementCustomizeContext();
return ( return (
<Box <Box

View File

@@ -0,0 +1,32 @@
import React, { createContext, useContext } from 'react';
interface ElementCustomizeValue {
PaperTemplate?: React.ReactNode;
CustomizeTabs: React.ReactNode;
}
const ElementCustomizeContext = createContext<ElementCustomizeValue>(
{} as ElementCustomizeValue,
);
export const ElementCustomizeProvider: React.FC<{
value: ElementCustomizeValue;
children: React.ReactNode;
}> = ({ value, children }) => {
return (
<ElementCustomizeContext.Provider value={{ ...value }}>
{children}
</ElementCustomizeContext.Provider>
);
};
export const useElementCustomizeContext = (): ElementCustomizeValue => {
const context = useContext<ElementCustomizeValue>(ElementCustomizeContext);
if (!context) {
throw new Error(
'useElementCustomize must be used within an ElementCustomizeProvider',
);
}
return context;
};

View File

@@ -1,28 +1,28 @@
import React from 'react';
import { Box, Stack } from '@/components'; import { Box, Stack } from '@/components';
import { Tab, Tabs } from '@blueprintjs/core'; import { Tab, Tabs } from '@blueprintjs/core';
import { InvoiceCustomizeHeader } from './InvoiceCustomizeHeader'; import { ElementCustomizeHeader } from './ElementCustomizeHeader';
import { import {
InvoiceCustomizeTabsEnum, ElementCustomizeTabsEnum,
useInvoiceCustomizeTabsController, useElementCustomizeTabsController,
} from './InvoiceCustomizeTabsController'; } from './ElementCustomizeTabsController';
import styles from './InvoiceCustomizeTabs.module.scss'; import { useElementCustomizeContext } from './ElementCustomizeProvider';
import { useInvoiceCustomizeContext } from './InvoiceCustomizeProvider'; import styles from './ElementCustomizeTabs.module.scss';
import React from 'react';
export function InvoiceCustomizeTabs() { export function ElementCustomizeTabs() {
const { setCurrentTabId } = useInvoiceCustomizeTabsController(); const { setCurrentTabId } = useElementCustomizeTabsController();
const { CustomizeTabs } = useInvoiceCustomizeContext(); const { CustomizeTabs } = useElementCustomizeContext();
const tabItems = React.Children.map(CustomizeTabs, (node) => ({ const tabItems = React.Children.map(CustomizeTabs, (node) => ({
...(React.isValidElement(node) ? node.props : {}), ...(React.isValidElement(node) ? node.props : {}),
})); }));
const handleChange = (value: InvoiceCustomizeTabsEnum) => { const handleChange = (value: ElementCustomizeTabsEnum) => {
setCurrentTabId(value); setCurrentTabId(value);
}; };
return ( return (
<Stack spacing={0} className={styles.root}> <Stack spacing={0} className={styles.root}>
<InvoiceCustomizeHeader label={''} /> <ElementCustomizeHeader label={''} />
<Box className={styles.content}> <Box className={styles.content}>
<Tabs <Tabs

View File

@@ -0,0 +1,46 @@
import React, { createContext, useContext, useState } from 'react';
export enum ElementCustomizeTabsEnum {
General = 'general',
Items = 'items',
Totals = 'totals'
}
const DEFAULT_TAB_ID = ElementCustomizeTabsEnum.General;
interface ElementCustomizeTabsControllerValue {
currentTabId: ElementCustomizeTabsEnum;
setCurrentTabId: React.Dispatch<
React.SetStateAction<ElementCustomizeTabsEnum>
>;
}
const ElementCustomizeTabsController = createContext(
{} as ElementCustomizeTabsControllerValue,
);
export const useElementCustomizeTabsController = () => {
return useContext(ElementCustomizeTabsController);
};
interface ElementCustomizeTabsControllerProps {
children: React.ReactNode;
}
export const ElementCustomizeTabsControllerProvider = ({
children,
}: ElementCustomizeTabsControllerProps) => {
const [currentTabId, setCurrentTabId] =
useState<ElementCustomizeTabsEnum>(DEFAULT_TAB_ID);
const value = {
currentTabId,
setCurrentTabId,
};
return (
<ElementCustomizeTabsController.Provider value={value}>
{children}
</ElementCustomizeTabsController.Provider>
);
};

View File

@@ -2,19 +2,19 @@
import React from 'react'; import React from 'react';
import { Formik, Form, FormikHelpers } from 'formik'; import { Formik, Form, FormikHelpers } from 'formik';
export interface InvoiceCustomizeFormProps<T> { export interface ElementCustomizeFormProps<T> {
initialValues?: T; initialValues?: T;
validationSchema?: any; validationSchema?: any;
onSubmit?: (values: T, formikHelpers: FormikHelpers<T>) => void; onSubmit?: (values: T, formikHelpers: FormikHelpers<T>) => void;
children?: React.ReactNode; children?: React.ReactNode;
} }
export function InvoiceCustomizeForm<T>({ export function ElementCustomizeForm<T>({
initialValues, initialValues,
validationSchema, validationSchema,
onSubmit, onSubmit,
children, children,
}: InvoiceCustomizeFormProps<T>) { }: ElementCustomizeFormProps<T>) {
return ( return (
<Formik<T> <Formik<T>
initialValues={{ ...initialValues }} initialValues={{ ...initialValues }}

View File

@@ -1,74 +1,65 @@
import React from 'react'; import React from 'react';
import { Box, Group } from '@/components'; import { Box } from '@/components';
import { InvoiceCustomizeProvider } from './InvoiceCustomizeProvider'; import { Classes } from '@blueprintjs/core';
import { import { InvoicePaperTemplate } from './InvoicePaperTemplate';
InvoiceCustomizeForm, import { ElementCustomize } from '../../../ElementCustomize/ElementCustomize';
InvoiceCustomizeFormProps, import { InvoiceCustomizeGeneralField } from './InvoiceCustomizeGeneralFields';
} from './InvoiceCustomizerForm'; import { InvoiceCustomizeContentFields } from './InvoiceCutomizeContentFields';
import { InvoiceCustomizeTabsControllerProvider } from './InvoiceCustomizeTabsController';
import { InvoiceCustomizeFields } from './InvoiceCustomizeFields';
import { InvoiceCustomizePreview } from './InvoiceCustomizePreview';
import { extractChildren } from '@/utils/extract-children';
export interface InvoiceCustomizeProps<T> extends InvoiceCustomizeFormProps<T> { interface InvoiceCustomizeValues {
children?: React.ReactNode; invoiceNumber?: string;
invoiceNumberLabel?: string;
dateIssue?: string;
dateIssueLabel?: string;
dueDate?: string;
dueDateLabel?: string;
companyName?: string;
bigtitle?: string;
itemRateLabel?: string;
itemQuantityLabel?: string;
itemTotalLabel?: string;
// Totals
showDueAmount?: boolean;
showDiscount?: boolean;
showPaymentMade?: boolean;
showTaxes?: boolean;
showSubtotal?: boolean;
showTotal?: boolean;
showBalanceDue?: boolean;
paymentMadeLabel?: string;
discountLabel?: string;
subtotalLabel?: string;
totalLabel?: string;
balanceDueLabel?: string;
} }
export function InvoiceCustomize<T>({ export default function InvoiceCustomizeContent() {
initialValues,
validationSchema,
onSubmit,
children,
}: InvoiceCustomizeProps<T>) {
const PaperTemplate = React.useMemo(
() => extractChildren(children, InvoiceCustomize.PaperTemplate),
[children],
);
const CustomizeTabs = React.useMemo(
() => extractChildren(children, InvoiceCustomize.FieldsTab),
[children],
);
const value = { PaperTemplate, CustomizeTabs };
return ( return (
<InvoiceCustomizeForm <Box className={Classes.DRAWER_BODY}>
initialValues={initialValues} <ElementCustomize<InvoiceCustomizeValues>>
validationSchema={validationSchema} <ElementCustomize.PaperTemplate>
onSubmit={onSubmit} <InvoicePaperTemplate />
> </ElementCustomize.PaperTemplate>
<InvoiceCustomizeTabsControllerProvider>
<InvoiceCustomizeProvider value={value}> <ElementCustomize.FieldsTab id={'general'} label={'General'}>
<Group spacing={0} align="stretch"> <InvoiceCustomizeGeneralField />
<InvoiceCustomizeFields /> </ElementCustomize.FieldsTab>
<InvoiceCustomizePreview />
</Group> <ElementCustomize.FieldsTab id={'content'} label={'Content'}>
</InvoiceCustomizeProvider> <InvoiceCustomizeContentFields />
</InvoiceCustomizeTabsControllerProvider> </ElementCustomize.FieldsTab>
</InvoiceCustomizeForm>
<ElementCustomize.FieldsTab id={'totals'} label={'Totals'}>
asdfasdfdsaf #3
</ElementCustomize.FieldsTab>
</ElementCustomize>
</Box>
); );
} }
export interface InvoiceCustomizePaperTemplateProps {
children?: React.ReactNode;
}
InvoiceCustomize.PaperTemplate = ({
children,
}: InvoiceCustomizePaperTemplateProps) => {
return <Box>{children}</Box>;
};
export interface InvoiceCustomizeContentProps {
id: string;
label: string;
children?: React.ReactNode;
}
InvoiceCustomize.FieldsTab = ({
id,
label,
children,
}: InvoiceCustomizeContentProps) => {
return <Box>{children}</Box>;
};

View File

@@ -1,65 +0,0 @@
import React from 'react';
import { Box } from '@/components';
import { Classes } from '@blueprintjs/core';
import { InvoicePaperTemplate } from './InvoicePaperTemplate';
import { InvoiceCustomize } from './InvoiceCustomize';
import { InvoiceCustomizeGeneralField } from './InvoiceCustomizeGeneralFields';
import { InvoiceCustomizeContentFields } from './InvoiceCutomizeContentFields';
interface InvoiceCustomizeValues {
invoiceNumber?: string;
invoiceNumberLabel?: string;
dateIssue?: string;
dateIssueLabel?: string;
dueDate?: string;
dueDateLabel?: string;
companyName?: string;
bigtitle?: string;
itemRateLabel?: string;
itemQuantityLabel?: string;
itemTotalLabel?: string;
// Totals
showDueAmount?: boolean;
showDiscount?: boolean;
showPaymentMade?: boolean;
showTaxes?: boolean;
showSubtotal?: boolean;
showTotal?: boolean;
showBalanceDue?: boolean;
paymentMadeLabel?: string;
discountLabel?: string;
subtotalLabel?: string;
totalLabel?: string;
balanceDueLabel?: string;
}
export default function InvoiceCustomizeContent() {
return (
<Box className={Classes.DRAWER_BODY}>
<InvoiceCustomize<InvoiceCustomizeValues>>
<InvoiceCustomize.PaperTemplate>
<InvoicePaperTemplate />
</InvoiceCustomize.PaperTemplate>
<InvoiceCustomize.FieldsTab id={'general'} label={'General'}>
<InvoiceCustomizeGeneralField />
</InvoiceCustomize.FieldsTab>
<InvoiceCustomize.FieldsTab id={'content'} label={'Content'}>
<InvoiceCustomizeContentFields />
</InvoiceCustomize.FieldsTab>
<InvoiceCustomize.FieldsTab id={'totals'} label={'Totals'}>
asdfasdfdsaf #3
</InvoiceCustomize.FieldsTab>
</InvoiceCustomize>
</Box>
);
}

View File

@@ -4,8 +4,8 @@ import * as R from 'ramda';
import { Drawer, DrawerSuspense } from '@/components'; import { Drawer, DrawerSuspense } from '@/components';
import withDrawers from '@/containers/Drawer/withDrawers'; import withDrawers from '@/containers/Drawer/withDrawers';
const InvoiceCustomizeContent = React.lazy( const InvoiceCustomize = React.lazy(
() => import('./InvoiceCustomizeContent'), () => import('./InvoiceCustomize'),
); );
/** /**
@@ -21,7 +21,7 @@ function InvoiceCustomizeDrawerRoot({
return ( return (
<Drawer isOpen={isOpen} name={name} size={'100%'}> <Drawer isOpen={isOpen} name={name} size={'100%'}>
<DrawerSuspense> <DrawerSuspense>
<InvoiceCustomizeContent /> <InvoiceCustomize />
</DrawerSuspense> </DrawerSuspense>
</Drawer> </Drawer>
); );

View File

@@ -1,9 +1,9 @@
// @ts-nocheck // @ts-nocheck
import { Box, FFormGroup, FSwitch, Group, Stack } from '@/components';
import { FColorInput } from './FColorField';
import styles from './InvoiceCustomizeFields.module.scss';
import { Classes, Text } from '@blueprintjs/core'; import { Classes, Text } from '@blueprintjs/core';
import { CreditCardIcon } from './CreditCardIcon'; import { FFormGroup, FSwitch, Group, Stack } from '@/components';
import { FColorInput } from '@/components/Forms/FColorInput';
import { CreditCardIcon } from '@/icons/CreditCardIcon';
import styles from './InvoiceCustomizeFields.module.scss';
export function InvoiceCustomizeGeneralField() { export function InvoiceCustomizeGeneralField() {
return ( return (

View File

@@ -1,32 +0,0 @@
import React, { createContext, useContext } from 'react';
interface InvoiceCustomizeValue {
PaperTemplate?: React.ReactNode;
CustomizeTabs: React.ReactNode;
}
const InvoiceCustomizeContext = createContext<InvoiceCustomizeValue>(
{} as InvoiceCustomizeValue,
);
export const InvoiceCustomizeProvider: React.FC<{
value: InvoiceCustomizeValue;
children: React.ReactNode;
}> = ({ value, children }) => {
return (
<InvoiceCustomizeContext.Provider value={{ ...value }}>
{children}
</InvoiceCustomizeContext.Provider>
);
};
export const useInvoiceCustomizeContext = (): InvoiceCustomizeValue => {
const context = useContext<InvoiceCustomizeValue>(InvoiceCustomizeContext);
if (!context) {
throw new Error(
'useInvoiceCustomize must be used within an InvoiceCustomizeProvider',
);
}
return context;
};

View File

@@ -1,46 +0,0 @@
import React, { createContext, useContext, useState } from 'react';
export enum InvoiceCustomizeTabsEnum {
General = 'general',
Items = 'items',
Totals = 'totals'
}
const DEFAULT_TAB_ID = InvoiceCustomizeTabsEnum.General;
interface InvoiceCustomizeTabsControllerValue {
currentTabId: InvoiceCustomizeTabsEnum;
setCurrentTabId: React.Dispatch<
React.SetStateAction<InvoiceCustomizeTabsEnum>
>;
}
const InvoiceCustomizeTabsController = createContext(
{} as InvoiceCustomizeTabsControllerValue,
);
export const useInvoiceCustomizeTabsController = () => {
return useContext(InvoiceCustomizeTabsController);
};
interface InvoiceCustomizeTabsControllerProps {
children: React.ReactNode;
}
export const InvoiceCustomizeTabsControllerProvider = ({
children,
}: InvoiceCustomizeTabsControllerProps) => {
const [currentTabId, setCurrentTabId] =
useState<InvoiceCustomizeTabsEnum>(DEFAULT_TAB_ID);
const value = {
currentTabId,
setCurrentTabId,
};
return (
<InvoiceCustomizeTabsController.Provider value={value}>
{children}
</InvoiceCustomizeTabsController.Provider>
);
};

View File

@@ -1,5 +1,5 @@
import { FInputGroup, FSwitch, Group, Stack } from '@/components';
import { Classes } from '@blueprintjs/core'; import { Classes } from '@blueprintjs/core';
import { FInputGroup, FSwitch, Group, Stack } from '@/components';
const items = [ const items = [
{ key: 'dueAmount', label: 'Due Amount' }, { key: 'dueAmount', label: 'Due Amount' },

View File

@@ -1,5 +1,5 @@
import clsx from 'classnames'; import clsx from 'classnames';
import styles from './PaperTemplate.module.scss'; import styles from './InvoicePaperTemplate.module.scss';
interface PaperTemplateProps { interface PaperTemplateProps {
invoiceNumber?: string; invoiceNumber?: string;