-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: add account info UI --------- Co-authored-by: Neil Campbell <[email protected]>
- Loading branch information
1 parent
e48655c
commit 89069fc
Showing
17 changed files
with
594 additions
and
4 deletions.
There are no files selected for viewing
66 changes: 66 additions & 0 deletions
66
src/features/accounts/components/account-activity-tabs.tsx
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,66 @@ | ||
import { OverflowAutoTabsContent, Tabs, TabsList, TabsTrigger } from '@/features/common/components/tabs' | ||
import { cn } from '@/features/common/utils' | ||
import { useMemo } from 'react' | ||
|
||
const accountVisualTransactionTabId = 'visual' | ||
const accountVisualAssetsTabId = 'table' | ||
const accountVisualCreatedAssetsTabId = 'created-assets' | ||
const accountVisualCreatedApplicationsTabId = 'created-applications' | ||
const accountVisualOptedApplicationsTabId = 'opted-applications' | ||
export const accountDetailsLabel = 'View account Details' | ||
export const accountVisualGraphTabLabel = 'Transactions' | ||
export const accountVisualAssetsTabLabel = 'Assets' | ||
export const accountVisualCreatedAssetsTabLabel = 'Created Assets' | ||
export const accountVisualCreatedApplicationsTabLabel = 'Created Applications' | ||
export const accountVisualOptedApplicationsTabLabel = 'Opted Applications' | ||
|
||
export function AccountActivityTabs() { | ||
const tabs = useMemo( | ||
() => [ | ||
{ | ||
id: accountVisualTransactionTabId, | ||
label: accountDetailsLabel, | ||
children: '', | ||
}, | ||
{ | ||
id: accountVisualAssetsTabId, | ||
label: accountVisualAssetsTabLabel, | ||
children: '', | ||
}, | ||
{ | ||
id: accountVisualCreatedAssetsTabId, | ||
label: accountVisualCreatedAssetsTabLabel, | ||
children: '', | ||
}, | ||
{ | ||
id: accountVisualCreatedApplicationsTabId, | ||
label: accountVisualCreatedApplicationsTabLabel, | ||
children: '', | ||
}, | ||
{ | ||
id: accountVisualOptedApplicationsTabId, | ||
label: accountVisualOptedApplicationsTabLabel, | ||
children: '', | ||
}, | ||
], | ||
[] | ||
) | ||
return ( | ||
<Tabs defaultValue={accountVisualTransactionTabId}> | ||
<TabsList aria-label={accountDetailsLabel}> | ||
{tabs.map((tab) => ( | ||
<TabsTrigger key={tab.id} className={cn('data-[state=active]:border-primary data-[state=active]:border-b-2 w-44')} value={tab.id}> | ||
{tab.label} | ||
</TabsTrigger> | ||
))} | ||
</TabsList> | ||
{tabs.map((tab) => ( | ||
<OverflowAutoTabsContent key={tab.id} value={tab.id} className={cn('border-solid border-2 border-border')}> | ||
<div className="grid"> | ||
<div className="overflow-auto p-4">{tab.children}</div> | ||
</div> | ||
</OverflowAutoTabsContent> | ||
))} | ||
</Tabs> | ||
) | ||
} |
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,36 @@ | ||
import { Card, CardContent } from '@/features/common/components/card' | ||
import { Account } from '../models' | ||
import { cn } from '@/features/common/utils' | ||
import { AccountActivityTabs } from './account-activity-tabs' | ||
import { AccountInfo } from './account-info' | ||
|
||
type Props = { | ||
account: Account | ||
} | ||
|
||
export const activityLabel = 'Activity' | ||
export const accountJsonLabel = 'Acount JSON' | ||
|
||
export function AccountDetails({ account }: Props) { | ||
return ( | ||
<div className={cn('space-y-6 pt-7')}> | ||
<AccountInfo account={account} /> | ||
<Card aria-label={activityLabel} className={cn('p-4')}> | ||
<CardContent className={cn('text-sm space-y-2')}> | ||
<h1 className={cn('text-2xl text-primary font-bold')}>{activityLabel}</h1> | ||
<div className={cn('border-solid border-2 border-border grid')}> | ||
<AccountActivityTabs /> | ||
</div> | ||
</CardContent> | ||
</Card> | ||
<Card className={cn('p-4')}> | ||
<CardContent aria-label={accountJsonLabel} className={cn('text-sm space-y-2')}> | ||
<h1 className={cn('text-2xl text-primary font-bold')}>{accountJsonLabel}</h1> | ||
<div className={cn('border-solid border-2 border-border h-96 grid')}> | ||
<pre className={cn('overflow-scroll p-4')}>{account.json}</pre> | ||
</div> | ||
</CardContent> | ||
</Card> | ||
</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,83 @@ | ||
import { useMemo } from 'react' | ||
import { Account } from '../models' | ||
import { Card, CardContent } from '@/features/common/components/card' | ||
import { DescriptionList } from '@/features/common/components/description-list' | ||
import { cn } from '@/features/common/utils' | ||
import { DisplayAlgo } from '@/features/common/components/display-algo' | ||
import { AccountLink } from './account-link' | ||
|
||
export const accountInformationLabel = 'Account Information' | ||
export const accountAddressLabel = 'Address' | ||
export const accountBalanceLabel = 'Balance' | ||
export const accountMinBalanceLabel = 'Min Balance' | ||
export const accountAssetsHeldLabel = 'Holding assets' | ||
export const accountAssetsCreatedLabel = 'Created assets' | ||
export const accountAssetsOptedInLabel = 'Opted assets' | ||
export const accountApplicationsCreatedLabel = 'Created applications' | ||
export const accountApplicationsOptedInLabel = 'Opted applications' | ||
export const accountRekeyedToLabel = 'Rekeyed to' | ||
|
||
export function AccountInfo({ account }: { account: Account }) { | ||
const accountInfoItems = useMemo(() => { | ||
const items = [ | ||
{ | ||
dt: accountAddressLabel, | ||
dd: account.address, | ||
}, | ||
{ | ||
dt: accountBalanceLabel, | ||
dd: <DisplayAlgo amount={account.balance} />, | ||
}, | ||
{ | ||
dt: accountMinBalanceLabel, | ||
dd: <DisplayAlgo amount={account.minBalance} />, | ||
}, | ||
{ | ||
dt: accountAssetsHeldLabel, | ||
dd: account.totalAssetsHeld, | ||
}, | ||
{ | ||
dt: accountAssetsCreatedLabel, | ||
dd: account.totalAssetsCreated, | ||
}, | ||
{ | ||
dt: accountAssetsOptedInLabel, | ||
dd: account.totalAssetsOptedIn, | ||
}, | ||
{ | ||
dt: accountApplicationsCreatedLabel, | ||
dd: account.totalApplicationsCreated ? account.totalApplicationsCreated : 0, | ||
}, | ||
{ | ||
dt: accountApplicationsOptedInLabel, | ||
dd: account.totalApplicationsOptedIn ? account.totalApplicationsOptedIn : 0, | ||
}, | ||
...(account.rekeyedTo | ||
? [ | ||
{ | ||
dt: accountRekeyedToLabel, | ||
dd: <AccountLink address={account.rekeyedTo}></AccountLink>, | ||
}, | ||
] | ||
: []), | ||
] | ||
return items | ||
}, [ | ||
account.address, | ||
account.balance, | ||
account.minBalance, | ||
account.totalAssetsHeld, | ||
account.totalAssetsCreated, | ||
account.totalAssetsOptedIn, | ||
account.totalApplicationsCreated, | ||
account.totalApplicationsOptedIn, | ||
account.rekeyedTo, | ||
]) | ||
return ( | ||
<Card aria-label={accountInformationLabel} className={cn('p-4')}> | ||
<CardContent className={cn('text-sm space-y-2')}> | ||
<DescriptionList items={accountInfoItems} /> | ||
</CardContent> | ||
</Card> | ||
) | ||
} |
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,16 @@ | ||
import { atom } from 'jotai' | ||
import { AccountResult, Address } from './types' | ||
import { algod } from '@/features/common/data' | ||
import { atomsInAtom } from '@/features/common/data/atoms-in-atom' | ||
|
||
const createAccountResultAtom = (address: Address) => | ||
atom<Promise<AccountResult> | AccountResult>(async (_get) => { | ||
return await algod | ||
.accountInformation(address) | ||
.do() | ||
.then((result) => { | ||
return result as AccountResult | ||
}) | ||
}) | ||
|
||
export const [accountResultsAtom, getAccountResultAtom] = atomsInAtom(createAccountResultAtom, (address) => address) |
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,26 @@ | ||
import { atom, useAtomValue, useStore } from 'jotai' | ||
import { Address } from './types' | ||
import { loadable } from 'jotai/utils' | ||
import { JotaiStore } from '@/features/common/data/types' | ||
import { useMemo } from 'react' | ||
import { asAccount } from '../mappers' | ||
import { getAccountResultAtom } from './account-result' | ||
|
||
const createAccountAtom = (store: JotaiStore, address: Address) => { | ||
return atom(async (get) => { | ||
const accountResult = await get(getAccountResultAtom(store, address)) | ||
return asAccount(accountResult) | ||
}) | ||
} | ||
|
||
const useAccountAtom = (address: Address) => { | ||
const store = useStore() | ||
|
||
return useMemo(() => { | ||
return createAccountAtom(store, address) | ||
}, [store, address]) | ||
} | ||
|
||
export const useLoadableAccountAtom = (address: Address) => { | ||
return useAtomValue(loadable(useAccountAtom(address))) | ||
} |
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,2 @@ | ||
export * from './account' | ||
export * from './account-result' |
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,43 @@ | ||
import { NoStringIndex } from '@/features/common/data/types' | ||
import { | ||
ApplicationResult as IndexerApplicationResult, | ||
AssetHolding as IndexerAssetHolding, | ||
AssetResult as IndexerAssetResult, | ||
AppLocalState as IndexerAppLocalState, | ||
AccountResult as IndexerAccountResult, | ||
SignatureType, | ||
} from '@algorandfoundation/algokit-utils/types/indexer' | ||
|
||
export type Address = string | ||
|
||
export type AppLocalState = Omit<IndexerAppLocalState, 'closed-out-at-round' | 'deleted' | 'opted-in-at-round'> | ||
export type AssetHolding = Omit<IndexerAssetHolding, 'deleted' | 'opted-in-at-round' | 'opted-out-at-round'> | ||
export type ApplicationResult = Omit<IndexerApplicationResult, 'created-at-round' | 'deleted' | 'deleted-at-round'> | ||
export type AssetResult = { | ||
index: number | ||
params: IndexerAssetResult['params'] | ||
} | ||
|
||
export type AccountResult = Omit< | ||
NoStringIndex<IndexerAccountResult>, | ||
| 'closed-at-round' | ||
| 'created-at-round' | ||
| 'deleted' | ||
| 'apps-local-state' | ||
| 'assets' | ||
| 'created-apps' | ||
| 'created-assets' | ||
| 'min-balance' | ||
| 'total-box-bytes' | ||
| 'total-boxes' | ||
| 'sig-type' | ||
> & { | ||
'apps-local-state'?: AppLocalState[] | ||
assets?: AssetHolding[] | ||
'created-apps'?: ApplicationResult[] | ||
'created-assets'?: AssetResult[] | ||
'min-balance': number | ||
'total-box-bytes'?: number | ||
'total-boxes'?: number | ||
'sig-type'?: SignatureType | ||
} |
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,19 @@ | ||
import { AccountResult } from '../data/types' | ||
import { Account } from '../models' | ||
import { asJson } from '@/utils/as-json' | ||
import { microAlgos } from '@algorandfoundation/algokit-utils' | ||
|
||
export const asAccount = (accountResult: AccountResult): Account => { | ||
return { | ||
address: accountResult.address, | ||
balance: microAlgos(accountResult.amount), | ||
minBalance: microAlgos(accountResult['min-balance']), | ||
totalAssetsCreated: accountResult['total-created-assets'], | ||
totalAssetsOptedIn: accountResult['total-assets-opted-in'], | ||
totalAssetsHeld: (accountResult.assets ?? []).length, | ||
totalApplicationsCreated: accountResult['total-created-apps'], | ||
totalApplicationsOptedIn: accountResult['total-apps-opted-in'], | ||
rekeyedTo: accountResult['auth-addr'], | ||
json: asJson(accountResult), | ||
} | ||
} |
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,15 @@ | ||
import { AlgoAmount } from '@algorandfoundation/algokit-utils/types/amount' | ||
import { Address } from '../data/types' | ||
|
||
export type Account = { | ||
address: Address | ||
balance: AlgoAmount | ||
minBalance: AlgoAmount | ||
totalAssetsCreated: number | ||
totalAssetsOptedIn: number | ||
totalAssetsHeld: number | ||
totalApplicationsCreated: number | ||
totalApplicationsOptedIn: number | ||
rekeyedTo?: Address | ||
json: string | ||
} |
Oops, something went wrong.