Commit d1d1939f authored by isstuev's avatar isstuev

sorting

parent 74067a0d
......@@ -12,6 +12,14 @@ export const txs = [
errorText: 'Error: (Awaiting internal transactions for reason)',
txType: 'contract-call',
method: 'CommitHash CommitHash CommitHash CommitHash',
amount: {
value: 0.04,
value_usd: 35.5,
},
fee: {
value: 0.002295904453623692,
value_usd: 2.84,
},
},
{
...tx,
......@@ -23,5 +31,13 @@ export const txs = [
alias: 'tkdkdkdkdkdkdkdkdkdkdkdkdkdkd.eth',
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
import type { ChangeEvent } from 'react';
import React from 'react';
import upDownArrow from 'icons/arrows/up-down.svg';
import filterIcon from 'icons/filter.svg';
import searchIcon from 'icons/search.svg';
const FilterIcon = <Icon as={ filterIcon } boxSize={ 5 }/>;
const Filters = () => {
const [ isActive, setIsActive ] = React.useState(false);
type Props = {
isMobile?: boolean;
}
const Filters = ({ isMobile }: Props) => {
const [ isFilterActive, setIsFilterActive ] = React.useState(false);
const [ value, setValue ] = React.useState('');
const [ isSortActive, setIsSortActive ] = React.useState(false);
const handleClick = React.useCallback(() => {
setIsActive(flag => !flag);
setIsFilterActive(flag => !flag);
}, []);
const handleChange = React.useCallback((event: ChangeEvent<HTMLInputElement>) => {
setValue(event.target.value);
}, []);
const handleSort = React.useCallback(() => {
setIsSortActive(flag => !flag);
}, []);
const badgeColor = useColorModeValue('white', 'black');
const badgeBgColor = useColorModeValue('blue.700', 'gray.50');
const searchIconColor = useColorModeValue('blackAlpha.600', 'whiteAlpha.600');
......@@ -31,19 +41,31 @@ const Filters = () => {
return (
<Flex>
<Button
leftIcon={ FilterIcon }
rightIcon={ isActive ? <Circle bg={ badgeBgColor } size={ 5 } color={ badgeColor }>2</Circle> : undefined }
leftIcon={ isMobile ? undefined : FilterIcon }
rightIcon={ isFilterActive ? <Circle bg={ badgeBgColor } size={ 5 } color={ badgeColor }>2</Circle> : undefined }
size="sm"
variant="outline"
colorScheme="gray-dark"
borderWidth="1px"
onClick={ handleClick }
isActive={ isActive }
isActive={ isFilterActive }
px={ 1.5 }
>
Filter
{ isMobile ? FilterIcon : 'Filter' }
</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 }>
<Icon as={ searchIcon } boxSize={ 5 } color={ searchIconColor }/>
</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 TxsContent from './TxsContent';
const TxsPending = () => {
return <div>Привет2</div>;
return <TxsContent isPending/>;
};
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 { txs } from 'data/txs';
import rightArrowIcon from 'icons/arrows/right.svg';
import TxsTableItem from './TxsTableItem';
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 });
return (
......@@ -23,12 +32,25 @@ const TxsTable = () => {
<Th width={ isLargeScreen ? '128px' : '58px' }>From</Th>
<Th width={ isLargeScreen ? '36px' : '0' }></Th>
<Th width={ isLargeScreen ? '128px' : '58px' }>To</Th>
<Th width="18%" isNumeric>{ `Value ${ CURRENCY }` }</Th>
<Th width="18%" isNumeric pr={ 5 }>{ `Fee ${ CURRENCY }` }</Th>
<Th width="18%" isNumeric>
<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>
</Thead>
<Tbody>
{ txs.map((item) => (
{ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ }
{ txs.map((item: any) => (
<TxsTableItem
key={ item.hash }
tx={ item }
......
import { Box } from '@chakra-ui/react';
import React from 'react';
import useIsMobile from 'lib/hooks/useIsMobile';
import Filters from 'ui/shared/Filters';
import Pagination from './Pagination';
import TxsList from './TxsList';
import TxsTable from './TxsTable';
import TxsContent from './TxsContent';
const TxsValidated = () => {
const isMobile = useIsMobile();
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>
</>
);
return <TxsContent/>;
};
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