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 { useUncontrolled } from '@/hooks/useUncontrolled';
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;
initialValue?: string;
onChange?: (value: string) => void;
@@ -23,7 +23,7 @@ export interface ColorFieldProps {
pickerWrapProps?: Partial<BoxProps>;
}
export function ColorField({
export function ColorInput({
value,
initialValue,
onChange,
@@ -31,7 +31,7 @@ export function ColorField({
inputProps,
pickerWrapProps,
pickerProps,
}: ColorFieldProps) {
}: ColorInputProps) {
const [_value, handleChange] = useUncontrolled({
value,
initialValue,

View File

@@ -2,27 +2,27 @@ import React from 'react';
import { getIn, FieldConfig, FieldProps } from 'formik';
import { Intent } from '@blueprintjs/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'>,
ColorFieldProps {}
ColorInputProps {}
export interface ColorFieldToInputProps
export interface ColorInputToInputProps
extends Omit<FieldProps, 'onChange'>,
ColorFieldProps {}
ColorInputProps {}
/**
* Transforms field props to input group props for ColorField.
* @param {ColorFieldToInputProps}
* @returns {ColorFieldProps}
* Transforms field props to input group props for ColorInput.
* @param {ColorInputToInputProps}
* @returns {ColorInputProps}
*/
function fieldToColorFieldInputGroup({
function fieldToColorInputInputGroup({
field: { onBlur: onFieldBlur, onChange: onFieldChange, value, ...field },
form: { touched, errors, setFieldValue },
onChange,
...props
}: ColorFieldToInputProps): ColorFieldProps {
}: ColorInputToInputProps): ColorInputProps {
const fieldError = getIn(errors, field.name);
const showError = getIn(touched, field.name) && !!fieldError;
@@ -42,23 +42,23 @@ function fieldToColorFieldInputGroup({
}
/**
* Transforms field props to input group props for ColorField.
* @param {ColorFieldToInputProps} props -
* Transforms field props to input group props for ColorInput.
* @param {ColorInputToInputProps} props -
* @returns {JSX.Element}
*/
function ColorFieldToInputGroup({
function ColorInputToInputGroup({
...props
}: ColorFieldToInputProps): JSX.Element {
return <ColorField {...fieldToColorFieldInputGroup(props)} />;
}: ColorInputToInputProps): JSX.Element {
return <ColorInput {...fieldToColorInputInputGroup(props)} />;
}
/**
* Input group Blueprint component binded with Formik for ColorField.
* @param {ColorFieldInputGroupProps}
* Input group Blueprint component binded with Formik for ColorInput.
* @param {ColorInputInputGroupProps}
* @returns {JSX.Element}
*/
export function FColorInput({
...props
}: ColorFieldInputGroupProps): JSX.Element {
return <Field {...props} component={ColorFieldToInputGroup} />;
}: ColorInputInputGroupProps): JSX.Element {
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 * as R from 'ramda';
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 { useInvoiceCustomizeContext } from './InvoiceCustomizeProvider';
import styles from './InvoiceCustomizeFields.module.scss';
import { Group, Stack } from '@/components';
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 styles from './ElementCustomize.module.scss';
export function InvoiceCustomizeFields() {
export function ElementCustomizeFields() {
return (
<Group spacing={0} align={'stretch'} className={styles.root}>
<InvoiceCustomizeTabs />
<InvoiceCustomizeFieldsMain />
<Group spacing={0} align={'stretch'} className={styles.root}>
<ElementCustomizeTabs />
<ElementCustomizeFieldsMain />
</Group>
);
}
export function InvoiceCustomizeFieldsMain() {
const { currentTabId } = useInvoiceCustomizeTabsController();
const { CustomizeTabs } = useInvoiceCustomizeContext();
export function ElementCustomizeFieldsMain() {
const { currentTabId } = useElementCustomizeTabsController();
const { CustomizeTabs } = useElementCustomizeContext();
const CustomizeTabPanel = React.useMemo(
() =>
@@ -35,17 +35,17 @@ export function InvoiceCustomizeFieldsMain() {
return (
<Stack spacing={0} className={styles.mainFields}>
<InvoiceCustomizeHeader label={'Customize'} />
<ElementCustomizeHeader label={'Customize'} />
<Stack spacing={0} style={{ flex: '1 1 auto', overflow: 'auto' }}>
{CustomizeTabPanel}
<InvoiceCustomizeFooterActions />
<ElementCustomizeFooterActions />
</Stack>
</Stack>
);
}
function InvoiceCustomizeFooterActionsRoot({ closeDrawer }) {
function ElementCustomizeFooterActionsRoot({ closeDrawer }) {
const { name } = useDrawerContext();
const { submitForm } = useFormikContext();
@@ -70,6 +70,6 @@ function InvoiceCustomizeFooterActionsRoot({ closeDrawer }) {
);
}
const InvoiceCustomizeFooterActions = R.compose(withDrawerActions)(
InvoiceCustomizeFooterActionsRoot,
const ElementCustomizeFooterActions = R.compose(withDrawerActions)(
ElementCustomizeFooterActionsRoot,
);

View File

@@ -1,20 +1,20 @@
import { Group, Icon } from '@/components';
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;
children?: React.ReactNode;
closeButton?: boolean;
onClose?: () => void;
}
export function InvoiceCustomizeHeader({
export function ElementCustomizeHeader({
label,
closeButton,
onClose,
children,
}: InvoiceCustomizeHeaderProps) {
}: ElementCustomizeHeaderProps) {
const handleClose = () => {
onClose && onClose();
};

View File

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

View File

@@ -1,8 +1,8 @@
import { Box } from '@/components';
import { useInvoiceCustomizeContext } from './InvoiceCustomizeProvider';
import { useElementCustomizeContext } from './ElementCustomizeProvider';
export function InvoiceCustomizePreviewContent() {
const { PaperTemplate } = useInvoiceCustomizeContext();
export function ElementCustomizePreviewContent() {
const { PaperTemplate } = useElementCustomizeContext();
return (
<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 { Tab, Tabs } from '@blueprintjs/core';
import { InvoiceCustomizeHeader } from './InvoiceCustomizeHeader';
import { ElementCustomizeHeader } from './ElementCustomizeHeader';
import {
InvoiceCustomizeTabsEnum,
useInvoiceCustomizeTabsController,
} from './InvoiceCustomizeTabsController';
import styles from './InvoiceCustomizeTabs.module.scss';
import { useInvoiceCustomizeContext } from './InvoiceCustomizeProvider';
import React from 'react';
ElementCustomizeTabsEnum,
useElementCustomizeTabsController,
} from './ElementCustomizeTabsController';
import { useElementCustomizeContext } from './ElementCustomizeProvider';
import styles from './ElementCustomizeTabs.module.scss';
export function InvoiceCustomizeTabs() {
const { setCurrentTabId } = useInvoiceCustomizeTabsController();
export function ElementCustomizeTabs() {
const { setCurrentTabId } = useElementCustomizeTabsController();
const { CustomizeTabs } = useInvoiceCustomizeContext();
const { CustomizeTabs } = useElementCustomizeContext();
const tabItems = React.Children.map(CustomizeTabs, (node) => ({
...(React.isValidElement(node) ? node.props : {}),
}));
const handleChange = (value: InvoiceCustomizeTabsEnum) => {
const handleChange = (value: ElementCustomizeTabsEnum) => {
setCurrentTabId(value);
};
return (
<Stack spacing={0} className={styles.root}>
<InvoiceCustomizeHeader label={''} />
<ElementCustomizeHeader label={''} />
<Box className={styles.content}>
<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 { Formik, Form, FormikHelpers } from 'formik';
export interface InvoiceCustomizeFormProps<T> {
export interface ElementCustomizeFormProps<T> {
initialValues?: T;
validationSchema?: any;
onSubmit?: (values: T, formikHelpers: FormikHelpers<T>) => void;
children?: React.ReactNode;
}
export function InvoiceCustomizeForm<T>({
export function ElementCustomizeForm<T>({
initialValues,
validationSchema,
onSubmit,
children,
}: InvoiceCustomizeFormProps<T>) {
}: ElementCustomizeFormProps<T>) {
return (
<Formik<T>
initialValues={{ ...initialValues }}

View File

@@ -1,74 +1,65 @@
import React from 'react';
import { Box, Group } from '@/components';
import { InvoiceCustomizeProvider } from './InvoiceCustomizeProvider';
import {
InvoiceCustomizeForm,
InvoiceCustomizeFormProps,
} from './InvoiceCustomizerForm';
import { InvoiceCustomizeTabsControllerProvider } from './InvoiceCustomizeTabsController';
import { InvoiceCustomizeFields } from './InvoiceCustomizeFields';
import { InvoiceCustomizePreview } from './InvoiceCustomizePreview';
import { extractChildren } from '@/utils/extract-children';
import { Box } from '@/components';
import { Classes } from '@blueprintjs/core';
import { InvoicePaperTemplate } from './InvoicePaperTemplate';
import { ElementCustomize } from '../../../ElementCustomize/ElementCustomize';
import { InvoiceCustomizeGeneralField } from './InvoiceCustomizeGeneralFields';
import { InvoiceCustomizeContentFields } from './InvoiceCutomizeContentFields';
export interface InvoiceCustomizeProps<T> extends InvoiceCustomizeFormProps<T> {
children?: React.ReactNode;
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 function InvoiceCustomize<T>({
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 };
export default function InvoiceCustomizeContent() {
return (
<InvoiceCustomizeForm
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={onSubmit}
>
<InvoiceCustomizeTabsControllerProvider>
<InvoiceCustomizeProvider value={value}>
<Group spacing={0} align="stretch">
<InvoiceCustomizeFields />
<InvoiceCustomizePreview />
</Group>
</InvoiceCustomizeProvider>
</InvoiceCustomizeTabsControllerProvider>
</InvoiceCustomizeForm>
<Box className={Classes.DRAWER_BODY}>
<ElementCustomize<InvoiceCustomizeValues>>
<ElementCustomize.PaperTemplate>
<InvoicePaperTemplate />
</ElementCustomize.PaperTemplate>
<ElementCustomize.FieldsTab id={'general'} label={'General'}>
<InvoiceCustomizeGeneralField />
</ElementCustomize.FieldsTab>
<ElementCustomize.FieldsTab id={'content'} label={'Content'}>
<InvoiceCustomizeContentFields />
</ElementCustomize.FieldsTab>
<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 withDrawers from '@/containers/Drawer/withDrawers';
const InvoiceCustomizeContent = React.lazy(
() => import('./InvoiceCustomizeContent'),
const InvoiceCustomize = React.lazy(
() => import('./InvoiceCustomize'),
);
/**
@@ -21,7 +21,7 @@ function InvoiceCustomizeDrawerRoot({
return (
<Drawer isOpen={isOpen} name={name} size={'100%'}>
<DrawerSuspense>
<InvoiceCustomizeContent />
<InvoiceCustomize />
</DrawerSuspense>
</Drawer>
);

View File

@@ -1,9 +1,9 @@
// @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 { 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() {
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 { FInputGroup, FSwitch, Group, Stack } from '@/components';
const items = [
{ key: 'dueAmount', label: 'Due Amount' },

View File

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