Skip to content

Commit

Permalink
Implement elements wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
selankon committed Sep 3, 2024
1 parent 2bca38d commit 2796c77
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 98 deletions.
120 changes: 51 additions & 69 deletions src/components/Accounts/Details/Fees.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
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 { TransactionType } from '@vocdoni/sdk'
import { PaginationProvider, usePagination } from '~components/Pagination/PaginationProvider'
import { Pagination } from '~components/Pagination/Pagination'
import { useAccountFees } from '~queries/accounts'
import { TransactionTypeBadge } from '~components/Transactions/TransactionCard'
import { generatePath, Link as RouterLink } from 'react-router-dom'
import { RoutePath } from '~constants'
import { ContentError, NoResultsError } from '~components/Layout/ContentError'
import { useOrganization } from '@vocdoni/react-providers'
import AsyncListLayout from '~components/Layout/AsyncListLayout'

const AccountFees = () => {
return (
Expand Down Expand Up @@ -39,74 +37,58 @@ const AccountFeesTable = () => {
},
})

if (isLoading) {
return <LoadingCards />
}

if (data?.pagination.totalItems === 0 || feesCount === 0) {
return <NoResultsError />
}

if (isError || !data) {
return <ContentError error={error} />
}

if (!data.fees.length) {
return (
<Text>
<Trans i18nKey={'account.fees.no_fees'}>No fees yet!</Trans>
</Text>
)
}

return (
<>
<Box overflow='auto' w='auto'>
<TableContainer>
<Table>
<Thead>
<Tr>
<Th>
<Trans i18nKey={'account.fees.tx_type'}>Tx Type</Trans>
</Th>
<Th>
<Trans i18nKey={'account.transfers.block'}>Block</Trans>
</Th>
<Th>
<Trans i18nKey={'account.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(), tab: null, page: null })}
>
{fee.height}
</Link>
</Td>
<Td>{fee.cost}</Td>
<AsyncListLayout
isLoading={isLoading}
elements={data?.fees}
isError={isError}
error={error}
pagination={data?.pagination}
routedPagination={false}
elementsWrapper={(elements) => (
<Box overflow='auto' w='auto' pb={4}>
<TableContainer>
<Table>
<Thead>
<Tr>
<Th>
<Trans i18nKey={'account.fees.tx_type'}>Tx Type</Trans>
</Th>
<Th>
<Trans i18nKey={'account.transfers.block'}>Block</Trans>
</Th>
<Th>
<Trans i18nKey={'account.fees.cost'}>Cost</Trans>
</Th>
</Tr>
))}
</Tbody>
</Table>
</TableContainer>
</Box>
<Box pt={4}>
<Pagination pagination={data.pagination} />
</Box>
</>
</Thead>
<Tbody {...elements} />
</Table>
</TableContainer>
</Box>
)}
component={({ element: 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(), tab: null, page: null })}
>
{fee.height}
</Link>
</Td>
<Td>{fee.cost}</Td>
</Tr>
)}
/>
)
}

Expand Down
46 changes: 24 additions & 22 deletions src/components/Envelope/EnvelopeList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ import { Flex, Grid } from '@chakra-ui/react'
import { useElection } from '@vocdoni/react-providers'
import { PublishedElection } from '@vocdoni/sdk'
import { useTranslation } from 'react-i18next'
import { ContentError, NoResultsError } from '~components/Layout/ContentError'
import { LoadingCards } from '~components/Layout/Loading'
import { Pagination } from '~components/Pagination/Pagination'
import { NoResultsError } from '~components/Layout/ContentError'
import { PaginationProvider, usePagination } from '~components/Pagination/PaginationProvider'
import { useElectionVotesList } from '~queries/processes'
import { EnvelopeCard } from './EnvelopeCard'
import AsyncListLayout from '~components/Layout/AsyncListLayout'
import { EnvelopeCard } from '~components/Envelope/EnvelopeCard'

export const PaginatedEnvelopeList = () => {
const { election: e } = useElection()
Expand Down Expand Up @@ -38,26 +37,29 @@ const EnvelopeList = () => {
enabled: !!election?.id,
})

if (isLoading) {
return <LoadingCards />
}

if (data && data.votes?.length <= 0) {
return <NoResultsError />
}

if (isError || !data) {
return <ContentError error={error} />
}
return (
<Flex direction={'column'} gap={4}>
<Grid
templateColumns={{ base: 'repeat(1, 1fr)', sm: 'repeat(2, 1fr)', md: 'repeat(3, 1fr)', lg: 'repeat(5, 1fr)' }}
gap={4}
>
{data?.votes.map((envelope, i) => <EnvelopeCard key={i} envelope={envelope} count={page * 10 + i + 1} />)}
</Grid>
<Pagination pagination={data.pagination} />
<AsyncListLayout
isLoading={isLoading}
elements={data?.votes}
isError={isError}
error={error}
pagination={data?.pagination}
component={({ element, i }) => <EnvelopeCard envelope={element} count={page * 10 + i + 1} />}
routedPagination={false}
elementsWrapper={(elements) => (
<Grid
templateColumns={{
base: 'repeat(1, 1fr)',
sm: 'repeat(2, 1fr)',
md: 'repeat(3, 1fr)',
lg: 'repeat(5, 1fr)',
}}
gap={4}
{...elements}
/>
)}
/>
</Flex>
)
}
17 changes: 10 additions & 7 deletions src/components/Layout/AsyncListLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@ import { ContentError, NoResultsError } from '~components/Layout/ContentError'
import { Pagination } from '~components/Pagination/Pagination'
import { RoutedPagination } from '~components/Pagination/RoutedPagination'
import { PaginationResponse } from '@vocdoni/sdk'
import { PropsWithChildren } from 'react'

type AsyncListLayoutProps<T> = {
elements: T[] | null | undefined
isLoading?: boolean
isError?: boolean
error?: Error | null
noResultsMsg?: string
component: React.ComponentType<{ element: T }>
component: React.ComponentType<{ element: T; i: number }>
pagination?: Pick<PaginationResponse, 'pagination'>['pagination']
routedPagination?: boolean
skeletonProps?: SkeletonCardsProps
elementsWrapper?: React.ComponentType<PropsWithChildren>
}

const AsyncListLayout = <T,>({
Expand All @@ -22,10 +24,11 @@ const AsyncListLayout = <T,>({
isError,
error,
noResultsMsg,
component,
component: Component,
pagination,
routedPagination = true,
skeletonProps,
elementsWrapper: ElementsWrapper = ({ children }) => <>{children}</>,
}: AsyncListLayoutProps<T>) => {
if (isLoading) {
return <LoadingCards spacing={4} {...skeletonProps} />
Expand All @@ -39,13 +42,13 @@ const AsyncListLayout = <T,>({
return <ContentError error={error} />
}

const Component = component

return (
<>
{elements.map((element, index) => (
<Component key={index} element={element} />
))}
<ElementsWrapper>
{elements.map((element, index) => (
<Component key={index} element={element} i={index} />
))}
</ElementsWrapper>
{pagination && routedPagination && <RoutedPagination pagination={pagination} />}
{pagination && !routedPagination && <Pagination pagination={pagination} />}
</>
Expand Down

0 comments on commit 2796c77

Please sign in to comment.