mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-20 23:00:34 +00:00
feat: select payment methods dialog
This commit is contained in:
@@ -53,6 +53,7 @@ import { ExportDialog } from '@/containers/Dialogs/ExportDialog';
|
|||||||
import { RuleFormDialog } from '@/containers/Banking/Rules/RuleFormDialog/RuleFormDialog';
|
import { RuleFormDialog } from '@/containers/Banking/Rules/RuleFormDialog/RuleFormDialog';
|
||||||
import { DisconnectBankAccountDialog } from '@/containers/CashFlow/AccountTransactions/dialogs/DisconnectBankAccountDialog/DisconnectBankAccountDialog';
|
import { DisconnectBankAccountDialog } from '@/containers/CashFlow/AccountTransactions/dialogs/DisconnectBankAccountDialog/DisconnectBankAccountDialog';
|
||||||
import { SharePaymentLinkDialog } from '@/containers/PaymentLink/dialogs/SharePaymentLinkDialog/SharePaymentLinkDialog';
|
import { SharePaymentLinkDialog } from '@/containers/PaymentLink/dialogs/SharePaymentLinkDialog/SharePaymentLinkDialog';
|
||||||
|
import { SelectPaymentMethodsDialog } from '@/containers/PaymentLink/dialogs/SelectPaymentMethodsDialog/SelectPaymentMethodsDialog';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dialogs container.
|
* Dialogs container.
|
||||||
@@ -153,6 +154,9 @@ export default function DialogsContainer() {
|
|||||||
dialogName={DialogsName.DisconnectBankAccountConfirmation}
|
dialogName={DialogsName.DisconnectBankAccountConfirmation}
|
||||||
/>
|
/>
|
||||||
<SharePaymentLinkDialog dialogName={DialogsName.SharePaymentLink} />
|
<SharePaymentLinkDialog dialogName={DialogsName.SharePaymentLink} />
|
||||||
|
<SelectPaymentMethodsDialog
|
||||||
|
dialogName={DialogsName.SelectPaymentMethod}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,5 +77,6 @@ export enum DialogsName {
|
|||||||
Export = 'Export',
|
Export = 'Export',
|
||||||
BankRuleForm = 'BankRuleForm',
|
BankRuleForm = 'BankRuleForm',
|
||||||
DisconnectBankAccountConfirmation = 'DisconnectBankAccountConfirmation',
|
DisconnectBankAccountConfirmation = 'DisconnectBankAccountConfirmation',
|
||||||
SharePaymentLink = 'SharePaymentLink'
|
SharePaymentLink = 'SharePaymentLink',
|
||||||
|
SelectPaymentMethod = 'SelectPaymentMethodsDialog',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import {
|
|||||||
Classes,
|
Classes,
|
||||||
NavbarDivider,
|
NavbarDivider,
|
||||||
Intent,
|
Intent,
|
||||||
|
Tooltip,
|
||||||
|
Position,
|
||||||
} from '@blueprintjs/core';
|
} from '@blueprintjs/core';
|
||||||
|
|
||||||
import { useInvoiceDetailDrawerContext } from './InvoiceDetailDrawerProvider';
|
import { useInvoiceDetailDrawerContext } from './InvoiceDetailDrawerProvider';
|
||||||
@@ -32,6 +34,7 @@ import { compose } from '@/utils';
|
|||||||
import { BadDebtMenuItem } from './utils';
|
import { BadDebtMenuItem } from './utils';
|
||||||
import { DRAWERS } from '@/constants/drawers';
|
import { DRAWERS } from '@/constants/drawers';
|
||||||
import { DialogsName } from '@/constants/dialogs';
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
import { ArrowBottomLeft } from '@/icons/ArrowBottomLeft';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoice details action bar.
|
* Invoice details action bar.
|
||||||
@@ -126,7 +129,7 @@ function InvoiceDetailActionsBar({
|
|||||||
<If condition={invoice.is_delivered && !invoice.is_fully_paid}>
|
<If condition={invoice.is_delivered && !invoice.is_fully_paid}>
|
||||||
<Button
|
<Button
|
||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
icon={<Icon icon="arrow-downward" iconSize={18} />}
|
icon={<ArrowBottomLeft size={16} />}
|
||||||
text={<T id={'add_payment'} />}
|
text={<T id={'add_payment'} />}
|
||||||
onClick={handleQuickPaymentInvoice}
|
onClick={handleQuickPaymentInvoice}
|
||||||
/>
|
/>
|
||||||
@@ -157,11 +160,15 @@ function InvoiceDetailActionsBar({
|
|||||||
onClick={handleDeleteInvoice}
|
onClick={handleDeleteInvoice}
|
||||||
/>
|
/>
|
||||||
</Can>
|
</Can>
|
||||||
<Button
|
<NavbarDivider />
|
||||||
className={Classes.MINIMAL}
|
<Tooltip content="Share" position={Position.BOTTOM} minimal>
|
||||||
text={'Share'}
|
<Button
|
||||||
onClick={handleShareButtonClick}
|
className={Classes.MINIMAL}
|
||||||
/>
|
icon={<Icon icon={'share'} iconSize={16} />}
|
||||||
|
onClick={handleShareButtonClick}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
|
||||||
<Can I={SaleInvoiceAction.Writeoff} a={AbilitySubject.Invoice}>
|
<Can I={SaleInvoiceAction.Writeoff} a={AbilitySubject.Invoice}>
|
||||||
<NavbarDivider />
|
<NavbarDivider />
|
||||||
<BadDebtMenuItem
|
<BadDebtMenuItem
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Formik, Form } from 'formik';
|
||||||
|
|
||||||
|
interface SelectPaymentMethodsFormValues {}
|
||||||
|
|
||||||
|
const initialValues: SelectPaymentMethodsFormValues = {};
|
||||||
|
|
||||||
|
export const SelectPaymentMethodsForm: React.FC<{
|
||||||
|
children: React.ReactNode;
|
||||||
|
}> = ({ children }) => {
|
||||||
|
const handleSubmit = (values: SelectPaymentMethodsFormValues) => {};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Formik initialValues={initialValues} onSubmit={handleSubmit}>
|
||||||
|
<Form>{children}</Form>
|
||||||
|
</Formik>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import React, { createContext, useContext, useState, ReactNode } from 'react';
|
||||||
|
|
||||||
|
interface SelectPaymentMethodsContextType {}
|
||||||
|
|
||||||
|
const SelectPaymentMethodsContext =
|
||||||
|
createContext<SelectPaymentMethodsContextType>(
|
||||||
|
{} as SelectPaymentMethodsContextType,
|
||||||
|
);
|
||||||
|
|
||||||
|
export const useSelectPaymentMethods = () => {
|
||||||
|
const context = useContext(SelectPaymentMethodsContext);
|
||||||
|
|
||||||
|
if (!context) {
|
||||||
|
throw new Error(
|
||||||
|
'useSelectPaymentMethods must be used within a SelectPaymentMethodsProvider',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface SelectPaymentMethodsProviderProps {
|
||||||
|
children: ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SelectPaymentMethodsBoot: React.FC<
|
||||||
|
SelectPaymentMethodsProviderProps
|
||||||
|
> = ({ children }) => {
|
||||||
|
return (
|
||||||
|
<SelectPaymentMethodsContext.Provider
|
||||||
|
value={{ }}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</SelectPaymentMethodsContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
import { SelectPaymentMethodsBoot } from './SelectPaymentMethodsBoot';
|
||||||
|
import { SelectPaymentMethodsForm } from './SelectPaymemtMethodsForm';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import { Group, Stack } from '@/components';
|
||||||
|
import {
|
||||||
|
DialogFooter,
|
||||||
|
Button,
|
||||||
|
Checkbox,
|
||||||
|
DialogBody,
|
||||||
|
Intent,
|
||||||
|
Text,
|
||||||
|
} from '@blueprintjs/core';
|
||||||
|
import { useDialogActions } from '@/hooks/state';
|
||||||
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
import { useUncontrolled } from '@/hooks/useUncontrolled';
|
||||||
|
|
||||||
|
export function SelectPaymentMethodsContent() {
|
||||||
|
const { closeDialog } = useDialogActions();
|
||||||
|
|
||||||
|
const handleCancelBtnClick = () => {
|
||||||
|
closeDialog(DialogsName.SelectPaymentMethod);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<SelectPaymentMethodsBoot>
|
||||||
|
<SelectPaymentMethodsForm>
|
||||||
|
<DialogBody>
|
||||||
|
<Stack spacing={12}>
|
||||||
|
<PaymentMethodSelect
|
||||||
|
label={'Card (Including Apple Pay, Google Pay and Link)'}
|
||||||
|
/>
|
||||||
|
<PaymentMethodSelect
|
||||||
|
label={'Card (Including Apple Pay, Google Pay and Link)'}
|
||||||
|
/>
|
||||||
|
<PaymentMethodSelect
|
||||||
|
label={'Card (Including Apple Pay, Google Pay and Link)'}
|
||||||
|
/>
|
||||||
|
<PaymentMethodSelect
|
||||||
|
label={'Card (Including Apple Pay, Google Pay and Link)'}
|
||||||
|
/>
|
||||||
|
<PaymentMethodSelect
|
||||||
|
label={'Card (Including Apple Pay, Google Pay and Link)'}
|
||||||
|
/>
|
||||||
|
<PaymentMethodSelect
|
||||||
|
label={'Card (Including Apple Pay, Google Pay and Link)'}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
</DialogBody>
|
||||||
|
|
||||||
|
<DialogFooter
|
||||||
|
actions={
|
||||||
|
<>
|
||||||
|
<Button onClick={handleCancelBtnClick}>Cancel</Button>
|
||||||
|
<Button intent={Intent.PRIMARY}>Submit</Button>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
></DialogFooter>
|
||||||
|
</SelectPaymentMethodsForm>
|
||||||
|
</SelectPaymentMethodsBoot>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PaymentMethodSelectProps {
|
||||||
|
label: string;
|
||||||
|
value?: boolean;
|
||||||
|
initialValue?: boolean;
|
||||||
|
onChange?: (value: boolean) => void;
|
||||||
|
}
|
||||||
|
function PaymentMethodSelect({
|
||||||
|
value,
|
||||||
|
initialValue,
|
||||||
|
onChange,
|
||||||
|
label,
|
||||||
|
}: PaymentMethodSelectProps) {
|
||||||
|
const [_value, handleChange] = useUncontrolled<boolean>({
|
||||||
|
value,
|
||||||
|
initialValue,
|
||||||
|
finalValue: false,
|
||||||
|
onChange,
|
||||||
|
});
|
||||||
|
const handleClick = () => {
|
||||||
|
handleChange(!_value);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PaymentMethodSelectRoot onClick={handleClick}>
|
||||||
|
<PaymentMethodCheckbox
|
||||||
|
label={''}
|
||||||
|
checked={_value}
|
||||||
|
onClick={handleClick}
|
||||||
|
/>
|
||||||
|
<PaymentMethodText>{label}</PaymentMethodText>
|
||||||
|
</PaymentMethodSelectRoot>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const PaymentMethodSelectRoot = styled(Group)`
|
||||||
|
border: 1px solid #d3d8de;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 10px;
|
||||||
|
gap: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const PaymentMethodCheckbox = styled(Checkbox)`
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
&.bp4-control .bp4-control-indicator {
|
||||||
|
box-shadow: 0 0 0 1px #c5cbd3;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const PaymentMethodText = styled(Text)`
|
||||||
|
color: #404854;
|
||||||
|
`;
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import React from 'react';
|
||||||
|
import { Dialog, DialogSuspense } from '@/components';
|
||||||
|
import withDialogRedux from '@/components/DialogReduxConnect';
|
||||||
|
import { compose } from '@/utils';
|
||||||
|
|
||||||
|
const SelectPaymentMethodsDialogContent = React.lazy(() =>
|
||||||
|
import('./SelectPaymentMethodsContent').then((module) => ({
|
||||||
|
default: module.SelectPaymentMethodsContent,
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select payment methods dialogs.
|
||||||
|
*/
|
||||||
|
function SelectPaymentMethodsDialogRoot({ dialogName, payload, isOpen }) {
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
name={dialogName}
|
||||||
|
isOpen={isOpen}
|
||||||
|
payload={payload}
|
||||||
|
title={'Share Link'}
|
||||||
|
canEscapeJeyClose={true}
|
||||||
|
autoFocus={true}
|
||||||
|
style={{ width: 570 }}
|
||||||
|
>
|
||||||
|
<DialogSuspense>
|
||||||
|
<SelectPaymentMethodsDialogContent />
|
||||||
|
</DialogSuspense>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SelectPaymentMethodsDialog = compose(withDialogRedux())(
|
||||||
|
SelectPaymentMethodsDialogRoot,
|
||||||
|
);
|
||||||
|
|
||||||
|
SelectPaymentMethodsDialog.displayName = 'SelectPaymentMethodsDialog';
|
||||||
@@ -3,10 +3,22 @@ import React from 'react';
|
|||||||
import intl from 'react-intl-universal';
|
import intl from 'react-intl-universal';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { FFormGroup, FEditableText, FormattedMessage as T } from '@/components';
|
import { FFormGroup, FEditableText, FormattedMessage as T } from '@/components';
|
||||||
|
import { useDialogActions } from '@/hooks/state';
|
||||||
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
|
||||||
export function InvoiceFormFooterLeft() {
|
export function InvoiceFormFooterLeft() {
|
||||||
|
const { openDialog } = useDialogActions();
|
||||||
|
|
||||||
|
const handleSelectPaymentMethodsClick = () => {
|
||||||
|
openDialog(DialogsName.SelectPaymentMethod, {});
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
|
<FFormGroup label={'Payment Options'} name={'payment_method_id'}>
|
||||||
|
<a href={'#'} onClick={handleSelectPaymentMethodsClick}>Payment Options</a>
|
||||||
|
</FFormGroup>
|
||||||
|
|
||||||
{/* --------- Invoice message --------- */}
|
{/* --------- Invoice message --------- */}
|
||||||
<InvoiceMsgFormGroup
|
<InvoiceMsgFormGroup
|
||||||
name={'invoice_message'}
|
name={'invoice_message'}
|
||||||
|
|||||||
28
packages/webapp/src/icons/ArrowBottomLeft.tsx
Normal file
28
packages/webapp/src/icons/ArrowBottomLeft.tsx
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
interface ArrowBottomLeftProps extends React.SVGProps<SVGSVGElement> {
|
||||||
|
size?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ArrowBottomLeft: React.FC<ArrowBottomLeftProps> = ({
|
||||||
|
size = 16,
|
||||||
|
...props
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
width={size}
|
||||||
|
height={size}
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fillRule="evenodd"
|
||||||
|
clipRule="evenodd"
|
||||||
|
d="M14 3C14 2.45 13.55 2 13 2C12.72 2 12.47 2.11 12.29 2.29L4 10.59V6C4 5.45 3.55 5 3 5S2 5.45 2 6V13C2 13.55 2.45 14 3 14H10C10.55 14 11 13.55 11 13C11 12.45 10.55 12 10 12H5.41L13.7 3.71C13.89 3.53 14 3.28 14 3Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user