mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
The addresses list endpoint returns a projection of an address — no tags, no name, no implementations. AddressesListItem guarded with `public_tags !== null`, which is true of an absent field, so every visit to /accounts read `.length` off undefined and the whole page fell to the error boundary. The type said the field was always present, so nothing caught it. Partial<AddressParam> states what the endpoint sends, and both read sites reach for the tags the same optional way. The error screen it fell to had its own defect: the status glyph is an inline-block div and gui's H1 renders inline, so the two shared a line box and "500" ran into "Oops! Something went wrong". The screen is a stack; it now says so. The heading's own top margin was being outranked by gui's atomic reset.
93 lines
2.8 KiB
TypeScript
93 lines
2.8 KiB
TypeScript
import BigNumber from 'bignumber.js';
|
|
import React from 'react';
|
|
|
|
import type { AddressesItem } from 'types/api/addresses';
|
|
|
|
import config from 'configs/app';
|
|
import { Skeleton } from '@luxfi/ui/skeleton';
|
|
import { TableCell, TableRow } from '@luxfi/ui/table';
|
|
import { Tag } from '@luxfi/ui/tag';
|
|
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
|
|
import SimpleValue from 'ui/shared/value/SimpleValue';
|
|
|
|
type Props = {
|
|
item: AddressesItem;
|
|
index: number;
|
|
totalSupply: BigNumber;
|
|
hasPercentage: boolean;
|
|
isLoading?: boolean;
|
|
};
|
|
|
|
const AddressesTableItem = ({
|
|
item,
|
|
index,
|
|
totalSupply,
|
|
hasPercentage,
|
|
isLoading,
|
|
}: Props) => {
|
|
|
|
const addressBalance = BigNumber(item.coin_balance || 0).div(BigNumber(10 ** config.chain.currency.decimals));
|
|
// On pruned nodes, coin_balance may be null even for addresses with transactions.
|
|
// Show "Pending" instead of a misleading "0".
|
|
const isBalancePending = item.coin_balance === null && Number(item.transactions_count) > 0;
|
|
|
|
return (
|
|
<TableRow>
|
|
<TableCell>
|
|
<Skeleton loading={ isLoading } display="inline-block" minW={ 6 } lineHeight="24px">
|
|
{ index }
|
|
</Skeleton>
|
|
</TableCell>
|
|
<TableCell>
|
|
<div className="flex items-center gap-x-2">
|
|
<AddressEntity
|
|
address={ item }
|
|
isLoading={ isLoading }
|
|
className="font-bold my-[2px]"
|
|
|
|
/>
|
|
{ item.public_tags?.map(tag => (
|
|
<Tag key={ tag.label } loading={ isLoading } truncated>{ tag.display_name }</Tag>
|
|
)) }
|
|
</div>
|
|
</TableCell>
|
|
<TableCell isNumeric>
|
|
{ isBalancePending ? (
|
|
<Skeleton loading={ isLoading } display="inline-block" lineHeight="24px">
|
|
<span className="text-[var(--color-text-secondary)] text-sm">Pending</span>
|
|
</Skeleton>
|
|
) : (
|
|
<SimpleValue
|
|
value={ addressBalance }
|
|
loading={ isLoading }
|
|
lineHeight="24px"
|
|
/>
|
|
) }
|
|
</TableCell>
|
|
{ hasPercentage && (
|
|
<TableCell isNumeric>
|
|
{ isBalancePending ? (
|
|
<Skeleton loading={ isLoading } display="inline-block" lineHeight="24px">
|
|
<span className="text-[var(--color-text-secondary)] text-sm">Pending</span>
|
|
</Skeleton>
|
|
) : (
|
|
<SimpleValue
|
|
value={ addressBalance.div(totalSupply).multipliedBy(100) }
|
|
loading={ isLoading }
|
|
postfix="%"
|
|
lineHeight="24px"
|
|
/>
|
|
) }
|
|
</TableCell>
|
|
) }
|
|
<TableCell isNumeric>
|
|
<Skeleton loading={ isLoading } display="inline-block" lineHeight="24px">
|
|
{ Number(item.transactions_count).toLocaleString() }
|
|
</Skeleton>
|
|
</TableCell>
|
|
</TableRow>
|
|
);
|
|
};
|
|
|
|
export default React.memo(AddressesTableItem);
|