Skip to content

Commit

Permalink
feat(ui): Show when the plaid link was last updated in the UI.
Browse files Browse the repository at this point in the history
There is now a card at the bottom of the budgeting sidebar that shows
when the plaid link was last updated. If you mouse over it it will also
show when the last attempt was made (not possible on mobile atm). This
is only present when the `plaidLink` sub object of a link is populated.
  • Loading branch information
elliotcourant committed Apr 19, 2024
1 parent 6e19c00 commit 061115e
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 5 deletions.
3 changes: 2 additions & 1 deletion interface/src/components/Layout/BankSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ function SidebarWrapper(props: SidebarWrapperProps): JSX.Element {
'items-center',
'lg:py-4',
'pt-2',
'pb-4',
'pb-8',
'lg:pb-4',
'w-16',
props.className,
);
Expand Down
6 changes: 4 additions & 2 deletions interface/src/components/Layout/BudgetingSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Link, useLocation } from 'react-router-dom';
import { AccountBalanceWalletOutlined, LocalAtmOutlined, PriceCheckOutlined, SavingsOutlined, ShoppingCartOutlined, TodayOutlined, TollOutlined } from '@mui/icons-material';

import BudgetingSidebarTitle from './BudgetingSidebarTitle';
import PlaidLastUpdatedCard from '@monetr/interface/components/Layout/PlaidLastUpdatedCard';
import MBadge from '@monetr/interface/components/MBadge';
import MDivider from '@monetr/interface/components/MDivider';
import MSelectAccount from '@monetr/interface/components/MSelectAccount';
Expand All @@ -26,7 +27,7 @@ export default function BudgetingSidebar(props: BudgetingSidebarProps): JSX.Elem


const className = mergeTailwind(
'w-72 h-full flex-none flex flex-col dark:border-r-dark-monetr-border border border-transparent items-center pb-4',
'w-72 h-full flex-none flex flex-col dark:border-r-dark-monetr-border border border-transparent items-center pb-6 lg:pb-4',
props.className,
);

Expand Down Expand Up @@ -85,7 +86,7 @@ export default function BudgetingSidebar(props: BudgetingSidebarProps): JSX.Elem
return (
<div className={ className }>
<BudgetingSidebarTitle />
<div className='flex h-full w-full flex-col items-center gap-4 px-2 py-4'>
<div className='flex h-full w-full flex-col items-center gap-4 px-2 pt-4'>
<MSelectAccount />
<MDivider className='w-1/2' />

Expand Down Expand Up @@ -137,6 +138,7 @@ export default function BudgetingSidebar(props: BudgetingSidebarProps): JSX.Elem
<NextFundingBadge />
</NavigationItem>
</div>
<PlaidLastUpdatedCard linkId={ bankAccount?.linkId } />
</div>
</div>
);
Expand Down
37 changes: 37 additions & 0 deletions interface/src/components/Layout/PlaidLastUpdatedCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* eslint-disable max-len */
import React from 'react';
import { formatDistanceToNow } from 'date-fns';

import MSpan from '@monetr/interface/components/MSpan';
import { useLink } from '@monetr/interface/hooks/links';

interface PlaidLastUpdatedCardProps {
linkId: number | null;
}

export default function PlaidLastUpdatedCard(props: PlaidLastUpdatedCardProps): JSX.Element {
const link = useLink(props?.linkId);

if (!link?.data?.plaidLink) {
return null;
}

const lastUpdateString = !!link?.data?.plaidLink?.lastSuccessfulUpdate ?
formatDistanceToNow(link.data.plaidLink.lastSuccessfulUpdate) :
'Never';

const lastAttemptString = !!link?.data?.plaidLink?.lastAttemptedUpdate ?
formatDistanceToNow(link.data.plaidLink.lastAttemptedUpdate) :
'Never';

return (
<div className='p-2 group border-[thin] dark:border-dark-monetr-border rounded-lg w-full ease-in-out transition-[height] h-10 hover:h-16 hover:delay-0 delay-500 hover:dark:border-dark-monetr-border-string' >
<MSpan size='sm' color='subtle'>
Last Updated: { lastUpdateString } ago
</MSpan>
<MSpan size='sm' color='subtle' className='transition-opacity opacity-0 group-hover:opacity-100 delay-500 group-hover:delay-0'>
Last Attempt: { lastAttemptString } ago
</MSpan>
</div>
);
}
4 changes: 3 additions & 1 deletion interface/src/hooks/links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ export function useDetectDuplicateLink(): (_metadata: PlaidLinkOnSuccessMetadata

export function useTriggerManualPlaidSync(): (_linkId: number) => Promise<void> {
const { enqueueSnackbar } = useSnackbar();
const queryClient = useQueryClient();
return async (linkId: number): Promise<void> => {
return request()
.post('/plaid/link/sync', {
Expand All @@ -120,8 +121,9 @@ export function useTriggerManualPlaidSync(): (_linkId: number) => Promise<void>
.then(() => void enqueueSnackbar('Triggered a manual sync in the background!', {
variant: 'success',
disableWindowBlurListener: true,

}))
// Will make things like the "last attempted update" timestamp thing update.
.then(() => setTimeout(() => queryClient.invalidateQueries(['/links']), 2000))
.catch(error => void enqueueSnackbar(
`Failed to trigger a manual sync: ${error?.response?.data?.error || 'unknown error'}.`,
{
Expand Down
1 change: 0 additions & 1 deletion interface/src/modals/UpdatePlaidAccountOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ function UpdatePlaidAccountOverlay({ link, updateAccountSelection }: UpdatePlaid
error,
metadata,
});
if (!metadata || !error) return;

modal.remove();
}, [modal]);
Expand Down

0 comments on commit 061115e

Please sign in to comment.