Commit d1d1939f authored by isstuev's avatar isstuev

sorting

parent 74067a0d
...@@ -12,6 +12,14 @@ export const txs = [ ...@@ -12,6 +12,14 @@ export const txs = [
errorText: 'Error: (Awaiting internal transactions for reason)', errorText: 'Error: (Awaiting internal transactions for reason)',
txType: 'contract-call', txType: 'contract-call',
method: 'CommitHash CommitHash CommitHash CommitHash', method: 'CommitHash CommitHash CommitHash CommitHash',
amount: {
value: 0.04,
value_usd: 35.5,
},
fee: {
value: 0.002295904453623692,
value_usd: 2.84,
},
}, },
{ {
...tx, ...tx,
...@@ -23,5 +31,13 @@ export const txs = [ ...@@ -23,5 +31,13 @@ export const txs = [
alias: 'tkdkdkdkdkdkdkdkdkdkdkdkdkdkd.eth', alias: 'tkdkdkdkdkdkdkdkdkdkdkdkdkdkd.eth',
type: 'ENS name', type: 'ENS name',
}, },
amount: {
value: 0.02,
value_usd: 35.5,
},
fee: {
value: 0.002495904453623692,
value_usd: 2.84,
},
}, },
]; ];
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.774 13.088a.936.936 0 0 0 0 1.325l2.814 2.812a.935.935 0 0 0 1.324 0l2.813-2.812A.935.935 0 1 0 8.4 13.088l-1.213 1.21v-9.95a.954.954 0 0 0-.938-.937.954.954 0 0 0-.937.938v9.95L4.1 13.088a.937.937 0 0 0-1.327 0ZM12.813 15.626a.937.937 0 1 0 1.875 0V5.702l1.213 1.21a.935.935 0 1 0 1.324-1.324l-2.812-2.813a.936.936 0 0 0-1.325 0l-2.812 2.813A.935.935 0 1 0 11.6 6.912l1.213-1.21v9.924Z" fill="currentColor"/>
</svg>
import type { NextPage } from 'next';
import Head from 'next/head';
import React from 'react';
import getNetworkTitle from 'lib/networks/getNetworkTitle';
import Transactions from 'ui/pages/Transactions';
type PageParams = {
network_type: string;
network_sub_type: string;
}
type Props = {
pageParams: PageParams;
}
const AddressTagsPage: NextPage<Props> = ({ pageParams }: Props) => {
const title = getNetworkTitle(pageParams);
return (
<>
<Head><title>{ title }</title></Head>
<Transactions tab="pending"/>
</>
);
};
export default AddressTagsPage;
export { getStaticPaths } from 'lib/next/account/getStaticPaths';
export { getStaticProps } from 'lib/next/getStaticProps';
...@@ -6,23 +6,33 @@ import { Flex, Icon, Button, Circle, InputGroup, InputLeftElement, Input, useCol ...@@ -6,23 +6,33 @@ import { Flex, Icon, Button, Circle, InputGroup, InputLeftElement, Input, useCol
import type { ChangeEvent } from 'react'; import type { ChangeEvent } from 'react';
import React from 'react'; import React from 'react';
import upDownArrow from 'icons/arrows/up-down.svg';
import filterIcon from 'icons/filter.svg'; import filterIcon from 'icons/filter.svg';
import searchIcon from 'icons/search.svg'; import searchIcon from 'icons/search.svg';
const FilterIcon = <Icon as={ filterIcon } boxSize={ 5 }/>; const FilterIcon = <Icon as={ filterIcon } boxSize={ 5 }/>;
const Filters = () => { type Props = {
const [ isActive, setIsActive ] = React.useState(false); isMobile?: boolean;
}
const Filters = ({ isMobile }: Props) => {
const [ isFilterActive, setIsFilterActive ] = React.useState(false);
const [ value, setValue ] = React.useState(''); const [ value, setValue ] = React.useState('');
const [ isSortActive, setIsSortActive ] = React.useState(false);
const handleClick = React.useCallback(() => { const handleClick = React.useCallback(() => {
setIsActive(flag => !flag); setIsFilterActive(flag => !flag);
}, []); }, []);
const handleChange = React.useCallback((event: ChangeEvent<HTMLInputElement>) => { const handleChange = React.useCallback((event: ChangeEvent<HTMLInputElement>) => {
setValue(event.target.value); setValue(event.target.value);
}, []); }, []);
const handleSort = React.useCallback(() => {
setIsSortActive(flag => !flag);
}, []);
const badgeColor = useColorModeValue('white', 'black'); const badgeColor = useColorModeValue('white', 'black');
const badgeBgColor = useColorModeValue('blue.700', 'gray.50'); const badgeBgColor = useColorModeValue('blue.700', 'gray.50');
const searchIconColor = useColorModeValue('blackAlpha.600', 'whiteAlpha.600'); const searchIconColor = useColorModeValue('blackAlpha.600', 'whiteAlpha.600');
...@@ -31,19 +41,31 @@ const Filters = () => { ...@@ -31,19 +41,31 @@ const Filters = () => {
return ( return (
<Flex> <Flex>
<Button <Button
leftIcon={ FilterIcon } leftIcon={ isMobile ? undefined : FilterIcon }
rightIcon={ isActive ? <Circle bg={ badgeBgColor } size={ 5 } color={ badgeColor }>2</Circle> : undefined } rightIcon={ isFilterActive ? <Circle bg={ badgeBgColor } size={ 5 } color={ badgeColor }>2</Circle> : undefined }
size="sm" size="sm"
variant="outline" variant="outline"
colorScheme="gray-dark" colorScheme="gray-dark"
borderWidth="1px"
onClick={ handleClick } onClick={ handleClick }
isActive={ isActive } isActive={ isFilterActive }
px={ 1.5 } px={ 1.5 }
> >
Filter { isMobile ? FilterIcon : 'Filter' }
</Button> </Button>
<InputGroup size="xs" ml={ 3 } maxW="360px"> { isMobile && (
<IconButton
icon={ <Icon as={ upDownArrow } boxSize={ 5 }/> }
aria-label="sort"
size="sm"
variant="outline"
colorScheme="gray-dark"
ml={ 2 }
minWidth="36px"
onClick={ handleSort }
isActive={ isSortActive }
/>
) }
<InputGroup size="xs" ml={ isMobile ? 2 : 3 } maxW="360px">
<InputLeftElement ml={ 1 }> <InputLeftElement ml={ 1 }>
<Icon as={ searchIcon } boxSize={ 5 } color={ searchIconColor }/> <Icon as={ searchIcon } boxSize={ 5 } color={ searchIconColor }/>
</InputLeftElement> </InputLeftElement>
......
import { Box } from '@chakra-ui/react';
import React, { useCallback, useEffect, useState } from 'react';
import { txs } from 'data/txs';
import useIsMobile from 'lib/hooks/useIsMobile';
import Filters from 'ui/shared/Filters';
import Pagination from './Pagination';
import TxsListItem from './TxsListItem';
import TxsTable from './TxsTable';
type Sort = 'val-desc' | 'val-asc' | 'fee-desc' | 'fee-asc' | undefined;
type Props = {
isPending?: boolean;
}
const TxsContent = ({ isPending }: Props) => {
const isMobile = useIsMobile();
const [ sorting, setSorting ] = useState<Sort>();
const [ sortedTxs, setSortedTxs ] = useState(txs);
// sorting should be preserved with pagination!
const sort = useCallback((field: 'val' | 'fee') => () => {
if (field === 'val') {
setSorting((prevVal => {
if (prevVal === 'val-asc') {
return undefined;
}
if (prevVal === 'val-desc') {
return 'val-asc';
}
return 'val-desc';
}));
}
if (field === 'fee') {
setSorting((prevVal => {
if (prevVal === 'fee-asc') {
return undefined;
}
if (prevVal === 'fee-desc') {
return 'fee-asc';
}
return 'fee-desc';
}));
}
}, []);
useEffect(() => {
switch (sorting) {
case 'val-desc':
setSortedTxs([ ...txs ].sort((tx1, tx2) => tx1.amount.value - tx2.amount.value));
break;
case 'val-asc':
setSortedTxs([ ...txs ].sort((tx1, tx2) => tx2.amount.value - tx1.amount.value));
break;
case 'fee-desc':
setSortedTxs([ ...txs ].sort((tx1, tx2) => tx1.fee.value - tx2.fee.value));
break;
case 'fee-asc':
setSortedTxs([ ...txs ].sort((tx1, tx2) => tx2.fee.value - tx1.fee.value));
break;
default:
setSortedTxs(txs);
}
}, [ sorting ]);
return (
<>
{ !isPending && <Box mb={ 12 }>Only the first 10,000 elements are displayed</Box> }
<Box mb={ 6 }><Filters isMobile={ isMobile }/></Box>
{ isMobile ?
sortedTxs.map(tx => <TxsListItem tx={ tx } key={ tx.hash }/>) :
<TxsTable txs={ sortedTxs } sort={ sort } sorting={ sorting }/> }
<Box mx={ isMobile ? 0 : 6 } my={ isMobile ? 6 : 3 }>
<Pagination currentPage={ 1 } isMobile={ isMobile }/>
</Box>
</>
);
};
export default TxsContent;
import { Box } from '@chakra-ui/react';
import React from 'react';
import { txs } from 'data/txs';
import TxsListItem from 'ui/txs/TxsListItem';
const TxsList = () => {
return (
<Box>
{ txs.map(tx => <TxsListItem tx={ tx } key={ tx.hash }/>) }
</Box>
);
};
export default TxsList;
import React from 'react'; import React from 'react';
import TxsContent from './TxsContent';
const TxsPending = () => { const TxsPending = () => {
return <div>Привет2</div>; return <TxsContent isPending/>;
}; };
export default TxsPending; export default TxsPending;
import { Table, Thead, Tbody, Tr, Th, TableContainer, useBreakpointValue } from '@chakra-ui/react'; import { Link, Table, Thead, Tbody, Tr, Th, TableContainer, useBreakpointValue, Icon } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { txs } from 'data/txs'; import rightArrowIcon from 'icons/arrows/right.svg';
import TxsTableItem from './TxsTableItem'; import TxsTableItem from './TxsTableItem';
const CURRENCY = 'xDAI'; const CURRENCY = 'xDAI';
const TxsTable = () => { export type Sort = 'val-desc' | 'val-asc' | 'fee-desc' | 'fee-asc' | undefined;
type Props = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
txs: any;
sort: (field: 'val' | 'fee') => () => void;
sorting: Sort;
}
const TxsTable = ({ txs, sort, sorting }: Props) => {
const isLargeScreen = useBreakpointValue({ base: false, xl: true }); const isLargeScreen = useBreakpointValue({ base: false, xl: true });
return ( return (
...@@ -23,12 +32,25 @@ const TxsTable = () => { ...@@ -23,12 +32,25 @@ const TxsTable = () => {
<Th width={ isLargeScreen ? '128px' : '58px' }>From</Th> <Th width={ isLargeScreen ? '128px' : '58px' }>From</Th>
<Th width={ isLargeScreen ? '36px' : '0' }></Th> <Th width={ isLargeScreen ? '36px' : '0' }></Th>
<Th width={ isLargeScreen ? '128px' : '58px' }>To</Th> <Th width={ isLargeScreen ? '128px' : '58px' }>To</Th>
<Th width="18%" isNumeric>{ `Value ${ CURRENCY }` }</Th> <Th width="18%" isNumeric>
<Th width="18%" isNumeric pr={ 5 }>{ `Fee ${ CURRENCY }` }</Th> <Link onClick={ sort('val') } display="flex" justifyContent="end">
{ sorting === 'val-asc' && <Icon boxSize={ 5 } as={ rightArrowIcon } transform="rotate(-90deg)"/> }
{ sorting === 'val-desc' && <Icon boxSize={ 5 } as={ rightArrowIcon } transform="rotate(90deg)"/> }
{ `Value ${ CURRENCY }` }
</Link>
</Th>
<Th width="18%" isNumeric pr={ 5 }>
<Link onClick={ sort('fee') } display="flex" justifyContent="end">
{ sorting === 'fee-asc' && <Icon boxSize={ 5 } as={ rightArrowIcon } transform="rotate(-90deg)"/> }
{ sorting === 'fee-desc' && <Icon boxSize={ 5 } as={ rightArrowIcon } transform="rotate(90deg)"/> }
{ `Fee ${ CURRENCY }` }
</Link>
</Th>
</Tr> </Tr>
</Thead> </Thead>
<Tbody> <Tbody>
{ txs.map((item) => ( { /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ }
{ txs.map((item: any) => (
<TxsTableItem <TxsTableItem
key={ item.hash } key={ item.hash }
tx={ item } tx={ item }
......
import { Box } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import useIsMobile from 'lib/hooks/useIsMobile'; import TxsContent from './TxsContent';
import Filters from 'ui/shared/Filters';
import Pagination from './Pagination';
import TxsList from './TxsList';
import TxsTable from './TxsTable';
const TxsValidated = () => { const TxsValidated = () => {
const isMobile = useIsMobile(); return <TxsContent/>;
return (
<>
<Box mb={ 12 }>Only the first 10,000 elements are displayed</Box>
<Box mb={ 6 }><Filters/></Box>
{ isMobile ? <TxsList/> : <TxsTable/> }
<Box mx={ isMobile ? 0 : 6 } my={ isMobile ? 6 : 3 }>
<Pagination currentPage={ 1 } isMobile={ isMobile }/>
</Box>
</>
);
}; };
export default TxsValidated; export default TxsValidated;
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