diff --git a/src/components/Dashboard/Menu/Options.tsx b/src/components/Dashboard/Menu/Options.tsx index 64bb4ca9..f3a74616 100644 --- a/src/components/Dashboard/Menu/Options.tsx +++ b/src/components/Dashboard/Menu/Options.tsx @@ -4,7 +4,7 @@ import { useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' import { HiSquares2X2 } from 'react-icons/hi2' import { IoIosSettings } from 'react-icons/io' -import { matchPath, useLocation } from 'react-router-dom' +import { generatePath, matchPath, useLocation } from 'react-router-dom' import { Routes } from '~src/router/routes' import { DashboardMenuItem } from './Item' @@ -30,9 +30,9 @@ export const DashboardMenuOptions = () => { label: t('voting_processes'), icon: HiSquares2X2, children: [ - { label: t('all'), route: Routes.dashboard.processes }, - { label: t('active'), route: '#active' }, - { label: t('finished'), route: '#finished' }, + { label: t('all'), route: generatePath(Routes.dashboard.processes, { page: 1 }) }, + { label: t('active'), route: generatePath(Routes.dashboard.processes, { status: 'ready', page: 1 }) }, + { label: t('finished'), route: generatePath(Routes.dashboard.processes, { status: 'results', page: 1 }) }, // { label: t('draft'), route: '#draft' }, ], }, diff --git a/src/components/Organization/Dashboard/ProcessesList.tsx b/src/components/Organization/Dashboard/ProcessesList.tsx index c5c97f01..6579a72b 100644 --- a/src/components/Organization/Dashboard/ProcessesList.tsx +++ b/src/components/Organization/Dashboard/ProcessesList.tsx @@ -9,13 +9,12 @@ import ProcessCard from './ProcessCard' type Election = PublishedElection | InvalidElection type ProcessesListProps = { - error: Error | null - loading: boolean - limit?: number + error?: Error | null + loading?: boolean processes?: Election[] } -const ProcessesList = ({ loading, processes, error, limit }: ProcessesListProps) => { +const ProcessesList = ({ loading, processes, error }: ProcessesListProps) => { const { t } = useTranslation() return ( @@ -47,13 +46,11 @@ const ProcessesList = ({ loading, processes, error, limit }: ProcessesListProps) {processes && processes.length && - processes?.map((election, key) => - limit && key >= limit ? null : ( - - - - ) - )} + processes?.map((election) => ( + + + + ))} {!loading && (!processes || !processes.length) && } diff --git a/src/components/Organization/Dashboard/Votings.tsx b/src/components/Organization/Dashboard/Votings.tsx index 466efd24..812d9135 100644 --- a/src/components/Organization/Dashboard/Votings.tsx +++ b/src/components/Organization/Dashboard/Votings.tsx @@ -1,33 +1,30 @@ import { Flex } from '@chakra-ui/react' import { RoutedPagination } from '@vocdoni/chakra-components' -import { RoutedPaginationProvider, useOrganization, useRoutedPagination } from '@vocdoni/react-providers' -import { usePaginatedElections } from '~src/queries/organization' +import { RoutedPaginationProvider, useOrganization } from '@vocdoni/react-providers' +import { ElectionListWithPagination } from '@vocdoni/sdk' import { Routes } from '~src/router/routes' import ProcessesList from './ProcessesList' -const Votings = () => { +const Votings = ({ data }: { data: ElectionListWithPagination }) => { const { organization } = useOrganization() if (!organization) return null return ( - + ) } -const VotingsList = () => { - const { page } = useRoutedPagination() - const { data, error, isLoading } = usePaginatedElections(page ?? 0) - +const VotingsList = ({ data }: { data: ElectionListWithPagination }) => { if (!data) return null const { elections, pagination } = data return ( - + {!!elections?.length && } diff --git a/src/elements/dashboard/processes/index.tsx b/src/elements/dashboard/processes/index.tsx index 843ffffa..16ae649c 100644 --- a/src/elements/dashboard/processes/index.tsx +++ b/src/elements/dashboard/processes/index.tsx @@ -1,6 +1,7 @@ +import { ElectionListWithPagination } from '@vocdoni/sdk' import { useEffect } from 'react' import { useTranslation } from 'react-i18next' -import { useOutletContext } from 'react-router-dom' +import { useLoaderData, useOutletContext } from 'react-router-dom' import { DashboardContents } from '~components/Layout/Dashboard' import Votings from '~components/Organization/Dashboard/Votings' import { DashboardLayoutContext } from '~elements/LayoutDashboard' @@ -8,6 +9,7 @@ import { DashboardLayoutContext } from '~elements/LayoutDashboard' const OrganizationVotings = () => { const { t } = useTranslation() const { setBack, setTitle } = useOutletContext() + const data = useLoaderData() // Set page title useEffect(() => { @@ -17,7 +19,7 @@ const OrganizationVotings = () => { return ( - + ) } diff --git a/src/queries/organization.ts b/src/queries/organization.ts index 21c18689..503ed188 100644 --- a/src/queries/organization.ts +++ b/src/queries/organization.ts @@ -1,24 +1,21 @@ -import { useQuery } from '@tanstack/react-query' -import { useClient } from '@vocdoni/react-providers' +import { AccountData, FetchElectionsParameters, VocdoniSDKClient } from '@vocdoni/sdk' -export const useLatestElections = (limit = 5) => { - const { client, account } = useClient() - - return useQuery({ - enabled: !!account?.address, - queryKey: ['organization', 'elections', account?.address, 0], - queryFn: async () => client.fetchElections({ organizationId: account?.address, page: 0, limit }), - select: (data) => data.elections, - retry: false, - }) +type PaginatedElectionsParams = { + page?: number + status?: FetchElectionsParameters['status'] } -export const usePaginatedElections = (page: number) => { - const { client, account } = useClient() - - return useQuery({ - enabled: !!account?.address, - queryKey: ['organization', 'elections', account?.address, page], - queryFn: async () => client.fetchElections({ organizationId: account?.address, page }), - }) -} +export const paginatedElectionsQuery = ( + account: AccountData, + client: VocdoniSDKClient, + params: PaginatedElectionsParams +) => ({ + enabled: !!account?.address, + queryKey: ['organization', 'elections', account?.address, params], + queryFn: async () => + client.fetchElections({ + organizationId: account?.address, + page: params.page ? Number(params.page) - 1 : 0, + status: params.status?.toUpperCase() as FetchElectionsParameters['status'], + }), +}) diff --git a/src/router/routes/dashboard.tsx b/src/router/routes/dashboard.tsx index 8f417dc2..d115fee6 100644 --- a/src/router/routes/dashboard.tsx +++ b/src/router/routes/dashboard.tsx @@ -1,11 +1,12 @@ import { useClient } from '@vocdoni/react-providers' -import { VocdoniSDKClient } from '@vocdoni/sdk' import { lazy } from 'react' // These aren't lazy loaded since they are main layouts and related components +import { useQueryClient } from '@tanstack/react-query' import { Params } from 'react-router-dom' import { Profile } from '~elements/dashboard/profile' import Error from '~elements/Error' import LayoutDashboard from '~elements/LayoutDashboard' +import { paginatedElectionsQuery } from '~src/queries/organization' import { Routes } from '.' import OrganizationProtectedRoute from '../OrganizationProtectedRoute' import { SuspenseLoader } from '../SuspenseLoader' @@ -19,76 +20,79 @@ const OrganizationTeam = lazy(() => import('~elements/dashboard/team')) // others const OrganizationDashboard = lazy(() => import('~components/Organization/Dashboard')) -const DashboardElements = (client: VocdoniSDKClient) => [ - { +export const useDashboardRoutes = () => { + const queryClient = useQueryClient() + const { client, account } = useClient() + + return { element: ( - + ), children: [ { - path: Routes.dashboard.base, - element: ( - - - - ), - }, - { - path: Routes.dashboard.process, - element: ( - - - - ), - loader: async ({ params }: { params: Params }) => client.fetchElection(params.id), - errorElement: , - }, - { - path: Routes.dashboard.organization, - element: ( - - - - ), - }, - { - path: Routes.dashboard.profile, element: ( - - - ), - }, - { - path: Routes.dashboard.processes, - element: ( - - - - ), - }, - { - path: Routes.dashboard.team, - element: ( - - + ), + children: [ + { + path: Routes.dashboard.base, + element: ( + + + + ), + }, + { + path: Routes.dashboard.process, + element: ( + + + + ), + loader: async ({ params }: { params: Params }) => client.fetchElection(params.id), + errorElement: , + }, + { + path: Routes.dashboard.organization, + element: ( + + + + ), + }, + { + path: Routes.dashboard.profile, + element: ( + + + + ), + }, + { + path: Routes.dashboard.processes, + element: ( + + + + ), + loader: async ({ params }) => + await queryClient.ensureQueryData(paginatedElectionsQuery(account, client, params)), + errorElement: , + }, + { + path: Routes.dashboard.team, + element: ( + + + + ), + }, + ], }, ], - }, -] - -export const useDashboardRoutes = () => { - const { client } = useClient() - return { - element: ( - - - - ), - children: DashboardElements(client), } }