Skip to content

Commit

Permalink
Implement useQuery params
Browse files Browse the repository at this point in the history
  • Loading branch information
selankon committed Jun 7, 2024
1 parent 0babf59 commit 5dffc2a
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 10 deletions.
43 changes: 39 additions & 4 deletions src/components/Process/ProcessList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,43 @@ import { LoadingCards } from '~src/layout/Loading'
import { useProcessesCount, useProcessList } from '~queries/processes'
import ElectionCard from './Card'
import { processListPath } from '~src/router'
import { Trans, useTranslation } from 'react-i18next'
import useQueryParams from '~src/router/use-query-params'
import { InputSearch } from '~src/layout/Inputs'
import { IElectionListFilter } from '@vocdoni/sdk'
import { Checkbox, Flex } from '@chakra-ui/react'

type FilterQueryParams = {
[K in keyof Omit<IElectionListFilter, 'organizationId'>]: string
}

export const PorcessSearchBox = () => {
const { t } = useTranslation()
const { queryParams, setQueryParams } = useQueryParams<FilterQueryParams>()

return (
<Flex direction={{ base: 'column', lg: 'row' }} align={'center'} justify={'end'} gap={4}>
<Checkbox onChange={(e) => setQueryParams({ ...queryParams, withResults: e.target.checked ? 'true' : 'false' })}>
<Trans i18nKey='process.show_with_results'>Show only processes with results</Trans>
</Checkbox>
<Flex justify='flex-end'>
<InputSearch
maxW={'300px'}
placeholder={t('process.search_by')}
onChange={(value: string) => {
setQueryParams({ ...queryParams, electionId: value })
}}
debounceTime={500}
/>
</Flex>
</Flex>
)
}
export const PaginatedProcessList = () => {
const { page }: { page?: number } = useParams()
const { data: processCount, isLoading: isLoadingCount } = useProcessesCount()
const count = processCount || 0
const { queryParams: processFilters } = useQueryParams<FilterQueryParams>()

const {
data: processes,
Expand All @@ -19,7 +51,12 @@ export const PaginatedProcessList = () => {
error,
} = useProcessList({
page: Number(page || 0),
filters: {},
filters: {
electionId: processFilters.electionId,
// organizationId: processFilters.electionId,
status: processFilters.status as IElectionListFilter['status'],
withResults: processFilters.withResults === 'true',
},
})

const isLoading = isLoadingCount || isLoadingOrgs
Expand All @@ -34,9 +71,7 @@ export const PaginatedProcessList = () => {

return (
<RoutedPaginationProvider totalPages={Math.ceil(count / 10)} path={processListPath}>
{processes?.elections.map((election, i) => (
<ElectionCard key={i} election={election} />
))}
{processes?.elections.map((election, i) => <ElectionCard key={i} election={election} />)}
<RoutedPagination />
</RoutedPaginationProvider>
)
Expand Down
10 changes: 7 additions & 3 deletions src/layout/ListPageLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Box, Flex, Heading, Text } from '@chakra-ui/react'
import { Flex, Heading, Text } from '@chakra-ui/react'
import { PropsWithChildren, ReactNode } from 'react'

const ListPageLayout = ({
Expand All @@ -13,14 +13,18 @@ const ListPageLayout = ({
} & PropsWithChildren) => {
return (
<Flex direction={'column'} mt={'40px'} gap={6}>
<Flex direction={{ base: 'column', md: 'row' }} justify={'space-between'}>
<Flex direction={{ base: 'column', md: 'row' }} justify={'space-between'} gap={4}>
<Flex direction={'column'}>
<Heading isTruncated wordBreak='break-word'>
{title}
</Heading>
{subtitle && <Text color={'lighterText'}>{subtitle}</Text>}
</Flex>
{rightComponent && <Box>{rightComponent}</Box>}
{rightComponent && (
<Flex align={'end'} justify={'end'} w={'full'}>
{rightComponent}
</Flex>
)}
</Flex>
{children}
</Flex>
Expand Down
4 changes: 2 additions & 2 deletions src/pages/Process/List.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import ListPageLayout from '~src/layout/ListPageLayout'
import { useTranslation } from 'react-i18next'
import { useProcessesCount } from '~queries/processes'
import { PaginatedProcessList } from '~components/Process/ProcessList'
import { PaginatedProcessList, PorcessSearchBox } from '~components/Process/ProcessList'

const ProcessList = () => {
const { t } = useTranslation()
Expand All @@ -10,7 +10,7 @@ const ProcessList = () => {
const subtitle = !isLoading ? t('process.process_count', { count: data || 0 }) : ''

return (
<ListPageLayout title={t('process.process_list')} subtitle={subtitle}>
<ListPageLayout title={t('process.process_list')} subtitle={subtitle} rightComponent={<PorcessSearchBox />}>
<PaginatedProcessList />
</ListPageLayout>
)
Expand Down
2 changes: 1 addition & 1 deletion src/queries/processes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const useProcessList = ({
} & Omit<UseQueryOptions<IElectionListResponse, Error, { elections: PublishedElection[] }>, 'queryKey'>) => {
const { client } = useClient<ExtendedSDKClient>()
return useQuery({
queryKey: ['organizations', 'list', page],
queryKey: ['organizations', 'list', page, filters],
queryFn: () => client.electionList(page, { ...filters }),

Check failure on line 18 in src/queries/processes.ts

View workflow job for this annotation

GitHub Actions / build-stg-explorer

Argument of type '{ organizationId?: string | undefined; electionId?: string | undefined; withResults?: boolean | undefined; status?: ElectionStatus.PROCESS_UNKNOWN | ElectionStatus.ENDED | ... 4 more ... | undefined; }' is not assignable to parameter of type 'string'.

Check failure on line 18 in src/queries/processes.ts

View workflow job for this annotation

GitHub Actions / build-dev-explorer

Argument of type '{ organizationId?: string | undefined; electionId?: string | undefined; withResults?: boolean | undefined; status?: ElectionStatus.PROCESS_UNKNOWN | ElectionStatus.ENDED | ... 4 more ... | undefined; }' is not assignable to parameter of type 'string'.
select: (data) => {
const elections = data?.elections.map((election) => {
Expand Down
34 changes: 34 additions & 0 deletions src/router/use-query-params.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { useMemo } from 'react'
import { useLocation, useNavigate } from 'react-router-dom'

const useQueryParams = <T extends Record<string, string>>() => {
const { search } = useLocation()
const navigate = useNavigate()
const location = useLocation()

const queryParams = useMemo(() => {
const params = new URLSearchParams(search)
const queryObj = {} as T
for (const [key, value] of params.entries()) {
// @ts-ignore
queryObj[key as keyof T] = value
}
return queryObj
}, [search])

const setQueryParams = (newParams: Partial<T>) => {
const params = new URLSearchParams(search)
for (const key in newParams) {
if (newParams[key]) {
params.set(key, newParams[key] as string)
} else {
params.delete(key)
}
}
navigate(`${location.pathname}?${params.toString()}`)
}

return { queryParams, setQueryParams }
}

export default useQueryParams

0 comments on commit 5dffc2a

Please sign in to comment.