actual/packages/desktop-client/src/components/accounts/AccountSyncCheck.js
Tom French 9c0df36e16
Sort import in alphabetical order (#238)
* style: enforce sorting of imports

* style: alphabetize imports

* style: merge duplicated imports
2022-09-02 15:07:24 +01:00

166 lines
4.3 KiB
JavaScript

import React, { useState } from 'react';
import { connect } from 'react-redux';
import * as actions from 'loot-core/src/client/actions';
import { View, Button, Tooltip } from 'loot-design/src/components/common';
import { colors } from 'loot-design/src/style';
import ExclamationOutline from 'loot-design/src/svg/v1/ExclamationOutline';
import { reauthorizeBank } from '../../plaid';
function getErrorMessage(type, code) {
switch (type.toUpperCase()) {
case 'ITEM_ERROR':
switch (code.toUpperCase()) {
case 'NO_ACCOUNTS':
return 'No open accounts could be found. Did you close the account? If so, unlink the account.';
case 'ITEM_LOGIN_REQUIRED':
return 'Your password or something else has changed with your bank and you need to login again.';
default:
}
break;
case 'INVALID_INPUT':
switch (code.toUpperCase()) {
case 'INVALID_ACCESS_TOKEN':
return 'Item is no longer authorized. You need to login again.';
default:
}
break;
case 'API_ERROR':
switch (code.toUpperCase()) {
case 'PLANNED_MAINTENANCE':
return 'Our servers are currently undergoing maintenance and will be available again soon.';
default:
}
break;
case 'RATE_LIMIT_EXCEEDED':
return 'Rate limit exceeded for this item. Please try again later.';
default:
}
return 'An internal error occurred. Try to login again, or contact help@actualbudget.com for support.';
}
function AccountSyncCheck({
id,
accounts,
failedAccounts,
syncAndDownload,
markAccountSuccess,
unlinkAccount,
pushModal,
closeModal,
getAccounts,
addNotification
}) {
if (!failedAccounts) {
return null;
}
let error = failedAccounts.get(id);
if (!error) {
return null;
}
let [open, setOpen] = useState(false);
let account = accounts.find(account => account.id === id);
let { type, code } = error;
let showAuth =
(type === 'ITEM_ERROR' && code === 'ITEM_LOGIN_REQUIRED') ||
(type === 'INVALID_INPUT' && code === 'INVALID_ACCESS_TOKEN');
function reauth() {
setOpen(false);
let modalOpened = reauthorizeBank(pushModal, account.bankId, () => {
closeModal();
// Re-sync accounts. If there are multiple failed account, that
// means all accounts were synced to resync all of them.
// Multiple accounts can be tied to the same bank id.
syncAndDownload(failedAccounts.size > 1 ? null : account.id);
});
if (!modalOpened) {
addNotification({
type: 'error',
message: 'Unable to process this item, sorry!'
});
}
}
async function unlink() {
unlinkAccount(account.id);
setOpen(false);
}
return (
<View>
<Button
bare
style={{
flexDirection: 'row',
alignItems: 'center',
color: colors.r5,
backgroundColor: colors.r10,
padding: '4px 8px',
borderRadius: 4
}}
onClick={() => setOpen(true)}
>
<ExclamationOutline
style={{
width: 14,
height: 14,
marginRight: 5,
color: 'currentColor'
}}
/>{' '}
This account is experiencing connection problems. Let{"'"}s fix it.
</Button>
{open && (
<Tooltip
position="bottom-left"
onClose={() => setOpen(false)}
style={{ fontSize: 14, padding: 15, maxWidth: 400 }}
>
<div style={{ marginBottom: '1.15em' }}>
The server returned the following error:
</div>
<div style={{ marginBottom: '1.25em', color: colors.r5 }}>
{getErrorMessage(error.type, error.code)}
</div>
<View style={{ justifyContent: 'flex-end', flexDirection: 'row' }}>
{showAuth ? (
<>
<Button onClick={unlink}>Unlink</Button>
<Button primary onClick={reauth} style={{ marginLeft: 5 }}>
Reauthorize
</Button>
</>
) : (
<Button onClick={unlink}>Unlink account</Button>
)}
</View>
</Tooltip>
)}
</View>
);
}
export default connect(
state => ({
accounts: state.queries.accounts,
failedAccounts: state.account.failedAccounts
}),
actions
)(AccountSyncCheck);