-
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.
* Create paginated Organizations list page * Implement organization id filter * Show organization id preview * Split logic * Show error * Fix footer relative path * Add some intl * Refactor name * Refactor to extrapolate layout * Use paths constants * Create loading cards loader * Clean code * Use organization image * Import images * Refator to PaginatedOrganizationsList * Create Loding layout * Reset page every time filter change * Fix relative path * Use path constant
- Loading branch information
Showing
22 changed files
with
571 additions
and
39 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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
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,56 @@ | ||
import { Box, Card, CardBody, Text } from '@chakra-ui/react' | ||
import { Trans, useTranslation } from 'react-i18next' | ||
import { ReducedTextAndCopy } from '~components/CopyBtn' | ||
import { OrganizationProvider, useOrganization } from '@vocdoni/react-providers' | ||
import { OrganizationImage as Avatar, OrganizationName } from '@vocdoni/chakra-components' | ||
|
||
interface IOrganizationCardProps { | ||
id: string | ||
electionCount?: number | ||
} | ||
|
||
const OrganizationCard = ({ id, ...rest }: IOrganizationCardProps) => { | ||
return ( | ||
<OrganizationProvider id={id}> | ||
<OrganizationCardContent id={id} {...rest} /> | ||
</OrganizationProvider> | ||
) | ||
} | ||
|
||
const OrganizationCardContent = ({ id, electionCount }: IOrganizationCardProps) => { | ||
const { organization, loading } = useOrganization() | ||
const { t } = useTranslation() | ||
|
||
return ( | ||
<Card direction={'row'} alignItems='center' overflow={'scroll'} pl={4}> | ||
<Box w={'50px'}> | ||
<Avatar | ||
mx='auto' | ||
fallbackSrc={'/images/fallback-account-dark.png'} | ||
alt={t('organization.avatar_alt', { | ||
name: organization?.account.name.default || organization?.address, | ||
}).toString()} | ||
/> | ||
</Box> | ||
<CardBody> | ||
{loading ? ( | ||
<Text fontWeight={'bold'} wordBreak='break-all' size='sm'> | ||
{id} | ||
</Text> | ||
) : ( | ||
<OrganizationName fontWeight={'bold'} wordBreak='break-all' size='sm' /> | ||
)} | ||
<ReducedTextAndCopy color={'textAccent1'} toCopy={id}> | ||
{id} | ||
</ReducedTextAndCopy> | ||
<Text fontSize={'sm'}> | ||
<Trans i18nKey={'organization.process_count'} count={electionCount}> | ||
<strong>Process:</strong> {{ count: electionCount }} | ||
</Trans> | ||
</Text> | ||
</CardBody> | ||
</Card> | ||
) | ||
} | ||
|
||
export default OrganizationCard |
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,61 @@ | ||
import { InputSearch } from '~src/layout/Inputs' | ||
import { useOrganizationCount, useOrganizationList } from '~queries/organizations' | ||
import { debounce } from '~utils/debounce' | ||
import { generatePath, useNavigate, useParams } from 'react-router-dom' | ||
import { RoutedPaginationProvider } from '~components/Pagination/PaginationProvider' | ||
import OrganizationCard from '~components/Organizations/Card' | ||
import { RoutedPagination } from '~components/Pagination/Pagination' | ||
import LoadingError from '~src/layout/LoadingError' | ||
import { useTranslation } from 'react-i18next' | ||
import { LoadingCards } from '~src/layout/Loading' | ||
import { ORGANIZATIONS_LIST_PATH } from '~src/router' | ||
|
||
export const OrganizationsFilter = () => { | ||
const { t } = useTranslation() | ||
const navigate = useNavigate() | ||
|
||
const debouncedSearch = debounce((value) => { | ||
navigate(generatePath(ORGANIZATIONS_LIST_PATH, { page: '0', query: value as string })) | ||
}, 1000) | ||
|
||
const searchOnChange = (event: any) => { | ||
debouncedSearch(event.target.value) | ||
} | ||
|
||
return <InputSearch maxW={'300px'} placeholder={t('organizations.search_by_org_id')} onChange={searchOnChange} /> | ||
} | ||
|
||
export const PaginatedOrganizationsList = () => { | ||
const { page, query }: { page?: number; query?: string } = useParams() | ||
const { data: orgsCount, isLoading: isLoadingCount } = useOrganizationCount() | ||
const count = orgsCount?.count || 0 | ||
|
||
const { | ||
data: orgs, | ||
isLoading: isLoadingOrgs, | ||
isError, | ||
error, | ||
} = useOrganizationList({ | ||
page: Number(page || 0), | ||
organizationId: query, | ||
}) | ||
|
||
const isLoading = isLoadingCount || isLoadingOrgs | ||
|
||
if (isLoading) { | ||
return <LoadingCards /> | ||
} | ||
|
||
if (!orgs || orgs?.organizations.length === 0 || isError) { | ||
return <LoadingError error={error} /> | ||
} | ||
|
||
return ( | ||
<RoutedPaginationProvider totalPages={Math.ceil(count / 10)} path={ORGANIZATIONS_LIST_PATH}> | ||
{orgs?.organizations.map((org) => ( | ||
<OrganizationCard key={org.organizationID} id={org.organizationID} electionCount={org.electionCount} /> | ||
))} | ||
<RoutedPagination /> | ||
</RoutedPaginationProvider> | ||
) | ||
} |
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,45 @@ | ||
import { Button, ButtonGroup } from '@chakra-ui/react' | ||
import { ReactElement, useMemo } from 'react' | ||
import { generatePath, Link as RouterLink, useParams } from 'react-router-dom' | ||
import { usePagination, useRoutedPagination } from './PaginationProvider' | ||
|
||
export const Pagination = () => { | ||
const { page, setPage, totalPages } = usePagination() | ||
|
||
const pages: ReactElement[] = useMemo(() => { | ||
const pages: ReactElement[] = [] | ||
for (let i = 0; i < totalPages; i++) { | ||
pages.push( | ||
<Button key={i} onClick={() => setPage(i)} isActive={page === i}> | ||
{i + 1} | ||
</Button> | ||
) | ||
} | ||
return pages | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [page, totalPages]) | ||
|
||
return <ButtonGroup isAttached>{pages.map((page) => page)}</ButtonGroup> | ||
} | ||
|
||
export const RoutedPagination = () => { | ||
const { path, totalPages } = useRoutedPagination() | ||
const { page }: { page?: number } = useParams() | ||
|
||
const p = Number(page) || 0 | ||
|
||
const pages: ReactElement[] = useMemo(() => { | ||
const pages: ReactElement[] = [] | ||
for (let i = 0; i < totalPages; i++) { | ||
pages.push( | ||
<Button as={RouterLink} key={i} to={generatePath(path, { page: i })} isActive={p === i}> | ||
{i + 1} | ||
</Button> | ||
) | ||
} | ||
return pages | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [p, totalPages]) | ||
|
||
return <ButtonGroup isAttached>{pages.map((page) => page)}</ButtonGroup> | ||
} |
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,50 @@ | ||
import { createContext, PropsWithChildren, useContext, useState } from 'react' | ||
|
||
export type PaginationContextProps = { | ||
page: number | ||
setPage: (page: number) => void | ||
totalPages: number | ||
} | ||
|
||
export type RoutedPaginationContextProps = Omit<PaginationContextProps, 'setPage' | 'page'> & { | ||
path: string | ||
} | ||
|
||
const PaginationContext = createContext<PaginationContextProps | undefined>(undefined) | ||
const RoutedPaginationContext = createContext<RoutedPaginationContextProps | undefined>(undefined) | ||
|
||
export const usePagination = (): PaginationContextProps => { | ||
const context = useContext(PaginationContext) | ||
if (!context) { | ||
throw new Error('usePagination must be used within a PaginationProvider') | ||
} | ||
return context | ||
} | ||
|
||
export const useRoutedPagination = (): RoutedPaginationContextProps => { | ||
const context = useContext(RoutedPaginationContext) | ||
if (!context) { | ||
throw new Error('useRoutedPagination must be used within a RoutedPaginationProvider') | ||
} | ||
return context | ||
} | ||
|
||
export type PaginationProviderProps = Pick<PaginationContextProps, 'totalPages'> | ||
|
||
export type RoutedPaginationProviderProps = PaginationProviderProps & { | ||
path: string | ||
} | ||
|
||
export const RoutedPaginationProvider = ({ | ||
totalPages, | ||
path, | ||
...rest | ||
}: PropsWithChildren<RoutedPaginationProviderProps>) => { | ||
return <RoutedPaginationContext.Provider value={{ totalPages, path }} {...rest} /> | ||
} | ||
|
||
export const PaginationProvider = ({ totalPages, ...rest }: PropsWithChildren<PaginationProviderProps>) => { | ||
const [page, setPage] = useState<number>(0) | ||
|
||
return <PaginationContext.Provider value={{ page, setPage, totalPages }} {...rest} /> | ||
} |
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
Oops, something went wrong.
baeea38
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://6660848fa727e3395f744d3b--vocdoni-explorer-stg.netlify.app
baeea38
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://6660849071cfdf37ff4a111a--vocdoni-explorer-dev.netlify.app