Commit 77f8ec65 authored by tom's avatar tom

public tags page

parent 457a59b9
...@@ -11,6 +11,7 @@ import ApiKeyModal from 'ui/apiKey/ApiKeyModal/ApiKeyModal'; ...@@ -11,6 +11,7 @@ import ApiKeyModal from 'ui/apiKey/ApiKeyModal/ApiKeyModal';
import ApiKeyListItem from 'ui/apiKey/ApiKeyTable/ApiKeyListItem'; import ApiKeyListItem from 'ui/apiKey/ApiKeyTable/ApiKeyListItem';
import ApiKeyTable from 'ui/apiKey/ApiKeyTable/ApiKeyTable'; import ApiKeyTable from 'ui/apiKey/ApiKeyTable/ApiKeyTable';
import DeleteApiKeyModal from 'ui/apiKey/DeleteApiKeyModal'; import DeleteApiKeyModal from 'ui/apiKey/DeleteApiKeyModal';
import AccountPageDescription from 'ui/shared/AccountPageDescription';
import AccountPageHeader from 'ui/shared/AccountPageHeader'; import AccountPageHeader from 'ui/shared/AccountPageHeader';
import Page from 'ui/shared/Page/Page'; import Page from 'ui/shared/Page/Page';
import SkeletonTable from 'ui/shared/SkeletonTable'; import SkeletonTable from 'ui/shared/SkeletonTable';
...@@ -50,10 +51,10 @@ const ApiKeysPage: React.FC = () => { ...@@ -50,10 +51,10 @@ const ApiKeysPage: React.FC = () => {
}, [ deleteModalProps ]); }, [ deleteModalProps ]);
const description = ( const description = (
<Text marginBottom={{ base: 6, lg: 12 }}> <AccountPageDescription>
Create API keys to use for your RPC and EthRPC API requests. For more information, see { space } Create API keys to use for your RPC and EthRPC API requests. For more information, see { space }
<Link href="#">“How to use a Blockscout API key”</Link>. <Link href="#">“How to use a Blockscout API key”</Link>.
</Text> </AccountPageDescription>
); );
const content = (() => { const content = (() => {
......
import { Box, Button, HStack, Text, Skeleton, useDisclosure } from '@chakra-ui/react'; import { Box, Button, HStack, Skeleton, useDisclosure } from '@chakra-ui/react';
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import React, { useCallback, useState } from 'react'; import React, { useCallback, useState } from 'react';
...@@ -10,6 +10,7 @@ import CustomAbiModal from 'ui/customAbi/CustomAbiModal/CustomAbiModal'; ...@@ -10,6 +10,7 @@ import CustomAbiModal from 'ui/customAbi/CustomAbiModal/CustomAbiModal';
import CustomAbiListItem from 'ui/customAbi/CustomAbiTable/CustomAbiListItem'; import CustomAbiListItem from 'ui/customAbi/CustomAbiTable/CustomAbiListItem';
import CustomAbiTable from 'ui/customAbi/CustomAbiTable/CustomAbiTable'; import CustomAbiTable from 'ui/customAbi/CustomAbiTable/CustomAbiTable';
import DeleteCustomAbiModal from 'ui/customAbi/DeleteCustomAbiModal'; import DeleteCustomAbiModal from 'ui/customAbi/DeleteCustomAbiModal';
import AccountPageDescription from 'ui/shared/AccountPageDescription';
import AccountPageHeader from 'ui/shared/AccountPageHeader'; import AccountPageHeader from 'ui/shared/AccountPageHeader';
import Page from 'ui/shared/Page/Page'; import Page from 'ui/shared/Page/Page';
import SkeletonTable from 'ui/shared/SkeletonTable'; import SkeletonTable from 'ui/shared/SkeletonTable';
...@@ -47,9 +48,9 @@ const CustomAbiPage: React.FC = () => { ...@@ -47,9 +48,9 @@ const CustomAbiPage: React.FC = () => {
}, [ deleteModalProps ]); }, [ deleteModalProps ]);
const description = ( const description = (
<Text marginBottom={{ base: 6, lg: 12 }}> <AccountPageDescription>
Add custom ABIs for any contract and access when logged into your account. Helpful for debugging, functional testing and contract interaction. Add custom ABIs for any contract and access when logged into your account. Helpful for debugging, functional testing and contract interaction.
</Text> </AccountPageDescription>
); );
const content = (() => { const content = (() => {
......
import { Tag, VStack, Text, HStack } from '@chakra-ui/react';
import React, { useCallback } from 'react';
import type { PublicTag } from 'types/api/account';
import AccountListItemMobile from 'ui/shared/AccountListItemMobile';
import AddressSnippet from 'ui/shared/AddressSnippet';
import TableItemActionButtons from 'ui/shared/TableItemActionButtons';
import TruncatedTextTooltip from 'ui/shared/TruncatedTextTooltip';
interface Props {
item: PublicTag;
onEditClick: (data: PublicTag) => void;
onDeleteClick: (data: PublicTag) => void;
}
const PublicTagListItem = ({ item, onEditClick, onDeleteClick }: Props) => {
const onItemEditClick = useCallback(() => {
return onEditClick(item);
}, [ item, onEditClick ]);
const onItemDeleteClick = useCallback(() => {
return onDeleteClick(item);
}, [ item, onDeleteClick ]);
return (
<AccountListItemMobile>
<VStack spacing={ 4 } alignItems="flex-start" maxW="100%">
<VStack spacing={ 4 } alignItems="unset" maxW="100%">
{ item.addresses.map((address) => <AddressSnippet key={ address } address={ address }/>) }
</VStack>
<HStack spacing={ 3 }>
<Text fontSize="sm" fontWeight={ 500 }>Public tags</Text>
<HStack spacing={ 2 } alignItems="baseline">
{ item.tags.split(';').map((tag) => {
return (
<TruncatedTextTooltip label={ tag } key={ tag }>
<Tag variant="gray" lineHeight="24px">
{ tag }
</Tag>
</TruncatedTextTooltip>
);
}) }
</HStack>
</HStack>
<Text fontSize="sm" fontWeight="500">Submitted</Text>
</VStack>
<TableItemActionButtons onDeleteClick={ onItemDeleteClick } onEditClick={ onItemEditClick }/>
</AccountListItemMobile>
);
};
export default React.memo(PublicTagListItem);
...@@ -2,7 +2,6 @@ import { ...@@ -2,7 +2,6 @@ import {
Tag, Tag,
Tr, Tr,
Td, Td,
HStack,
VStack, VStack,
Text, Text,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
...@@ -11,8 +10,7 @@ import React, { useCallback } from 'react'; ...@@ -11,8 +10,7 @@ import React, { useCallback } from 'react';
import type { PublicTag } from 'types/api/account'; import type { PublicTag } from 'types/api/account';
import AddressSnippet from 'ui/shared/AddressSnippet'; import AddressSnippet from 'ui/shared/AddressSnippet';
import DeleteButton from 'ui/shared/DeleteButton'; import TableItemActionButtons from 'ui/shared/TableItemActionButtons';
import EditButton from 'ui/shared/EditButton';
import TruncatedTextTooltip from 'ui/shared/TruncatedTextTooltip'; import TruncatedTextTooltip from 'ui/shared/TruncatedTextTooltip';
interface Props { interface Props {
...@@ -56,10 +54,7 @@ const PublicTagTableItem = ({ item, onEditClick, onDeleteClick }: Props) => { ...@@ -56,10 +54,7 @@ const PublicTagTableItem = ({ item, onEditClick, onDeleteClick }: Props) => {
</VStack> </VStack>
</Td> </Td>
<Td> <Td>
<HStack spacing={ 6 }> <TableItemActionButtons onDeleteClick={ onItemDeleteClick } onEditClick={ onItemEditClick }/>
<EditButton onClick={ onItemEditClick }/>
<DeleteButton onClick={ onItemDeleteClick }/>
</HStack>
</Td> </Td>
</Tr> </Tr>
); );
......
import { Box, Text, Button, Skeleton, useDisclosure } from '@chakra-ui/react'; import { Box, Button, Skeleton, useDisclosure } from '@chakra-ui/react';
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import React, { useCallback, useState } from 'react'; import React, { useCallback, useState } from 'react';
import type { PublicTags, PublicTag } from 'types/api/account'; import type { PublicTags, PublicTag } from 'types/api/account';
import fetch from 'lib/client/fetch'; import fetch from 'lib/client/fetch';
import useIsMobile from 'lib/hooks/useIsMobile';
import PublicTagListItem from 'ui/publicTags/PublicTagTable/PublicTagListItem';
import AccountPageDescription from 'ui/shared/AccountPageDescription';
import DataFetchAlert from 'ui/shared/DataFetchAlert'; import DataFetchAlert from 'ui/shared/DataFetchAlert';
import SkeletonTable from 'ui/shared/SkeletonTable'; import SkeletonTable from 'ui/shared/SkeletonTable';
...@@ -19,6 +22,7 @@ type Props = { ...@@ -19,6 +22,7 @@ type Props = {
const PublicTagsData = ({ changeToFormScreen, onTagDelete }: Props) => { const PublicTagsData = ({ changeToFormScreen, onTagDelete }: Props) => {
const deleteModalProps = useDisclosure(); const deleteModalProps = useDisclosure();
const [ deleteModalData, setDeleteModalData ] = useState<PublicTag>(); const [ deleteModalData, setDeleteModalData ] = useState<PublicTag>();
const isMobile = useIsMobile();
const { data, isLoading, isError } = useQuery<unknown, unknown, PublicTags>([ 'public-tags' ], async() => await fetch('/api/account/public-tags')); const { data, isLoading, isError } = useQuery<unknown, unknown, PublicTags>([ 'public-tags' ], async() => await fetch('/api/account/public-tags'));
...@@ -41,12 +45,12 @@ const PublicTagsData = ({ changeToFormScreen, onTagDelete }: Props) => { ...@@ -41,12 +45,12 @@ const PublicTagsData = ({ changeToFormScreen, onTagDelete }: Props) => {
}, [ deleteModalProps ]); }, [ deleteModalProps ]);
const description = ( const description = (
<Text marginBottom={ 12 }> <AccountPageDescription>
You can request a public category tag which is displayed to all Blockscout users. You can request a public category tag which is displayed to all Blockscout users.
Public tags may be added to contract or external addresses, and any associated transactions will inherit that tag. Public tags may be added to contract or external addresses, and any associated transactions will inherit that tag.
Clicking a tag opens a page with related information and helps provide context and data organization. Clicking a tag opens a page with related information and helps provide context and data organization.
Requests are sent to a moderator for review and approval. This process can take several days. Requests are sent to a moderator for review and approval. This process can take several days.
</Text> </AccountPageDescription>
); );
if (isLoading) { if (isLoading) {
...@@ -63,10 +67,25 @@ const PublicTagsData = ({ changeToFormScreen, onTagDelete }: Props) => { ...@@ -63,10 +67,25 @@ const PublicTagsData = ({ changeToFormScreen, onTagDelete }: Props) => {
return <DataFetchAlert/>; return <DataFetchAlert/>;
} }
const list = isMobile ? (
<Box>
{ data.map((item) => (
<PublicTagListItem
item={ item }
key={ item.id }
onDeleteClick={ onItemDeleteClick }
onEditClick={ onItemEditClick }
/>
)) }
</Box>
) : (
<PublicTagTable data={ data } onEditClick={ onItemEditClick } onDeleteClick={ onItemDeleteClick }/>
);
return ( return (
<> <>
{ description } { description }
{ data.length > 0 && <PublicTagTable data={ data } onEditClick={ onItemEditClick } onDeleteClick={ onItemDeleteClick }/> } { data.length > 0 && list }
<Box marginTop={ 8 }> <Box marginTop={ 8 }>
<Button <Button
variant="primary" variant="primary"
......
import { Text } from '@chakra-ui/react';
import React from 'react';
const AccountPageDescription = ({ children }: {children: React.ReactNode}) => {
return (
<Text marginBottom={{ base: 6, lg: 12 }}>
{ children }
</Text>
);
};
export default AccountPageDescription;
import { Heading } from '@chakra-ui/react'; import { Heading } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
const PageHeader = ({ text }: {text: string}) => { const AccountPageHeader = ({ text }: {text: string}) => {
return ( return (
<Heading as="h1" size="lg" marginBottom={{ base: 6, lg: 8 }}>{ text }</Heading> <Heading as="h1" size="lg" marginBottom={{ base: 6, lg: 8 }}>{ text }</Heading>
); );
}; };
export default PageHeader; export default AccountPageHeader;
...@@ -4,7 +4,7 @@ import Jazzicon, { jsNumberForAddress } from 'react-jazzicon'; ...@@ -4,7 +4,7 @@ import Jazzicon, { jsNumberForAddress } from 'react-jazzicon';
const AddressIcon = ({ address }: {address: string}) => { const AddressIcon = ({ address }: {address: string}) => {
return ( return (
<Box width="24px"> <Box width="24px" display="inline-flex">
<Jazzicon diameter={ 24 } seed={ jsNumberForAddress(address) }/> <Jazzicon diameter={ 24 } seed={ jsNumberForAddress(address) }/>
</Box> </Box>
); );
......
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