-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve organization page info (#67)
* Add tabs to org detail * Implement account transfers This is not really ended, it needs vocdoni/vocdoni-sdk#400 to be merged * Implement transfers table * Split org components into multiple files * Bump extended-sdk * Fix transfers pagination * Fix default translation * Implement error page * Implement organization fees * Use filter.map * Delete commented * Implement text and tag
- Loading branch information
Showing
12 changed files
with
888 additions
and
436 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { Box, HStack, Tag } from '@chakra-ui/react' | ||
import { TagProps } from '@chakra-ui/tag/dist/tag' | ||
|
||
const TextAndTag = ({ text, tagLabel, ...rest }: { text: string; tagLabel: string } & TagProps) => { | ||
return ( | ||
<HStack spacing={2}> | ||
<Box>{text}</Box> | ||
<Tag borderRadius='full' colorScheme='green' {...rest}> | ||
{tagLabel} | ||
</Tag> | ||
</HStack> | ||
) | ||
} | ||
|
||
export default TextAndTag |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,123 +1,86 @@ | ||
import { Box, Flex, Icon, Text, VStack } from '@chakra-ui/react' | ||
import { OrganizationDescription, OrganizationHeader, OrganizationName } from '@vocdoni/chakra-components' | ||
import { Tab, TabList, TabPanel, TabPanels, VStack } from '@chakra-ui/react' | ||
import { OrganizationHeader, OrganizationName } from '@vocdoni/chakra-components' | ||
import { useOrganization } from '@vocdoni/react-providers' | ||
import { AccountData, ensure0x, PublishedElection } from '@vocdoni/sdk' | ||
import { Trans } from 'react-i18next' | ||
import { FaUserAlt } from 'react-icons/fa' | ||
import { useParams } from 'react-router-dom' | ||
import { Trans, useTranslation } from 'react-i18next' | ||
import { ReducedTextAndCopy } from '~components/Layout/CopyButton' | ||
import { HeroHeaderLayout } from '~components/Layout/HeroHeaderLayout' | ||
import { LoadingCards } from '~components/Layout/Loading' | ||
import ShowRawButton from '~components/Layout/ShowRawButton' | ||
import { RoutedPagination } from '~components/Pagination/Pagination' | ||
import { RoutedPaginationProvider } from '~components/Pagination/PaginationProvider' | ||
import { ElectionCard } from '~components/Process/Card' | ||
import { AppBaseURL, FallbackHeaderImg, PaginationItemsPerPage, RoutePath } from '~constants' | ||
import { useOrganizationElections } from '~queries/organizations' | ||
import { retryUnlessNotFound } from '~utils/queries' | ||
import { QueryParamsTabs } from '~components/Layout/QueryParamsTabs' | ||
import { RawContentBox } from '~components/Layout/ShowRawButton' | ||
import { FallbackHeaderImg } from '~constants' | ||
import { useAccountTransfersCount } from '~queries/organizations' | ||
import AccountTransfers from '~components/Organizations/Details/Transfers' | ||
import OrganizationElections from './Details/Elections' | ||
import OrgDetails from './Details/OrgDetails' | ||
import AccountFees from '~components/Organizations/Details/Fees' | ||
import TextAndTag from '~components/Layout/TextAndTag' | ||
|
||
const OrganizationDetail = () => { | ||
const { organization } = useOrganization() | ||
const { data } = useAccountTransfersCount({ | ||
address: organization?.address || '', | ||
}) | ||
const { t } = useTranslation() | ||
|
||
// Should be already loaded | ||
if (!organization) return null | ||
|
||
const id = organization.address | ||
const transfersCount = data?.count | ||
|
||
return ( | ||
<> | ||
<HeroHeaderLayout header={<OrganizationHeader fallbackSrc={FallbackHeaderImg} />}> | ||
<VStack> | ||
<OrganizationName fontSize='4xl' wordBreak='break-word' /> | ||
<OrganizationName fontSize='4xl' wordBreak='break-word' textAlign={'center'} /> | ||
<ReducedTextAndCopy color={'textAccent1'} toCopy={id} fontWeight={'normal'} h={0} fontSize={'md'}> | ||
{id} | ||
</ReducedTextAndCopy> | ||
<Flex | ||
as={'a'} | ||
target='blank' | ||
href={`${AppBaseURL}/organization/${ensure0x(id)}`} | ||
pt={4} | ||
align={'end'} | ||
gap={3} | ||
color={'blueText'} | ||
> | ||
<Box> | ||
<Icon as={FaUserAlt} boxSize={5} /> | ||
</Box> | ||
<Box> | ||
<Text fontSize='xl' verticalAlign='bottom'> | ||
<Trans i18nKey={'organization.view_profile'}>(View profile)</Trans> | ||
</Text> | ||
</Box> | ||
</Flex> | ||
</VStack> | ||
</HeroHeaderLayout> | ||
|
||
<Flex align='start' gap={2} direction={'column'}> | ||
{organization.account.description.default && ( | ||
<> | ||
<Text fontSize='xl' color={'blueText'}> | ||
<Trans i18nKey={'organization.description'}>Description</Trans> | ||
</Text> | ||
<OrganizationDescription /> | ||
</> | ||
)} | ||
</Flex> | ||
<Text fontSize='xl' color={'blueText'}> | ||
<Trans i18nKey={'organization.elections_list'}>Elections List:</Trans> | ||
</Text> | ||
<OrganizationElections org={organization} /> | ||
<ShowRawButton obj={organization} mt={4} /> | ||
<QueryParamsTabs isLazy> | ||
<TabList display='flex' flexWrap='wrap'> | ||
<Tab> | ||
<Trans i18nKey={'process.tab_details'}>Details</Trans> | ||
</Tab> | ||
<Tab> | ||
<TextAndTag | ||
text={t('organization.elections_count', { defaultValue: 'Elections' })} | ||
tagLabel={organization.electionIndex.toString()} | ||
/> | ||
</Tab> | ||
<Tab> | ||
<TextAndTag | ||
text={t('organization.transfers_count', { defaultValue: 'Transfers' })} | ||
tagLabel={transfersCount?.toString() ?? '0'} | ||
/> | ||
</Tab> | ||
<Tab> | ||
<Trans i18nKey={'organization.fees'}>Fees</Trans> | ||
</Tab> | ||
<Tab> | ||
<Trans i18nKey={'raw'}>Raw</Trans> | ||
</Tab> | ||
</TabList> | ||
<TabPanels> | ||
<TabPanel> | ||
<OrgDetails org={organization} /> | ||
</TabPanel> | ||
<TabPanel> | ||
<OrganizationElections org={organization} /> | ||
</TabPanel> | ||
<TabPanel> | ||
<AccountTransfers org={organization} txCount={transfersCount} /> | ||
</TabPanel> | ||
<TabPanel> | ||
<AccountFees org={organization} /> | ||
</TabPanel> | ||
<TabPanel> | ||
<RawContentBox obj={organization} /> | ||
</TabPanel> | ||
</TabPanels> | ||
</QueryParamsTabs> | ||
</> | ||
) | ||
} | ||
|
||
const OrganizationElections = ({ org }: { org: AccountData }) => { | ||
if (org.electionIndex === 0) { | ||
return ( | ||
<Text> | ||
<Trans i18nKey={'organization.no_elections'}>No elections yet!</Trans> | ||
</Text> | ||
) | ||
} | ||
|
||
return ( | ||
<RoutedPaginationProvider | ||
totalPages={Math.ceil(org.electionIndex / PaginationItemsPerPage)} | ||
path={RoutePath.Organization} | ||
> | ||
<Flex direction={'column'} gap={4}> | ||
<OrganizationElectionsList org={org} /> | ||
<RoutedPagination /> | ||
</Flex> | ||
</RoutedPaginationProvider> | ||
) | ||
} | ||
|
||
const OrganizationElectionsList = ({ org }: { org: AccountData }) => { | ||
const { page } = useParams() | ||
|
||
const { data: elections, isLoading } = useOrganizationElections({ | ||
address: org.address, | ||
page: Number(page) - 1 || 0, | ||
options: { | ||
enabled: !!org.address, | ||
retry: retryUnlessNotFound, | ||
}, | ||
}) | ||
|
||
if (isLoading) { | ||
return <LoadingCards /> | ||
} | ||
|
||
return ( | ||
<Flex direction={'column'} gap={4}> | ||
{elections?.map((election) => { | ||
if (election instanceof PublishedElection) return <ElectionCard key={election.id} election={election} /> | ||
return null | ||
})} | ||
</Flex> | ||
) | ||
} | ||
|
||
export default OrganizationDetail |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import { Flex, Text } from '@chakra-ui/react' | ||
import { AccountData, PublishedElection } from '@vocdoni/sdk' | ||
import { Trans } from 'react-i18next' | ||
import { useParams } from 'react-router-dom' | ||
import { LoadingCards } from '~components/Layout/Loading' | ||
import { RoutedPagination } from '~components/Pagination/Pagination' | ||
import { RoutedPaginationProvider } from '~components/Pagination/PaginationProvider' | ||
import { ElectionCard } from '~components/Process/Card' | ||
import { PaginationItemsPerPage, RoutePath } from '~constants' | ||
import { useOrganizationElections } from '~queries/organizations' | ||
import { retryUnlessNotFound } from '~utils/queries' | ||
|
||
interface OrgComponentProps { | ||
org: AccountData | ||
} | ||
|
||
const OrganizationElections = ({ org }: OrgComponentProps) => { | ||
if (org.electionIndex === 0) { | ||
return ( | ||
<Text> | ||
<Trans i18nKey={'organization.no_elections'}>No elections yet!</Trans> | ||
</Text> | ||
) | ||
} | ||
|
||
return ( | ||
<RoutedPaginationProvider | ||
totalPages={Math.ceil(org.electionIndex / PaginationItemsPerPage)} | ||
path={RoutePath.Organization} | ||
> | ||
<Flex direction={'column'} gap={4}> | ||
<OrganizationElectionsList org={org} /> | ||
<RoutedPagination /> | ||
</Flex> | ||
</RoutedPaginationProvider> | ||
) | ||
} | ||
|
||
const OrganizationElectionsList = ({ org }: OrgComponentProps) => { | ||
const { page } = useParams() | ||
|
||
const { data: elections, isLoading } = useOrganizationElections({ | ||
address: org.address, | ||
page: Number(page) - 1 || 0, | ||
options: { | ||
enabled: !!org.address, | ||
retry: retryUnlessNotFound, | ||
}, | ||
}) | ||
|
||
if (isLoading) { | ||
return <LoadingCards /> | ||
} | ||
|
||
return ( | ||
<Flex direction={'column'} gap={4}> | ||
{elections | ||
?.filter((election) => { | ||
return election instanceof PublishedElection | ||
}) | ||
.map((election) => { | ||
return <ElectionCard key={election.id} election={election as PublishedElection} /> | ||
})} | ||
</Flex> | ||
) | ||
} | ||
|
||
export default OrganizationElections |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import { Box, Flex, Link, Table, TableContainer, Tbody, Td, Text, Th, Thead, Tr } from '@chakra-ui/react' | ||
import { Trans } from 'react-i18next' | ||
import { LoadingCards } from '~components/Layout/Loading' | ||
import { useDateFns } from '~i18n/use-date-fns' | ||
import { AccountData, TransactionType } from '@vocdoni/sdk' | ||
import { PaginationProvider, usePagination } from '~components/Pagination/PaginationProvider' | ||
import { Pagination } from '~components/Pagination/Pagination' | ||
import { useAccountFees } from '~queries/organizations' | ||
import { retryUnlessNotFound } from '~utils/queries' | ||
import LoadingError from '~components/Layout/LoadingError' | ||
import { TransactionTypeBadge } from '~components/Transactions/TransactionCard' | ||
import { generatePath, Link as RouterLink } from 'react-router-dom' | ||
import { RoutePath } from '~constants' | ||
|
||
const AccountFees = (org: { org: AccountData }) => { | ||
return ( | ||
<PaginationProvider> | ||
<AccountFeesTable {...org} /> | ||
</PaginationProvider> | ||
) | ||
} | ||
|
||
const AccountFeesTable = ({ org }: { org: AccountData }) => { | ||
const { page } = usePagination() | ||
const { formatDistance } = useDateFns() | ||
|
||
const { data, isLoading, isError, error } = useAccountFees({ | ||
address: org.address, | ||
page: Number(page) - 1 || 0, | ||
options: { | ||
retry: retryUnlessNotFound, | ||
}, | ||
}) | ||
|
||
if (isLoading) { | ||
return <LoadingCards /> | ||
} | ||
|
||
if (isError || !data) { | ||
return <LoadingError error={error} /> | ||
} | ||
|
||
if (!data.fees.length) { | ||
return ( | ||
<Text> | ||
<Trans i18nKey={'organization.fees.no_fees'}>No fees yet!</Trans> | ||
</Text> | ||
) | ||
} | ||
|
||
return ( | ||
<> | ||
<Box overflow='auto' w='auto'> | ||
<TableContainer> | ||
<Table> | ||
<Thead> | ||
<Tr> | ||
<Th> | ||
<Trans i18nKey={'organization.fees.tx_type'}>Tx Type</Trans> | ||
</Th> | ||
<Th> | ||
<Trans i18nKey={'organization.transfers.block'}>Block</Trans> | ||
</Th> | ||
<Th> | ||
<Trans i18nKey={'organization.fees.cost'}>Cost</Trans> | ||
</Th> | ||
</Tr> | ||
</Thead> | ||
<Tbody> | ||
{data.fees.map((fee, i) => ( | ||
<Tr key={i}> | ||
<Td> | ||
<Flex direction={'column'} align={'start'} gap={3}> | ||
<TransactionTypeBadge transactionType={fee.txType as TransactionType} /> | ||
<Text fontWeight={100} color={'lighterText'} fontSize={'sm'}> | ||
{formatDistance(new Date(fee.timestamp), new Date())} | ||
</Text> | ||
</Flex> | ||
</Td> | ||
<Td> | ||
<Link | ||
as={RouterLink} | ||
to={generatePath(RoutePath.Block, { height: fee.height.toString(), page: null })} | ||
> | ||
{fee.height} | ||
</Link> | ||
</Td> | ||
<Td>{fee.cost}</Td> | ||
</Tr> | ||
))} | ||
</Tbody> | ||
</Table> | ||
</TableContainer> | ||
</Box> | ||
<Box pt={4}> | ||
<Pagination /> | ||
</Box> | ||
</> | ||
) | ||
} | ||
|
||
export default AccountFees |
Oops, something went wrong.
9652ed6
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
π Published on https://vocdoni-explorer-dev.netlify.app as production
π Deployed on https://66a0b26ca909f1d245b8a563--vocdoni-explorer-dev.netlify.app
9652ed6
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
π Published on https://vocdoni-explorer-stg.netlify.app as production
π Deployed on https://66a0b27285a14b7885d321d5--vocdoni-explorer-stg.netlify.app