Skip to content

Commit

Permalink
Merge branch 'main'
Browse files Browse the repository at this point in the history
  • Loading branch information
cristiano cardelli committed Aug 15, 2024
2 parents 74b9774 + 7e68cc6 commit 901e771
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 17 deletions.
52 changes: 49 additions & 3 deletions src/app/grants/[grantId]/@list/page.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,59 @@
import { dehydrate, HydrationBoundary } from '@tanstack/react-query';

import { getQueryClient } from '@/shared/utils/get-query-client';

import { grantQueryKeys } from '@/grants/core/query-keys';
import { getGranteeDetails } from '@/grants/data/get-grantee-details';
import { getGranteeProject } from '@/grants/data/get-grantee-project';
import { getGranteesList } from '@/grants/data/get-grantees-list';
import { GranteeList } from '@/grants/components/grantee-list';

interface Props {
params: { grantId: string };
}

const ParallelGranteeList = ({}: Props) => {
// TODO: React-Query SSR grantee list
const ParallelGranteeList = async ({ params: { grantId } }: Props) => {
const queryClient = getQueryClient();

const [granteeListResult] = await Promise.all([
// Prefetch list
queryClient.fetchInfiniteQuery({
queryKey: grantQueryKeys.grantees(grantId, ''),
queryFn: async ({ pageParam: page }) =>
getGranteesList({ page, grantId }),
initialPageParam: 1,
}),
]);

// Prefetch data for first item only (default for the page enough for seo)
const grantee = granteeListResult.pages.flatMap((page) => page.data).at(0);
if (grantee) {
// Prefetch grantee details
const promises = [
queryClient.prefetchQuery({
queryKey: grantQueryKeys.grantee(grantee.id),
queryFn: () => getGranteeDetails(grantee.id),
}),
];

// Prefetch first project details
if (grantee.projects.length > 0) {
promises.push(
queryClient.prefetchQuery({
queryKey: grantQueryKeys.project(grantee.projects[0]),
queryFn: () => getGranteeProject(grantee.projects[0]),
}),
);
}

await Promise.all(promises);
}

return <GranteeList />;
return (
<HydrationBoundary state={dehydrate(queryClient)}>
<GranteeList />
</HydrationBoundary>
);
};

export default ParallelGranteeList;
32 changes: 30 additions & 2 deletions src/grants/components/grant-list/use-grant-list.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
import { useEffect } from 'react';
import { useInView } from 'react-intersection-observer';

import { getQueryClient } from '@/shared/utils/get-query-client';

import { grantQueryKeys } from '@/grants/core/query-keys';
import { getGrantDetails } from '@/grants/data/get-grant-details';
import { useGrantListQuery } from '@/grants/hooks/use-grant-list-query';

export const useGrantList = () => {
const { data, error, fetchNextPage, hasNextPage, isPending, isFetching } =
useGrantListQuery();
const queryClient = getQueryClient();

const {
data,
error,
fetchNextPage,
hasNextPage,
isPending,
isFetching,
isSuccess,
} = useGrantListQuery();

// Next page fetch on scroll
const { ref: inViewRef } = useInView({
Expand All @@ -14,6 +28,20 @@ export const useGrantList = () => {
},
});

// Prefetch grant details
useEffect(() => {
if (isSuccess && data) {
const items = data.pages.flatMap((d) => d.data);
for (const item of items) {
const { id } = item;
queryClient.prefetchQuery({
queryKey: grantQueryKeys.details(id),
queryFn: () => getGrantDetails(id),
});
}
}
});

return {
grants: data?.pages.flatMap((d) => d.data) ?? [],
error,
Expand Down
42 changes: 37 additions & 5 deletions src/grants/pages/grant-list-page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,43 @@
import { dehydrate, HydrationBoundary } from '@tanstack/react-query';

import { getQueryClient } from '@/shared/utils/get-query-client';

import { grantQueryKeys } from '@/grants/core/query-keys';
import { getGrantDetails } from '@/grants/data/get-grant-details';
import { getGrantList } from '@/grants/data/get-grant-list';
import { GrantList } from '@/grants/components/grant-list/grant-list';

export const GrantListPage = () => {
// TODO: React-Query SSR grant list
// TODO: Check if need to use search params(filter related), if so need to force dynamic

export const GrantListPage = async () => {
const queryClient = getQueryClient();

const [grantListResult] = await Promise.all([
// Prefetch list
queryClient.fetchInfiniteQuery({
queryKey: grantQueryKeys.list(''),
queryFn: async ({ pageParam }) => getGrantList(pageParam),
initialPageParam: 1,
}),
]);

// Prefetch details for each grant item
await Promise.all(
grantListResult.pages
.flatMap((page) => page.data)
.map(({ id }) =>
queryClient.prefetchQuery({
queryKey: grantQueryKeys.details(id),
queryFn: () => getGrantDetails(id),
}),
),
);

return (
<div className="p-8">
<GrantList />
</div>
<HydrationBoundary state={dehydrate(queryClient)}>
<div className="p-8">
<GrantList />
</div>
</HydrationBoundary>
);
};
14 changes: 7 additions & 7 deletions src/shared/utils/get-query-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ export const getQueryClient = () => {
if (typeof window === 'undefined') {
// Server: always make a new query client
return makeQueryClient();
} else {
// Browser: make a new query client if we don't already have one
// This is very important so we don't re-make a new client if React
// supsends during the initial render. This may not be needed if we
// have a suspense boundary BELOW the creation of the query client
if (!browserQueryClient) browserQueryClient = makeQueryClient();
return browserQueryClient;
}

// Browser: make a new query client if we don't already have one
// This is very important so we don't re-make a new client if React
// supsends during the initial render. This may not be needed if we
// have a suspense boundary BELOW the creation of the query client
if (!browserQueryClient) browserQueryClient = makeQueryClient();
return browserQueryClient;
};

0 comments on commit 901e771

Please sign in to comment.