Compare commits
1 Commits
auth-pages
...
organize-p
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
96b16831e9 |
@@ -204,10 +204,7 @@ module.exports = {
|
||||
plaid: {
|
||||
env: process.env.PLAID_ENV || 'sandbox',
|
||||
clientId: process.env.PLAID_CLIENT_ID,
|
||||
secretDevelopment: process.env.PLAID_SECRET_DEVELOPMENT,
|
||||
secretSandbox: process.env.PLAID_SECRET_SANDBOX,
|
||||
redirectSandBox: process.env.PLAID_SANDBOX_REDIRECT_URI,
|
||||
redirectDevelopment: process.env.PLAID_DEVELOPMENT_REDIRECT_URI,
|
||||
secret: process.env.PLAID_SECRET,
|
||||
linkWebhook: process.env.PLAID_LINK_WEBHOOK,
|
||||
},
|
||||
|
||||
|
||||
@@ -70,10 +70,7 @@ export class PlaidClientWrapper {
|
||||
baseOptions: {
|
||||
headers: {
|
||||
'PLAID-CLIENT-ID': config.plaid.clientId,
|
||||
'PLAID-SECRET':
|
||||
config.plaid.env === 'development'
|
||||
? config.plaid.secretDevelopment
|
||||
: config.plaid.secretSandbox,
|
||||
'PLAID-SECRET': config.plaid.secret,
|
||||
'Plaid-Version': '2020-09-14',
|
||||
},
|
||||
},
|
||||
|
||||
@@ -50,7 +50,6 @@ import InvoiceMailDialog from '@/containers/Sales/Invoices/InvoiceMailDialog/Inv
|
||||
import EstimateMailDialog from '@/containers/Sales/Estimates/EstimateMailDialog/EstimateMailDialog';
|
||||
import ReceiptMailDialog from '@/containers/Sales/Receipts/ReceiptMailDialog/ReceiptMailDialog';
|
||||
import PaymentMailDialog from '@/containers/Sales/PaymentReceives/PaymentMailDialog/PaymentMailDialog';
|
||||
import { ConnectBankDialog } from '@/containers/CashFlow/ConnectBankDialog';
|
||||
import { ExportDialog } from '@/containers/Dialogs/ExportDialog';
|
||||
|
||||
/**
|
||||
@@ -97,7 +96,6 @@ export default function DialogsContainer() {
|
||||
<NotifyPaymentReceiveViaSMSDialog
|
||||
dialogName={DialogsName.NotifyPaymentViaForm}
|
||||
/>
|
||||
|
||||
<BadDebtDialog dialogName={DialogsName.BadDebtForm} />
|
||||
<SMSMessageDialog dialogName={DialogsName.SMSMessageForm} />
|
||||
<RefundCreditNoteDialog dialogName={DialogsName.RefundCreditNote} />
|
||||
@@ -148,8 +146,6 @@ export default function DialogsContainer() {
|
||||
<EstimateMailDialog dialogName={DialogsName.EstimateMail} />
|
||||
<ReceiptMailDialog dialogName={DialogsName.ReceiptMail} />
|
||||
<PaymentMailDialog dialogName={DialogsName.PaymentMail} />
|
||||
<ConnectBankDialog dialogName={DialogsName.ConnectBankCreditCard} />
|
||||
|
||||
<ExportDialog dialogName={DialogsName.Export} />
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
FeatureCan,
|
||||
} from '@/components';
|
||||
import { useRefreshCashflowAccounts } from '@/hooks/query';
|
||||
import { useOpenPlaidConnect } from '@/hooks/utils/useOpenPlaidConnect';
|
||||
import { CashflowAction, AbilitySubject } from '@/constants/abilityOption';
|
||||
|
||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||
@@ -39,6 +40,9 @@ function CashFlowAccountsActionsBar({
|
||||
}) {
|
||||
const { refresh } = useRefreshCashflowAccounts();
|
||||
|
||||
// Opens the Plaid popup.
|
||||
const { openPlaidAsync, isPlaidLoading } = useOpenPlaidConnect();
|
||||
|
||||
// Handle refresh button click.
|
||||
const handleRefreshBtnClick = () => {
|
||||
refresh();
|
||||
@@ -64,7 +68,7 @@ function CashFlowAccountsActionsBar({
|
||||
};
|
||||
// Handle connect button click.
|
||||
const handleConnectToBank = () => {
|
||||
openDialog(DialogsName.ConnectBankCreditCard);
|
||||
openPlaidAsync();
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -116,6 +120,7 @@ function CashFlowAccountsActionsBar({
|
||||
className={Classes.MINIMAL}
|
||||
text={'Connect to Bank / Credit Card'}
|
||||
onClick={handleConnectToBank}
|
||||
disabled={isPlaidLoading}
|
||||
/>
|
||||
<NavbarDivider />
|
||||
</FeatureCan>
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { Dialog, DialogSuspense } from '@/components';
|
||||
import withDialogRedux from '@/components/DialogReduxConnect';
|
||||
import { compose } from '@/utils';
|
||||
|
||||
const ConnectBankDialogBody = React.lazy(
|
||||
() => import('./ConnectBankDialogBody'),
|
||||
);
|
||||
|
||||
/**
|
||||
* Connect bank dialog.
|
||||
*/
|
||||
function ConnectBankDialogRoot({ dialogName, payload = {}, isOpen }) {
|
||||
return (
|
||||
<Dialog
|
||||
name={dialogName}
|
||||
title={'Securly connect your bank or credit card.'}
|
||||
isOpen={isOpen}
|
||||
canEscapeJeyClose={true}
|
||||
autoFocus={true}
|
||||
>
|
||||
<DialogSuspense>
|
||||
<ConnectBankDialogBody dialogName={dialogName} />
|
||||
</DialogSuspense>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
export const ConnectBankDialog = compose(withDialogRedux())(
|
||||
ConnectBankDialogRoot,
|
||||
);
|
||||
@@ -1,61 +0,0 @@
|
||||
// @ts-nocheck
|
||||
import * as R from 'ramda';
|
||||
import { Form, Formik, FormikHelpers } from 'formik';
|
||||
import classNames from 'classnames';
|
||||
import { ConnectBankDialogContent } from './ConnectBankDialogContent';
|
||||
import { useGetPlaidLinkToken } from '@/hooks/query';
|
||||
import { useSetBankingPlaidToken } from '@/hooks/state/banking';
|
||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||
import { CLASSES } from '@/constants';
|
||||
import { AppToaster } from '@/components';
|
||||
import { Intent } from '@blueprintjs/core';
|
||||
import { DialogsName } from '@/constants/dialogs';
|
||||
|
||||
const initialValues: ConnectBankDialogForm = {
|
||||
serviceProvider: 'plaid',
|
||||
};
|
||||
|
||||
interface ConnectBankDialogForm {
|
||||
serviceProvider: 'plaid';
|
||||
}
|
||||
|
||||
function ConnectBankDialogBodyRoot({
|
||||
// #withDialogActions
|
||||
closeDialog,
|
||||
}) {
|
||||
const { mutateAsync: getPlaidLinkToken } = useGetPlaidLinkToken();
|
||||
const setPlaidId = useSetBankingPlaidToken();
|
||||
|
||||
// Handles the form submitting.
|
||||
const handleSubmit = (
|
||||
values: ConnectBankDialogForm,
|
||||
{ setSubmitting }: FormikHelpers<ConnectBankDialogForm>,
|
||||
) => {
|
||||
setSubmitting(true);
|
||||
getPlaidLinkToken()
|
||||
.then((res) => {
|
||||
setSubmitting(false);
|
||||
closeDialog(DialogsName.ConnectBankCreditCard);
|
||||
setPlaidId(res.data.link_token);
|
||||
})
|
||||
.catch(() => {
|
||||
setSubmitting(false);
|
||||
AppToaster.show({
|
||||
message: 'Something went wrong.',
|
||||
intent: Intent.DANGER,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={classNames(CLASSES.DIALOG_BODY)}>
|
||||
<Formik initialValues={initialValues} onSubmit={handleSubmit}>
|
||||
<Form>
|
||||
<ConnectBankDialogContent />
|
||||
</Form>
|
||||
</Formik>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default R.compose(withDialogActions)(ConnectBankDialogBodyRoot);
|
||||
@@ -1,48 +0,0 @@
|
||||
// @ts-nocheck
|
||||
import styled from 'styled-components';
|
||||
import { Stack } from '@/components';
|
||||
import { TellerIcon } from '../Icons/TellerIcon';
|
||||
import { YodleeIcon } from '../Icons/YodleeIcon';
|
||||
import { PlaidIcon } from '../Icons/PlaidIcon';
|
||||
import { BankServiceCard } from './ConnectBankServiceCard';
|
||||
|
||||
const TopDesc = styled('p')`
|
||||
margin-bottom: 20px;
|
||||
color: #5f6b7c;
|
||||
`;
|
||||
|
||||
export function ConnectBankDialogContent() {
|
||||
return (
|
||||
<div>
|
||||
<TopDesc>
|
||||
Connect your bank accounts and fetch the bank transactions using
|
||||
one of our supported third-party service providers.
|
||||
</TopDesc>
|
||||
|
||||
<Stack>
|
||||
<BankServiceCard
|
||||
title={'Plaid (US, UK & Canada)'}
|
||||
icon={<PlaidIcon />}
|
||||
>
|
||||
Plaid gives the connection to 12,000 financial institutions across US, UK and Canada.
|
||||
</BankServiceCard>
|
||||
|
||||
<BankServiceCard
|
||||
title={'Teller (US) — Soon'}
|
||||
icon={<TellerIcon />}
|
||||
disabled
|
||||
>
|
||||
Connect instantly with more than 5,000 financial institutions across US.
|
||||
</BankServiceCard>
|
||||
|
||||
<BankServiceCard
|
||||
title={'Yodlee (Global) — Soon'}
|
||||
icon={<YodleeIcon />}
|
||||
disabled
|
||||
>
|
||||
Connect instantly with a global network of financial institutions.
|
||||
</BankServiceCard>
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
import styled from 'styled-components';
|
||||
import { Group } from '@/components';
|
||||
|
||||
const BankServiceIcon = styled('div')`
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
border: 1px solid #c8cad0;
|
||||
border-radius: 3px;
|
||||
display: flex;
|
||||
|
||||
svg {
|
||||
margin: auto;
|
||||
}
|
||||
`;
|
||||
const BankServiceContent = styled(`div`)`
|
||||
flex: 1 0;
|
||||
`;
|
||||
const BankServiceCardRoot = styled('button')`
|
||||
border-radius: 3px;
|
||||
border: 1px solid #c8cad0;
|
||||
transition: all 0.1s ease-in-out;
|
||||
background: transparent;
|
||||
text-align: inherit;
|
||||
padding: 14px;
|
||||
|
||||
&:not(:disabled) {
|
||||
cursor: pointer;
|
||||
}
|
||||
&:hover:not(:disabled) {
|
||||
border-color: #0153cc;
|
||||
}
|
||||
&:disabled {
|
||||
background: #f9fdff;
|
||||
}
|
||||
`;
|
||||
const BankServiceTitle = styled(`h3`)`
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
color: #2d333d;
|
||||
`;
|
||||
const BankServiceDesc = styled('p')`
|
||||
margin-top: 4px;
|
||||
margin-bottom: 6px;
|
||||
font-size: 13px;
|
||||
color: #738091;
|
||||
`;
|
||||
|
||||
interface BankServiceCardProps {
|
||||
title: string;
|
||||
children: React.ReactNode;
|
||||
disabled?: boolean;
|
||||
icon: React.ReactNode;
|
||||
}
|
||||
|
||||
export function BankServiceCard({
|
||||
title,
|
||||
children,
|
||||
icon,
|
||||
disabled,
|
||||
}: BankServiceCardProps) {
|
||||
return (
|
||||
<BankServiceCardRoot disabled={disabled}>
|
||||
<Group>
|
||||
<BankServiceIcon>{icon}</BankServiceIcon>
|
||||
<BankServiceContent>
|
||||
<BankServiceTitle>{title}</BankServiceTitle>
|
||||
<BankServiceDesc>{children}</BankServiceDesc>
|
||||
</BankServiceContent>
|
||||
</Group>
|
||||
</BankServiceCardRoot>
|
||||
);
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
export * from './ConnectBankDialog';
|
||||
25
packages/webapp/src/hooks/utils/useOpenPlaidConnect.ts
Normal file
25
packages/webapp/src/hooks/utils/useOpenPlaidConnect.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { useCallback } from 'react';
|
||||
import { useSetBankingPlaidToken } from '../state/banking';
|
||||
import { AppToaster } from '@/components';
|
||||
import { useGetPlaidLinkToken } from '../query';
|
||||
import { Intent } from '@blueprintjs/core';
|
||||
|
||||
export const useOpenPlaidConnect = () => {
|
||||
const { mutateAsync: getPlaidLinkToken, isLoading } = useGetPlaidLinkToken();
|
||||
const setPlaidId = useSetBankingPlaidToken();
|
||||
|
||||
const openPlaidAsync = useCallback(() => {
|
||||
return getPlaidLinkToken()
|
||||
.then((res) => {
|
||||
setPlaidId(res.data.link_token);
|
||||
})
|
||||
.catch(() => {
|
||||
AppToaster.show({
|
||||
message: 'Something went wrong.',
|
||||
intent: Intent.DANGER,
|
||||
});
|
||||
});
|
||||
}, [getPlaidLinkToken, setPlaidId]);
|
||||
|
||||
return { openPlaidAsync, isPlaidLoading: isLoading };
|
||||
};
|
||||
Reference in New Issue
Block a user