-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: detailed and recent transactions (#87)
- Loading branch information
1 parent
898631f
commit 79fac2f
Showing
10 changed files
with
534 additions
and
83 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { TransactionDetail } from '@/views/transactions/TransactionDetail'; | ||
|
||
export default function Page({ params }: { params: { id: string } }) { | ||
return <TransactionDetail id={params.id} />; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import { sortBy } from 'lodash'; | ||
import Link from 'next/link'; | ||
import { useTranslations } from 'next-intl'; | ||
import { FC, useMemo } from 'react'; | ||
|
||
import { Skeleton } from '@/components/ui/skeleton'; | ||
import { useToast } from '@/components/ui/use-toast'; | ||
import { useGetWalletQuery } from '@/graphql/queries/__generated__/wallet.generated'; | ||
import { handleApolloError } from '@/utils/error'; | ||
import { cryptoToUsd } from '@/utils/fiat'; | ||
import { ROUTES } from '@/utils/routes'; | ||
|
||
import { Transaction } from '../transactions/Transaction'; | ||
import { TransactionEntry } from '../transactions/Transactions'; | ||
|
||
export const RecentTransactions: FC<{ id: string }> = ({ id }) => { | ||
const t = useTranslations('App'); | ||
const { toast } = useToast(); | ||
|
||
const { data, loading, error } = useGetWalletQuery({ | ||
variables: { id }, | ||
onError: err => { | ||
const messages = handleApolloError(err); | ||
|
||
toast({ | ||
variant: 'destructive', | ||
title: 'Error getting transactions.', | ||
description: messages.join(', '), | ||
}); | ||
}, | ||
}); | ||
|
||
const transactions = useMemo(() => { | ||
if (loading || error) return []; | ||
if (!data?.wallets.find_one.accounts.length) return []; | ||
|
||
const { accounts } = data.wallets.find_one; | ||
|
||
const transactions: TransactionEntry[] = []; | ||
|
||
accounts.forEach(a => { | ||
if (!a.liquid) return; | ||
|
||
a.liquid.transactions.forEach(t => { | ||
transactions.push({ | ||
id: t.id, | ||
balance: t.balance, | ||
formatted_balance: cryptoToUsd( | ||
t.balance, | ||
t.asset_info.precision, | ||
t.asset_info.ticker, | ||
t.fiat_info.fiat_to_btc | ||
), | ||
date: t.date, | ||
ticker: t.asset_info.ticker, | ||
precision: t.asset_info.precision, | ||
}); | ||
}); | ||
}); | ||
|
||
const sorted = sortBy(transactions, t => | ||
t.date ? new Date(t.date) : new Date() | ||
).reverse(); | ||
|
||
return sorted.slice(0, 5); | ||
}, [data, loading, error]); | ||
|
||
return ( | ||
<div> | ||
<div className="mb-4 flex w-full justify-between space-x-2 lg:mb-6"> | ||
<p className="text-2xl font-semibold">{t('Dashboard.transactions')}</p> | ||
|
||
<Link | ||
href={ROUTES.transactions.home} | ||
className="font-medium text-primary transition-colors hover:text-primary-hover" | ||
> | ||
{t('view-all')} | ||
</Link> | ||
</div> | ||
|
||
<div className="w-full max-w-[calc(100dvw-32px)] space-y-2"> | ||
{loading ? ( | ||
Array.from({ length: 5 }).map((_, i) => ( | ||
<Skeleton key={i} className="h-[52px] w-full rounded-xl" /> | ||
)) | ||
) : ( | ||
<> | ||
{transactions.length ? ( | ||
transactions.map(t => ( | ||
<Transaction | ||
key={t.id} | ||
id={t.id} | ||
balance={t.balance} | ||
precision={t.precision} | ||
date={t.date} | ||
formatted_balance={t.formatted_balance} | ||
ticker={t.ticker} | ||
/> | ||
)) | ||
) : ( | ||
<p className="font-semibold"> | ||
{t('Wallet.Transactions.no-results')} | ||
</p> | ||
)} | ||
</> | ||
)} | ||
</div> | ||
</div> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { format, formatDistanceToNowStrict } from 'date-fns'; | ||
import { es } from 'date-fns/locale'; | ||
import { ArrowDown, ArrowUp } from 'lucide-react'; | ||
import Link from 'next/link'; | ||
import { useLocale, useTranslations } from 'next-intl'; | ||
import { FC } from 'react'; | ||
|
||
import { cn } from '@/utils/cn'; | ||
import { numberWithPrecisionAndDecimals } from '@/utils/numbers'; | ||
import { ROUTES } from '@/utils/routes'; | ||
|
||
export const Transaction: FC<{ | ||
id: string; | ||
balance: string; | ||
precision: number; | ||
date: string | undefined | null; | ||
formatted_balance: string; | ||
ticker: string; | ||
}> = ({ id, balance, precision, date, formatted_balance, ticker }) => { | ||
const t = useTranslations(); | ||
const locale = useLocale(); | ||
|
||
const balanceNum = Number(balance); | ||
|
||
const formatted = numberWithPrecisionAndDecimals( | ||
parseFloat(balance), | ||
precision | ||
); | ||
|
||
return ( | ||
<Link href={ROUTES.transactions.tx(id)} className="block"> | ||
<div className="group flex w-full items-center justify-between space-x-2 overflow-x-auto whitespace-nowrap rounded-xl bg-slate-100 px-2 py-1 transition-colors dark:bg-neutral-900 dark:hover:bg-neutral-800"> | ||
<div className="flex items-center space-x-2"> | ||
<div className="flex h-10 w-10 items-center justify-center rounded-full bg-white transition-colors group-hover:bg-slate-100 dark:bg-neutral-800 group-hover:dark:bg-neutral-800"> | ||
{balanceNum < 0 ? ( | ||
<ArrowUp size={24} /> | ||
) : ( | ||
<ArrowDown size={24} className="text-green-400" /> | ||
)} | ||
</div> | ||
|
||
{date ? ( | ||
<div> | ||
<p className="font-medium"> | ||
{locale === 'es' | ||
? t('App.Wallet.Transactions.ago') + | ||
' ' + | ||
formatDistanceToNowStrict(date, { | ||
locale: es, | ||
}) | ||
: formatDistanceToNowStrict(date) + | ||
' ' + | ||
t('App.Wallet.Transactions.ago')} | ||
</p> | ||
|
||
<p className="text-sm text-slate-600 dark:text-neutral-400"> | ||
{format(date, 'MMM dd, yyyy')} | ||
</p> | ||
</div> | ||
) : ( | ||
<p>{t('App.Wallet.Transactions.pending')}</p> | ||
)} | ||
</div> | ||
|
||
<div className="text-right"> | ||
<p className={cn('font-medium', balanceNum > 0 && 'text-green-400')}> | ||
{formatted_balance.includes('-') | ||
? '-' + formatted_balance.replaceAll('-', '') | ||
: '+' + formatted_balance} | ||
</p> | ||
|
||
<p className="text-sm text-slate-600 dark:text-neutral-400"> | ||
{formatted.includes('-') ? formatted : '+' + formatted} {ticker} | ||
</p> | ||
</div> | ||
</div> | ||
</Link> | ||
); | ||
}; |
Oops, something went wrong.