Commit 69ca5430 authored by tom's avatar tom

fix more ts errors

parent 49a53378
...@@ -2,12 +2,12 @@ import { usePathname } from 'next/navigation'; ...@@ -2,12 +2,12 @@ import { usePathname } from 'next/navigation';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import React from 'react'; import React from 'react';
import type { ColorMode } from 'toolkit/chakra/color-mode';
import { useColorMode } from 'toolkit/chakra/color-mode';
import config from 'configs/app'; import config from 'configs/app';
import * as cookies from 'lib/cookies'; import * as cookies from 'lib/cookies';
import getQueryParamString from 'lib/router/getQueryParamString'; import getQueryParamString from 'lib/router/getQueryParamString';
import { COLOR_THEMES } from 'lib/settings/colorTheme'; import { COLOR_THEMES } from 'lib/settings/colorTheme';
import { useColorMode } from 'toolkit/chakra/color-mode';
import type { ColorMode } from 'toolkit/chakra/color-mode';
import getPageType from './getPageType'; import getPageType from './getPageType';
import getTabName from './getTabName'; import getTabName from './getTabName';
......
...@@ -56,7 +56,7 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) { ...@@ -56,7 +56,7 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
React.useEffect(() => { React.useEffect(() => {
setMounted(true); setMounted(true);
}, []); }, []);
useLoadFeatures(pageProps.uuid); useLoadFeatures(pageProps.uuid);
useNotifyOnNavigation(); useNotifyOnNavigation();
......
...@@ -35,6 +35,8 @@ export const Alert = React.forwardRef<HTMLDivElement, AlertProps>( ...@@ -35,6 +35,8 @@ export const Alert = React.forwardRef<HTMLDivElement, AlertProps>(
...rest ...rest
} = props; } = props;
const [ isOpen, setIsOpen ] = React.useState(true);
const defaultIcon = <IconSvg name="info_filled" w="100%" h="100%"/>; const defaultIcon = <IconSvg name="info_filled" w="100%" h="100%"/>;
const iconElement = (() => { const iconElement = (() => {
...@@ -49,6 +51,15 @@ export const Alert = React.forwardRef<HTMLDivElement, AlertProps>( ...@@ -49,6 +51,15 @@ export const Alert = React.forwardRef<HTMLDivElement, AlertProps>(
return <ChakraAlert.Indicator>{ icon || defaultIcon }</ChakraAlert.Indicator>; return <ChakraAlert.Indicator>{ icon || defaultIcon }</ChakraAlert.Indicator>;
})(); })();
const handleClose = React.useCallback(() => {
setIsOpen(false);
onClose?.();
}, [ onClose ]);
if (closable && !isOpen) {
return null;
}
return ( return (
<Skeleton loading={ loading } asChild> <Skeleton loading={ loading } asChild>
<ChakraAlert.Root ref={ ref } { ...rest }> <ChakraAlert.Root ref={ ref } { ...rest }>
...@@ -67,7 +78,7 @@ export const Alert = React.forwardRef<HTMLDivElement, AlertProps>( ...@@ -67,7 +78,7 @@ export const Alert = React.forwardRef<HTMLDivElement, AlertProps>(
pos="relative" pos="relative"
size="sm" size="sm"
alignSelf="flex-start" alignSelf="flex-start"
onClick={ onClose } onClick={ handleClose }
/> />
) } ) }
</ChakraAlert.Root> </ChakraAlert.Root>
......
...@@ -32,7 +32,7 @@ export interface CheckboxGroupProps extends HTMLChakraProps<'div', ArkCheckbox.G ...@@ -32,7 +32,7 @@ export interface CheckboxGroupProps extends HTMLChakraProps<'div', ArkCheckbox.G
export const CheckboxGroup = React.forwardRef<HTMLDivElement, CheckboxGroupProps>( export const CheckboxGroup = React.forwardRef<HTMLDivElement, CheckboxGroupProps>(
function CheckboxGroup(props, ref) { function CheckboxGroup(props, ref) {
const { children, orientation = 'horizontal', ...rest } = props; const { children, orientation = 'vertical', ...rest } = props;
return ( return (
<ChakraCheckboxGroup <ChakraCheckboxGroup
ref={ ref } ref={ ref }
......
...@@ -51,6 +51,14 @@ export interface SkeletonProps extends Omit<ChakraSkeletonProps, 'loading'> { ...@@ -51,6 +51,14 @@ export interface SkeletonProps extends Omit<ChakraSkeletonProps, 'loading'> {
export const Skeleton = React.forwardRef<HTMLDivElement, SkeletonProps>( export const Skeleton = React.forwardRef<HTMLDivElement, SkeletonProps>(
function Skeleton(props, ref) { function Skeleton(props, ref) {
const { loading = false, ...rest } = props; const { loading = false, ...rest } = props;
return <ChakraSkeleton loading={ loading } { ...(loading ? { 'data-loading': true } : {}) } { ...rest } ref={ ref }/>; return (
<ChakraSkeleton
loading={ loading }
css={ !loading ? { animation: 'none' } : {} }
{ ...(loading ? { 'data-loading': true } : {}) }
{ ...rest }
ref={ ref }
/>
);
}, },
); );
// eslint-disable-next-line no-restricted-imports /* eslint-disable no-restricted-imports */
import type { UseDisclosureProps } from '@chakra-ui/react';
import { useDisclosure as useDisclosureChakra } from '@chakra-ui/react'; import { useDisclosure as useDisclosureChakra } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
export function useDisclosure() { export function useDisclosure(props?: UseDisclosureProps) {
const { open, onOpen, onClose, onToggle } = useDisclosureChakra(); const { open, onOpen, onClose, onToggle } = useDisclosureChakra(props);
const onOpenChange = React.useCallback(({ open }: { open: boolean }) => { const onOpenChange = React.useCallback(({ open }: { open: boolean }) => {
if (open) { if (open) {
...@@ -13,11 +14,11 @@ export function useDisclosure() { ...@@ -13,11 +14,11 @@ export function useDisclosure() {
} }
}, [ onOpen, onClose ]); }, [ onOpen, onClose ]);
return { return React.useMemo(() => ({
open, open,
onOpenChange, onOpenChange,
onClose, onClose,
onOpen, onOpen,
onToggle, onToggle,
}; }), [ open, onOpenChange, onClose, onOpen, onToggle ]);
} }
...@@ -68,6 +68,6 @@ export const recipe = defineSlotRecipe({ ...@@ -68,6 +68,6 @@ export const recipe = defineSlotRecipe({
defaultVariants: { defaultVariants: {
size: 'md', size: 'md',
variant: 'solid', variant: 'solid',
orientation: 'horizontal', orientation: 'vertical',
}, },
}); });
...@@ -111,7 +111,6 @@ const ContractSubmitAuditForm = ({ address, onSuccess }: Props) => { ...@@ -111,7 +111,6 @@ const ContractSubmitAuditForm = ({ address, onSuccess }: Props) => {
</VStack> </VStack>
<Button <Button
type="submit" type="submit"
size="lg"
mt={ 8 } mt={ 8 }
loading={ formState.isSubmitting } loading={ formState.isSubmitting }
loadingText="Send request" loadingText="Send request"
......
...@@ -114,7 +114,7 @@ const AddressVerificationStepAddress = ({ defaultAddress, onContinue }: Props) = ...@@ -114,7 +114,7 @@ const AddressVerificationStepAddress = ({ defaultAddress, onContinue }: Props) =
mt={ 8 } mt={ 8 }
/> />
<Flex alignItems={{ base: 'flex-start', lg: 'center' }} mt={ 8 } columnGap={ 5 } rowGap={ 2 } flexDir={{ base: 'column', lg: 'row' }}> <Flex alignItems={{ base: 'flex-start', lg: 'center' }} mt={ 8 } columnGap={ 5 } rowGap={ 2 } flexDir={{ base: 'column', lg: 'row' }}>
<Button size="lg" type="submit" loading={ formState.isSubmitting } loadingText="Continue" flexShrink={ 0 }> <Button type="submit" loading={ formState.isSubmitting } loadingText="Continue" flexShrink={ 0 }>
Continue Continue
</Button> </Button>
<AdminSupportText/> <AdminSupportText/>
......
...@@ -123,7 +123,6 @@ const AddressVerificationStepSignature = ({ address, signingMessage, contractCre ...@@ -123,7 +123,6 @@ const AddressVerificationStepSignature = ({ address, signingMessage, contractCre
if (signMethod === 'manual') { if (signMethod === 'manual') {
return ( return (
<Button <Button
size="lg"
onClick={ handleManualSignClick } onClick={ handleManualSignClick }
loading={ formState.isSubmitting } loading={ formState.isSubmitting }
loadingText="Verifying" loadingText="Verifying"
...@@ -135,7 +134,6 @@ const AddressVerificationStepSignature = ({ address, signingMessage, contractCre ...@@ -135,7 +134,6 @@ const AddressVerificationStepSignature = ({ address, signingMessage, contractCre
return ( return (
<Button <Button
size="lg"
onClick={ isConnected ? handleWeb3SignClick : handleOpenWeb3Modal } onClick={ isConnected ? handleWeb3SignClick : handleOpenWeb3Modal }
loading={ formState.isSubmitting || isSigning } loading={ formState.isSubmitting || isSigning }
loadingText={ isSigning ? 'Signing' : 'Verifying' } loadingText={ isSigning ? 'Signing' : 'Verifying' }
......
...@@ -21,11 +21,11 @@ const AddressVerificationStepSuccess = ({ onAddTokenInfoClick, onShowListClick, ...@@ -21,11 +21,11 @@ const AddressVerificationStepSuccess = ({ onAddTokenInfoClick, onShowListClick,
</Alert> </Alert>
<p>You may now submit the “Add token information” request</p> <p>You may now submit the “Add token information” request</p>
<Flex alignItems="center" mt={ 8 } columnGap={ 5 } flexWrap="wrap" rowGap={ 5 }> <Flex alignItems="center" mt={ 8 } columnGap={ 5 } flexWrap="wrap" rowGap={ 5 }>
<Button size="lg" variant={ isToken ? 'outline' : 'solid' } onClick={ onShowListClick }> <Button variant={ isToken ? 'outline' : 'solid' } onClick={ onShowListClick }>
View my verified addresses View my verified addresses
</Button> </Button>
{ isToken && ( { isToken && (
<Button size="lg" onClick={ onAddTokenInfoClick }> <Button onClick={ onAddTokenInfoClick }>
Add token information Add token information
</Button> </Button>
) } ) }
......
...@@ -39,7 +39,7 @@ const TypeFilter = ({ value = [ RESET_VALUE ], handleFilterChange }: Props) => { ...@@ -39,7 +39,7 @@ const TypeFilter = ({ value = [ RESET_VALUE ], handleFilterChange }: Props) => {
const onReset = React.useCallback(() => setCurrentValue([ RESET_VALUE ]), []); const onReset = React.useCallback(() => setCurrentValue([ RESET_VALUE ]), []);
const onFilter = React.useCallback(() => { const onFilter = React.useCallback(() => {
const value: Array<AdvancedFilterType> = currentValue.filter(item => item !== RESET_VALUE); const value: Array<AdvancedFilterType> = currentValue.filter(item => item !== RESET_VALUE) as Array<AdvancedFilterType>;
handleFilterChange(FILTER_PARAM, value); handleFilterChange(FILTER_PARAM, value);
}, [ handleFilterChange, currentValue ]); }, [ handleFilterChange, currentValue ]);
......
...@@ -113,7 +113,6 @@ const ApiKeyForm: React.FC<Props> = ({ data, onOpenChange, setAlertVisible }) => ...@@ -113,7 +113,6 @@ const ApiKeyForm: React.FC<Props> = ({ data, onOpenChange, setAlertVisible }) =>
/> />
<Box marginTop={ 8 }> <Box marginTop={ 8 }>
<Button <Button
size="lg"
type="submit" type="submit"
disabled={ !formApi.formState.isDirty } disabled={ !formApi.formState.isDirty }
loading={ isPending } loading={ isPending }
......
...@@ -10,7 +10,6 @@ import { WEI, ZERO_ADDRESS } from 'lib/consts'; ...@@ -10,7 +10,6 @@ import { WEI, ZERO_ADDRESS } from 'lib/consts';
import { Link } from 'toolkit/chakra/link'; import { Link } from 'toolkit/chakra/link';
import AddressFromTo from 'ui/shared/address/AddressFromTo'; import AddressFromTo from 'ui/shared/address/AddressFromTo';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo'; import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import TokenEntity from 'ui/shared/entities/token/TokenEntity'; import TokenEntity from 'ui/shared/entities/token/TokenEntity';
import IconSvg from 'ui/shared/IconSvg'; import IconSvg from 'ui/shared/IconSvg';
......
...@@ -9,7 +9,6 @@ import { space } from 'lib/html-entities'; ...@@ -9,7 +9,6 @@ import { space } from 'lib/html-entities';
import { currencyUnits } from 'lib/units'; import { currencyUnits } from 'lib/units';
import { Tooltip } from 'toolkit/chakra/tooltip'; import { Tooltip } from 'toolkit/chakra/tooltip';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo'; import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import IconSvg from 'ui/shared/IconSvg'; import IconSvg from 'ui/shared/IconSvg';
import Utilization from 'ui/shared/Utilization/Utilization'; import Utilization from 'ui/shared/Utilization/Utilization';
......
import { Accordion, AccordionButton, AccordionIcon, AccordionItem, AccordionPanel, Divider, Grid, GridItem, useColorModeValue } from '@chakra-ui/react'; import { Separator, Grid, GridItem } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { ZilliqaNestedQuorumCertificate, ZilliqaQuorumCertificate } from 'types/api/block'; import type { ZilliqaNestedQuorumCertificate, ZilliqaQuorumCertificate } from 'types/api/block';
import { apos, ndash } from 'lib/html-entities'; import { apos, ndash } from 'lib/html-entities';
import { AccordionRoot, AccordionItem, AccordionItemTrigger, AccordionItemContent } from 'toolkit/chakra/accordion';
import CopyToClipboard from 'ui/shared/CopyToClipboard'; import CopyToClipboard from 'ui/shared/CopyToClipboard';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo'; import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import Hint from 'ui/shared/Hint'; import Hint from 'ui/shared/Hint';
function formatSigners(signers: Array<number>) { function formatSigners(signers: Array<number>) {
...@@ -20,8 +20,6 @@ interface Props { ...@@ -20,8 +20,6 @@ interface Props {
} }
const BlockDetailsZilliqaQuorumCertificate = ({ data }: Props) => { const BlockDetailsZilliqaQuorumCertificate = ({ data }: Props) => {
const nestedBlockBgColor = useColorModeValue('blackAlpha.50', 'whiteAlpha.50');
const hint = (isNested?: boolean) => ( const hint = (isNested?: boolean) => (
<> <>
The iteration of the consensus round in which the block was proposed:<br/><br/> The iteration of the consensus round in which the block was proposed:<br/><br/>
...@@ -46,8 +44,7 @@ const BlockDetailsZilliqaQuorumCertificate = ({ data }: Props) => { ...@@ -46,8 +44,7 @@ const BlockDetailsZilliqaQuorumCertificate = ({ data }: Props) => {
</DetailedInfo.ItemLabel> </DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue rowGap={ 0 }> <DetailedInfo.ItemValue rowGap={ 0 }>
<Grid <Grid
fontSize="sm" textStyle="sm"
lineHeight={ 5 }
gridTemplateColumns="min-content 1fr" gridTemplateColumns="min-content 1fr"
columnGap={ 5 } columnGap={ 5 }
> >
...@@ -61,66 +58,56 @@ const BlockDetailsZilliqaQuorumCertificate = ({ data }: Props) => { ...@@ -61,66 +58,56 @@ const BlockDetailsZilliqaQuorumCertificate = ({ data }: Props) => {
</GridItem> </GridItem>
<DetailedInfo.ItemDivider my={{ base: 2, lg: 2 }} colSpan={ 2 }/> <DetailedInfo.ItemDivider my={{ base: 2, lg: 2 }} colSpan={ 2 }/>
<GridItem fontWeight={ 600 }>Signers</GridItem> <GridItem fontWeight={ 600 }>Signers</GridItem>
<GridItem >{ formatSigners(data.signers) }</GridItem> <GridItem whiteSpace="pre-wrap">{ formatSigners(data.signers) }</GridItem>
</Grid> </Grid>
{ data.nested_quorum_certificates && data.nested_quorum_certificates.length > 0 && ( { data.nested_quorum_certificates && data.nested_quorum_certificates.length > 0 && (
<> <>
<Divider my={ 2 }/> <Separator my={ 2 }/>
<Accordion <AccordionRoot
allowToggle multiple
w="100%" w="100%"
fontSize="sm" textStyle="sm"
lineHeight={ 5 }
> >
<AccordionItem borderWidth={ 0 } _last={{ borderBottomWidth: 0 }}> <AccordionItem
{ ({ isExpanded }) => ( value="nested-quorum-certificates"
<> borderWidth={ 0 }
<AccordionButton _last={{ borderBottomWidth: 0 }}
fontSize="sm" >
lineHeight={ 5 } <AccordionItemTrigger
fontWeight={ 600 } textStyle="sm"
display="flex" fontWeight={ 600 }
alignItems="center" >
columnGap={ 1 } <span>Nested quorum certificates</span>
px={ 0 } <Hint label={ hint(true) }/>
pt={ 0 } </AccordionItemTrigger>
pb={ 2 } <AccordionItemContent display="flex" flexDirection="column" rowGap={ 2 } p={ 0 }>
_hover={{ bgColor: 'inherit' }} { data.nested_quorum_certificates?.map((item, index) => (
<Grid
key={ index }
gridTemplateColumns="90px 1fr"
columnGap={ 3 }
rowGap={ 2 }
bgColor={{ _light: 'blackAlpha.50', _dark: 'whiteAlpha.50' }}
p={ 4 }
borderRadius="md"
_first={{ borderTopRightRadius: 0, borderTopLeftRadius: 0 }}
> >
<span>Nested quorum certificates</span> <GridItem>View</GridItem>
<Hint label={ hint(true) }/> <GridItem>{ item.view }</GridItem>
<AccordionIcon flexShrink={ 0 } boxSize={ 5 } transform={ isExpanded ? 'rotate(0deg)' : 'rotate(-90deg)' } color="gray.500"/> <GridItem>Signature</GridItem>
</AccordionButton> <GridItem whiteSpace="pre-wrap" wordBreak="break-word" display="flex" alignItems="flex-start" columnGap={ 3 }>
<AccordionPanel display="flex" flexDirection="column" rowGap={ 2 } p={ 0 }> { item.signature }
{ data.nested_quorum_certificates?.map((item, index) => ( <CopyToClipboard text={ item.signature }/>
<Grid </GridItem>
key={ index } <GridItem>Signers</GridItem>
gridTemplateColumns="90px 1fr" <GridItem >{ formatSigners(item.signers) }</GridItem>
columnGap={ 3 } <GridItem whiteSpace="pre-wrap">Proposed by validator</GridItem>
rowGap={ 2 } <GridItem >{ item.proposed_by_validator_index }</GridItem>
bgColor={ nestedBlockBgColor } </Grid>
p={ 4 } )) }
borderRadius="md" </AccordionItemContent>
_first={{ borderTopRightRadius: 0, borderTopLeftRadius: 0 }}
>
<GridItem>View</GridItem>
<GridItem>{ item.view }</GridItem>
<GridItem>Signature</GridItem>
<GridItem whiteSpace="pre-wrap" wordBreak="break-word" display="flex" alignItems="flex-start" columnGap={ 3 }>
{ item.signature }
<CopyToClipboard text={ item.signature }/>
</GridItem>
<GridItem>Signers</GridItem>
<GridItem >{ formatSigners(item.signers) }</GridItem>
<GridItem whiteSpace="pre-wrap">Proposed by validator</GridItem>
<GridItem >{ item.proposed_by_validator_index }</GridItem>
</Grid>
)) }
</AccordionPanel>
</>
) }
</AccordionItem> </AccordionItem>
</Accordion> </AccordionRoot>
</> </>
) } ) }
</DetailedInfo.ItemValue> </DetailedInfo.ItemValue>
......
...@@ -3,8 +3,8 @@ import React from 'react'; ...@@ -3,8 +3,8 @@ import React from 'react';
import { useFormContext } from 'react-hook-form'; import { useFormContext } from 'react-hook-form';
import type { FormFields } from '../types'; import type { FormFields } from '../types';
import type { Option } from 'ui/shared/forms/inputs/select/types';
import type { SelectOption } from 'toolkit/chakra/select';
import FormFieldSelect from 'ui/shared/forms/fields/FormFieldSelect'; import FormFieldSelect from 'ui/shared/forms/fields/FormFieldSelect';
import ContractVerificationFormRow from '../ContractVerificationFormRow'; import ContractVerificationFormRow from '../ContractVerificationFormRow';
...@@ -12,7 +12,7 @@ import ContractVerificationFormRow from '../ContractVerificationFormRow'; ...@@ -12,7 +12,7 @@ import ContractVerificationFormRow from '../ContractVerificationFormRow';
const SOURCIFY_ERROR_REGEXP = /\(([^()]*)\)/; const SOURCIFY_ERROR_REGEXP = /\(([^()]*)\)/;
const ContractVerificationFieldContractIndex = () => { const ContractVerificationFieldContractIndex = () => {
const [ options, setOptions ] = React.useState<Array<Option>>([]); const [ options, setOptions ] = React.useState<Array<SelectOption>>([]);
const { formState, watch } = useFormContext<FormFields>(); const { formState, watch } = useFormContext<FormFields>();
const sources = watch('sources'); const sources = watch('sources');
......
...@@ -104,7 +104,6 @@ const CsvExportForm = ({ hash, resource, filterType, filterValue, fileNameTempla ...@@ -104,7 +104,6 @@ const CsvExportForm = ({ hash, resource, filterType, filterValue, fileNameTempla
<ReCaptcha ref={ recaptcha.ref }/> <ReCaptcha ref={ recaptcha.ref }/>
<Button <Button
variant="solid" variant="solid"
size="lg"
type="submit" type="submit"
mt={ 8 } mt={ 8 }
loading={ formState.isSubmitting } loading={ formState.isSubmitting }
......
...@@ -135,7 +135,6 @@ const CustomAbiForm: React.FC<Props> = ({ data, onOpenChange, onSuccess, setAler ...@@ -135,7 +135,6 @@ const CustomAbiForm: React.FC<Props> = ({ data, onOpenChange, onSuccess, setAler
/> />
<Box> <Box>
<Button <Button
size="lg"
type="submit" type="submit"
disabled={ !formApi.formState.isDirty } disabled={ !formApi.formState.isDirty }
loading={ isPending } loading={ isPending }
......
import { Link } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { MarketplaceAppSocialInfo } from 'types/client/marketplace'; import type { MarketplaceAppSocialInfo } from 'types/client/marketplace';
import { Link } from 'toolkit/chakra/link';
import type { IconName } from 'ui/shared/IconSvg'; import type { IconName } from 'ui/shared/IconSvg';
import IconSvg from 'ui/shared/IconSvg'; import IconSvg from 'ui/shared/IconSvg';
...@@ -23,7 +23,7 @@ const SocialLink = ({ href, icon, title }: Props) => { ...@@ -23,7 +23,7 @@ const SocialLink = ({ href, icon, title }: Props) => {
display="inline-flex" display="inline-flex"
alignItems="center" alignItems="center"
> >
<IconSvg name={ icon } boxSize={ 5 } mr={ 2 } color="text_secondary"/> <IconSvg name={ icon } boxSize={ 5 } mr={ 2 } color="text.secondary"/>
<span>{ title }</span> <span>{ title }</span>
</Link> </Link>
); );
......
import { Box, CheckboxGroup, Fieldset, Flex, HStack, Text, chakra, createListCollection } from '@chakra-ui/react'; import { Box, Fieldset, Flex, HStack, Text, chakra, createListCollection } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type * as bens from '@blockscout/bens-types'; import type * as bens from '@blockscout/bens-types';
...@@ -7,7 +7,7 @@ import type { PaginationParams } from 'ui/shared/pagination/types'; ...@@ -7,7 +7,7 @@ import type { PaginationParams } from 'ui/shared/pagination/types';
import useIsInitialLoading from 'lib/hooks/useIsInitialLoading'; import useIsInitialLoading from 'lib/hooks/useIsInitialLoading';
import { Button } from 'toolkit/chakra/button'; import { Button } from 'toolkit/chakra/button';
import { Checkbox } from 'toolkit/chakra/checkbox'; import { Checkbox, CheckboxGroup } from 'toolkit/chakra/checkbox';
import { Image } from 'toolkit/chakra/image'; import { Image } from 'toolkit/chakra/image';
import ActionBar from 'ui/shared/ActionBar'; import ActionBar from 'ui/shared/ActionBar';
import FilterInput from 'ui/shared/filters/FilterInput'; import FilterInput from 'ui/shared/filters/FilterInput';
...@@ -95,32 +95,28 @@ const NameDomainsActionBar = ({ ...@@ -95,32 +95,28 @@ const NameDomainsActionBar = ({
Reset Reset
</Button> </Button>
</Flex> </Flex>
<Fieldset.Root> <CheckboxGroup defaultValue={ protocolsFilterValue } onValueChange={ onProtocolsFilterChange } value={ protocolsFilterValue } name="token_type">
<CheckboxGroup defaultValue={ protocolsFilterValue } onValueChange={ onProtocolsFilterChange } value={ protocolsFilterValue } name="token_type"> { protocolsData.map((protocol) => {
<Fieldset.Content gap={ 5 } alignItems="flex-start"> const topLevelDomains = protocol.tld_list.map((domain) => `.${ domain }`).join(' ');
{ protocolsData.map((protocol) => { return (
const topLevelDomains = protocol.tld_list.map((domain) => `.${ domain }`).join(' '); <Checkbox key={ protocol.id } value={ protocol.id }>
return ( <Flex alignItems="center">
<Checkbox key={ protocol.id } value={ protocol.id }> <Image
<Flex alignItems="center"> src={ protocol.icon_url }
<Image boxSize={ 5 }
src={ protocol.icon_url } borderRadius="sm"
boxSize={ 5 } mr={ 2 }
borderRadius="sm" alt={ `${ protocol.title } protocol icon` }
mr={ 2 } fallback={ <IconSvg name="ENS_slim" boxSize={ 5 } mr={ 2 }/> }
alt={ `${ protocol.title } protocol icon` } // fallbackStrategy={ protocol.icon_url ? 'onError' : 'beforeLoadOrError' }
fallback={ <IconSvg name="ENS_slim" boxSize={ 5 } mr={ 2 }/> } />
// fallbackStrategy={ protocol.icon_url ? 'onError' : 'beforeLoadOrError' } <span>{ protocol.short_name }</span>
/> <chakra.span color="text.secondary" whiteSpace="pre"> { topLevelDomains }</chakra.span>
<span>{ protocol.short_name }</span> </Flex>
<chakra.span color="text_secondary" whiteSpace="pre"> { topLevelDomains }</chakra.span> </Checkbox>
</Flex> );
</Checkbox> }) }
); </CheckboxGroup>
}) }
</Fieldset.Content>
</CheckboxGroup>
</Fieldset.Root>
{ filterGroupDivider } { filterGroupDivider }
</> </>
) } ) }
...@@ -133,7 +129,7 @@ const NameDomainsActionBar = ({ ...@@ -133,7 +129,7 @@ const NameDomainsActionBar = ({
</Checkbox> </Checkbox>
<Checkbox <Checkbox
value="resolved_to" value="resolved_to"
mt={ 5 } mt={ 3 }
disabled={ !isAddressSearch } disabled={ !isAddressSearch }
> >
Resolved to address Resolved to address
......
...@@ -108,7 +108,6 @@ const ApiKeysPage: React.FC = () => { ...@@ -108,7 +108,6 @@ const ApiKeysPage: React.FC = () => {
rowGap={ 5 } rowGap={ 5 }
> >
<Button <Button
size="lg"
onClick={ apiKeyModalProps.onOpen } onClick={ apiKeyModalProps.onOpen }
disabled={ !canAdd } disabled={ !canAdd }
> >
......
...@@ -92,7 +92,6 @@ const CustomAbiPage: React.FC = () => { ...@@ -92,7 +92,6 @@ const CustomAbiPage: React.FC = () => {
{ Boolean(data?.length) && list } { Boolean(data?.length) && list }
<Skeleton mt={ 8 } loading={ isPlaceholderData } display="inline-block"> <Skeleton mt={ 8 } loading={ isPlaceholderData } display="inline-block">
<Button <Button
size="lg"
onClick={ customAbiModalProps.onOpen } onClick={ customAbiModalProps.onOpen }
> >
Add custom ABI Add custom ABI
......
import { VStack, Textarea, Alert, Code, Flex, Box } from '@chakra-ui/react'; import { VStack, Textarea, Code, Flex, Box } from '@chakra-ui/react';
import mixpanel from 'mixpanel-browser'; import mixpanel from 'mixpanel-browser';
import type { ChangeEvent } from 'react'; import type { ChangeEvent } from 'react';
import React from 'react'; import React from 'react';
...@@ -8,6 +8,7 @@ import * as cookies from 'lib/cookies'; ...@@ -8,6 +8,7 @@ import * as cookies from 'lib/cookies';
import useFeatureValue from 'lib/growthbook/useFeatureValue'; import useFeatureValue from 'lib/growthbook/useFeatureValue';
import useGradualIncrement from 'lib/hooks/useGradualIncrement'; import useGradualIncrement from 'lib/hooks/useGradualIncrement';
import { useRollbar } from 'lib/rollbar'; import { useRollbar } from 'lib/rollbar';
import { Alert } from 'toolkit/chakra/alert';
import { Button } from 'toolkit/chakra/button'; import { Button } from 'toolkit/chakra/button';
import { toaster } from 'toolkit/chakra/toaster'; import { toaster } from 'toolkit/chakra/toaster';
import PageTitle from 'ui/shared/Page/PageTitle'; import PageTitle from 'ui/shared/Page/PageTitle';
...@@ -64,16 +65,15 @@ const Login = () => { ...@@ -64,16 +65,15 @@ const Login = () => {
<PageTitle title="Login page 😂"/> <PageTitle title="Login page 😂"/>
{ isFormVisible && ( { isFormVisible && (
<> <>
<Alert.Root status="error" flexDirection="column" alignItems="flex-start"> <Alert
<Alert.Title fontSize="md"> status="warning"
!!! Temporary solution for authentication on localhost !!! title="!!! Temporary solution for authentication on localhost !!!"
</Alert.Title> inline={ false }
<Alert.Description mt={ 3 }> >
To Sign in go to production instance first, sign in there, copy obtained API token from cookie To Sign in go to production instance first, sign in there, copy obtained API token from cookie
<Code ml={ 1 }>{ cookies.NAMES.API_TOKEN }</Code> and paste it in the form below. After submitting the form you should be successfully <Code ml={ 1 }>{ cookies.NAMES.API_TOKEN }</Code> and paste it in the form below. After submitting the form you should be successfully
authenticated in current environment authenticated in current environment
</Alert.Description> </Alert>
</Alert.Root>
<Textarea value={ token } onChange={ handleTokenChange } placeholder="API token"/> <Textarea value={ token } onChange={ handleTokenChange } placeholder="API token"/>
<Button onClick={ handleSetTokenClick }>Set cookie</Button> <Button onClick={ handleSetTokenClick }>Set cookie</Button>
</> </>
......
...@@ -113,14 +113,14 @@ const VerifiedAddresses = () => { ...@@ -113,14 +113,14 @@ const VerifiedAddresses = () => {
const addButton = (() => { const addButton = (() => {
if (userWithoutEmail) { if (userWithoutEmail) {
return ( return (
<Button size="lg" disabled mt={ 8 }> <Button disabled mt={ 8 }>
Add address Add address
</Button> </Button>
); );
} }
return ( return (
<Button size="lg" onClick={ modalProps.onOpen } loadingSkeleton={ isLoading } mt={ 8 }> <Button onClick={ modalProps.onOpen } loadingSkeleton={ isLoading } mt={ 8 }>
Add address Add address
</Button> </Button>
); );
...@@ -206,7 +206,7 @@ const VerifiedAddresses = () => { ...@@ -206,7 +206,7 @@ const VerifiedAddresses = () => {
<chakra.p fontWeight={ 600 } mt={ 5 }> <chakra.p fontWeight={ 600 } mt={ 5 }>
Before starting, make sure that: Before starting, make sure that:
</chakra.p> </chakra.p>
<List.Root ml={ 6 } as="ol"> <List.Root pl={ 5 } as="ol">
<List.Item>The source code for the smart contract is deployed on “{ config.chain.name }”.</List.Item> <List.Item>The source code for the smart contract is deployed on “{ config.chain.name }”.</List.Item>
<List.Item> <List.Item>
<span>The source code is verified (if not yet verified, you can use </span> <span>The source code is verified (if not yet verified, you can use </span>
......
...@@ -122,7 +122,6 @@ const WatchList: React.FC = () => { ...@@ -122,7 +122,6 @@ const WatchList: React.FC = () => {
</DataListDisplay> </DataListDisplay>
<Skeleton mt={ 8 } loading={ isPlaceholderData } display="inline-block"> <Skeleton mt={ 8 } loading={ isPlaceholderData } display="inline-block">
<Button <Button
size="lg"
onClick={ addressModalProps.onOpen } onClick={ addressModalProps.onOpen }
> >
Add address Add address
......
...@@ -99,7 +99,6 @@ const AddressForm: React.FC<Props> = ({ data, onOpenChange, onSuccess, setAlertV ...@@ -99,7 +99,6 @@ const AddressForm: React.FC<Props> = ({ data, onOpenChange, onSuccess, setAlertV
mb={ 8 } mb={ 8 }
/> />
<Button <Button
size="lg"
type="submit" type="submit"
disabled={ !formApi.formState.isDirty } disabled={ !formApi.formState.isDirty }
loading={ pending } loading={ pending }
......
...@@ -99,7 +99,6 @@ const PrivateAddressTags = () => { ...@@ -99,7 +99,6 @@ const PrivateAddressTags = () => {
</DataListDisplay> </DataListDisplay>
<Skeleton mt={ 8 } loading={ isPlaceholderData } display="inline-block"> <Skeleton mt={ 8 } loading={ isPlaceholderData } display="inline-block">
<Button <Button
size="lg"
onClick={ addressModalProps.onOpen } onClick={ addressModalProps.onOpen }
> >
Add address tag Add address tag
......
...@@ -98,7 +98,6 @@ const PrivateTransactionTags = () => { ...@@ -98,7 +98,6 @@ const PrivateTransactionTags = () => {
</DataListDisplay> </DataListDisplay>
<Skeleton mt={ 8 } loading={ isPlaceholderData } display="inline-block"> <Skeleton mt={ 8 } loading={ isPlaceholderData } display="inline-block">
<Button <Button
size="lg"
onClick={ transactionModalProps.onOpen } onClick={ transactionModalProps.onOpen }
> >
Add transaction tag Add transaction tag
......
...@@ -110,7 +110,6 @@ const TransactionForm: React.FC<Props> = ({ data, onOpenChange, onSuccess, setAl ...@@ -110,7 +110,6 @@ const TransactionForm: React.FC<Props> = ({ data, onOpenChange, onSuccess, setAl
/> />
<Box marginTop={ 8 }> <Box marginTop={ 8 }>
<Button <Button
size="lg"
type="submit" type="submit"
disabled={ !formApi.formState.isDirty } disabled={ !formApi.formState.isDirty }
loading={ pending } loading={ pending }
......
...@@ -135,7 +135,6 @@ const PublicTagsSubmitForm = ({ config, userInfo, onSubmitResult }: Props) => { ...@@ -135,7 +135,6 @@ const PublicTagsSubmitForm = ({ config, userInfo, onSubmitResult }: Props) => {
<Button <Button
variant="solid" variant="solid"
size="lg"
type="submit" type="submit"
mt={ 3 } mt={ 3 }
loading={ formApi.formState.isSubmitting } loading={ formApi.formState.isSubmitting }
......
...@@ -71,13 +71,13 @@ const PublicTagsSubmitResult = ({ data }: Props) => { ...@@ -71,13 +71,13 @@ const PublicTagsSubmitResult = ({ data }: Props) => {
<Flex flexDir={{ base: 'column', lg: 'row' }} columnGap={ 6 } mt={ 8 } rowGap={ 3 }> <Flex flexDir={{ base: 'column', lg: 'row' }} columnGap={ 6 } mt={ 8 } rowGap={ 3 }>
{ hasErrors && ( { hasErrors && (
<Link href={ route({ pathname: '/public-tags/submit', query: startOverButtonQuery }) } asChild> <Link href={ route({ pathname: '/public-tags/submit', query: startOverButtonQuery }) } asChild>
<Button size="lg" variant="outline"> <Button variant="outline">
Start over Start over
</Button> </Button>
</Link> </Link>
) } ) }
<Link href={ route({ pathname: '/public-tags/submit' }) } asChild> <Link href={ route({ pathname: '/public-tags/submit' }) } asChild>
<Button size="lg">Add new tag</Button> <Button>Add new tag</Button>
</Link> </Link>
</Flex> </Flex>
</div> </div>
......
...@@ -18,13 +18,13 @@ import PrivateTagMenuItem from './items/PrivateTagMenuItem'; ...@@ -18,13 +18,13 @@ import PrivateTagMenuItem from './items/PrivateTagMenuItem';
import PublicTagMenuItem from './items/PublicTagMenuItem'; import PublicTagMenuItem from './items/PublicTagMenuItem';
import TokenInfoMenuItem from './items/TokenInfoMenuItem'; import TokenInfoMenuItem from './items/TokenInfoMenuItem';
// TODO @tom2drum fix account modals
interface Props { interface Props {
isLoading?: boolean; isLoading?: boolean;
className?: string; className?: string;
showUpdateMetadataItem?: boolean; showUpdateMetadataItem?: boolean;
} }
// TODO @tom2drum fix modal open on menu item click
const AccountActionsMenu = ({ isLoading, className, showUpdateMetadataItem }: Props) => { const AccountActionsMenu = ({ isLoading, className, showUpdateMetadataItem }: Props) => {
const router = useRouter(); const router = useRouter();
...@@ -46,10 +46,10 @@ const AccountActionsMenu = ({ isLoading, className, showUpdateMetadataItem }: Pr ...@@ -46,10 +46,10 @@ const AccountActionsMenu = ({ isLoading, className, showUpdateMetadataItem }: Pr
render: (props: ItemProps) => <MetadataUpdateMenuItem { ...props }/>, render: (props: ItemProps) => <MetadataUpdateMenuItem { ...props }/>,
enabled: isTokenInstancePage && showUpdateMetadataItem, enabled: isTokenInstancePage && showUpdateMetadataItem,
}, },
// { {
// render: (props: ItemProps) => <TokenInfoMenuItem { ...props }/>, render: (props: ItemProps) => <TokenInfoMenuItem { ...props }/>,
// enabled: config.features.account.isEnabled && isTokenPage && config.features.addressVerification.isEnabled && !userWithoutEmail, enabled: config.features.account.isEnabled && isTokenPage && config.features.addressVerification.isEnabled && !userWithoutEmail,
// }, },
{ {
render: (props: ItemProps) => <PrivateTagMenuItem { ...props } entityType={ isTxPage ? 'tx' : 'address' }/>, render: (props: ItemProps) => <PrivateTagMenuItem { ...props } entityType={ isTxPage ? 'tx' : 'address' }/>,
enabled: config.features.account.isEnabled, enabled: config.features.account.isEnabled,
......
...@@ -84,7 +84,7 @@ const TokenInfoMenuItem = ({ hash, type }: ItemProps) => { ...@@ -84,7 +84,7 @@ const TokenInfoMenuItem = ({ hash, type }: ItemProps) => {
{ ({ onClick }) => ( { ({ onClick }) => (
<MenuItem onClick={ onClick } value="add-token-info"> <MenuItem onClick={ onClick } value="add-token-info">
{ icon } { icon }
<chakra.span ml={ 2 }>{ label }</chakra.span> <chakra.span>{ label }</chakra.span>
</MenuItem> </MenuItem>
) } ) }
</AuthGuard> </AuthGuard>
...@@ -99,8 +99,8 @@ const TokenInfoMenuItem = ({ hash, type }: ItemProps) => { ...@@ -99,8 +99,8 @@ const TokenInfoMenuItem = ({ hash, type }: ItemProps) => {
<AddressVerificationModal <AddressVerificationModal
defaultAddress={ hash } defaultAddress={ hash }
pageType={ PAGE_TYPE_DICT['/token/[hash]'] } pageType={ PAGE_TYPE_DICT['/token/[hash]'] }
isOpen={ modal.open } open={ modal.open }
onClose={ modal.onClose } onOpenChange={ modal.onOpenChange }
onSubmit={ handleVerifiedAddressSubmit } onSubmit={ handleVerifiedAddressSubmit }
onAddTokenInfoClick={ handleAddApplicationClick } onAddTokenInfoClick={ handleAddApplicationClick }
onShowListClick={ handleShowMyAddressesClick } onShowListClick={ handleShowMyAddressesClick }
......
import { Box, Button, Text } from '@chakra-ui/react'; import { Box, Text } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
...@@ -8,6 +8,8 @@ import getErrorCause from 'lib/errors/getErrorCause'; ...@@ -8,6 +8,8 @@ import getErrorCause from 'lib/errors/getErrorCause';
import getErrorCauseStatusCode from 'lib/errors/getErrorCauseStatusCode'; import getErrorCauseStatusCode from 'lib/errors/getErrorCauseStatusCode';
import getErrorObjStatusCode from 'lib/errors/getErrorObjStatusCode'; import getErrorObjStatusCode from 'lib/errors/getErrorObjStatusCode';
import getResourceErrorPayload from 'lib/errors/getResourceErrorPayload'; import getResourceErrorPayload from 'lib/errors/getResourceErrorPayload';
import { Button } from 'toolkit/chakra/button';
import { Link } from 'toolkit/chakra/link';
import AdBannerContent from 'ui/shared/ad/AdBannerContent'; import AdBannerContent from 'ui/shared/ad/AdBannerContent';
import AppErrorIcon from './AppErrorIcon'; import AppErrorIcon from './AppErrorIcon';
...@@ -87,16 +89,18 @@ const AppError = ({ error, className }: Props) => { ...@@ -87,16 +89,18 @@ const AppError = ({ error, className }: Props) => {
<> <>
<AppErrorIcon statusCode={ statusCode }/> <AppErrorIcon statusCode={ statusCode }/>
<AppErrorTitle title={ title }/> <AppErrorTitle title={ title }/>
<Text variant="secondary" mt={ 3 }>{ text }</Text> <Text color="text.secondary" mt={ 3 }>{ text }</Text>
<Button <Link
mt={ 8 }
size="lg"
variant="outline"
as="a"
href={ route({ pathname: '/' }) } href={ route({ pathname: '/' }) }
asChild
> >
Back to home <Button
</Button> mt={ 8 }
variant="outline"
>
Back to home
</Button>
</Link>
{ statusCode === 404 && adBannerProvider && <AdBannerContent mt={ 12 } provider={ adBannerProvider }/> } { statusCode === 404 && adBannerProvider && <AdBannerContent mt={ 12 } provider={ adBannerProvider }/> }
</> </>
); );
......
import { Heading } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { Heading } from 'toolkit/chakra/heading';
interface Props { interface Props {
title: string; title: string;
} }
const AppErrorTitle = ({ title }: Props) => { const AppErrorTitle = ({ title }: Props) => {
return <Heading mt={ 8 } size="2xl" fontFamily="body">{ title }</Heading>; return <Heading mt={ 8 } textStyle="heading.xl" as="h1">{ title }</Heading>;
}; };
export default AppErrorTitle; export default AppErrorTitle;
import { Button } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
import { Button } from 'toolkit/chakra/button';
import { Link } from 'toolkit/chakra/link';
import AppErrorIcon from '../AppErrorIcon'; import AppErrorIcon from '../AppErrorIcon';
import AppErrorTitle from '../AppErrorTitle'; import AppErrorTitle from '../AppErrorTitle';
...@@ -15,15 +17,14 @@ const AppErrorBlockConsensus = ({ hash }: Props) => { ...@@ -15,15 +17,14 @@ const AppErrorBlockConsensus = ({ hash }: Props) => {
<> <>
<AppErrorIcon statusCode={ 404 }/> <AppErrorIcon statusCode={ 404 }/>
<AppErrorTitle title="Block removed due to chain reorganization"/> <AppErrorTitle title="Block removed due to chain reorganization"/>
<Button <Link href={ hash ? route({ pathname: '/block/[height_or_hash]', query: { height_or_hash: hash } }) : route({ pathname: '/' }) } asChild>
mt={ 8 } <Button
size="lg" mt={ 8 }
variant="outline" variant="outline"
as="a" >
href={ hash ? route({ pathname: '/block/[height_or_hash]', query: { height_or_hash: hash } }) : route({ pathname: '/' }) } { hash ? 'View reorg' : 'Back to home' }
> </Button>
{ hash ? 'View reorg' : 'Back to home' } </Link>
</Button>
</> </>
); );
}; };
......
import { Button, Text } from '@chakra-ui/react'; import { Text } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { toaster } from 'toolkit/chakra/toaster';
import config from 'configs/app'; import config from 'configs/app';
import buildUrl from 'lib/api/buildUrl'; import buildUrl from 'lib/api/buildUrl';
import useFetch from 'lib/hooks/useFetch'; import useFetch from 'lib/hooks/useFetch';
import { Button } from 'toolkit/chakra/button';
import { toaster } from 'toolkit/chakra/toaster';
import ReCaptcha from 'ui/shared/reCaptcha/ReCaptcha'; import ReCaptcha from 'ui/shared/reCaptcha/ReCaptcha';
import useReCaptcha from 'ui/shared/reCaptcha/useReCaptcha'; import useReCaptcha from 'ui/shared/reCaptcha/useReCaptcha';
...@@ -48,7 +49,7 @@ const AppErrorTooManyRequests = () => { ...@@ -48,7 +49,7 @@ const AppErrorTooManyRequests = () => {
<> <>
<AppErrorIcon statusCode={ 429 }/> <AppErrorIcon statusCode={ 429 }/>
<AppErrorTitle title="Too many requests"/> <AppErrorTitle title="Too many requests"/>
<Text variant="secondary" mt={ 3 }> <Text color="text.secondary" mt={ 3 }>
You have exceeded the request rate for a given time period. Please reduce the number of requests and try again soon. You have exceeded the request rate for a given time period. Please reduce the number of requests and try again soon.
</Text> </Text>
<ReCaptcha ref={ recaptcha.ref }/> <ReCaptcha ref={ recaptcha.ref }/>
......
/* eslint-disable max-len */ /* eslint-disable max-len */
import { Box, OrderedList, ListItem, useColorModeValue, Flex, chakra, Button } from '@chakra-ui/react'; import { Box, Flex, List, chakra } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
import { Button } from 'toolkit/chakra/button';
import { Link } from 'toolkit/chakra/link';
import IconSvg from 'ui/shared/IconSvg'; import IconSvg from 'ui/shared/IconSvg';
import AppErrorTitle from '../AppErrorTitle'; import AppErrorTitle from '../AppErrorTitle';
const AppErrorTxNotFound = () => { const AppErrorTxNotFound = () => {
const snippet = { const snippet = {
borderColor: useColorModeValue('blackAlpha.300', 'whiteAlpha.300'), borderColor: { _light: 'blackAlpha.300', _dark: 'whiteAlpha.300' },
iconBg: useColorModeValue('blackAlpha.800', 'whiteAlpha.800'), iconBg: { _light: 'blackAlpha.800', _dark: 'whiteAlpha.800' },
iconColor: useColorModeValue('white', 'black'), iconColor: { _light: 'white', _dark: 'black' },
}; };
return ( return (
...@@ -37,31 +39,30 @@ const AppErrorTxNotFound = () => { ...@@ -37,31 +39,30 @@ const AppErrorTxNotFound = () => {
</Flex> </Flex>
</Box> </Box>
<AppErrorTitle title="Sorry, we are unable to locate this transaction hash"/> <AppErrorTitle title="Sorry, we are unable to locate this transaction hash"/>
<OrderedList mt={ 3 } spacing={ 3 }> <List.Root mt={ 3 } gap={ 3 } as="ol" pl={ 5 }>
<ListItem> <List.Item>
If you have just submitted this transaction please wait for at least 30 seconds before refreshing this page. If you have just submitted this transaction please wait for at least 30 seconds before refreshing this page.
</ListItem> </List.Item>
<ListItem> <List.Item>
It could still be in the TX Pool of a different node, waiting to be broadcasted. It could still be in the TX Pool of a different node, waiting to be broadcasted.
</ListItem> </List.Item>
<ListItem> <List.Item>
During times when the network is busy (i.e during ICOs) it can take a while for your transaction to propagate through the network and for us to index it. During times when the network is busy (i.e during ICOs) it can take a while for your transaction to propagate through the network and for us to index it.
</ListItem> </List.Item>
<ListItem> <List.Item>
<span>If it still does not show up after 1 hour, please check with your </span> <span>If it still does not show up after 1 hour, please check with your </span>
<chakra.span fontWeight={ 600 }>sender/exchange/wallet/transaction provider</chakra.span> <chakra.span fontWeight={ 600 }>sender/exchange/wallet/transaction provider</chakra.span>
<span> for additional information.</span> <span> for additional information.</span>
</ListItem> </List.Item>
</OrderedList> </List.Root>
<Button <Link href={ route({ pathname: '/' }) } asChild>
mt={ 8 } <Button
size="lg" mt={ 8 }
variant="outline" variant="outline"
as="a" >
href={ route({ pathname: '/' }) } Back to home
> </Button>
Back to home </Link>
</Button>
</> </>
); );
}; };
......
...@@ -59,7 +59,6 @@ const DeleteModal: React.FC<Props> = ({ ...@@ -59,7 +59,6 @@ const DeleteModal: React.FC<Props> = ({
</DialogBody> </DialogBody>
<DialogFooter> <DialogFooter>
<Button <Button
size="lg"
onClick={ onDeleteClick } onClick={ onDeleteClick }
loading={ isPending } loading={ isPending }
> >
......
import { chakra, Image } from '@chakra-ui/react'; import { chakra } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { EntityTag as TEntityTag } from './types'; import type { EntityTag as TEntityTag } from './types';
import { Image } from 'toolkit/chakra/image';
import IconSvg from 'ui/shared/IconSvg'; import IconSvg from 'ui/shared/IconSvg';
interface Props { interface Props {
data: TEntityTag; data: TEntityTag;
iconColor?: string; iconColor?: string;
......
import type { SkeletonProps } from '@chakra-ui/react';
// eslint-disable-next-line no-restricted-imports
import { Skeleton as ChakraSkeleton } from '@chakra-ui/react';
import { forwardRef } from 'react';
const Skeleton = forwardRef<HTMLDivElement, SkeletonProps>((props, ref) => {
if (props.isLoaded) {
return <ChakraSkeleton ref={ ref } { ...props } sx={{ animation: 'none' }}/>;
}
return <ChakraSkeleton ref={ ref } { ...props }/>;
});
Skeleton.displayName = 'Skeleton';
export default Skeleton;
import { CheckboxGroup, Text, Flex, useCheckboxGroup, Fieldset } from '@chakra-ui/react'; import { Text, Flex, useCheckboxGroup, Fieldset } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { NFTTokenType, TokenType } from 'types/api/token'; import type { NFTTokenType, TokenType } from 'types/api/token';
import { TOKEN_TYPES, TOKEN_TYPE_IDS, NFT_TOKEN_TYPE_IDS } from 'lib/token/tokenTypes'; import { TOKEN_TYPES, TOKEN_TYPE_IDS, NFT_TOKEN_TYPE_IDS } from 'lib/token/tokenTypes';
import { Button } from 'toolkit/chakra/button'; import { Button } from 'toolkit/chakra/button';
import { Checkbox } from 'toolkit/chakra/checkbox'; import { Checkbox, CheckboxGroup } from 'toolkit/chakra/checkbox';
type Props<T extends TokenType | NFTTokenType> = { type Props<T extends TokenType | NFTTokenType> = {
onChange: (nextValue: Array<T>) => void; onChange: (nextValue: Array<T>) => void;
......
import React from 'react';
import type { Path, FieldValues } from 'react-hook-form';
import { useController, useFormContext } from 'react-hook-form';
import type { FormFieldPropsBase } from './types';
// import type { Option } from 'ui/shared/forms/inputs/select/types';
import useIsMobile from 'lib/hooks/useIsMobile';
import type { Props as FancySelectProps } from 'ui/shared/forms/inputs/select/FancySelect';
import FancySelect from 'ui/shared/forms/inputs/select/FancySelect';
// FIXME: Try to get this to work to add more constraints to the props type
// this type only works for plain objects, not for nested objects or arrays (e.g. ui/publicTags/submit/types.ts:FormFields)
// type SelectField<O> = { [K in keyof O]: NonNullable<O[K]> extends Option ? K : never }[keyof O];
// TODO @tom2drum remove this component
type Props<
FormFields extends FieldValues,
Name extends Path<FormFields>,
> = Omit<FormFieldPropsBase<FormFields, Name>, 'bgColor' | 'size'> & Partial<FancySelectProps> & {
size?: 'md' | 'lg';
};
const FormFieldFancySelect = <
FormFields extends FieldValues,
Name extends Path<FormFields>,
>(props: Props<FormFields, Name>) => {
const isMobile = useIsMobile();
const defaultSize = isMobile ? 'md' : 'lg';
const { control } = useFormContext<FormFields>();
const { field, fieldState, formState } = useController<FormFields, typeof props.name>({
control,
name: props.name,
rules: { ...props.rules, required: props.isRequired },
});
const isDisabled = formState.isSubmitting;
return (
<FancySelect
{ ...field }
{ ...props }
size={ props.size || defaultSize }
error={ fieldState.error }
isDisabled={ isDisabled }
/>
);
};
export default React.memo(FormFieldFancySelect) as typeof FormFieldFancySelect;
import { FormLabel, chakra } from '@chakra-ui/react';
import React from 'react';
import type { FieldError } from 'react-hook-form';
interface Props {
text: string;
icon?: React.ReactNode;
error?: Partial<FieldError>;
isFancy?: boolean;
}
// TODO @tom2drum remove this component
const FormInputPlaceholder = ({ text, icon, error, isFancy }: Props) => {
let errorMessage = error?.message;
if (!errorMessage && error?.type === 'pattern') {
errorMessage = 'Invalid format';
}
return (
<FormLabel
alignItems="center"
{ ...(isFancy ? { 'data-fancy': true } : {}) }
variant="floating"
>
{ icon }
<chakra.span>{ text }</chakra.span>
{ errorMessage && (
<chakra.span order={ 3 } whiteSpace="pre">
{ ' ' }
- { errorMessage }
</chakra.span>
) }
</FormLabel>
);
};
export default React.memo(FormInputPlaceholder);
import { noop } from 'es-toolkit';
import React from 'react';
import { test, expect } from 'playwright/lib';
import FancySelect from './FancySelect';
const OPTIONS = [
{ value: 'v0.8.17+commit.8df45f5f', label: 'v0.8.17+commit.8df45f5f' },
{ value: 'v0.8.16+commit.07a7930e', label: 'v0.8.16+commit.07a7930e' },
{ value: 'v0.8.15+commit.e14f2714', label: 'v0.8.15+commit.e14f2714' },
];
test.use({ viewport: { width: 500, height: 300 } });
const defaultProps = {
options: OPTIONS,
isRequired: true,
placeholder: 'Compiler',
name: 'compiler',
onChange: noop,
};
[ 'md' as const, 'lg' as const ].forEach((size) => {
test.describe(`size ${ size } +@dark-mode`, () => {
test('empty', async({ render, page }) => {
const component = await render(
<FancySelect
{ ...defaultProps }
size={ size }
value={ null }
/>,
);
await expect(component).toHaveScreenshot();
await component.getByLabel(/compiler/i).focus();
await component.getByLabel(/compiler/i).type('1');
await expect(page).toHaveScreenshot();
});
test('filled', async({ render }) => {
const component = await render(
<FancySelect
{ ...defaultProps }
size={ size }
value={ OPTIONS[0] }
/>,
);
await expect(component).toHaveScreenshot();
});
test('error', async({ render }) => {
const component = await render(
<FancySelect
{ ...defaultProps }
size={ size }
value={ null }
error={{
type: 'unknown',
message: 'cannot be empty',
}}
/>,
);
await expect(component).toHaveScreenshot();
await component.getByLabel(/compiler/i).focus();
await component.getByLabel(/compiler/i).type('1');
await expect(component).toHaveScreenshot();
});
test('disabled', async({ render }) => {
const component = await render(
<FancySelect
{ ...defaultProps }
size={ size }
value={ OPTIONS[0] }
isDisabled
/>,
);
await expect(component).toHaveScreenshot();
});
test('read-only', async({ render }) => {
const component = await render(
<FancySelect
{ ...defaultProps }
size={ size }
value={ OPTIONS[0] }
isReadOnly
/>,
);
await expect(component).toHaveScreenshot();
});
});
});
import { FormControl, useToken, useColorMode } from '@chakra-ui/react';
import React from 'react';
import type { FieldError, FieldErrorsImpl, Merge } from 'react-hook-form';
import type { Option } from './types';
import { Select, AsyncSelect } from 'chakra-react-select';
import type { CSSObjectWithLabel, GroupBase, SingleValue, MultiValue, AsyncProps, Props as SelectProps } from 'chakra-react-select';
import FormInputPlaceholder from 'ui/shared/forms/inputs/FormInputPlaceholder';
import { getChakraStyles } from 'ui/shared/forms/inputs/select/utils';
interface CommonProps {
error?: Merge<FieldError, FieldErrorsImpl<Option>> | undefined;
placeholderIcon?: React.ReactNode;
}
interface RegularSelectProps extends SelectProps<Option, boolean, GroupBase<Option>>, CommonProps {
isAsync?: false;
onChange: (newValue: SingleValue<Option> | MultiValue<Option>) => void;
}
interface AsyncSelectProps extends AsyncProps<Option, boolean, GroupBase<Option>>, CommonProps {
isAsync: true;
onChange: (newValue: SingleValue<Option> | MultiValue<Option>) => void;
}
export type Props = RegularSelectProps | AsyncSelectProps;
const FancySelect = (props: Props, ref: React.LegacyRef<HTMLDivElement>) => {
const menuZIndex = useToken('zIndices', 'dropdown');
const { colorMode } = useColorMode();
const styles = React.useMemo(() => ({
menuPortal: (provided: CSSObjectWithLabel) => ({ ...provided, zIndex: menuZIndex }),
}), [ menuZIndex ]);
const chakraStyles = React.useMemo(() => getChakraStyles(colorMode), [ colorMode ]);
const SelectComponent = props.isAsync ? AsyncSelect : Select;
return (
<FormControl
variant="floating"
size={ props.size || 'md' }
isRequired={ props.isRequired }
ref={ ref }
{ ...(props.error ? { 'aria-invalid': true } : {}) }
{ ...(props.isDisabled ? { 'aria-disabled': true } : {}) }
{ ...(props.value ? { 'data-active': true } : {}) }
>
<SelectComponent
{ ...props }
size={ props.size || 'md' }
menuPortalTarget={ window.document.body }
placeholder=""
styles={ styles }
chakraStyles={ chakraStyles }
isInvalid={ Boolean(props.error) }
useBasicStyles
/>
<FormInputPlaceholder
text={ typeof props.placeholder === 'string' ? props.placeholder : '' }
icon={ props.placeholderIcon }
error={ props.error }
isFancy
/>
</FormControl>
);
};
export default React.memo(React.forwardRef(FancySelect));
export interface Option<T extends string = string> {
label: string;
value: T;
}
import type { ColorMode } from '@chakra-ui/react';
import type { Option } from './types';
import type { Size, ChakraStylesConfig } from 'chakra-react-select';
import theme from 'theme/theme';
import getFormStyles from 'theme/utils/getFormStyles';
function getValueContainerStyles(size?: Size) {
switch (size) {
case 'sm':
case 'md': {
return {
paddingLeft: 4,
};
}
case 'lg': {
return {
paddingLeft: 6,
};
}
default: {
return {};
}
}
}
function getSingleValueStyles(size?: Size) {
switch (size) {
case 'sm':
case 'md': {
return {
top: '26px',
};
}
case 'lg': {
return {
top: '38px',
};
}
default: {
return {};
}
}
}
const getChakraStyles: (colorMode: ColorMode) => ChakraStylesConfig<Option> = (colorMode) => {
const formColor = getFormStyles({ colorMode, colorScheme: 'blue', theme });
return {
control: (provided, state) => ({
...provided,
borderColor: state.hasValue ? formColor.input.filled.borderColor : formColor.input.empty.borderColor,
}),
inputContainer: (provided) => ({
...provided,
py: 0,
mx: 0,
}),
valueContainer: (provided, state) => ({
...provided,
...getValueContainerStyles(state.selectProps.size),
py: 0,
}),
singleValue: (provided, state) => ({
...provided,
mx: 0,
transform: 'none',
...getSingleValueStyles(state.selectProps.size),
}),
};
};
export { getChakraStyles };
...@@ -4,12 +4,12 @@ import React from 'react'; ...@@ -4,12 +4,12 @@ import React from 'react';
import type { Route } from 'nextjs-routes'; import type { Route } from 'nextjs-routes';
import { toaster } from 'toolkit/chakra/toaster';
import config from 'configs/app'; import config from 'configs/app';
import useApiFetch from 'lib/api/useApiFetch'; import useApiFetch from 'lib/api/useApiFetch';
import { getResourceKey } from 'lib/api/useApiQuery'; import { getResourceKey } from 'lib/api/useApiQuery';
import * as cookies from 'lib/cookies'; import * as cookies from 'lib/cookies';
import * as mixpanel from 'lib/mixpanel'; import * as mixpanel from 'lib/mixpanel';
import { toaster } from 'toolkit/chakra/toaster';
const PROTECTED_ROUTES: Array<Route['pathname']> = [ const PROTECTED_ROUTES: Array<Route['pathname']> = [
'/account/api-key', '/account/api-key',
......
import type { GridProps, HTMLChakraProps } from '@chakra-ui/react'; import type { GridProps, HTMLChakraProps } from '@chakra-ui/react';
import { Box, Grid, Flex, Text, Link, VStack } from '@chakra-ui/react'; import { Box, Grid, Flex, Text, VStack } from '@chakra-ui/react';
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import React from 'react'; import React from 'react';
...@@ -11,6 +11,7 @@ import useApiQuery from 'lib/api/useApiQuery'; ...@@ -11,6 +11,7 @@ import useApiQuery from 'lib/api/useApiQuery';
import useFetch from 'lib/hooks/useFetch'; import useFetch from 'lib/hooks/useFetch';
import useIssueUrl from 'lib/hooks/useIssueUrl'; import useIssueUrl from 'lib/hooks/useIssueUrl';
import { copy } from 'lib/html-entities'; import { copy } from 'lib/html-entities';
import { Link } from 'toolkit/chakra/link';
import { Skeleton } from 'toolkit/chakra/skeleton'; import { Skeleton } from 'toolkit/chakra/skeleton';
import IconSvg from 'ui/shared/IconSvg'; import IconSvg from 'ui/shared/IconSvg';
import { CONTENT_MAX_WIDTH } from 'ui/shared/layout/utils'; import { CONTENT_MAX_WIDTH } from 'ui/shared/layout/utils';
...@@ -174,9 +175,9 @@ const Footer = () => { ...@@ -174,9 +175,9 @@ const Footer = () => {
return ( return (
<Box gridArea={ gridArea } textStyle="xs" mt={ 6 }> <Box gridArea={ gridArea } textStyle="xs" mt={ 6 }>
<span>This site is protected by reCAPTCHA and the Google </span> <span>This site is protected by reCAPTCHA and the Google </span>
<Link href="https://policies.google.com/privacy" target="_blank" rel="noopener noreferrer">Privacy Policy</Link> <Link href="https://policies.google.com/privacy" external noIcon>Privacy Policy</Link>
<span> and </span> <span> and </span>
<Link href="https://policies.google.com/terms" target="_blank" rel="noopener noreferrer">Terms of Service</Link> <Link href="https://policies.google.com/terms" external noIcon>Terms of Service</Link>
<span> apply.</span> <span> apply.</span>
</Box> </Box>
); );
......
import { Flex, Link, chakra } from '@chakra-ui/react'; import { Flex, chakra } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import config from 'configs/app'; import config from 'configs/app';
...@@ -6,6 +6,7 @@ import useApiQuery from 'lib/api/useApiQuery'; ...@@ -6,6 +6,7 @@ import useApiQuery from 'lib/api/useApiQuery';
import dayjs from 'lib/date/dayjs'; import dayjs from 'lib/date/dayjs';
import useIsMobile from 'lib/hooks/useIsMobile'; import useIsMobile from 'lib/hooks/useIsMobile';
import { HOMEPAGE_STATS } from 'stubs/stats'; import { HOMEPAGE_STATS } from 'stubs/stats';
import { Link } from 'toolkit/chakra/link';
import { Skeleton } from 'toolkit/chakra/skeleton'; import { Skeleton } from 'toolkit/chakra/skeleton';
import GasInfoTooltip from 'ui/shared/gas/GasInfoTooltip'; import GasInfoTooltip from 'ui/shared/gas/GasInfoTooltip';
import GasPrice from 'ui/shared/gas/GasPrice'; import GasPrice from 'ui/shared/gas/GasPrice';
......
...@@ -21,6 +21,8 @@ const SettingsAddressFormat = () => { ...@@ -21,6 +21,8 @@ const SettingsAddressFormat = () => {
onChange={ toggleAddressFormat } mt={ 4 } onChange={ toggleAddressFormat } mt={ 4 }
size="sm" size="sm"
flexDirection="row-reverse" flexDirection="row-reverse"
justifyContent="space-between"
w="100%"
gap={ 2 } gap={ 2 }
fontWeight="400" fontWeight="400"
color="text.secondary" color="text.secondary"
......
import { FormLabel, FormControl, Switch, Box } from '@chakra-ui/react'; import { Box } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import config from 'configs/app'; import config from 'configs/app';
import { useAppContext } from 'lib/contexts/app'; import { useAppContext } from 'lib/contexts/app';
import * as cookies from 'lib/cookies'; import * as cookies from 'lib/cookies';
import { Switch } from 'toolkit/chakra/switch';
const SettingsScamTokens = () => { const SettingsScamTokens = () => {
const { cookies: appCookies } = useAppContext(); const { cookies: appCookies } = useAppContext();
...@@ -28,12 +29,20 @@ const SettingsScamTokens = () => { ...@@ -28,12 +29,20 @@ const SettingsScamTokens = () => {
return ( return (
<> <>
<Box borderColor="divider" borderTopWidth="1px" my={ 3 }/> <Box borderColor="divider" borderTopWidth="1px" my={ 3 }/>
<FormControl display="flex" alignItems="center" columnGap={ 2 } mt={ 4 }> <Switch
<FormLabel htmlFor="scam-tokens" m="0" fontWeight={ 400 } fontSize="sm" lineHeight={ 5 }> id="scam-tokens"
Hide scam tokens checked={ isChecked }
</FormLabel> onChange={ handleChange }
<Switch id="scam-tokens" isChecked={ isChecked } onChange={ handleChange }/> size="sm"
</FormControl> flexDirection="row-reverse"
justifyContent="space-between"
w="100%"
gap={ 2 }
fontWeight="400"
color="text.secondary"
>
Hide scam tokens
</Switch>
</> </>
); );
}; };
......
import { Box, Separator, Flex, Link, VStack } from '@chakra-ui/react'; import { Box, Separator, Flex, VStack } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { NavLink } from './types'; import type { NavLink } from './types';
...@@ -10,6 +10,7 @@ import config from 'configs/app'; ...@@ -10,6 +10,7 @@ import config from 'configs/app';
import { useMarketplaceContext } from 'lib/contexts/marketplace'; import { useMarketplaceContext } from 'lib/contexts/marketplace';
import shortenString from 'lib/shortenString'; import shortenString from 'lib/shortenString';
import { Button } from 'toolkit/chakra/button'; import { Button } from 'toolkit/chakra/button';
import { Link } from 'toolkit/chakra/link';
import Hint from 'ui/shared/Hint'; import Hint from 'ui/shared/Hint';
import TruncatedValue from 'ui/shared/TruncatedValue'; import TruncatedValue from 'ui/shared/TruncatedValue';
import useLogout from 'ui/snippets/auth/useLogout'; import useLogout from 'ui/snippets/auth/useLogout';
...@@ -96,7 +97,7 @@ const UserProfileContent = ({ data, onClose, onLogin, onAddEmail, onAddAddress } ...@@ -96,7 +97,7 @@ const UserProfileContent = ({ data, onClose, onLogin, onAddEmail, onAddAddress }
/> />
{ data?.address_hash ? { data?.address_hash ?
<Box ml="auto">{ shortenString(data?.address_hash) }</Box> : <Box ml="auto">{ shortenString(data?.address_hash) }</Box> :
<Link ml="auto" onClick={ onAddAddress } _hover={{ color: 'link.primary.hover' }}>Add address</Link> <Link ml="auto" onClick={ onAddAddress }>Add address</Link>
} }
</Flex> </Flex>
) } ) }
...@@ -104,7 +105,7 @@ const UserProfileContent = ({ data, onClose, onLogin, onAddEmail, onAddAddress } ...@@ -104,7 +105,7 @@ const UserProfileContent = ({ data, onClose, onLogin, onAddEmail, onAddAddress }
<Box mr="auto">Email</Box> <Box mr="auto">Email</Box>
{ data?.email ? { data?.email ?
<TruncatedValue value={ data.email }/> : <TruncatedValue value={ data.email }/> :
<Link onClick={ onAddEmail } _hover={{ color: 'link.primary.hover' }}>Add email</Link> <Link onClick={ onAddEmail }>Add email</Link>
} }
</Flex> </Flex>
</Box> </Box>
......
import { Alert, CloseButton, Link, Text, useDisclosure } from '@chakra-ui/react'; import { Text } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { apos } from 'lib/html-entities'; import { apos } from 'lib/html-entities';
import { Alert } from 'toolkit/chakra/alert';
import { Link } from 'toolkit/chakra/link';
function ChartsLoadingErrorAlert() { function ChartsLoadingErrorAlert() {
const { return (
isOpen: isVisible, <Alert status="warning" mb={ 4 } closable>
onClose,
} = useDisclosure({ defaultIsOpen: true });
return isVisible ? (
<Alert status="warning" mb={ 4 }>
<Text mr={ 2 }> <Text mr={ 2 }>
{ `Some of the charts did not load because the server didn${ apos }t respond. To reload charts ` } { `Some of the charts did not load because the server didn${ apos }t respond. To reload charts ` }
<Link href={ window.document.location.href }>click once again.</Link> <Link href={ window.document.location.href }>click once again.</Link>
</Text> </Text>
<CloseButton
alignSelf={{ base: 'flex-start', lg: 'center' }}
ml="auto"
onClick={ onClose }
/>
</Alert> </Alert>
) : null; );
} }
export default ChartsLoadingErrorAlert; export default ChartsLoadingErrorAlert;
...@@ -187,7 +187,6 @@ const TokenInfoForm = ({ address, tokenName, application, onSubmit }: Props) => ...@@ -187,7 +187,6 @@ const TokenInfoForm = ({ address, tokenName, application, onSubmit }: Props) =>
</Grid> </Grid>
<Button <Button
type="submit" type="submit"
size="lg"
mt={ 8 } mt={ 8 }
loading={ formState.isSubmitting } loading={ formState.isSubmitting }
loadingText="Send request" loadingText="Send request"
......
import { CheckboxGroup, Text, Flex, useCheckboxGroup, chakra, Fieldset } from '@chakra-ui/react'; import { Text, Flex, useCheckboxGroup, chakra } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import config from 'configs/app'; import config from 'configs/app';
import { Button } from 'toolkit/chakra/button'; import { Button } from 'toolkit/chakra/button';
import { Checkbox } from 'toolkit/chakra/checkbox'; import { Checkbox, CheckboxGroup } from 'toolkit/chakra/checkbox';
const feature = config.features.bridgedTokens; const feature = config.features.bridgedTokens;
...@@ -44,18 +44,14 @@ const TokensBridgedChainsFilter = ({ onChange, defaultValue }: Props) => { ...@@ -44,18 +44,14 @@ const TokensBridgedChainsFilter = ({ onChange, defaultValue }: Props) => {
Reset Reset
</Button> </Button>
</Flex> </Flex>
<Fieldset.Root> <CheckboxGroup defaultValue={ defaultValue } onValueChange={ handleChange } value={ value } name="bridged_token_chain">
<CheckboxGroup defaultValue={ defaultValue } onValueChange={ handleChange } value={ value } name="bridged_token_chain"> { feature.chains.map(({ title, id, short_title: shortTitle }) => (
<Fieldset.Content> <Checkbox key={ id } value={ id } whiteSpace="pre-wrap">
{ feature.chains.map(({ title, id, short_title: shortTitle }) => ( <span>{ title }</span>
<Checkbox key={ id } value={ id } textStyle="md" whiteSpace="pre-wrap"> <chakra.span color="text.secondary"> ({ shortTitle })</chakra.span>
<span>{ title }</span> </Checkbox>
<chakra.span color="text_secondary"> ({ shortTitle })</chakra.span> )) }
</Checkbox> </CheckboxGroup>
)) }
</Fieldset.Content>
</CheckboxGroup>
</Fieldset.Root>
</> </>
); );
}; };
......
...@@ -9,7 +9,6 @@ import { currencyUnits } from 'lib/units'; ...@@ -9,7 +9,6 @@ import { currencyUnits } from 'lib/units';
import { Badge } from 'toolkit/chakra/badge'; import { Badge } from 'toolkit/chakra/badge';
import CurrencyValue from 'ui/shared/CurrencyValue'; import CurrencyValue from 'ui/shared/CurrencyValue';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo'; import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import LogDecodedInputData from 'ui/shared/logs/LogDecodedInputData'; import LogDecodedInputData from 'ui/shared/logs/LogDecodedInputData';
......
...@@ -10,7 +10,6 @@ import { generateListStub } from 'stubs/utils'; ...@@ -10,7 +10,6 @@ import { generateListStub } from 'stubs/utils';
import ActionBar, { ACTION_BAR_HEIGHT_DESKTOP } from 'ui/shared/ActionBar'; import ActionBar, { ACTION_BAR_HEIGHT_DESKTOP } from 'ui/shared/ActionBar';
import DataListDisplay from 'ui/shared/DataListDisplay'; import DataListDisplay from 'ui/shared/DataListDisplay';
// import FilterInput from 'ui/shared/filters/FilterInput'; // import FilterInput from 'ui/shared/filters/FilterInput';
// import TxInternalsFilter from 'ui/tx/internals/TxInternalsFilter';
import Pagination from 'ui/shared/pagination/Pagination'; import Pagination from 'ui/shared/pagination/Pagination';
import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages'; import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages';
import { default as getNextSortValueShared } from 'ui/shared/sort/getNextSortValue'; import { default as getNextSortValueShared } from 'ui/shared/sort/getNextSortValue';
...@@ -117,7 +116,6 @@ const TxInternals = ({ txQuery }: Props) => { ...@@ -117,7 +116,6 @@ const TxInternals = ({ txQuery }: Props) => {
const actionBar = pagination.isVisible ? ( const actionBar = pagination.isVisible ? (
<ActionBar mt={ -6 }> <ActionBar mt={ -6 }>
{ /* <TxInternalsFilter onFilterChange={ handleFilterChange } defaultFilters={ filters } appliedFiltersNum={ filters.length }/> */ }
{ /* <FilterInput onChange={ setSearchTerm } maxW="360px" ml={ 3 } size="xs" placeholder="Search by addresses, hash, method..."/> */ } { /* <FilterInput onChange={ setSearchTerm } maxW="360px" ml={ 3 } size="xs" placeholder="Search by addresses, hash, method..."/> */ }
<Pagination ml="auto" { ...pagination }/> <Pagination ml="auto" { ...pagination }/>
</ActionBar> </ActionBar>
......
import { CheckboxGroup, Checkbox, Text } from '@chakra-ui/react';
import React from 'react';
import type { TxInternalsType } from 'types/api/internalTransaction';
import PopoverFilter from 'ui/shared/filters/PopoverFilter';
import { TX_INTERNALS_ITEMS } from 'ui/tx/internals/utils';
interface Props {
appliedFiltersNum?: number;
defaultFilters: Array<TxInternalsType>;
onFilterChange: (nextValue: Array<TxInternalsType>) => void;
}
const TxInternalsFilter = ({ onFilterChange, defaultFilters, appliedFiltersNum }: Props) => {
return (
<PopoverFilter appliedFiltersNum={ appliedFiltersNum } contentProps={{ w: { md: '100%', lg: '438px' } }}>
<CheckboxGroup size="lg" onChange={ onFilterChange } defaultValue={ defaultFilters }>
{ TX_INTERNALS_ITEMS.map(({ title, id }) => <Checkbox key={ id } value={ id }><Text fontSize="md">{ title }</Text></Checkbox>) }
</CheckboxGroup>
</PopoverFilter>
);
};
export default React.memo(TxInternalsFilter);
import {
Checkbox,
CheckboxGroup,
Grid,
Text,
} from '@chakra-ui/react';
import React, { useCallback, useState } from 'react';
import type { TTxsFilters, TypeFilter, MethodFilter } from 'types/api/txsFilters';
import PopoverFilter from 'ui/shared/filters/PopoverFilter';
interface Props {
appliedFiltersNum?: number;
filters: Partial<TTxsFilters>;
onFiltersChange: (val: Partial<TTxsFilters>) => void;
}
const TYPE_OPTIONS = [
{ title: 'Token transfer', id: 'token_transfer' },
{ title: 'Contract Creation', id: 'contract_creation' },
{ title: 'Contract Call', id: 'contract_call' },
{ title: 'Coin Transfer', id: 'coin_transfer' },
{ title: 'Token Creation', id: 'token_creation' },
];
const METHOD_OPTIONS = [
{ title: 'Approve', id: 'approve' },
{ title: 'Transfer', id: 'transfer' },
{ title: 'Multicall', id: 'multicall' },
{ title: 'Mint', id: 'mint' },
{ title: 'Commit', id: 'commit' },
];
const TxsFilters = ({ filters, appliedFiltersNum }: Props) => {
const [ typeFilter, setTypeFilter ] = useState<Array<TypeFilter>>(filters.type || []);
const [ methodFilter, setMethodFilter ] = useState<Array<MethodFilter>>(filters.method || []);
const onTypeFilterChange = useCallback((val: Array<TypeFilter>) => {
setTypeFilter(val);
}, []);
const onMethodFilterChange = useCallback((val: Array<MethodFilter>) => {
setMethodFilter(val);
}, []);
return (
<PopoverFilter contentProps={{ w: { md: '100%', lg: '438px' } }} appliedFiltersNum={ appliedFiltersNum }>
<Text variant="secondary" fontWeight="600" fontSize="sm">Type</Text>
<Grid gridTemplateColumns="1fr 1fr" rowGap={ 5 } mt={ 4 } mb={ 4 } pb={ 6 } borderBottom="1px solid" borderColor="border.divider">
<CheckboxGroup size="lg" onChange={ onTypeFilterChange } defaultValue={ typeFilter }>
{ TYPE_OPTIONS.map(({ title, id }) => <Checkbox key={ id } value={ id }><Text fontSize="md">{ title }</Text></Checkbox>) }
</CheckboxGroup>
</Grid>
<Text variant="secondary" fontWeight="600" fontSize="sm">Method</Text>
<Grid gridTemplateColumns="1fr 1fr" rowGap={ 5 } mt={ 4 } mb={ 4 } pb={ 6 } borderBottom="1px solid" borderColor="border.divider">
<CheckboxGroup size="lg" onChange={ onMethodFilterChange } defaultValue={ methodFilter }>
{ METHOD_OPTIONS.map(({ title, id }) => <Checkbox key={ id } value={ id }><Text fontSize="md">{ title }</Text></Checkbox>) }
</CheckboxGroup>
</Grid>
</PopoverFilter>
);
};
export default React.memo(TxsFilters);
...@@ -12,8 +12,6 @@ import Sort from 'ui/shared/sort/Sort'; ...@@ -12,8 +12,6 @@ import Sort from 'ui/shared/sort/Sort';
import { SORT_OPTIONS } from './useTxsSort'; import { SORT_OPTIONS } from './useTxsSort';
// import TxsFilters from './TxsFilters';
type Props = { type Props = {
sorting: TransactionsSortingValue; sorting: TransactionsSortingValue;
setSorting: (val: TransactionsSortingValue) => void; setSorting: (val: TransactionsSortingValue) => void;
......
...@@ -180,16 +180,14 @@ const AddressForm: React.FC<Props> = ({ data, onSuccess, setAlertVisible, isAdd ...@@ -180,16 +180,14 @@ const AddressForm: React.FC<Props> = ({ data, onSuccess, setAlertVisible, isAdd
/> />
</> </>
) } ) }
<Box marginTop={ 8 }> <Button
<Button type="submit"
size="lg" loading={ pending }
type="submit" disabled={ !formApi.formState.isDirty }
loading={ pending } mt={ 8 }
disabled={ !formApi.formState.isDirty } >
> { !isAdd ? 'Save changes' : 'Add address' }
{ !isAdd ? 'Save changes' : 'Add address' } </Button>
</Button>
</Box>
</form> </form>
</FormProvider> </FormProvider>
); );
......
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