Commit 54951e67 authored by tom's avatar tom

private tags for txs

parent 90780a00
import { ADDRESS_PARAMS, ADDRESS_HASH } from './addressParams';
import { TX_HASH } from './tx';
export const PRIVATE_TAG_ADDRESS = {
address: ADDRESS_PARAMS,
......@@ -6,3 +7,9 @@ export const PRIVATE_TAG_ADDRESS = {
id: '4',
name: 'placeholder',
};
export const PRIVATE_TAG_TX = {
id: 1,
name: 'placeholder',
transaction_hash: TX_HASH,
};
......@@ -84,8 +84,7 @@ const PrivateAddressTags = () => {
Private tags are saved in your account and are only visible when you are logged in.
</AccountPageDescription>
{ Boolean(addressTagsData?.length) && list }
<Box marginTop={ 8 }>
<Skeleton isLoaded={ !isPlaceholderData } display="inline-block">
<Skeleton mt={ 8 } isLoaded={ !isPlaceholderData } display="inline-block">
<Button
size="lg"
onClick={ addressModalProps.onOpen }
......@@ -93,7 +92,6 @@ const PrivateAddressTags = () => {
Add address tag
</Button>
</Skeleton>
</Box>
<AddressModal { ...addressModalProps } onClose={ onAddressModalClose } data={ addressModalData }/>
{ deleteModalData && (
<DeletePrivateTagModal
......
......@@ -5,10 +5,9 @@ import type { TransactionTag } from 'types/api/account';
import useApiQuery from 'lib/api/useApiQuery';
import useIsMobile from 'lib/hooks/useIsMobile';
import { PRIVATE_TAG_TX } from 'stubs/account';
import AccountPageDescription from 'ui/shared/AccountPageDescription';
import DataFetchAlert from 'ui/shared/DataFetchAlert';
import SkeletonListAccount from 'ui/shared/skeletons/SkeletonListAccount';
import SkeletonTable from 'ui/shared/skeletons/SkeletonTable';
import DeletePrivateTagModal from './DeletePrivateTagModal';
import TransactionModal from './TransactionModal/TransactionModal';
......@@ -16,7 +15,12 @@ import TransactionTagListItem from './TransactionTagTable/TransactionTagListItem
import TransactionTagTable from './TransactionTagTable/TransactionTagTable';
const PrivateTransactionTags = () => {
const { data: transactionTagsData, isLoading, isError, error } = useApiQuery('private_tags_tx', { queryOptions: { refetchOnMount: false } });
const { data: transactionTagsData, isPlaceholderData, isError, error } = useApiQuery('private_tags_tx', {
queryOptions: {
refetchOnMount: false,
placeholderData: Array(3).fill(PRIVATE_TAG_TX),
},
});
const transactionModalProps = useDisclosure();
const deleteModalProps = useDisclosure();
......@@ -52,22 +56,6 @@ const PrivateTransactionTags = () => {
</AccountPageDescription>
);
if (isLoading && !transactionTagsData) {
const loader = isMobile ? <SkeletonListAccount/> : (
<>
<SkeletonTable columns={ [ '75%', '25%', '108px' ] }/>
<Skeleton height="44px" width="156px" marginTop={ 8 }/>
</>
);
return (
<>
{ description }
{ loader }
</>
);
}
if (isError) {
if (error.status === 403) {
throw new Error('Unverified email error', { cause: error });
......@@ -77,10 +65,11 @@ const PrivateTransactionTags = () => {
const list = isMobile ? (
<Box>
{ transactionTagsData.map((item) => (
{ transactionTagsData?.map((item, index) => (
<TransactionTagListItem
key={ item.id + (isPlaceholderData ? index : '') }
item={ item }
key={ item.id }
isLoading={ isPlaceholderData }
onDeleteClick={ onDeleteClick }
onEditClick={ onEditClick }
/>
......@@ -89,6 +78,7 @@ const PrivateTransactionTags = () => {
) : (
<TransactionTagTable
data={ transactionTagsData }
isLoading={ isPlaceholderData }
onDeleteClick={ onDeleteClick }
onEditClick={ onEditClick }
/>
......@@ -97,15 +87,15 @@ const PrivateTransactionTags = () => {
return (
<>
{ description }
{ Boolean(transactionTagsData.length) && list }
<Box marginTop={ 8 }>
{ Boolean(transactionTagsData?.length) && list }
<Skeleton mt={ 8 } isLoaded={ !isPlaceholderData } display="inline-block">
<Button
size="lg"
onClick={ transactionModalProps.onOpen }
>
Add transaction tag
</Button>
</Box>
</Skeleton>
<TransactionModal { ...transactionModalProps } onClose={ onAddressModalClose } data={ transactionModalData }/>
{ deleteModalData && (
<DeletePrivateTagModal
......
import { Tag, HStack, Text, Flex } from '@chakra-ui/react';
import { HStack, Text, Flex } from '@chakra-ui/react';
import React, { useCallback } from 'react';
import type { TransactionTag } from 'types/api/account';
import Tag from 'ui/shared/chakra/Tag';
import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
import TableItemActionButtons from 'ui/shared/TableItemActionButtons';
import TransactionSnippet from 'ui/shared/TransactionSnippet';
interface Props {
item: TransactionTag;
isLoading?: boolean;
onEditClick: (data: TransactionTag) => void;
onDeleteClick: (data: TransactionTag) => void;
}
const TransactionTagListItem = ({ item, onEditClick, onDeleteClick }: Props) => {
const TransactionTagListItem = ({ item, isLoading, onEditClick, onDeleteClick }: Props) => {
const onItemEditClick = useCallback(() => {
return onEditClick(item);
}, [ item, onEditClick ]);
......@@ -25,15 +27,13 @@ const TransactionTagListItem = ({ item, onEditClick, onDeleteClick }: Props) =>
return (
<ListItemMobile>
<Flex alignItems="flex-start" flexDirection="column" maxW="100%">
<TransactionSnippet hash={ item.transaction_hash }/>
<TransactionSnippet hash={ item.transaction_hash } isLoading={ isLoading }/>
<HStack spacing={ 3 } mt={ 4 }>
<Text fontSize="sm" fontWeight={ 500 }>Private tag</Text>
<Tag>
{ item.name }
</Tag>
<Tag isLoading={ isLoading } isTruncated>{ item.name }</Tag>
</HStack>
</Flex>
<TableItemActionButtons onDeleteClick={ onItemDeleteClick } onEditClick={ onItemEditClick }/>
<TableItemActionButtons onDeleteClick={ onItemDeleteClick } onEditClick={ onItemEditClick } isLoading={ isLoading }/>
</ListItemMobile>
);
};
......
......@@ -12,12 +12,13 @@ import type { TransactionTags, TransactionTag } from 'types/api/account';
import TransactionTagTableItem from './TransactionTagTableItem';
interface Props {
data: TransactionTags;
data?: TransactionTags;
isLoading: boolean;
onEditClick: (data: TransactionTag) => void;
onDeleteClick: (data: TransactionTag) => void;
}
const AddressTagTable = ({ data, onDeleteClick, onEditClick }: Props) => {
const AddressTagTable = ({ data, isLoading, onDeleteClick, onEditClick }: Props) => {
return (
<Table variant="simple" minWidth="600px">
<Thead>
......@@ -28,10 +29,11 @@ const AddressTagTable = ({ data, onDeleteClick, onEditClick }: Props) => {
</Tr>
</Thead>
<Tbody>
{ data.map((item) => (
{ data?.map((item, index) => (
<TransactionTagTableItem
key={ item.id + (isLoading ? index : '') }
item={ item }
key={ item.id }
isLoading={ isLoading }
onDeleteClick={ onDeleteClick }
onEditClick={ onEditClick }
/>
......
import {
Tag,
Tr,
Td,
Tooltip,
} from '@chakra-ui/react';
import React, { useCallback } from 'react';
import type { TransactionTag } from 'types/api/account';
import Tag from 'ui/shared/chakra/Tag';
import TableItemActionButtons from 'ui/shared/TableItemActionButtons';
import TransactionSnippet from 'ui/shared/TransactionSnippet';
interface Props {
item: TransactionTag;
isLoading?: boolean;
onEditClick: (data: TransactionTag) => void;
onDeleteClick: (data: TransactionTag) => void;
}
const TransactionTagTableItem = ({ item, onEditClick, onDeleteClick }: Props) => {
const TransactionTagTableItem = ({ item, isLoading, onEditClick, onDeleteClick }: Props) => {
const onItemEditClick = useCallback(() => {
return onEditClick(item);
}, [ item, onEditClick ]);
......@@ -29,17 +29,13 @@ const TransactionTagTableItem = ({ item, onEditClick, onDeleteClick }: Props) =>
return (
<Tr alignItems="top" key={ item.id }>
<Td>
<TransactionSnippet hash={ item.transaction_hash }/>
<TransactionSnippet hash={ item.transaction_hash } isLoading={ isLoading }/>
</Td>
<Td>
<Tooltip label={ item.name }>
<Tag>
{ item.name }
</Tag>
</Tooltip>
<Tag isLoading={ isLoading } isTruncated>{ item.name }</Tag>
</Td>
<Td>
<TableItemActionButtons onDeleteClick={ onItemDeleteClick } onEditClick={ onItemEditClick }/>
<TableItemActionButtons onDeleteClick={ onItemDeleteClick } onEditClick={ onItemEditClick } isLoading={ isLoading }/>
</Td>
</Tr>
);
......
......@@ -17,8 +17,8 @@ const TableItemActionButtons = ({ onEditClick, onDeleteClick, isLoading }: Props
if (isLoading) {
return (
<HStack spacing={ 6 } alignSelf="flex-end">
<Skeleton boxSize={ 5 } flexShrink={ 0 } borderRadius="base"/>
<Skeleton boxSize={ 5 } flexShrink={ 0 } borderRadius="base"/>
<Skeleton boxSize={ 5 } flexShrink={ 0 } borderRadius="sm"/>
<Skeleton boxSize={ 5 } flexShrink={ 0 } borderRadius="sm"/>
</HStack>
);
}
......
import { Icon, useColorModeValue } from '@chakra-ui/react';
import { Icon, Skeleton, useColorModeValue } from '@chakra-ui/react';
import React from 'react';
import transactionIcon from 'icons/transactions.svg';
......@@ -8,14 +8,17 @@ import CopyToClipboard from 'ui/shared/CopyToClipboard';
interface Props {
hash: string;
isLoading?: boolean;
}
const TransactionSnippet = ({ hash }: Props) => {
const TransactionSnippet = ({ hash, isLoading }: Props) => {
return (
<Address maxW="100%">
<Skeleton isLoaded={ !isLoading } boxSize={ 6 } borderRadius="base">
<Icon as={ transactionIcon } boxSize={ 6 } color={ useColorModeValue('gray.500', 'gray.400') }/>
<AddressLink hash={ hash } fontWeight="600" type="transaction" ml={ 2 }/>
<CopyToClipboard text={ hash } ml={ 1 }/>
</Skeleton>
<AddressLink hash={ hash } fontWeight="600" type="transaction" ml={ 2 } isLoading={ isLoading }/>
<CopyToClipboard text={ hash } isLoading={ isLoading }/>
</Address>
);
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment